https://github.com/zahiraam updated https://github.com/llvm/llvm-project/pull/88978
>From 3acc848f4fcc68445dfc849f9c6f8d384d3692af Mon Sep 17 00:00:00 2001 From: Zahira Ammarguellat <zahira.ammarguel...@intel.com> Date: Tue, 16 Apr 2024 13:09:58 -0700 Subject: [PATCH 1/2] Adding C23 constexpr math functions fmin and frexp. --- clang/include/clang/Basic/Builtins.td | 4 +-- clang/lib/AST/ExprConstant.cpp | 16 ++++++++- clang/test/CodeGen/constexpr-math.cpp | 51 +++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 clang/test/CodeGen/constexpr-math.cpp diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 52c0dd52c28b11..a35c77286229ff 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -3440,7 +3440,7 @@ def Fmod : FPMathTemplate, LibBuiltin<"math.h"> { def Frexp : FPMathTemplate, LibBuiltin<"math.h"> { let Spellings = ["frexp"]; - let Attributes = [NoThrow]; + let Attributes = [NoThrow, Constexpr]; let Prototype = "T(T, int*)"; let AddBuiltinPrefixedAlias = 1; } @@ -3618,7 +3618,7 @@ def Fmax : FPMathTemplate, LibBuiltin<"math.h"> { def Fmin : FPMathTemplate, LibBuiltin<"math.h"> { let Spellings = ["fmin"]; - let Attributes = [NoThrow, Const]; + let Attributes = [NoThrow, Const, Constexpr]; let Prototype = "T(T, T)"; let AddBuiltinPrefixedAlias = 1; let OnlyBuiltinPrefixedAliasIsConstexpr = 1; diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 5a36621dc5cce2..506621ac7e9c1b 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -2922,7 +2922,7 @@ static bool handleFloatFloatBinOp(EvalInfo &Info, const BinaryOperator *E, // If during the evaluation of an expression, the result is not // mathematically defined [...], the behavior is undefined. // FIXME: C++ rules require us to not conform to IEEE 754 here. - if (LHS.isNaN()) { + if (!Info.getLangOpts().CPlusPlus23 && LHS.isNaN()) { Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN(); return Info.noteUndefinedBehavior(); } @@ -14547,6 +14547,18 @@ bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) { default: return false; + case Builtin::BI__builtin_frexpf: + case Builtin::BI__builtin_frexp: { + LValue Pointer; + if (!EvaluateFloat(E->getArg(0), Result, Info) || + !EvaluatePointer(E->getArg(1), Pointer, Info)) + return false; + llvm::RoundingMode RM = + E->getFPFeaturesInEffect(Info.Ctx.getLangOpts()).getRoundingMode(); + int FrexpExp; + Result = llvm::frexp(Result, FrexpExp, RM); + return true; + } case Builtin::BI__builtin_huge_val: case Builtin::BI__builtin_huge_valf: case Builtin::BI__builtin_huge_vall: @@ -14638,6 +14650,8 @@ bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) { return true; } + case Builtin::BIfmin: + case Builtin::BIfminf: case Builtin::BI__builtin_fmin: case Builtin::BI__builtin_fminf: case Builtin::BI__builtin_fminl: diff --git a/clang/test/CodeGen/constexpr-math.cpp b/clang/test/CodeGen/constexpr-math.cpp new file mode 100644 index 00000000000000..446bf3f4f7a504 --- /dev/null +++ b/clang/test/CodeGen/constexpr-math.cpp @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 -x c++ -triple x86_64-unknown-unknown -std=c++23 \ +// RUN: -emit-llvm -o - %s | FileCheck %s + +// RUN %clang_cc1 -x c++ -triple x86_64-linux-gnu -emit-llvm -o - %s \ +// RUN -std=c++23 + +#define INFINITY ((float)(1e+300 * 1e+300)) +#define NAN (-(float)(INFINITY * 0.0F)) + +//constexpr double frexp ( double num, int* exp ); +//constexpr float foo ( float num, int* exp ); + +int func() +{ + int i; + + // fmin + constexpr double f1 = __builtin_fmin(15.24, 1.3); + constexpr double f2 = __builtin_fmin(-0.0, +0.0); + constexpr double f3 = __builtin_fmin(+0.0, -0.0); + constexpr float f4 = __builtin_fminf(NAN, NAN); + constexpr float f5 = __builtin_fminf(NAN, -1); + constexpr float f6 = __builtin_fminf(-INFINITY, 0); + constexpr float f7 = __builtin_fminf(INFINITY, 0); + + // frexp + constexpr double f8 = __builtin_frexp(123.45, &i); + constexpr double f9 = __builtin_frexp(0.0, &i); + constexpr double f10 = __builtin_frexp(-0.0, &i); + constexpr double f11 = __builtin_frexpf(NAN, &i); + constexpr double f12 = __builtin_frexpf(-NAN, &i); + constexpr double f13 = __builtin_frexpf(INFINITY, &i); + constexpr double f14 = __builtin_frexpf(INFINITY, &i); + + return 0; +} + +// CHECK: store double 1.300000e+00, ptr {{.*}} +// CHECK: store double -0.000000e+00, ptr {{.*}} +// CHECK: store double -0.000000e+00, ptr {{.*}} +// CHECK: store float 0xFFF8000000000000, ptr {{.*}} +// CHECK: store float -1.000000e+00, ptr {{.*}} +// CHECK: store float 0xFFF0000000000000, ptr {{.*}} + +// CHECK: store double 0x3FEEDCCCCCCCCCCD, ptr {{.*}} +// CHECK: store double 0.000000e+00, ptr {{.*}} +// CHECK: store double -0.000000e+00, ptr {{.*}} +// CHECK: store double 0xFFF8000000000000, ptr {{.*}} +// CHECK: store double 0x7FF8000000000000, ptr {{.*}} +// CHECK: store double 0x7FF0000000000000, ptr {{.*}} +// CHECK: store double 0x7FF0000000000000, ptr {{.*}} >From d7050b53a75a23024502a9e4f56b385256c4722f Mon Sep 17 00:00:00 2001 From: Zahira Ammarguellat <zahira.ammarguel...@intel.com> Date: Mon, 22 Apr 2024 13:32:56 -0700 Subject: [PATCH 2/2] Addressed review comments. --- clang/lib/AST/ExprConstant.cpp | 3 +- .../constexpr-math.cpp | 20 ++++--- clang/test/SemaCXX/constexpr-math.cpp | 57 +++++++++++++++++++ 3 files changed, 70 insertions(+), 10 deletions(-) rename clang/test/{CodeGen => CodeGenCXX}/constexpr-math.cpp (75%) create mode 100644 clang/test/SemaCXX/constexpr-math.cpp diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 506621ac7e9c1b..1a6abb386071c7 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -14553,8 +14553,7 @@ bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) { if (!EvaluateFloat(E->getArg(0), Result, Info) || !EvaluatePointer(E->getArg(1), Pointer, Info)) return false; - llvm::RoundingMode RM = - E->getFPFeaturesInEffect(Info.Ctx.getLangOpts()).getRoundingMode(); + llvm::RoundingMode RM = getActiveRoundingMode(Info, E); int FrexpExp; Result = llvm::frexp(Result, FrexpExp, RM); return true; diff --git a/clang/test/CodeGen/constexpr-math.cpp b/clang/test/CodeGenCXX/constexpr-math.cpp similarity index 75% rename from clang/test/CodeGen/constexpr-math.cpp rename to clang/test/CodeGenCXX/constexpr-math.cpp index 446bf3f4f7a504..ad7b6779a4ae0e 100644 --- a/clang/test/CodeGen/constexpr-math.cpp +++ b/clang/test/CodeGenCXX/constexpr-math.cpp @@ -1,14 +1,16 @@ // RUN: %clang_cc1 -x c++ -triple x86_64-unknown-unknown -std=c++23 \ -// RUN: -emit-llvm -o - %s | FileCheck %s +// RUN: -DWIN -emit-llvm -o - %s | FileCheck %s --check-prefixes=WIN -// RUN %clang_cc1 -x c++ -triple x86_64-linux-gnu -emit-llvm -o - %s \ -// RUN -std=c++23 +// RUN: %clang_cc1 -x c++ -triple x86_64-unknown-unknown -std=c++23 \ +// RUN: -emit-llvm -o - %s | FileCheck %s --check-prefixes=LNX +#ifdef WIN #define INFINITY ((float)(1e+300 * 1e+300)) #define NAN (-(float)(INFINITY * 0.0F)) - -//constexpr double frexp ( double num, int* exp ); -//constexpr float foo ( float num, int* exp ); +#else +#define NAN (__builtin_nanf("")) +#define INFINITY (__builtin_inff()) +#endif int func() { @@ -38,7 +40,8 @@ int func() // CHECK: store double 1.300000e+00, ptr {{.*}} // CHECK: store double -0.000000e+00, ptr {{.*}} // CHECK: store double -0.000000e+00, ptr {{.*}} -// CHECK: store float 0xFFF8000000000000, ptr {{.*}} +// WIN: store float 0xFFF8000000000000, ptr {{.*}} +// LNX: store float 0x7FF8000000000000, ptr {{.*}} // CHECK: store float -1.000000e+00, ptr {{.*}} // CHECK: store float 0xFFF0000000000000, ptr {{.*}} @@ -46,6 +49,7 @@ int func() // CHECK: store double 0.000000e+00, ptr {{.*}} // CHECK: store double -0.000000e+00, ptr {{.*}} // CHECK: store double 0xFFF8000000000000, ptr {{.*}} -// CHECK: store double 0x7FF8000000000000, ptr {{.*}} +// WIN: store double 0x7FF8000000000000, ptr {{.*}} +// LNX: store double 0xFFF8000000000000, ptr {{.*}} // CHECK: store double 0x7FF0000000000000, ptr {{.*}} // CHECK: store double 0x7FF0000000000000, ptr {{.*}} diff --git a/clang/test/SemaCXX/constexpr-math.cpp b/clang/test/SemaCXX/constexpr-math.cpp new file mode 100644 index 00000000000000..f51ea1bcaf7bad --- /dev/null +++ b/clang/test/SemaCXX/constexpr-math.cpp @@ -0,0 +1,57 @@ +// RUN: %clang_cc1 -DWIN -verify -std=c++23 -fsyntax-only %s +// RUN: %clang_cc1 -verify -std=c++23 -fsyntax-only %s + +// expected-no-diagnostics + + +#ifdef WIN +#define INFINITY ((float)(1e+300 * 1e+300)) +#define NAN (-(float)(INFINITY * 0.0F)) +#else +#define NAN (__builtin_nanf("")) +#define INFINITY (__builtin_inff()) +#endif + +extern "C" void abort() noexcept; +extern "C" int write(int, const void*, unsigned long); + +#define assert(condition) \ + do { \ + if (!(condition)) { \ + write(2, "Assertion failed: ", 18); \ + write(2, #condition, sizeof(#condition) - 1); \ + write(2, "\n", 1); \ + abort(); \ + } \ + } while (false) + +int main() { + int i; + + // fmin + static_assert(__builtin_fmin(15.24, 1.3) == 1.3, ""); + static_assert(__builtin_fmin(-0.0, +0.0) == -0.0, ""); + static_assert(__builtin_fmin(+0.0, -0.0) == -0.0, ""); + assert(__builtin_isnan(__builtin_fminf(NAN,NAN))); + assert(__builtin_isnan(__builtin_fminf(NAN, -1))); + assert(__builtin_isnan(__builtin_fminf(-INFINITY, 0))); + assert(__builtin_iszero(__builtin_fminf(+INFINITY, 0))); + + // frexp + static_assert(__builtin_frexp(123.45, &i) == 0.96445312500000002); + static_assert(!__builtin_isnan(__builtin_frexp(123.45, &i)), ""); + assert(i==0); + static_assert(__builtin_iszero(__builtin_frexp(0.0, &i)), ""); + assert(i==0); + static_assert(__builtin_iszero(__builtin_frexp(-0.0, &i)), ""); + assert(i==0); + assert(__builtin_isnan(__builtin_frexp(NAN, &i))); + assert(i==0); + assert(__builtin_isnan(__builtin_frexp(-NAN, &i))); + assert(i==0); + assert(!__builtin_isfinite(__builtin_frexp(INFINITY, &i))); + assert(i==0); + assert(!__builtin_isfinite(__builtin_frexp(-INFINITY, &i))); + assert(i==0); + return 0; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits