34 changes: 34 additions & 0 deletions clang/test/SemaCXX/builtin-is-bitwise-cloneable-fsanitize.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux -DSANITIZER_ENABLED -fsanitize=address -fsanitize-address-field-padding=1 %s
// RUN: %clang_cc1 -triple x86_64-unknown-linux %s

struct S {
~S() {}
virtual void foo() {}

int buffer[1];
int other_field = 0;
};

union U {
S s;
};

struct Derived : S {};

static_assert(!__is_trivially_copyable(S));
#ifdef SANITIZER_ENABLED
// Don't allow memcpy when the struct has poisoned padding bits.
// The sanitizer adds posion padding bits to struct S.
static_assert(sizeof(S) > 16);
static_assert(!__is_bitwise_cloneable(S));
static_assert(sizeof(U) == sizeof(S)); // no padding bit for U.
static_assert(!__is_bitwise_cloneable(U));
static_assert(!__is_bitwise_cloneable(S[2]));
static_assert(!__is_bitwise_cloneable(Derived));
#else
static_assert(sizeof(S) == 16);
static_assert(__is_bitwise_cloneable(S));
static_assert(__is_bitwise_cloneable(U));
static_assert(__is_bitwise_cloneable(S[2]));
static_assert(__is_bitwise_cloneable(Derived));
#endif
8 changes: 8 additions & 0 deletions clang/test/SemaCXX/builtin-is-bitwise-cloneable.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
//
struct DynamicClass { virtual int Foo(); };
static_assert(!__is_trivially_copyable(DynamicClass));
static_assert(__is_bitwise_cloneable(DynamicClass));

struct InComplete; // expected-note{{forward declaration}}
static_assert(!__is_bitwise_cloneable(InComplete)); // expected-error{{incomplete type 'InComplete' used in type trait expression}}
4 changes: 2 additions & 2 deletions clang/test/SemaCXX/constexpr-default-arg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ void test_default_arg2() {
}

// Check that multiple CXXDefaultInitExprs don't cause an assertion failure.
struct A { int &&r = 0; };
struct A { int &&r = 0; }; // expected-note 2{{default member initializer}}
struct B { A x, y; };
B b = {}; // expected-no-diagnostics
B b = {}; // expected-warning 2{{lifetime extension of temporary created by aggregate initialization using a default member initializer is not yet supported}}

}
74 changes: 0 additions & 74 deletions clang/test/SemaCXX/cxx11-default-member-initializers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,80 +27,6 @@ class MemInit {
C m = s;
};

namespace std {
typedef decltype(sizeof(int)) size_t;

// libc++'s implementation
template <class _E> class initializer_list {
const _E *__begin_;
size_t __size_;

initializer_list(const _E *__b, size_t __s) : __begin_(__b), __size_(__s) {}

public:
typedef _E value_type;
typedef const _E &reference;
typedef const _E &const_reference;
typedef size_t size_type;

typedef const _E *iterator;
typedef const _E *const_iterator;

initializer_list() : __begin_(nullptr), __size_(0) {}

size_t size() const { return __size_; }
const _E *begin() const { return __begin_; }
const _E *end() const { return __begin_ + __size_; }
};
} // namespace std

#if __cplusplus >= 201703L
namespace test_rebuild {
template <typename T, int> class C {
public:
C(std::initializer_list<T>);
};

template <typename T> using Ptr = __remove_pointer(T) *;
template <typename T> C(T) -> C<Ptr<T>, sizeof(T)>;

class A {
public:
template <typename T1, typename T2> T1 *some_func(T2 &&);
};

struct B : A {
// Test CXXDefaultInitExpr rebuild issue in
// https://github.com/llvm/llvm-project/pull/87933
int *ar = some_func<int>(C{some_func<int>(0)});
B() {}
};

int TestBody_got;
template <int> class Vector {
public:
Vector(std::initializer_list<int>);
};
template <typename... Ts> Vector(Ts...) -> Vector<sizeof...(Ts)>;
class ProgramBuilder {
public:
template <typename T, typename ARGS> int *create(ARGS);
};

struct TypeTest : ProgramBuilder {
int *str_f16 = create<int>(Vector{0});
TypeTest() {}
};
class TypeTest_Element_Test : TypeTest {
void TestBody();
};
void TypeTest_Element_Test::TestBody() {
int *expect = str_f16;
&TestBody_got != expect; // expected-warning {{inequality comparison result unused}}
}
} // namespace test_rebuild
#endif // __cplusplus >= 201703L

#if __cplusplus >= 202002L
// This test ensures cleanup expressions are correctly produced
// in the presence of default member initializers.
Expand Down
6 changes: 4 additions & 2 deletions clang/test/SemaCXX/eval-crashes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ namespace pr33140_0b {
}

namespace pr33140_2 {
struct A { int &&r = 0; };
// FIXME: The declaration of 'b' below should lifetime-extend two int
// temporaries.
struct A { int &&r = 0; }; // expected-note 2{{initializing field 'r' with default member initializer}}
struct B { A x, y; };
B b = {};
B b = {}; // expected-warning 2{{lifetime extension of temporary created by aggregate initialization using a default member initializer is not yet supported}}
}

namespace pr33140_3 {
Expand Down
1 change: 1 addition & 0 deletions clang/test/SemaCXX/nullptr_in_arithmetic_ops.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -Wno-tautological-pointer-compare -fblocks -std=c++11 -verify %s
// RUN: %clang_cc1 -fsyntax-only -Wno-tautological-pointer-compare -fblocks -std=c++11 -verify %s -fexperimental-new-constant-interpreter

void foo() {
int a;
Expand Down
9 changes: 9 additions & 0 deletions clang/test/SemaObjCXX/arc-type-traits.mm
Original file line number Diff line number Diff line change
Expand Up @@ -221,3 +221,12 @@
TRAIT_IS_TRUE(__is_trivially_relocatable, HasStrong);
TRAIT_IS_FALSE(__is_trivially_relocatable, HasWeak);
TRAIT_IS_TRUE(__is_trivially_relocatable, HasUnsafeUnretained);

// __is_bitwise_cloneable
TRAIT_IS_FALSE(__is_bitwise_cloneable, __strong id);
TRAIT_IS_FALSE(__is_bitwise_cloneable, __weak id);
TRAIT_IS_FALSE(__is_bitwise_cloneable, __autoreleasing id);
TRAIT_IS_TRUE(__is_trivial, __unsafe_unretained id);
TRAIT_IS_FALSE(__is_bitwise_cloneable, HasStrong);
TRAIT_IS_FALSE(__is_bitwise_cloneable, HasWeak);
TRAIT_IS_TRUE(__is_bitwise_cloneable, HasUnsafeUnretained);
6 changes: 4 additions & 2 deletions clang/test/SemaOpenCL/builtins-amdgcn-gfx940-err.cl
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@

typedef unsigned int u32;

void test_global_load_lds_unsupported_size(global u32* src, local u32 *dst, u32 size) {
__builtin_amdgcn_global_load_lds(src, dst, size, /*offset=*/0, /*aux=*/0); // expected-error{{expression is not an integer constant expression}}
void test_global_load_lds_unsupported_size(global u32* src, local u32 *dst, u32 size, u32 offset, u32 aux) {
__builtin_amdgcn_global_load_lds(src, dst, size, /*offset=*/0, /*aux=*/0); // expected-error{{argument to '__builtin_amdgcn_global_load_lds' must be a constant integer}}
__builtin_amdgcn_global_load_lds(src, dst, /*size=*/4, offset, /*aux=*/0); // expected-error{{argument to '__builtin_amdgcn_global_load_lds' must be a constant integer}}
__builtin_amdgcn_global_load_lds(src, dst, /*size=*/4, /*offset=*/0, aux); // expected-error{{argument to '__builtin_amdgcn_global_load_lds' must be a constant integer}}
__builtin_amdgcn_global_load_lds(src, dst, /*size=*/5, /*offset=*/0, /*aux=*/0); // expected-error{{invalid size value}} expected-note {{size must be 1, 2, or 4}}
__builtin_amdgcn_global_load_lds(src, dst, /*size=*/0, /*offset=*/0, /*aux=*/0); // expected-error{{invalid size value}} expected-note {{size must be 1, 2, or 4}}
__builtin_amdgcn_global_load_lds(src, dst, /*size=*/3, /*offset=*/0, /*aux=*/0); // expected-error{{invalid size value}} expected-note {{size must be 1, 2, or 4}}
Expand Down
46 changes: 46 additions & 0 deletions clang/unittests/AST/Interp/toAPValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,49 @@ TEST(ToAPValue, FunctionPointersC) {
ASSERT_EQ(I, 17);
}
}

TEST(ToAPValue, MemberPointers) {
constexpr char Code[] = "struct S {\n"
" int m, n;\n"
"};\n"
"constexpr int S::*pm = &S::m;\n"
"constexpr int S::*nn = nullptr;\n";

auto AST = tooling::buildASTFromCodeWithArgs(
Code, {"-fexperimental-new-constant-interpreter"});

auto &Ctx = AST->getASTContext().getInterpContext();
Program &Prog = Ctx.getProgram();

auto getDecl = [&](const char *Name) -> const ValueDecl * {
auto Nodes =
match(valueDecl(hasName(Name)).bind("var"), AST->getASTContext());
assert(Nodes.size() == 1);
const auto *D = Nodes[0].getNodeAs<ValueDecl>("var");
assert(D);
return D;
};

auto getGlobalPtr = [&](const char *Name) -> Pointer {
const VarDecl *D = cast<VarDecl>(getDecl(Name));
return Prog.getPtrGlobal(*Prog.getGlobal(D));
};

{
const Pointer &GP = getGlobalPtr("pm");
ASSERT_TRUE(GP.isLive());
const MemberPointer &FP = GP.deref<MemberPointer>();
APValue A = FP.toAPValue();
ASSERT_EQ(A.getMemberPointerDecl(), getDecl("m"));
ASSERT_EQ(A.getKind(), APValue::MemberPointer);
}

{
const Pointer &GP = getGlobalPtr("nn");
ASSERT_TRUE(GP.isLive());
const MemberPointer &NP = GP.deref<MemberPointer>();
ASSERT_TRUE(NP.isZero());
APValue A = NP.toAPValue();
ASSERT_EQ(A.getKind(), APValue::MemberPointer);
}
}
8 changes: 8 additions & 0 deletions clang/unittests/Format/FormatTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9241,6 +9241,14 @@ TEST_F(FormatTest, AlignsAfterOpenBracket) {
" b));",
Style);

Style.ColumnLimit = 30;
verifyFormat("for (int foo = 0; foo < FOO;\n"
" ++foo) {\n"
" bar(foo);\n"
"}",
Style);
Style.ColumnLimit = 80;

Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak;
Style.BinPackArguments = false;
Style.BinPackParameters = false;
Expand Down
2 changes: 1 addition & 1 deletion clang/www/cxx_dr_status.html
Original file line number Diff line number Diff line change
Expand Up @@ -10698,7 +10698,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/1815.html">1815</a></td>
<td>CD4</td>
<td>Lifetime extension in aggregate initialization</td>
<td class="unreleased" align="center">Clang 19</td>
<td class="none" align="center">No</td>
</tr>
<tr id="1816">
<td><a href="https://cplusplus.github.io/CWG/issues/1816.html">1816</a></td>
Expand Down
8 changes: 4 additions & 4 deletions compiler-rt/lib/sanitizer_common/sanitizer_bitvector.h
Original file line number Diff line number Diff line change
Expand Up @@ -321,23 +321,23 @@ class TwoLevelBitVector {
};

private:
void check(uptr idx) const { CHECK_LE(idx, size()); }
void check(uptr idx) const { CHECK_LT(idx, size()); }

uptr idx0(uptr idx) const {
uptr res = idx / (BV::kSize * BV::kSize);
CHECK_LE(res, kLevel1Size);
CHECK_LT(res, kLevel1Size);
return res;
}

uptr idx1(uptr idx) const {
uptr res = (idx / BV::kSize) % BV::kSize;
CHECK_LE(res, BV::kSize);
CHECK_LT(res, BV::kSize);
return res;
}

uptr idx2(uptr idx) const {
uptr res = idx % BV::kSize;
CHECK_LE(res, BV::kSize);
CHECK_LT(res, BV::kSize);
return res;
}

Expand Down
16 changes: 14 additions & 2 deletions compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@
# undef MAP_NORESERVE
# define MAP_NORESERVE 0
extern const Elf_Auxinfo *__elf_aux_vector;
extern "C" int __sys_sigaction(int signum, const struct sigaction *act,
struct sigaction *oldact);
# endif

# if SANITIZER_NETBSD
Expand Down Expand Up @@ -93,12 +95,22 @@ SANITIZER_WEAK_ATTRIBUTE int real_sigaction(int signum, const void *act,
void *oldact);

int internal_sigaction(int signum, const void *act, void *oldact) {
# if !SANITIZER_GO
# if SANITIZER_FREEBSD
// On FreeBSD, call the sigaction syscall directly (part of libsys in FreeBSD
// 15) since the libc version goes via a global interposing table. Due to
// library initialization order the table can be relocated after the call to
// InitializeDeadlySignals() which then crashes when dereferencing the
// uninitialized pointer in libc.
return __sys_sigaction(signum, (const struct sigaction *)act,
(struct sigaction *)oldact);
# else
# if !SANITIZER_GO
if (&real_sigaction)
return real_sigaction(signum, act, oldact);
# endif
# endif
return sigaction(signum, (const struct sigaction *)act,
(struct sigaction *)oldact);
# endif
}

void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,17 @@ const uptr kAllocatorSpace = ~(uptr)0;
const uptr kAllocatorSize = 0x2000000000ULL; // 128G.
static const u64 kAddressSpaceSize = 1ULL << 38;
typedef VeryDenseSizeClassMap SizeClassMap;
#else
# elif SANITIZER_APPLE
static const uptr kAllocatorSpace = 0x700000000000ULL;
static const uptr kAllocatorSize = 0x010000000000ULL; // 1T.
static const u64 kAddressSpaceSize = 1ULL << 47;
typedef DefaultSizeClassMap SizeClassMap;
#endif
# else
static const uptr kAllocatorSpace = 0x500000000000ULL;
static const uptr kAllocatorSize = 0x010000000000ULL; // 1T.
static const u64 kAddressSpaceSize = 1ULL << 47;
typedef DefaultSizeClassMap SizeClassMap;
# endif

template <typename AddressSpaceViewTy>
struct AP64 { // Allocator Params. Short name for shorter demangled names..
Expand Down
19 changes: 19 additions & 0 deletions compiler-rt/test/dfsan/sscanf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// RUN: %clang_dfsan %s -o %t && %run %t
// XFAIL: *

#include <assert.h>
#include <stdio.h>

int main(int argc, char *argv[]) {
char buf[256] = "10000000000-100000000000 rw-p 00000000 00:00 0";
long rss = 0;
// This test exposes a bug in DFSan's sscanf, that leads to flakiness
// in release_shadow_space.c (see
// https://github.com/llvm/llvm-project/issues/91287)
if (sscanf(buf, "Garbage text before, %ld, Garbage text after", &rss) == 1) {
printf("Error: matched %ld\n", rss);
return 1;
}

return 0;
}
1 change: 1 addition & 0 deletions flang/cmake/modules/AddFlangOffloadRuntime.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ macro(enable_omp_offload_compilation files)
"gfx908;gfx90a;gfx90c;gfx940;gfx1010;gfx1030"
"gfx1031;gfx1032;gfx1033;gfx1034;gfx1035;gfx1036"
"gfx1100;gfx1101;gfx1102;gfx1103;gfx1150;gfx1151"
"gfx1152"
)
set(all_nvptx_architectures
"sm_35;sm_37;sm_50;sm_52;sm_53;sm_60;sm_61;sm_62"
Expand Down
31 changes: 31 additions & 0 deletions flang/docs/Intrinsics.md
Original file line number Diff line number Diff line change
Expand Up @@ -967,4 +967,35 @@ program test_etime
print *, tarray(1)
print *, tarray(2)
end program test_etime
```

### Non-Standard Intrinsics: GETCWD

#### Description
`GETCWD(C, STATUS)` returns current working directory.

This intrinsic is provided in both subroutine and function forms; however, only one form can be used in any given program unit.

*C* and *STATUS* are `INTENT(OUT)` and provide the following:

| | |
|------------|---------------------------------------------------------------------------------------------------|
| `C` | Current work directory. The type shall be `CHARACTER` and of default kind. |
| `STATUS` | (Optional) Status flag. Returns 0 on success, a system specific and nonzero error code otherwise. The type shall be `INTEGER` and of a kind greater or equal to 4. |

#### Usage and Info

- **Standard:** GNU extension
- **Class:** Subroutine, function
- **Syntax:** `CALL GETCWD(C, STATUS)`, `STATUS = GETCWD(C)`

#### Example
```Fortran
PROGRAM example_getcwd
CHARACTER(len=255) :: cwd
INTEGER :: status
CALL getcwd(cwd, status)
PRINT *, cwd
PRINT *, status
END PROGRAM
```
2 changes: 2 additions & 0 deletions flang/include/flang/Optimizer/Builder/IntrinsicCall.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,8 @@ struct IntrinsicLibrary {
mlir::Value genFloor(mlir::Type, llvm::ArrayRef<mlir::Value>);
mlir::Value genFraction(mlir::Type resultType,
mlir::ArrayRef<mlir::Value> args);
fir::ExtendedValue genGetCwd(std::optional<mlir::Type> resultType,
llvm::ArrayRef<fir::ExtendedValue> args);
void genGetCommand(mlir::ArrayRef<fir::ExtendedValue> args);
mlir::Value genGetPID(mlir::Type resultType,
llvm::ArrayRef<mlir::Value> args);
Expand Down
5 changes: 5 additions & 0 deletions flang/include/flang/Optimizer/Builder/Runtime/Command.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,10 @@ mlir::Value genGetEnvVariable(fir::FirOpBuilder &, mlir::Location,
mlir::Value length, mlir::Value trimName,
mlir::Value errmsg);

/// Generate a call to the GetCwd runtime function which implements
/// the GETCWD intrinsic.
mlir::Value genGetCwd(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value c);

} // namespace fir::runtime
#endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_COMMAND_H
30 changes: 30 additions & 0 deletions flang/include/flang/Optimizer/Dialect/FIRAttr.td
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,36 @@ def fir_BoxFieldAttr : I32EnumAttr<
let cppNamespace = "fir";
}

def fir_ReduceOperationEnum : I32BitEnumAttr<"ReduceOperationEnum",
"intrinsic operations and functions supported by DO CONCURRENT REDUCE",
[
I32BitEnumAttrCaseBit<"Add", 0, "add">,
I32BitEnumAttrCaseBit<"Multiply", 1, "multiply">,
I32BitEnumAttrCaseBit<"AND", 2, "and">,
I32BitEnumAttrCaseBit<"OR", 3, "or">,
I32BitEnumAttrCaseBit<"EQV", 4, "eqv">,
I32BitEnumAttrCaseBit<"NEQV", 5, "neqv">,
I32BitEnumAttrCaseBit<"MAX", 6, "max">,
I32BitEnumAttrCaseBit<"MIN", 7, "min">,
I32BitEnumAttrCaseBit<"IAND", 8, "iand">,
I32BitEnumAttrCaseBit<"IOR", 9, "ior">,
I32BitEnumAttrCaseBit<"EIOR", 10, "eior">
]> {
let separator = ", ";
let cppNamespace = "::fir";
let printBitEnumPrimaryGroups = 1;
}

def fir_ReduceAttr : fir_Attr<"Reduce"> {
let mnemonic = "reduce_attr";

let parameters = (ins
"ReduceOperationEnum":$reduce_operation
);

let assemblyFormat = "`<` $reduce_operation `>`";
}

// mlir::SideEffects::Resource for modelling operations which add debugging information
def DebuggingResource : Resource<"::fir::DebuggingResource">;

Expand Down
35 changes: 27 additions & 8 deletions flang/include/flang/Optimizer/Dialect/FIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -2125,8 +2125,8 @@ class region_Op<string mnemonic, list<Trait> traits = []> :
let hasVerifier = 1;
}

def fir_DoLoopOp : region_Op<"do_loop",
[DeclareOpInterfaceMethods<LoopLikeOpInterface,
def fir_DoLoopOp : region_Op<"do_loop", [AttrSizedOperandSegments,
DeclareOpInterfaceMethods<LoopLikeOpInterface,
["getYieldedValuesMutable"]>]> {
let summary = "generalized loop operation";
let description = [{
Expand Down Expand Up @@ -2156,9 +2156,11 @@ def fir_DoLoopOp : region_Op<"do_loop",
Index:$lowerBound,
Index:$upperBound,
Index:$step,
Variadic<AnyType>:$reduceOperands,
Variadic<AnyType>:$initArgs,
OptionalAttr<UnitAttr>:$unordered,
OptionalAttr<UnitAttr>:$finalValue
OptionalAttr<UnitAttr>:$finalValue,
OptionalAttr<ArrayAttr>:$reduceAttrs
);
let results = (outs Variadic<AnyType>:$results);
let regions = (region SizedRegion<1>:$region);
Expand All @@ -2169,6 +2171,8 @@ def fir_DoLoopOp : region_Op<"do_loop",
"mlir::Value":$step, CArg<"bool", "false">:$unordered,
CArg<"bool", "false">:$finalCountValue,
CArg<"mlir::ValueRange", "std::nullopt">:$iterArgs,
CArg<"mlir::ValueRange", "std::nullopt">:$reduceOperands,
CArg<"llvm::ArrayRef<mlir::Attribute>", "{}">:$reduceAttrs,
CArg<"llvm::ArrayRef<mlir::NamedAttribute>", "{}">:$attributes)>
];

Expand All @@ -2181,11 +2185,12 @@ def fir_DoLoopOp : region_Op<"do_loop",
return getBody()->getArguments().drop_front();
}
mlir::Operation::operand_range getIterOperands() {
return getOperands().drop_front(getNumControlOperands());
return getOperands()
.drop_front(getNumControlOperands() + getNumReduceOperands());
}
llvm::MutableArrayRef<mlir::OpOperand> getInitsMutable() {
return
getOperation()->getOpOperands().drop_front(getNumControlOperands());
return getOperation()->getOpOperands()
.drop_front(getNumControlOperands() + getNumReduceOperands());
}

void setLowerBound(mlir::Value bound) { (*this)->setOperand(0, bound); }
Expand All @@ -2200,11 +2205,25 @@ def fir_DoLoopOp : region_Op<"do_loop",
unsigned getNumControlOperands() { return 3; }
/// Does the operation hold operands for loop-carried values
bool hasIterOperands() {
return (*this)->getNumOperands() > getNumControlOperands();
return getNumIterOperands() > 0;
}
/// Does the operation hold operands for reduction variables
bool hasReduceOperands() {
return getNumReduceOperands() > 0;
}
/// Get Number of variadic operands
unsigned getNumOperands(unsigned idx) {
auto segments = (*this)->getAttrOfType<mlir::DenseI32ArrayAttr>(
getOperandSegmentSizeAttr());
return static_cast<unsigned>(segments[idx]);
}
// Get Number of reduction operands
unsigned getNumReduceOperands() {
return getNumOperands(3);
}
/// Get Number of loop-carried values
unsigned getNumIterOperands() {
return (*this)->getNumOperands() - getNumControlOperands();
return getNumOperands(4);
}

/// Get the body of the loop
Expand Down
3 changes: 0 additions & 3 deletions flang/include/flang/Optimizer/Transforms/Passes.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,6 @@ std::unique_ptr<mlir::Pass> createAffineDemotionPass();
std::unique_ptr<mlir::Pass>
createArrayValueCopyPass(fir::ArrayValueCopyOptions options = {});
std::unique_ptr<mlir::Pass> createCFGConversionPassWithNSW();
std::unique_ptr<mlir::Pass> createExternalNameConversionPass();
std::unique_ptr<mlir::Pass>
createExternalNameConversionPass(bool appendUnderscore);
std::unique_ptr<mlir::Pass> createMemDataFlowOptPass();
std::unique_ptr<mlir::Pass> createPromoteToAffinePass();
std::unique_ptr<mlir::Pass>
Expand Down
1 change: 0 additions & 1 deletion flang/include/flang/Optimizer/Transforms/Passes.td
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@ def ExternalNameConversion : Pass<"external-name-interop", "mlir::ModuleOp"> {
let description = [{
Demangle FIR internal name and mangle them for external interoperability.
}];
let constructor = "::fir::createExternalNameConversionPass()";
let options = [
Option<"appendUnderscoreOpt", "append-underscore",
"bool", /*default=*/"true",
Expand Down
4 changes: 4 additions & 0 deletions flang/include/flang/Runtime/command.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ std::int32_t RTNAME(GetEnvVariable)(const Descriptor &name,
const Descriptor *value = nullptr, const Descriptor *length = nullptr,
bool trim_name = true, const Descriptor *errmsg = nullptr,
const char *sourceFile = nullptr, int line = 0);

// Calls getcwd()
std::int32_t RTNAME(GetCwd)(
const Descriptor &cwd, const char *sourceFile, int line);
}
} // namespace Fortran::runtime

Expand Down
5 changes: 5 additions & 0 deletions flang/include/flang/Runtime/magic-numbers.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ Additional status code for a bad pointer DEALLOCATE.
#endif
#define FORTRAN_RUNTIME_STAT_BAD_POINTER_DEALLOCATION 110

#if 0
Status codes for GETCWD.
#endif
#define FORTRAN_RUNTIME_STAT_MISSING_CWD 111

#if 0
ieee_class_type values
The sequence is that of F18 Clause 17.2p3, but nothing depends on that.
Expand Down
5 changes: 2 additions & 3 deletions flang/include/flang/Tools/CLOptions.inc
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,8 @@ inline void addBoxedProcedurePass(mlir::PassManager &pm) {

inline void addExternalNameConversionPass(
mlir::PassManager &pm, bool appendUnderscore = true) {
addPassConditionally(pm, disableExternalNameConversion, [&]() {
return fir::createExternalNameConversionPass(appendUnderscore);
});
addPassConditionally(pm, disableExternalNameConversion,
[&]() { return fir::createExternalNameConversion({appendUnderscore}); });
}

// Use inliner extension point callback to register the default inliner pass.
Expand Down
12 changes: 11 additions & 1 deletion flang/lib/Evaluate/intrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,10 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
{"gamma", {{"x", SameReal}}, SameReal},
{"get_team", {{"level", DefaultInt, Rank::scalar, Optionality::optional}},
TeamType, Rank::scalar, IntrinsicClass::transformationalFunction},
{"getcwd",
{{"c", DefaultChar, Rank::scalar, Optionality::required,
common::Intent::Out}},
TypePattern{IntType, KindCode::greaterOrEqualToKind, 4}},
{"getpid", {}, DefaultInt},
{"huge",
{{"x", SameIntOrReal, Rank::anyOrAssumedRank, Optionality::required,
Expand Down Expand Up @@ -1406,6 +1410,12 @@ static const IntrinsicInterface intrinsicSubroutine[]{
{"errmsg", DefaultChar, Rank::scalar, Optionality::optional,
common::Intent::InOut}},
{}, Rank::elemental, IntrinsicClass::impureSubroutine},
{"getcwd",
{{"c", DefaultChar, Rank::scalar, Optionality::required,
common::Intent::Out},
{"status", TypePattern{IntType, KindCode::greaterOrEqualToKind, 4},
Rank::scalar, Optionality::optional, common::Intent::Out}},
{}, Rank::elemental, IntrinsicClass::impureSubroutine},
{"move_alloc",
{{"from", SameType, Rank::known, Optionality::required,
common::Intent::InOut},
Expand Down Expand Up @@ -2574,7 +2584,7 @@ bool IntrinsicProcTable::Implementation::IsDualIntrinsic(
const std::string &name) const {
// Collection for some intrinsics with function and subroutine form,
// in order to pass the semantic check.
static const std::string dualIntrinsic[]{{"etime"}};
static const std::string dualIntrinsic[]{{"etime"}, {"getcwd"}};

return std::find_if(std::begin(dualIntrinsic), std::end(dualIntrinsic),
[&name](const std::string &dualName) {
Expand Down
50 changes: 42 additions & 8 deletions flang/lib/Lower/OpenMP/Clauses.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,30 +36,64 @@ struct TypeTy : public evaluate::SomeType {
bool operator==(const TypeTy &t) const { return true; }
};

using IdTy = semantics::Symbol *;
template <typename ExprTy>
struct IdTyTemplate {
// "symbol" is always non-null for id's of actual objects.
Fortran::semantics::Symbol *symbol;
std::optional<ExprTy> designator;

bool operator==(const IdTyTemplate &other) const {
// If symbols are different, then the objects are different.
if (symbol != other.symbol)
return false;
if (symbol == nullptr)
return true;
// Equal symbols don't necessarily indicate identical objects,
// for example, a derived object component may use a single symbol,
// which will refer to different objects for different designators,
// e.g. a%c and b%c.
return designator == other.designator;
}

operator bool() const { return symbol != nullptr; }
};

using ExprTy = SomeExpr;

template <typename T>
using List = tomp::ListT<T>;
} // namespace Fortran::lower::omp

// Specialization of the ObjectT template
namespace tomp::type {
template <>
struct ObjectT<Fortran::lower::omp::IdTy, Fortran::lower::omp::ExprTy> {
using IdTy = Fortran::lower::omp::IdTy;
struct ObjectT<Fortran::lower::omp::IdTyTemplate<Fortran::lower::omp::ExprTy>,
Fortran::lower::omp::ExprTy> {
using IdTy = Fortran::lower::omp::IdTyTemplate<Fortran::lower::omp::ExprTy>;
using ExprTy = Fortran::lower::omp::ExprTy;

IdTy id() const { return symbol; }
Fortran::semantics::Symbol *sym() const { return symbol; }
const std::optional<ExprTy> &ref() const { return designator; }
IdTy id() const { return identity; }
Fortran::semantics::Symbol *sym() const { return identity.symbol; }
const std::optional<ExprTy> &ref() const { return identity.designator; }

IdTy symbol;
std::optional<ExprTy> designator;
IdTy identity;
};
} // namespace tomp::type

namespace Fortran::lower::omp {
using IdTy = IdTyTemplate<ExprTy>;
}

namespace std {
template <>
struct hash<Fortran::lower::omp::IdTy> {
size_t operator()(const Fortran::lower::omp::IdTy &id) const {
return static_cast<size_t>(reinterpret_cast<uintptr_t>(id.symbol));
}
};
} // namespace std

namespace Fortran::lower::omp {
using Object = tomp::ObjectT<IdTy, ExprTy>;
using ObjectList = tomp::ObjectListT<IdTy, ExprTy>;

Expand Down
4 changes: 3 additions & 1 deletion flang/lib/Lower/OpenMP/DataSharingProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ class DataSharingProcessor {
void Post(const T &) {}

bool Pre(const parser::OpenMPConstruct &omp) {
currentConstruct = &omp;
// Skip constructs that may not have privatizations.
if (!std::holds_alternative<parser::OpenMPCriticalConstruct>(omp.u))
currentConstruct = &omp;
return true;
}

Expand Down
2 changes: 1 addition & 1 deletion flang/lib/Lower/OpenMP/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ void addChildIndexAndMapToParent(
std::map<const semantics::Symbol *,
llvm::SmallVector<OmpMapMemberIndicesData>> &parentMemberIndices,
mlir::omp::MapInfoOp &mapOp, semantics::SemanticsContext &semaCtx) {
std::optional<evaluate::DataRef> dataRef = ExtractDataRef(object.designator);
std::optional<evaluate::DataRef> dataRef = ExtractDataRef(object.ref());
assert(dataRef.has_value() &&
"DataRef could not be extracted during mapping of derived type "
"cannot proceed");
Expand Down
35 changes: 35 additions & 0 deletions flang/lib/Optimizer/Builder/IntrinsicCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,10 @@ static constexpr IntrinsicHandler handlers[]{
{"trim_name", asAddr, handleDynamicOptional},
{"errmsg", asBox, handleDynamicOptional}}},
/*isElemental=*/false},
{"getcwd",
&I::genGetCwd,
{{{"c", asBox}, {"status", asAddr, handleDynamicOptional}}},
/*isElemental=*/false},
{"getpid", &I::genGetPID},
{"iachar", &I::genIchar},
{"iall",
Expand Down Expand Up @@ -3476,6 +3480,37 @@ mlir::Value IntrinsicLibrary::genFraction(mlir::Type resultType,
fir::runtime::genFraction(builder, loc, fir::getBase(args[0])));
}

// GETCWD
fir::ExtendedValue
IntrinsicLibrary::genGetCwd(std::optional<mlir::Type> resultType,
llvm::ArrayRef<fir::ExtendedValue> args) {
assert((args.size() == 1 && resultType.has_value()) ||
(args.size() >= 1 && !resultType.has_value()));

mlir::Value cwd = fir::getBase(args[0]);
mlir::Value statusValue = fir::runtime::genGetCwd(builder, loc, cwd);

if (resultType.has_value()) {
// Function form, return status.
return statusValue;
} else {
// Subroutine form, store status and return none.
const fir::ExtendedValue &status = args[1];
if (!isStaticallyAbsent(status)) {
mlir::Value statusAddr = fir::getBase(status);
mlir::Value statusIsPresentAtRuntime =
builder.genIsNotNullAddr(loc, statusAddr);
builder.genIfThen(loc, statusIsPresentAtRuntime)
.genThen([&]() {
builder.createStoreWithConvert(loc, statusValue, statusAddr);
})
.end();
}
}

return {};
}

// GET_COMMAND
void IntrinsicLibrary::genGetCommand(llvm::ArrayRef<fir::ExtendedValue> args) {
assert(args.size() == 4);
Expand Down
13 changes: 13 additions & 0 deletions flang/lib/Optimizer/Builder/Runtime/Command.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,16 @@ mlir::Value fir::runtime::genGetEnvVariable(fir::FirOpBuilder &builder,
sourceFile, sourceLine);
return builder.create<fir::CallOp>(loc, runtimeFunc, args).getResult(0);
}

mlir::Value fir::runtime::genGetCwd(fir::FirOpBuilder &builder,
mlir::Location loc, mlir::Value cwd) {
mlir::func::FuncOp func =
fir::runtime::getRuntimeFunc<mkRTKey(GetCwd)>(loc, builder);
auto runtimeFuncTy = func.getFunctionType();
mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc);
mlir::Value sourceLine =
fir::factory::locationToLineNo(builder, loc, runtimeFuncTy.getInput(2));
llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
builder, loc, runtimeFuncTy, cwd, sourceFile, sourceLine);
return builder.create<fir::CallOp>(loc, func, args).getResult(0);
}
4 changes: 2 additions & 2 deletions flang/lib/Optimizer/Dialect/FIRAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,6 @@ void fir::printFirAttribute(FIROpsDialect *dialect, mlir::Attribute attr,

void FIROpsDialect::registerAttributes() {
addAttributes<ClosedIntervalAttr, ExactTypeAttr, FortranVariableFlagsAttr,
LowerBoundAttr, PointIntervalAttr, RealAttr, SubclassAttr,
UpperBoundAttr>();
LowerBoundAttr, PointIntervalAttr, RealAttr, ReduceAttr,
SubclassAttr, UpperBoundAttr>();
}
73 changes: 66 additions & 7 deletions flang/lib/Optimizer/Dialect/FIROps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2456,9 +2456,16 @@ void fir::DoLoopOp::build(mlir::OpBuilder &builder,
mlir::OperationState &result, mlir::Value lb,
mlir::Value ub, mlir::Value step, bool unordered,
bool finalCountValue, mlir::ValueRange iterArgs,
mlir::ValueRange reduceOperands,
llvm::ArrayRef<mlir::Attribute> reduceAttrs,
llvm::ArrayRef<mlir::NamedAttribute> attributes) {
result.addOperands({lb, ub, step});
result.addOperands(reduceOperands);
result.addOperands(iterArgs);
result.addAttribute(getOperandSegmentSizeAttr(),
builder.getDenseI32ArrayAttr(
{1, 1, 1, static_cast<int32_t>(reduceOperands.size()),
static_cast<int32_t>(iterArgs.size())}));
if (finalCountValue) {
result.addTypes(builder.getIndexType());
result.addAttribute(getFinalValueAttrName(result.name),
Expand All @@ -2477,6 +2484,9 @@ void fir::DoLoopOp::build(mlir::OpBuilder &builder,
if (unordered)
result.addAttribute(getUnorderedAttrName(result.name),
builder.getUnitAttr());
if (!reduceAttrs.empty())
result.addAttribute(getReduceAttrsAttrName(result.name),
builder.getArrayAttr(reduceAttrs));
result.addAttributes(attributes);
}

Expand All @@ -2502,24 +2512,51 @@ mlir::ParseResult fir::DoLoopOp::parse(mlir::OpAsmParser &parser,
if (mlir::succeeded(parser.parseOptionalKeyword("unordered")))
result.addAttribute("unordered", builder.getUnitAttr());

// Parse the reduction arguments.
llvm::SmallVector<mlir::OpAsmParser::UnresolvedOperand> reduceOperands;
llvm::SmallVector<mlir::Type> reduceArgTypes;
if (succeeded(parser.parseOptionalKeyword("reduce"))) {
// Parse reduction attributes and variables.
llvm::SmallVector<ReduceAttr> attributes;
if (failed(parser.parseCommaSeparatedList(
mlir::AsmParser::Delimiter::Paren, [&]() {
if (parser.parseAttribute(attributes.emplace_back()) ||
parser.parseArrow() ||
parser.parseOperand(reduceOperands.emplace_back()) ||
parser.parseColonType(reduceArgTypes.emplace_back()))
return mlir::failure();
return mlir::success();
})))
return mlir::failure();
// Resolve input operands.
for (auto operand_type : llvm::zip(reduceOperands, reduceArgTypes))
if (parser.resolveOperand(std::get<0>(operand_type),
std::get<1>(operand_type), result.operands))
return mlir::failure();
llvm::SmallVector<mlir::Attribute> arrayAttr(attributes.begin(),
attributes.end());
result.addAttribute(getReduceAttrsAttrName(result.name),
builder.getArrayAttr(arrayAttr));
}

// Parse the optional initial iteration arguments.
llvm::SmallVector<mlir::OpAsmParser::Argument> regionArgs;
llvm::SmallVector<mlir::OpAsmParser::UnresolvedOperand> operands;
llvm::SmallVector<mlir::OpAsmParser::UnresolvedOperand> iterOperands;
llvm::SmallVector<mlir::Type> argTypes;
bool prependCount = false;
regionArgs.push_back(inductionVariable);

if (succeeded(parser.parseOptionalKeyword("iter_args"))) {
// Parse assignment list and results type list.
if (parser.parseAssignmentList(regionArgs, operands) ||
if (parser.parseAssignmentList(regionArgs, iterOperands) ||
parser.parseArrowTypeList(result.types))
return mlir::failure();
if (result.types.size() == operands.size() + 1)
if (result.types.size() == iterOperands.size() + 1)
prependCount = true;
// Resolve input operands.
llvm::ArrayRef<mlir::Type> resTypes = result.types;
for (auto operand_type :
llvm::zip(operands, prependCount ? resTypes.drop_front() : resTypes))
for (auto operand_type : llvm::zip(
iterOperands, prependCount ? resTypes.drop_front() : resTypes))
if (parser.resolveOperand(std::get<0>(operand_type),
std::get<1>(operand_type), result.operands))
return mlir::failure();
Expand All @@ -2530,6 +2567,12 @@ mlir::ParseResult fir::DoLoopOp::parse(mlir::OpAsmParser &parser,
prependCount = true;
}

// Set the operandSegmentSizes attribute
result.addAttribute(getOperandSegmentSizeAttr(),
builder.getDenseI32ArrayAttr(
{1, 1, 1, static_cast<int32_t>(reduceOperands.size()),
static_cast<int32_t>(iterOperands.size())}));

if (parser.parseOptionalAttrDictWithKeyword(result.attributes))
return mlir::failure();

Expand Down Expand Up @@ -2606,6 +2649,10 @@ mlir::LogicalResult fir::DoLoopOp::verify() {

i++;
}
auto reduceAttrs = getReduceAttrsAttr();
if (getNumReduceOperands() != (reduceAttrs ? reduceAttrs.size() : 0))
return emitOpError(
"mismatch in number of reduction variables and reduction attributes");
return mlir::success();
}

Expand All @@ -2615,6 +2662,17 @@ void fir::DoLoopOp::print(mlir::OpAsmPrinter &p) {
<< getUpperBound() << " step " << getStep();
if (getUnordered())
p << " unordered";
if (hasReduceOperands()) {
p << " reduce(";
auto attrs = getReduceAttrsAttr();
auto operands = getReduceOperands();
llvm::interleaveComma(llvm::zip(attrs, operands), p, [&](auto it) {
p << std::get<0>(it) << " -> " << std::get<1>(it) << " : "
<< std::get<1>(it).getType();
});
p << ')';
printBlockTerminators = true;
}
if (hasIterOperands()) {
p << " iter_args(";
auto regionArgs = getRegionIterArgs();
Expand All @@ -2628,8 +2686,9 @@ void fir::DoLoopOp::print(mlir::OpAsmPrinter &p) {
p << " -> " << getResultTypes();
printBlockTerminators = true;
}
p.printOptionalAttrDictWithKeyword((*this)->getAttrs(),
{"unordered", "finalValue"});
p.printOptionalAttrDictWithKeyword(
(*this)->getAttrs(),
{"unordered", "finalValue", "reduceAttrs", "operandSegmentSizes"});
p << ' ';
p.printRegion(getRegion(), /*printEntryBlockArgs=*/false,
printBlockTerminators);
Expand Down
23 changes: 4 additions & 19 deletions flang/lib/Optimizer/Transforms/ExternalNameConversion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,25 +45,18 @@ namespace {
class ExternalNameConversionPass
: public fir::impl::ExternalNameConversionBase<ExternalNameConversionPass> {
public:
ExternalNameConversionPass(bool appendUnderscoring)
: appendUnderscores(appendUnderscoring) {}

ExternalNameConversionPass() { usePassOpt = true; }
using ExternalNameConversionBase<
ExternalNameConversionPass>::ExternalNameConversionBase;

mlir::ModuleOp getModule() { return getOperation(); }
void runOnOperation() override;

private:
bool appendUnderscores;
bool usePassOpt = false;
};
} // namespace

void ExternalNameConversionPass::runOnOperation() {
auto op = getOperation();
auto *context = &getContext();

appendUnderscores = (usePassOpt) ? appendUnderscoreOpt : appendUnderscores;
llvm::DenseMap<mlir::StringAttr, mlir::FlatSymbolRefAttr> remappings;
// Update names of external Fortran functions and names of Common Block
// globals.
Expand All @@ -74,7 +67,8 @@ void ExternalNameConversionPass::runOnOperation() {
mlir::SymbolTable::getSymbolAttrName());
auto deconstructedName = fir::NameUniquer::deconstruct(symName);
if (fir::NameUniquer::isExternalFacingUniquedName(deconstructedName)) {
auto newName = mangleExternalName(deconstructedName, appendUnderscores);
auto newName =
mangleExternalName(deconstructedName, appendUnderscoreOpt);
auto newAttr = mlir::StringAttr::get(context, newName);
mlir::SymbolTable::setSymbolName(&funcOrGlobal, newAttr);
auto newSymRef = mlir::FlatSymbolRefAttr::get(newAttr);
Expand All @@ -101,12 +95,3 @@ void ExternalNameConversionPass::runOnOperation() {
nestedOp->setAttr(update.first, update.second);
});
}

std::unique_ptr<mlir::Pass> fir::createExternalNameConversionPass() {
return std::make_unique<ExternalNameConversionPass>();
}

std::unique_ptr<mlir::Pass>
fir::createExternalNameConversionPass(bool appendUnderscoring) {
return std::make_unique<ExternalNameConversionPass>(appendUnderscoring);
}
26 changes: 26 additions & 0 deletions flang/runtime/command.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,19 @@

#ifdef _WIN32
#include "flang/Common/windows-include.h"
#include <direct.h>
#define getcwd _getcwd
#define PATH_MAX MAX_PATH

// On Windows GetCurrentProcessId returns a DWORD aka uint32_t
#include <processthreadsapi.h>
inline pid_t getpid() { return GetCurrentProcessId(); }
#else
#include <unistd.h> //getpid()

#ifndef PATH_MAX
#define PATH_MAX 4096
#endif
#endif

namespace Fortran::runtime {
Expand Down Expand Up @@ -239,4 +246,23 @@ std::int32_t RTNAME(GetEnvVariable)(const Descriptor &name,
return StatOk;
}

std::int32_t RTNAME(GetCwd)(
const Descriptor &cwd, const char *sourceFile, int line) {
Terminator terminator{sourceFile, line};

RUNTIME_CHECK(terminator, IsValidCharDescriptor(&cwd));

char *buf{(char *)AllocateMemoryOrCrash(terminator, PATH_MAX)};

if (!getcwd(buf, PATH_MAX)) {
return StatMissingCurrentWorkDirectory;
}

std::int64_t strLen{StringLength(buf)};
std::int32_t status{CopyCharsToDescriptor(cwd, buf, strLen)};

std::free(buf);
return status;
}

} // namespace Fortran::runtime
1 change: 1 addition & 0 deletions flang/runtime/stat.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ enum Stat {
StatLocked = FORTRAN_RUNTIME_STAT_LOCKED,
StatLockedOtherImage = FORTRAN_RUNTIME_STAT_LOCKED_OTHER_IMAGE,
StatMissingEnvVariable = FORTRAN_RUNTIME_STAT_MISSING_ENV_VAR,
StatMissingCurrentWorkDirectory = FORTRAN_RUNTIME_STAT_MISSING_CWD,
StatStoppedImage = FORTRAN_RUNTIME_STAT_STOPPED_IMAGE,
StatUnlocked = FORTRAN_RUNTIME_STAT_UNLOCKED,
StatUnlockedFailedImage = FORTRAN_RUNTIME_STAT_UNLOCKED_FAILED_IMAGE,
Expand Down
17 changes: 17 additions & 0 deletions flang/test/Fir/loop03.fir
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Test the reduction semantics of fir.do_loop
// RUN: fir-opt %s | FileCheck %s

func.func @reduction() {
%bound = arith.constant 10 : index
%step = arith.constant 1 : index
%sum = fir.alloca i32
// CHECK: %[[VAL_0:.*]] = fir.alloca i32
// CHECK: fir.do_loop %[[VAL_1:.*]] = %[[VAL_2:.*]] to %[[VAL_3:.*]] step %[[VAL_4:.*]] unordered reduce(#fir.reduce_attr<add> -> %[[VAL_0]] : !fir.ref<i32>) {
fir.do_loop %iv = %step to %bound step %step unordered reduce(#fir.reduce_attr<add> -> %sum : !fir.ref<i32>) {
%index = fir.convert %iv : (index) -> i32
%1 = fir.load %sum : !fir.ref<i32>
%2 = arith.addi %index, %1 : i32
fir.store %2 to %sum : !fir.ref<i32>
}
return
}
23 changes: 23 additions & 0 deletions flang/test/Lower/Intrinsics/getcwd-function.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
! Test GETCWD with dynamically optional arguments.
! RUN: bbc -emit-fir %s -o - | FileCheck %s

! CHECK-LABEL: func.func @_QPtest(
! CHECK-SAME: %[[cwdArg:.*]]: !fir.boxchar<1> {fir.bindc_name = "cwd"}) -> i32 {
integer function test(cwd)
CHARACTER(len=255) :: cwd
test = getcwd(cwd)
! CHECK-NEXT: %[[c8:.*]] = arith.constant 8 : i32
! CHECK-NEXT: %[[c255:.*]] = arith.constant 255 : index
! CHECK-NEXT: %[[DSCOPE:.*]] = fir.dummy_scope : !fir.dscope
! CHECK-NEXT: %[[cwdUnbox:.*]]:2 = fir.unboxchar %[[cwdArg]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
! CHECK-NEXT: %[[cwdCast:.*]] = fir.convert %[[cwdUnbox]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.char<1,255>>
! CHECK-NEXT: %[[cwdDeclare:.*]] = fir.declare %[[cwdCast]] typeparams %[[c255]] dummy_scope %[[DSCOPE]] {uniq_name = "_QFtestEcwd"} : (!fir.ref<!fir.char<1,255>>, index, !fir.dscope) -> !fir.ref<!fir.char<1,255>>
! CHECK-NEXT: %[[test:.*]] = fir.alloca i32 {bindc_name = "test", uniq_name = "_QFtestEtest"}
! CHECK-NEXT: %[[testAddr:.*]] = fir.declare %[[test]] {uniq_name = "_QFtestEtest"} : (!fir.ref<i32>) -> !fir.ref<i32>
! CHECK-NEXT: %[[cwdBox:.*]] = fir.embox %[[cwdDeclare]] : (!fir.ref<!fir.char<1,255>>) -> !fir.box<!fir.char<1,255>>
! CHECK: %[[cwd:.*]] = fir.convert %[[cwdBox]] : (!fir.box<!fir.char<1,255>>) -> !fir.box<none>
! CHECK: %[[statusValue:.*]] = fir.call @_FortranAGetCwd(%[[cwd]], %[[VAL_9:.*]], %[[c8]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> i32
! CHECK-NEXT: fir.store %[[statusValue]] to %[[testAddr]] : !fir.ref<i32>
! CHECK-NEXT: %[[returnValue:.*]] = fir.load %[[testAddr]] : !fir.ref<i32>
! CHECK-NEXT: return %[[returnValue]] : i32
end function
29 changes: 29 additions & 0 deletions flang/test/Lower/Intrinsics/getcwd-optional.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
! Test GETCWD with dynamically optional arguments.
! RUN: bbc -emit-fir %s -o - | FileCheck %s


! CHECK-LABEL: func.func @_QPtest(
! CHECK-SAME: %[[cwdArg:.*]]: !fir.boxchar<1> {fir.bindc_name = "cwd"},
! CHECK-SAME: %[[statusArg:.*]]: !fir.ref<i32> {fir.bindc_name = "status", fir.optional}) {
subroutine test(cwd, status)
CHARACTER(len=255) :: cwd
INTEGER, OPTIONAL :: status
call getcwd(cwd, status)
! CHECK-NEXT: %[[c0:.*]] = arith.constant 0 : i64
! CHECK-NEXT: %[[c11:.*]] = arith.constant 11 : i32
! CHECK-NEXT: %[[c255:.*]] = arith.constant 255 : index
! CHECK-NEXT: %[[DSCOPE:.*]] = fir.dummy_scope : !fir.dscope
! CHECK-NEXT: %[[cwdUnbox:.*]]:2 = fir.unboxchar %[[cwdArg]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
! CHECK-NEXT: %[[cwdCast:.*]] = fir.convert %[[cwdUnbox]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.char<1,255>>
! CHECK-NEXT: %[[cwdDeclare:.*]] = fir.declare %[[cwdCast]] typeparams %[[c255]] dummy_scope %[[DSCOPE]] {uniq_name = "_QFtestEcwd"} : (!fir.ref<!fir.char<1,255>>, index, !fir.dscope) -> !fir.ref<!fir.char<1,255>>
! CHECK-NEXT: %[[statusAddr:.*]] = fir.declare %[[statusArg]] dummy_scope %[[DSCOPE]] {fortran_attrs = #fir.var_attrs<optional>, uniq_name = "_QFtestEstatus"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
! CHECK-NEXT: %[[cwdBox:.*]] = fir.embox %[[cwdDeclare]] : (!fir.ref<!fir.char<1,255>>) -> !fir.box<!fir.char<1,255>>
! CHECK: %[[cwd:.*]] = fir.convert %[[cwdBox]] : (!fir.box<!fir.char<1,255>>) -> !fir.box<none>
! CHECK: %[[statusValue:.*]] = fir.call @_FortranAGetCwd(%[[cwd]], %[[VAL_8:.*]], %[[c11]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> i32
! CHECK-NEXT: %[[statusCast:.*]] = fir.convert %[[statusAddr]] : (!fir.ref<i32>) -> i64
! CHECK-NEXT: %[[isPresent:.*]] = arith.cmpi ne, %[[statusCast]], %[[c0]] : i64
! CHECK-NEXT: fir.if %[[isPresent]] {
! CHECK-NEXT: fir.store %[[statusValue]] to %[[statusAddr]] : !fir.ref<i32>
! CHECK-NEXT: }
! CHECK-NEXT: return
end subroutine
44 changes: 44 additions & 0 deletions flang/test/Lower/Intrinsics/getcwd.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
! RUN: bbc -emit-fir %s -o - | FileCheck %s

! CHECK-LABEL: func.func @_QPcwd_only(
! CHECK-SAME: %[[cwdArg:.*]]: !fir.boxchar<1> {fir.bindc_name = "cwd"}) {
subroutine cwd_only(cwd)
CHARACTER(len=255) :: cwd
call getcwd(cwd)
! CHECK-NEXT: %[[c7:.*]] = arith.constant 7 : i32
! CHECK-NEXT: %[[c255:.*]] = arith.constant 255 : index
! CHECK-NEXT: %[[DSCOPE:.*]] = fir.dummy_scope : !fir.dscope
! CHECK-NEXT: %[[cwdUnbox:.*]]:2 = fir.unboxchar %[[cwdArg]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
! CHECK-NEXT: %[[cwdCast:.*]] = fir.convert %[[cwdUnbox]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.char<1,255>>
! CHECK-NEXT: %[[cwdDeclare:.*]] = fir.declare %[[cwdCast]] typeparams %[[c255]] dummy_scope %[[DSCOPE]] {uniq_name = "_QFcwd_onlyEcwd"} : (!fir.ref<!fir.char<1,255>>, index, !fir.dscope) -> !fir.ref<!fir.char<1,255>>
! CHECK-NEXT: %[[cwdBox:.*]] = fir.embox %[[cwdDeclare]] : (!fir.ref<!fir.char<1,255>>) -> !fir.box<!fir.char<1,255>>
! CHECK: %[[cwd:.*]] = fir.convert %[[cwdBox]] : (!fir.box<!fir.char<1,255>>) -> !fir.box<none>
! CHECK: %[[statusValue:.*]] = fir.call @_FortranAGetCwd(%[[cwd]], %[[VAL_7:.*]], %[[c7]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> i32
! CHECK-NEXT: return
end subroutine cwd_only

! CHECK-LABEL: func.func @_QPall_arguments(
! CHECK-SAME: %[[cwdArg:.*]]: !fir.boxchar<1> {fir.bindc_name = "cwd"},
! CHECK-SAME: %[[statusArg:.*]]: !fir.ref<i32> {fir.bindc_name = "status"}) {
subroutine all_arguments(cwd, status)
CHARACTER(len=255) :: cwd
INTEGER :: status
call getcwd(cwd, status)
! CHECK-NEXT: %[[c0:.*]] = arith.constant 0 : i64
! CHECK-NEXT: %[[c26:.*]] = arith.constant 26 : i32
! CHECK-NEXT: %[[c255:.*]] = arith.constant 255 : index
! CHECK-NEXT: %[[DSCOPE:.*]] = fir.dummy_scope : !fir.dscope
! CHECK-NEXT: %[[cwdUnbox:.*]]:2 = fir.unboxchar %[[cwdArg]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
! CHECK-NEXT: %[[cwdCast:.*]] = fir.convert %[[cwdUnbox]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.char<1,255>>
! CHECK-NEXT: %[[cwdDeclare:.*]] = fir.declare %[[cwdCast]] typeparams %[[c255]] dummy_scope %[[DSCOPE]] {uniq_name = "_QFall_argumentsEcwd"} : (!fir.ref<!fir.char<1,255>>, index, !fir.dscope) -> !fir.ref<!fir.char<1,255>>
! CHECK-NEXT: %[[statusAddr:.*]] = fir.declare %[[statusArg]] dummy_scope %0 {uniq_name = "_QFall_argumentsEstatus"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
! CHECK-NEXT: %[[cwdBox:.*]] = fir.embox %[[cwdDeclare]] : (!fir.ref<!fir.char<1,255>>) -> !fir.box<!fir.char<1,255>>
! CHECK: %[[cwd:.*]] = fir.convert %[[cwdBox]] : (!fir.box<!fir.char<1,255>>) -> !fir.box<none>
! CHECK: %[[statusValue:.*]] = fir.call @_FortranAGetCwd(%[[cwd]], %[[VAL_8:.*]], %[[c26]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> i32
! CHECK-NEXT: %[[statusCast:.*]] = fir.convert %[[statusAddr]] : (!fir.ref<i32>) -> i64
! CHECK-NEXT: %[[isPresent:.*]] = arith.cmpi ne, %[[statusCast]], %[[c0]] : i64
! CHECK-NEXT: fir.if %[[isPresent]] {
! CHECK-NEXT: fir.store %[[statusValue]] to %[[statusAddr]] : !fir.ref<i32>
! CHECK-NEXT: }
! CHECK-NEXT: return
end subroutine all_arguments
24 changes: 24 additions & 0 deletions flang/test/Lower/OpenMP/critical.f90
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,27 @@ subroutine predetermined_privatization()
end do
!$omp end parallel do
end

! https://github.com/llvm/llvm-project/issues/75767
!CHECK-LABEL: func @_QPparallel_critical_privatization(
subroutine parallel_critical_privatization()
integer :: i

!CHECK: %[[I:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFparallel_critical_privatizationEi"}
!CHECK: %[[I_DECL:.*]]:2 = hlfir.declare %[[I]] {uniq_name = "_QFparallel_critical_privatizationEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
!CHECK: omp.parallel {
!CHECK: %[[PRIV_I:.*]] = fir.alloca i32 {bindc_name = "i", pinned, uniq_name = "_QFparallel_critical_privatizationEi"}
!CHECK: %[[PRIV_I_DECL:.*]]:2 = hlfir.declare %[[PRIV_I]] {uniq_name = "_QFparallel_critical_privatizationEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
!CHECK: %[[TEMP:.*]] = fir.load %[[I_DECL]]#0 : !fir.ref<i32>
!CHECK: hlfir.assign %[[TEMP]] to %[[PRIV_I_DECL]]#0 temporary_lhs : i32, !fir.ref<i32>
!$omp parallel default(firstprivate)
!CHECK: omp.critical {
!$omp critical
!CHECK: %[[C200:.*]] = arith.constant 200 : i32
!CHECK: hlfir.assign %[[C200]] to %[[PRIV_I_DECL]]#0 : i32, !fir.ref<i32>
i = 200
!CHECK: }
!$omp end critical
!CHECK: }
!$omp end parallel
end subroutine
41 changes: 32 additions & 9 deletions flang/test/Lower/OpenMP/map-component-ref.f90
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
! RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
! RUN: bbc -fopenmp -emit-hlfir %s -o - | FileCheck %s

! CHECK: %[[V0:[0-9]+]] = fir.alloca !fir.type<_QFfooTt0{a0:i32,a1:i32}> {bindc_name = "a", uniq_name = "_QFfooEa"}
! CHECK: %[[V1:[0-9]+]]:2 = hlfir.declare %[[V0]] {uniq_name = "_QFfooEa"} : (!fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>) -> (!fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>, !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>)
! CHECK: %[[V2:[0-9]+]] = hlfir.designate %[[V1]]#0{"a1"} : (!fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>) -> !fir.ref<i32>
! CHECK-LABEL: func.func @_QPfoo1
! CHECK: %[[V0:[0-9]+]] = fir.alloca !fir.type<_QFfoo1Tt0{a0:i32,a1:i32}> {bindc_name = "a", uniq_name = "_QFfoo1Ea"}
! CHECK: %[[V1:[0-9]+]]:2 = hlfir.declare %[[V0]] {uniq_name = "_QFfoo1Ea"} : (!fir.ref<!fir.type<_QFfoo1Tt0{a0:i32,a1:i32}>>) -> (!fir.ref<!fir.type<_QFfoo1Tt0{a0:i32,a1:i32}>>, !fir.ref<!fir.type<_QFfoo1Tt0{a0:i32,a1:i32}>>)
! CHECK: %[[V2:[0-9]+]] = hlfir.designate %[[V1]]#0{"a1"} : (!fir.ref<!fir.type<_QFfoo1Tt0{a0:i32,a1:i32}>>) -> !fir.ref<i32>
! CHECK: %[[V3:[0-9]+]] = omp.map.info var_ptr(%[[V2]] : !fir.ref<i32>, i32) map_clauses(tofrom) capture(ByRef) -> !fir.ref<i32> {name = "a%a1"}
! CHECK: %[[V4:[0-9]+]] = omp.map.info var_ptr(%[[V1]]#1 : !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>, !fir.type<_QFfooTt0{a0:i32,a1:i32}>) map_clauses(tofrom) capture(ByRef) members(%[[V3]] : [1] : !fir.ref<i32>) -> !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>> {name = "a", partial_map = true}
! CHECK: omp.target map_entries(%[[V3]] -> %arg0, %[[V4]] -> %arg1 : !fir.ref<i32>, !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>) {
! CHECK: ^bb0(%arg0: !fir.ref<i32>, %arg1: !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>):
! CHECK: %[[V5:[0-9]+]]:2 = hlfir.declare %arg1 {uniq_name = "_QFfooEa"} : (!fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>) -> (!fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>, !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>)
! CHECK: %[[V4:[0-9]+]] = omp.map.info var_ptr(%[[V1]]#1 : !fir.ref<!fir.type<_QFfoo1Tt0{a0:i32,a1:i32}>>, !fir.type<_QFfoo1Tt0{a0:i32,a1:i32}>) map_clauses(tofrom) capture(ByRef) members(%[[V3]] : [1] : !fir.ref<i32>) -> !fir.ref<!fir.type<_QFfoo1Tt0{a0:i32,a1:i32}>> {name = "a", partial_map = true}
! CHECK: omp.target map_entries(%[[V3]] -> %arg0, %[[V4]] -> %arg1 : !fir.ref<i32>, !fir.ref<!fir.type<_QFfoo1Tt0{a0:i32,a1:i32}>>) {
! CHECK: ^bb0(%arg0: !fir.ref<i32>, %arg1: !fir.ref<!fir.type<_QFfoo1Tt0{a0:i32,a1:i32}>>):
! CHECK: %[[V5:[0-9]+]]:2 = hlfir.declare %arg1 {uniq_name = "_QFfoo1Ea"} : (!fir.ref<!fir.type<_QFfoo1Tt0{a0:i32,a1:i32}>>) -> (!fir.ref<!fir.type<_QFfoo1Tt0{a0:i32,a1:i32}>>, !fir.ref<!fir.type<_QFfoo1Tt0{a0:i32,a1:i32}>>)
! CHECK: %c0_i32 = arith.constant 0 : i32
! CHECK: %[[V6:[0-9]+]] = hlfir.designate %[[V5]]#0{"a1"} : (!fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>) -> !fir.ref<i32>
! CHECK: %[[V6:[0-9]+]] = hlfir.designate %[[V5]]#0{"a1"} : (!fir.ref<!fir.type<_QFfoo1Tt0{a0:i32,a1:i32}>>) -> !fir.ref<i32>
! CHECK: hlfir.assign %c0_i32 to %[[V6]] : i32, !fir.ref<i32>
! CHECK: omp.terminator
! CHECK: }

subroutine foo()
subroutine foo1()
implicit none

type t0
Expand All @@ -29,3 +30,25 @@ subroutine foo()
!$omp end target
end


! CHECK-LABEL: func.func @_QPfoo2
! CHECK-DAG: omp.map.info var_ptr(%{{[0-9]+}} : {{.*}} map_clauses(to) capture(ByRef) bounds(%{{[0-9]+}}) -> {{.*}} {name = "t%b(1_8)%a(1)"}
! CHECK-DAG: omp.map.info var_ptr(%{{[0-9]+}} : {{.*}} map_clauses(from) capture(ByRef) bounds(%{{[0-9]+}}) -> {{.*}} {name = "u%b(1_8)%a(1)"}
subroutine foo2()
implicit none

type t0
integer :: a(10)
end type

type t1
type(t0) :: b(10)
end type

type(t1) :: t, u

!$omp target map(to: t%b(1)%a(1)) map(from: u%b(1)%a(1))
t%b(1)%a(1) = u%b(1)%a(1)
!$omp end target

end
35 changes: 35 additions & 0 deletions flang/test/Semantics/getcwd.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
! RUN: %python %S/test_errors.py %s %flang_fc1 -pedantic
! Tests for the GETCWD intrinsics

subroutine bad_kind_error(cwd, status)
CHARACTER(len=255) :: cwd
INTEGER(2) :: status
!ERROR: Actual argument for 'status=' has bad type or kind 'INTEGER(2)'
call getcwd(cwd, status)
end subroutine bad_kind_error

subroutine bad_args_error()
!ERROR: missing mandatory 'c=' argument
call getcwd()
end subroutine bad_args_error

subroutine bad_apply_form(cwd)
CHARACTER(len=255) :: cwd
INTEGER :: status
!Declaration of 'getcwd'
call getcwd(cwd, status)
!ERROR: Cannot call subroutine 'getcwd' like a function
status = getcwd(cwd)
end subroutine bad_apply_form

subroutine good_subroutine(cwd, status)
CHARACTER(len=255) :: cwd
INTEGER :: status
call getcwd(cwd, status)
end subroutine good_subroutine

subroutine good_function(cwd, status)
CHARACTER(len=255) :: cwd
INTEGER :: status
status = getcwd(cwd)
end subroutine good_function
11 changes: 11 additions & 0 deletions libc/config/gpu/entrypoints.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
if(LIBC_TARGET_ARCHITECTURE_IS_AMDGPU)
set(extra_entrypoints
# stdio.h entrypoints
libc.src.stdio.sprintf
libc.src.stdio.snprintf
libc.src.stdio.vsprintf
libc.src.stdio.vsnprintf
)
endif()

set(TARGET_LIBC_ENTRYPOINTS
# assert.h entrypoints
libc.src.assert.__assert_fail
Expand Down Expand Up @@ -175,6 +185,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.errno.errno

# stdio.h entrypoints
${extra_entrypoints}
libc.src.stdio.feof
libc.src.stdio.ferror
libc.src.stdio.fseek
Expand Down
15 changes: 15 additions & 0 deletions libc/config/linux/aarch64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -506,14 +506,29 @@ if(LIBC_TYPES_HAS_FLOAT16)
libc.src.math.fdimf16
libc.src.math.floorf16
libc.src.math.fmaxf16
libc.src.math.fmaximumf16
libc.src.math.fmaximum_magf16
libc.src.math.fmaximum_mag_numf16
libc.src.math.fmaximum_numf16
libc.src.math.fminf16
libc.src.math.fminimumf16
libc.src.math.fminimum_magf16
libc.src.math.fminimum_mag_numf16
libc.src.math.fminimum_numf16
libc.src.math.fromfpf16
libc.src.math.fromfpxf16
libc.src.math.llrintf16
libc.src.math.llroundf16
libc.src.math.lrintf16
libc.src.math.lroundf16
libc.src.math.nearbyintf16
libc.src.math.nextafterf16
libc.src.math.nextdownf16
# Temporarily disable nexttowardf16 on aarch64 because the conversion
# between _Float16 and long double will crash clang-11. This is fixed in
# clang-12 and after: https://godbolt.org/z/8ceT9454c
# libc.src.math.nexttowardf16
libc.src.math.nextupf16
libc.src.math.rintf16
libc.src.math.roundf16
libc.src.math.roundevenf16
Expand Down
15 changes: 14 additions & 1 deletion libc/config/linux/x86_64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,6 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.stdlib.atoll
libc.src.stdlib.bsearch
libc.src.stdlib.div
libc.src.stdlib.quick_exit
libc.src.stdlib.labs
libc.src.stdlib.ldiv
libc.src.stdlib.llabs
Expand Down Expand Up @@ -539,14 +538,26 @@ if(LIBC_TYPES_HAS_FLOAT16)
libc.src.math.fdimf16
libc.src.math.floorf16
libc.src.math.fmaxf16
libc.src.math.fmaximumf16
libc.src.math.fmaximum_magf16
libc.src.math.fmaximum_mag_numf16
libc.src.math.fmaximum_numf16
libc.src.math.fminf16
libc.src.math.fminimumf16
libc.src.math.fminimum_magf16
libc.src.math.fminimum_mag_numf16
libc.src.math.fminimum_numf16
libc.src.math.fromfpf16
libc.src.math.fromfpxf16
libc.src.math.llrintf16
libc.src.math.llroundf16
libc.src.math.lrintf16
libc.src.math.lroundf16
libc.src.math.nearbyintf16
libc.src.math.nextafterf16
libc.src.math.nextdownf16
libc.src.math.nexttowardf16
libc.src.math.nextupf16
libc.src.math.rintf16
libc.src.math.roundf16
libc.src.math.roundevenf16
Expand Down Expand Up @@ -758,9 +769,11 @@ if(LLVM_LIBC_FULL_BUILD)
# stdlib.h entrypoints
libc.src.stdlib._Exit
libc.src.stdlib.abort
libc.src.stdlib.at_quick_exit
libc.src.stdlib.atexit
libc.src.stdlib.exit
libc.src.stdlib.getenv
libc.src.stdlib.quick_exit

# signal.h entrypoints
libc.src.signal.raise
Expand Down
18 changes: 10 additions & 8 deletions libc/docs/c23.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,17 @@ Additions:
* ufromfp* |check|
* fromfpx* |check|
* ufromfpx* |check|
* nextup*
* nextdown*
* nextup* |check|
* nextdown* |check|
* canonicalize* |check|
* fmaximum*
* fminimum*
* fmaximum_mag*
* fminimum_mag*
* fmaximum_mag_num*
* fminimum_mag_num*
* fmaximum* |check|
* fminimum* |check|
* fmaximum_mag* |check|
* fminimum_mag* |check|
* fmaximum_num* |check|
* fminimum_num* |check|
* fmaximum_mag_num* |check|
* fminimum_mag_num* |check|
* fadd*
* fsub*
* fmul*
Expand Down
24 changes: 12 additions & 12 deletions libc/docs/math/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -138,23 +138,23 @@ Basic Operations
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| fmax | |check| | |check| | |check| | |check| | |check| | 7.12.12.2 | F.10.9.2 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| fmaximum | |check| | |check| | |check| | | |check| | 7.12.12.4 | F.10.9.4 |
| fmaximum | |check| | |check| | |check| | |check| | |check| | 7.12.12.4 | F.10.9.4 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| fmaximum_mag | |check| | |check| | |check| | | |check| | 7.12.12.6 | F.10.9.4 |
| fmaximum_mag | |check| | |check| | |check| | |check| | |check| | 7.12.12.6 | F.10.9.4 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| fmaximum_mag_num | |check| | |check| | |check| | | |check| | 7.12.12.10 | F.10.9.5 |
| fmaximum_mag_num | |check| | |check| | |check| | |check| | |check| | 7.12.12.10 | F.10.9.5 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| fmaximum_num | |check| | |check| | |check| | | |check| | 7.12.12.8 | F.10.9.5 |
| fmaximum_num | |check| | |check| | |check| | |check| | |check| | 7.12.12.8 | F.10.9.5 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| fmin | |check| | |check| | |check| | |check| | |check| | 7.12.12.3 | F.10.9.3 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| fminimum | |check| | |check| | |check| | | |check| | 7.12.12.5 | F.10.9.4 |
| fminimum | |check| | |check| | |check| | |check| | |check| | 7.12.12.5 | F.10.9.4 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| fminimum_mag | |check| | |check| | |check| | | |check| | 7.12.12.7 | F.10.9.4 |
| fminimum_mag | |check| | |check| | |check| | |check| | |check| | 7.12.12.7 | F.10.9.4 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| fminimum_mag_num | |check| | |check| | |check| | | |check| | 7.12.12.11 | F.10.9.5 |
| fminimum_mag_num | |check| | |check| | |check| | |check| | |check| | 7.12.12.11 | F.10.9.5 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| fminimum_num | |check| | |check| | |check| | | |check| | 7.12.12.9 | F.10.9.5 |
| fminimum_num | |check| | |check| | |check| | |check| | |check| | 7.12.12.9 | F.10.9.5 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| fmod | |check| | |check| | |check| | | |check| | 7.12.10.1 | F.10.7.1 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
Expand Down Expand Up @@ -190,13 +190,13 @@ Basic Operations
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| nearbyint | |check| | |check| | |check| | |check| | |check| | 7.12.9.3 | F.10.6.3 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| nextafter | |check| | |check| | |check| | | |check| | 7.12.11.3 | F.10.8.3 |
| nextafter | |check| | |check| | |check| | |check| | |check| | 7.12.11.3 | F.10.8.3 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| nextdown | |check| | |check| | |check| | | |check| | 7.12.11.6 | F.10.8.6 |
| nextdown | |check| | |check| | |check| | |check| | |check| | 7.12.11.6 | F.10.8.6 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| nexttoward | |check| | |check| | |check| | | N/A | 7.12.11.4 | F.10.8.4 |
| nexttoward | |check| | |check| | |check| | |check| | N/A | 7.12.11.4 | F.10.8.4 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| nextup | |check| | |check| | |check| | | |check| | 7.12.11.5 | F.10.8.5 |
| nextup | |check| | |check| | |check| | |check| | |check| | 7.12.11.5 | F.10.8.5 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| remainder | |check| | |check| | |check| | | | 7.12.10.2 | F.10.7.2 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
Expand Down
9 changes: 9 additions & 0 deletions libc/hdr/types/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,12 @@ add_proxy_header_library(
libc.include.llvm-libc-types.pid_t
libc.include.sys_types
)

add_proxy_header_library(
atexithandler_t
HDRS
atexithandler_t.h
FULL_BUILD_DEPENDS
libc.include.llvm-libc-types.atexithandler_t
libc.include.stdlib
)
22 changes: 22 additions & 0 deletions libc/hdr/types/atexithandler_t.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//===-- Definition of macros from atexithandler_t.h -----------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_HDR_ATEXITHANDLER_T_H
#define LLVM_LIBC_HDR_ATEXITHANDLER_T_H

#ifdef LIBC_FULL_BUILD

#include "include/llvm-libc-types/__atexithandler_t.h"

#else // overlay mode

#error // type not available in overlay mode

#endif // LLVM_LIBC_FULL_BUILD

#endif // LLVM_LIBC_HDR_ATEXITHANDLER_T_H
15 changes: 14 additions & 1 deletion libc/spec/stdc.td
Original file line number Diff line number Diff line change
Expand Up @@ -427,41 +427,49 @@ def StdC : StandardSpec<"stdc"> {
FunctionSpec<"fmaximum", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
FunctionSpec<"fmaximumf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
FunctionSpec<"fmaximuml", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"fmaximumf16", RetValSpec<Float16Type>, [ArgSpec<Float16Type>, ArgSpec<Float16Type>], "LIBC_TYPES_HAS_FLOAT16">,
GuardedFunctionSpec<"fmaximumf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,

FunctionSpec<"fmaximum_num", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
FunctionSpec<"fmaximum_numf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
FunctionSpec<"fmaximum_numl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"fmaximum_numf16", RetValSpec<Float16Type>, [ArgSpec<Float16Type>, ArgSpec<Float16Type>], "LIBC_TYPES_HAS_FLOAT16">,
GuardedFunctionSpec<"fmaximum_numf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,

FunctionSpec<"fmaximum_mag", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
FunctionSpec<"fmaximum_magf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
FunctionSpec<"fmaximum_magl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"fmaximum_magf16", RetValSpec<Float16Type>, [ArgSpec<Float16Type>, ArgSpec<Float16Type>], "LIBC_TYPES_HAS_FLOAT16">,
GuardedFunctionSpec<"fmaximum_magf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,

FunctionSpec<"fmaximum_mag_num", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
FunctionSpec<"fmaximum_mag_numf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
FunctionSpec<"fmaximum_mag_numl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"fmaximum_mag_numf16", RetValSpec<Float16Type>, [ArgSpec<Float16Type>, ArgSpec<Float16Type>], "LIBC_TYPES_HAS_FLOAT16">,
GuardedFunctionSpec<"fmaximum_mag_numf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,

FunctionSpec<"fminimum", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
FunctionSpec<"fminimumf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
FunctionSpec<"fminimuml", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"fminimumf16", RetValSpec<Float16Type>, [ArgSpec<Float16Type>, ArgSpec<Float16Type>], "LIBC_TYPES_HAS_FLOAT16">,
GuardedFunctionSpec<"fminimumf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,

FunctionSpec<"fminimum_num", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
FunctionSpec<"fminimum_numf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
FunctionSpec<"fmaximum_numl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"fminimum_numf16", RetValSpec<Float16Type>, [ArgSpec<Float16Type>, ArgSpec<Float16Type>], "LIBC_TYPES_HAS_FLOAT16">,
GuardedFunctionSpec<"fminimum_numf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,

FunctionSpec<"fminimum_mag", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
FunctionSpec<"fminimum_magf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
FunctionSpec<"fminimum_magl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"fminimum_magf16", RetValSpec<Float16Type>, [ArgSpec<Float16Type>, ArgSpec<Float16Type>], "LIBC_TYPES_HAS_FLOAT16">,
GuardedFunctionSpec<"fminimum_magf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,

FunctionSpec<"fminimum_mag_num", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
FunctionSpec<"fminimum_mag_numf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
FunctionSpec<"fminimum_mag_numl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"fminimum_mag_numf16", RetValSpec<Float16Type>, [ArgSpec<Float16Type>, ArgSpec<Float16Type>], "LIBC_TYPES_HAS_FLOAT16">,
GuardedFunctionSpec<"fminimum_mag_numf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,

FunctionSpec<"fma", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
Expand Down Expand Up @@ -634,20 +642,24 @@ def StdC : StandardSpec<"stdc"> {
FunctionSpec<"nextafterf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
FunctionSpec<"nextafter", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
FunctionSpec<"nextafterl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"nextafterf16", RetValSpec<Float16Type>, [ArgSpec<Float16Type>, ArgSpec<Float16Type>], "LIBC_TYPES_HAS_FLOAT16">,
GuardedFunctionSpec<"nextafterf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,

FunctionSpec<"nexttowardf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<LongDoubleType>]>,
FunctionSpec<"nexttoward", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<LongDoubleType>]>,
FunctionSpec<"nexttowardl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"nexttowardf16", RetValSpec<Float16Type>, [ArgSpec<Float16Type>, ArgSpec<Float16Type>], "LIBC_TYPES_HAS_FLOAT16">,

FunctionSpec<"nextdown", RetValSpec<DoubleType>, [ArgSpec<DoubleType>]>,
FunctionSpec<"nextdownf", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
FunctionSpec<"nextdownl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"nextdownf16", RetValSpec<Float16Type>, [ArgSpec<Float16Type>], "LIBC_TYPES_HAS_FLOAT16">,
GuardedFunctionSpec<"nextdownf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,

FunctionSpec<"nextup", RetValSpec<DoubleType>, [ArgSpec<DoubleType>]>,
FunctionSpec<"nextupf", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
FunctionSpec<"nextupl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"nextupf16", RetValSpec<Float16Type>, [ArgSpec<Float16Type>], "LIBC_TYPES_HAS_FLOAT16">,
GuardedFunctionSpec<"nextupf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,

FunctionSpec<"powf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
Expand Down Expand Up @@ -1095,8 +1107,9 @@ def StdC : StandardSpec<"stdc"> {
FunctionSpec<"free", RetValSpec<VoidType>, [ArgSpec<VoidPtr>]>,

FunctionSpec<"_Exit", RetValSpec<NoReturn>, [ArgSpec<IntType>]>,
FunctionSpec<"exit", RetValSpec<NoReturn>, [ArgSpec<IntType>]>,
FunctionSpec<"at_quick_exit", RetValSpec<IntType>, [ArgSpec<AtexitHandlerT>]>,
FunctionSpec<"atexit", RetValSpec<IntType>, [ArgSpec<AtexitHandlerT>]>,
FunctionSpec<"exit", RetValSpec<NoReturn>, [ArgSpec<IntType>]>,
FunctionSpec<"quick_exit", RetValSpec<NoReturn>, [ArgSpec<IntType>]>,
]
>;
Expand Down
18 changes: 17 additions & 1 deletion libc/src/__support/fixedvector.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ template <typename T, size_t CAPACITY> class FixedVector {
public:
constexpr FixedVector() = default;

using iterator = typename cpp::array<T, CAPACITY>::iterator;
constexpr FixedVector(iterator begin, iterator end) {
for (; begin != end; ++begin)
push_back(*begin);
}

constexpr FixedVector(size_t count, const T &value) {
for (size_t i = 0; i < count; ++i)
push_back(value);
}

bool push_back(const T &obj) {
if (item_count == CAPACITY)
return false;
Expand All @@ -43,8 +54,14 @@ template <typename T, size_t CAPACITY> class FixedVector {
return true;
}

T &operator[](size_t idx) { return store[idx]; }

const T &operator[](size_t idx) const { return store[idx]; }

bool empty() const { return item_count == 0; }

size_t size() const { return item_count; }

// Empties the store for all practical purposes.
void reset() { item_count = 0; }

Expand All @@ -64,7 +81,6 @@ template <typename T, size_t CAPACITY> class FixedVector {
}
LIBC_INLINE constexpr reverse_iterator rend() { return store.rend(); }

using iterator = typename cpp::array<T, CAPACITY>::iterator;
LIBC_INLINE constexpr iterator begin() { return store.begin(); }
LIBC_INLINE constexpr iterator end() { return iterator{&store[item_count]}; }
};
Expand Down
12 changes: 12 additions & 0 deletions libc/src/math/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -135,41 +135,49 @@ add_math_entrypoint_object(fminf16)
add_math_entrypoint_object(fmaximum)
add_math_entrypoint_object(fmaximumf)
add_math_entrypoint_object(fmaximuml)
add_math_entrypoint_object(fmaximumf16)
add_math_entrypoint_object(fmaximumf128)

add_math_entrypoint_object(fmaximum_num)
add_math_entrypoint_object(fmaximum_numf)
add_math_entrypoint_object(fmaximum_numl)
add_math_entrypoint_object(fmaximum_numf16)
add_math_entrypoint_object(fmaximum_numf128)

add_math_entrypoint_object(fmaximum_mag)
add_math_entrypoint_object(fmaximum_magf)
add_math_entrypoint_object(fmaximum_magl)
add_math_entrypoint_object(fmaximum_magf16)
add_math_entrypoint_object(fmaximum_magf128)

add_math_entrypoint_object(fmaximum_mag_num)
add_math_entrypoint_object(fmaximum_mag_numf)
add_math_entrypoint_object(fmaximum_mag_numl)
add_math_entrypoint_object(fmaximum_mag_numf16)
add_math_entrypoint_object(fmaximum_mag_numf128)

add_math_entrypoint_object(fminimum)
add_math_entrypoint_object(fminimumf)
add_math_entrypoint_object(fminimuml)
add_math_entrypoint_object(fminimumf16)
add_math_entrypoint_object(fminimumf128)

add_math_entrypoint_object(fminimum_num)
add_math_entrypoint_object(fminimum_numf)
add_math_entrypoint_object(fminimum_numl)
add_math_entrypoint_object(fminimum_numf16)
add_math_entrypoint_object(fminimum_numf128)

add_math_entrypoint_object(fminimum_mag)
add_math_entrypoint_object(fminimum_magf)
add_math_entrypoint_object(fminimum_magl)
add_math_entrypoint_object(fminimum_magf16)
add_math_entrypoint_object(fminimum_magf128)

add_math_entrypoint_object(fminimum_mag_num)
add_math_entrypoint_object(fminimum_mag_numf)
add_math_entrypoint_object(fminimum_mag_numl)
add_math_entrypoint_object(fminimum_mag_numf16)
add_math_entrypoint_object(fminimum_mag_numf128)

add_math_entrypoint_object(fmod)
Expand Down Expand Up @@ -272,20 +280,24 @@ add_math_entrypoint_object(nearbyintf128)
add_math_entrypoint_object(nextafter)
add_math_entrypoint_object(nextafterf)
add_math_entrypoint_object(nextafterl)
add_math_entrypoint_object(nextafterf16)
add_math_entrypoint_object(nextafterf128)

add_math_entrypoint_object(nexttoward)
add_math_entrypoint_object(nexttowardf)
add_math_entrypoint_object(nexttowardl)
add_math_entrypoint_object(nexttowardf16)

add_math_entrypoint_object(nextdown)
add_math_entrypoint_object(nextdownf)
add_math_entrypoint_object(nextdownl)
add_math_entrypoint_object(nextdownf16)
add_math_entrypoint_object(nextdownf128)

add_math_entrypoint_object(nextup)
add_math_entrypoint_object(nextupf)
add_math_entrypoint_object(nextupl)
add_math_entrypoint_object(nextupf16)
add_math_entrypoint_object(nextupf128)

add_math_entrypoint_object(pow)
Expand Down
20 changes: 20 additions & 0 deletions libc/src/math/fmaximum_mag_numf16.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation header for fmaximum_mag_numf16 -----------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_MATH_FMAXIMUM_MAG_NUMF16_H
#define LLVM_LIBC_SRC_MATH_FMAXIMUM_MAG_NUMF16_H

#include "src/__support/macros/properties/types.h"

namespace LIBC_NAMESPACE {

float16 fmaximum_mag_numf16(float16 x, float16 y);

} // namespace LIBC_NAMESPACE

#endif // LLVM_LIBC_SRC_MATH_FMAXIMUM_MAG_NUMF16_H
20 changes: 20 additions & 0 deletions libc/src/math/fmaximum_magf16.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation header for fmaximum_magf16 ---------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_MATH_FMAXIMUM_MAGF16_H
#define LLVM_LIBC_SRC_MATH_FMAXIMUM_MAGF16_H

#include "src/__support/macros/properties/types.h"

namespace LIBC_NAMESPACE {

float16 fmaximum_magf16(float16 x, float16 y);

} // namespace LIBC_NAMESPACE

#endif // LLVM_LIBC_SRC_MATH_FMAXIMUM_MAGF16_H
20 changes: 20 additions & 0 deletions libc/src/math/fmaximum_numf16.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation header for fmaximum_numf16 ---------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_MATH_FMAXIMUM_NUMF16_H
#define LLVM_LIBC_SRC_MATH_FMAXIMUM_NUMF16_H

#include "src/__support/macros/properties/types.h"

namespace LIBC_NAMESPACE {

float16 fmaximum_numf16(float16 x, float16 y);

} // namespace LIBC_NAMESPACE

#endif // LLVM_LIBC_SRC_MATH_FMAXIMUM_NUMF16_H
20 changes: 20 additions & 0 deletions libc/src/math/fmaximumf16.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation header for fmaximumf16 -------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_MATH_FMAXIMUMF16_H
#define LLVM_LIBC_SRC_MATH_FMAXIMUMF16_H

#include "src/__support/macros/properties/types.h"

namespace LIBC_NAMESPACE {

float16 fmaximumf16(float16 x, float16 y);

} // namespace LIBC_NAMESPACE

#endif // LLVM_LIBC_SRC_MATH_FMAXIMUMF16_H
20 changes: 20 additions & 0 deletions libc/src/math/fminimum_mag_numf16.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation header for fminimum_mag_numf16 -----------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_MATH_FMINIMUM_MAG_NUMF16_H
#define LLVM_LIBC_SRC_MATH_FMINIMUM_MAG_NUMF16_H

#include "src/__support/macros/properties/types.h"

namespace LIBC_NAMESPACE {

float16 fminimum_mag_numf16(float16 x, float16 y);

} // namespace LIBC_NAMESPACE

#endif // LLVM_LIBC_SRC_MATH_FMINIMUM_MAG_NUMF16_H
20 changes: 20 additions & 0 deletions libc/src/math/fminimum_magf16.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation header for fminimum_magf16 ---------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_MATH_FMINIMUM_MAGF16_H
#define LLVM_LIBC_SRC_MATH_FMINIMUM_MAGF16_H

#include "src/__support/macros/properties/types.h"

namespace LIBC_NAMESPACE {

float16 fminimum_magf16(float16 x, float16 y);

} // namespace LIBC_NAMESPACE

#endif // LLVM_LIBC_SRC_MATH_FMINIMUM_MAGF16_H
20 changes: 20 additions & 0 deletions libc/src/math/fminimum_numf16.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation header for fminimum_numf16 ---------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_MATH_FMINIMUM_NUMF16_H
#define LLVM_LIBC_SRC_MATH_FMINIMUM_NUMF16_H

#include "src/__support/macros/properties/types.h"

namespace LIBC_NAMESPACE {

float16 fminimum_numf16(float16 x, float16 y);

} // namespace LIBC_NAMESPACE

#endif // LLVM_LIBC_SRC_MATH_FMINIMUM_NUMF16_H
20 changes: 20 additions & 0 deletions libc/src/math/fminimumf16.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation header for fminimumf16 -------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_MATH_FMINIMUMF16_H
#define LLVM_LIBC_SRC_MATH_FMINIMUMF16_H

#include "src/__support/macros/properties/types.h"

namespace LIBC_NAMESPACE {

float16 fminimumf16(float16 x, float16 y);

} // namespace LIBC_NAMESPACE

#endif // LLVM_LIBC_SRC_MATH_FMINIMUMF16_H
158 changes: 156 additions & 2 deletions libc/src/math/generic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1894,6 +1894,19 @@ add_entrypoint_object(
-O2
)

add_entrypoint_object(
fmaximumf16
SRCS
fmaximumf16.cpp
HDRS
../fmaximumf16.h
DEPENDS
libc.src.__support.macros.properties.types
libc.src.__support.FPUtil.basic_operations
COMPILE_OPTIONS
-O3
)

add_entrypoint_object(
fmaximumf128
SRCS
Expand Down Expand Up @@ -1943,6 +1956,19 @@ add_entrypoint_object(
-O2
)

add_entrypoint_object(
fmaximum_numf16
SRCS
fmaximum_numf16.cpp
HDRS
../fmaximum_numf16.h
DEPENDS
libc.src.__support.macros.properties.types
libc.src.__support.FPUtil.basic_operations
COMPILE_OPTIONS
-O3
)

add_entrypoint_object(
fmaximum_numf128
SRCS
Expand Down Expand Up @@ -1992,6 +2018,19 @@ add_entrypoint_object(
-O2
)

add_entrypoint_object(
fmaximum_magf16
SRCS
fmaximum_magf16.cpp
HDRS
../fmaximum_magf16.h
DEPENDS
libc.src.__support.macros.properties.types
libc.src.__support.FPUtil.basic_operations
COMPILE_OPTIONS
-O3
)

add_entrypoint_object(
fmaximum_magf128
SRCS
Expand All @@ -2005,7 +2044,6 @@ add_entrypoint_object(
-O3
)


add_entrypoint_object(
fmaximum_mag_num
SRCS
Expand Down Expand Up @@ -2042,6 +2080,19 @@ add_entrypoint_object(
-O2
)

add_entrypoint_object(
fmaximum_mag_numf16
SRCS
fmaximum_mag_numf16.cpp
HDRS
../fmaximum_mag_numf16.h
DEPENDS
libc.src.__support.macros.properties.types
libc.src.__support.FPUtil.basic_operations
COMPILE_OPTIONS
-O3
)

add_entrypoint_object(
fmaximum_mag_numf128
SRCS
Expand Down Expand Up @@ -2091,6 +2142,19 @@ add_entrypoint_object(
-O2
)

add_entrypoint_object(
fminimumf16
SRCS
fminimumf16.cpp
HDRS
../fminimumf16.h
DEPENDS
libc.src.__support.macros.properties.types
libc.src.__support.FPUtil.basic_operations
COMPILE_OPTIONS
-O3
)

add_entrypoint_object(
fminimumf128
SRCS
Expand Down Expand Up @@ -2140,6 +2204,19 @@ add_entrypoint_object(
-O2
)

add_entrypoint_object(
fminimum_numf16
SRCS
fminimum_numf16.cpp
HDRS
../fminimum_numf16.h
DEPENDS
libc.src.__support.macros.properties.types
libc.src.__support.FPUtil.basic_operations
COMPILE_OPTIONS
-O3
)

add_entrypoint_object(
fminimum_numf128
SRCS
Expand Down Expand Up @@ -2189,6 +2266,19 @@ add_entrypoint_object(
-O2
)

add_entrypoint_object(
fminimum_magf16
SRCS
fminimum_magf16.cpp
HDRS
../fminimum_magf16.h
DEPENDS
libc.src.__support.macros.properties.types
libc.src.__support.FPUtil.basic_operations
COMPILE_OPTIONS
-O3
)

add_entrypoint_object(
fminimum_magf128
SRCS
Expand All @@ -2202,7 +2292,6 @@ add_entrypoint_object(
-O3
)


add_entrypoint_object(
fminimum_mag_num
SRCS
Expand Down Expand Up @@ -2239,6 +2328,19 @@ add_entrypoint_object(
-O2
)

add_entrypoint_object(
fminimum_mag_numf16
SRCS
fminimum_mag_numf16.cpp
HDRS
../fminimum_mag_numf16.h
DEPENDS
libc.src.__support.macros.properties.types
libc.src.__support.FPUtil.basic_operations
COMPILE_OPTIONS
-O3
)

add_entrypoint_object(
fminimum_mag_numf128
SRCS
Expand Down Expand Up @@ -2550,6 +2652,19 @@ add_entrypoint_object(
-O3
)

add_entrypoint_object(
nextafterf16
SRCS
nextafterf16.cpp
HDRS
../nextafterf16.h
DEPENDS
libc.src.__support.macros.properties.types
libc.src.__support.FPUtil.manipulation_functions
COMPILE_OPTIONS
-O3
)

add_entrypoint_object(
nextafterf128
SRCS
Expand Down Expand Up @@ -2599,6 +2714,19 @@ add_entrypoint_object(
-O3
)

add_entrypoint_object(
nexttowardf16
SRCS
nexttowardf16.cpp
HDRS
../nexttowardf16.h
DEPENDS
libc.src.__support.macros.properties.types
libc.src.__support.FPUtil.manipulation_functions
COMPILE_OPTIONS
-O3
)

add_entrypoint_object(
nextdown
SRCS
Expand Down Expand Up @@ -2635,6 +2763,19 @@ add_entrypoint_object(
-O3
)

add_entrypoint_object(
nextdownf16
SRCS
nextdownf16.cpp
HDRS
../nextdownf16.h
DEPENDS
libc.src.__support.macros.properties.types
libc.src.__support.FPUtil.manipulation_functions
COMPILE_OPTIONS
-O3
)

add_entrypoint_object(
nextdownf128
SRCS
Expand Down Expand Up @@ -2684,6 +2825,19 @@ add_entrypoint_object(
-O3
)

add_entrypoint_object(
nextupf16
SRCS
nextupf16.cpp
HDRS
../nextupf16.h
DEPENDS
libc.src.__support.macros.properties.types
libc.src.__support.FPUtil.manipulation_functions
COMPILE_OPTIONS
-O3
)

add_entrypoint_object(
nextupf128
SRCS
Expand Down
19 changes: 19 additions & 0 deletions libc/src/math/generic/fmaximum_mag_numf16.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===-- Implementation of fmaximum_mag_numf16 function --------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/math/fmaximum_mag_numf16.h"
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/common.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float16, fmaximum_mag_numf16, (float16 x, float16 y)) {
return fputil::fmaximum_mag_num(x, y);
}

} // namespace LIBC_NAMESPACE
19 changes: 19 additions & 0 deletions libc/src/math/generic/fmaximum_magf16.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===-- Implementation of fmaximum_magf16 function ------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/math/fmaximum_magf16.h"
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/common.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float16, fmaximum_magf16, (float16 x, float16 y)) {
return fputil::fmaximum_mag(x, y);
}

} // namespace LIBC_NAMESPACE
19 changes: 19 additions & 0 deletions libc/src/math/generic/fmaximum_numf16.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===-- Implementation of fmaximum_numf16 function ------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/math/fmaximum_numf16.h"
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/common.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float16, fmaximum_numf16, (float16 x, float16 y)) {
return fputil::fmaximum_num(x, y);
}

} // namespace LIBC_NAMESPACE
19 changes: 19 additions & 0 deletions libc/src/math/generic/fmaximumf16.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===-- Implementation of fmaximumf16 function ----------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/math/fmaximumf16.h"
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/common.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float16, fmaximumf16, (float16 x, float16 y)) {
return fputil::fmaximum(x, y);
}

} // namespace LIBC_NAMESPACE
19 changes: 19 additions & 0 deletions libc/src/math/generic/fminimum_mag_numf16.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===-- Implementation of fminimum_mag_numf16 function --------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/math/fminimum_mag_numf16.h"
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/common.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float16, fminimum_mag_numf16, (float16 x, float16 y)) {
return fputil::fminimum_mag_num(x, y);
}

} // namespace LIBC_NAMESPACE
19 changes: 19 additions & 0 deletions libc/src/math/generic/fminimum_magf16.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===-- Implementation of fminimum_magf16 function ------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/math/fminimum_magf16.h"
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/common.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float16, fminimum_magf16, (float16 x, float16 y)) {
return fputil::fminimum_mag(x, y);
}

} // namespace LIBC_NAMESPACE
19 changes: 19 additions & 0 deletions libc/src/math/generic/fminimum_numf16.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===-- Implementation of fminimum_numf16 function ------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/math/fminimum_numf16.h"
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/common.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float16, fminimum_numf16, (float16 x, float16 y)) {
return fputil::fminimum_num(x, y);
}

} // namespace LIBC_NAMESPACE
19 changes: 19 additions & 0 deletions libc/src/math/generic/fminimumf16.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===-- Implementation of fminimumf16 function ----------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/math/fminimumf16.h"
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/common.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float16, fminimumf16, (float16 x, float16 y)) {
return fputil::fminimum(x, y);
}

} // namespace LIBC_NAMESPACE
19 changes: 19 additions & 0 deletions libc/src/math/generic/nextafterf16.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===-- Implementation of nextafterf16 function ---------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/math/nextafterf16.h"
#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/__support/common.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float16, nextafterf16, (float16 x, float16 y)) {
return fputil::nextafter(x, y);
}

} // namespace LIBC_NAMESPACE
19 changes: 19 additions & 0 deletions libc/src/math/generic/nextdownf16.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===-- Implementation of nextdownf16 function ----------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/math/nextdownf16.h"
#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/__support/common.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float16, nextdownf16, (float16 x)) {
return fputil::nextupdown</*IsDown=*/true>(x);
}

} // namespace LIBC_NAMESPACE
21 changes: 21 additions & 0 deletions libc/src/math/generic/nexttowardf16.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===-- Implementation of nexttowardf16 function --------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/math/nexttowardf16.h"
#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/__support/common.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float16, nexttowardf16, (float16 x, long double y)) {
// We can reuse the nextafter implementation because the internal nextafter is
// templated on the types of the arguments.
return fputil::nextafter(x, y);
}

} // namespace LIBC_NAMESPACE
19 changes: 19 additions & 0 deletions libc/src/math/generic/nextupf16.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===-- Implementation of nextupf16 function ------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/math/nextupf16.h"
#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/__support/common.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float16, nextupf16, (float16 x)) {
return fputil::nextupdown</*IsDown=*/false>(x);
}

} // namespace LIBC_NAMESPACE
20 changes: 20 additions & 0 deletions libc/src/math/nextafterf16.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation header for nextafterf16 ------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_MATH_NEXTAFTERF16_H
#define LLVM_LIBC_SRC_MATH_NEXTAFTERF16_H

#include "src/__support/macros/properties/types.h"

namespace LIBC_NAMESPACE {

float16 nextafterf16(float16 x, float16 y);

} // namespace LIBC_NAMESPACE

#endif // LLVM_LIBC_SRC_MATH_NEXTAFTERF16_H
20 changes: 20 additions & 0 deletions libc/src/math/nextdownf16.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation header for nextdownf16 -------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_MATH_NEXTDOWNF16_H
#define LLVM_LIBC_SRC_MATH_NEXTDOWNF16_H

#include "src/__support/macros/properties/types.h"

namespace LIBC_NAMESPACE {

float16 nextdownf16(float16 x);

} // namespace LIBC_NAMESPACE

#endif // LLVM_LIBC_SRC_MATH_NEXTDOWNF16_H
20 changes: 20 additions & 0 deletions libc/src/math/nexttowardf16.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation header for nexttowardf16 -----------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_MATH_NEXTTOWARDF16_H
#define LLVM_LIBC_SRC_MATH_NEXTTOWARDF16_H

#include "src/__support/macros/properties/types.h"

namespace LIBC_NAMESPACE {

float16 nexttowardf16(float16 x, long double y);

} // namespace LIBC_NAMESPACE

#endif // LLVM_LIBC_SRC_MATH_NEXTTOWARDF16_H
20 changes: 20 additions & 0 deletions libc/src/math/nextupf16.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation header for nextupf16 ---------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_MATH_NEXTUPF16_H
#define LLVM_LIBC_SRC_MATH_NEXTUPF16_H

#include "src/__support/macros/properties/types.h"

namespace LIBC_NAMESPACE {

float16 nextupf16(float16 x);

} // namespace LIBC_NAMESPACE

#endif // LLVM_LIBC_SRC_MATH_NEXTUPF16_H
Loading