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/3] 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/3] 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;
+}

>From 625028aed5ad85922f082f5192abd5ceedb0b68d Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguel...@intel.com>
Date: Wed, 1 May 2024 08:44:50 -0700
Subject: [PATCH 3/3] Responded to review comments.

---
 clang/include/clang/Basic/Builtins.td    |  1 +
 clang/lib/AST/ExprConstant.cpp           |  8 +++--
 clang/test/CodeGenCXX/constexpr-math.cpp | 16 ++++++----
 clang/test/SemaCXX/constexpr-math.cpp    | 37 ++++++------------------
 4 files changed, 26 insertions(+), 36 deletions(-)

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index a35c77286229ff..419e623c7bc04c 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -3443,6 +3443,7 @@ def Frexp : FPMathTemplate, LibBuiltin<"math.h"> {
   let Attributes = [NoThrow, Constexpr];
   let Prototype = "T(T, int*)";
   let AddBuiltinPrefixedAlias = 1;
+  let OnlyBuiltinPrefixedAliasIsConstexpr = 1;
 }
 
 def Ldexp : FPMathTemplate, LibBuiltin<"math.h"> {
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 1a6abb386071c7..4e664905969ee9 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -14547,15 +14547,18 @@ bool FloatExprEvaluator::VisitCallExpr(const CallExpr 
*E) {
   default:
     return false;
 
+  case Builtin::BI__builtin_frexp:
   case Builtin::BI__builtin_frexpf:
-  case Builtin::BI__builtin_frexp: {
+  case Builtin::BI__builtin_frexpl: {
     LValue Pointer;
     if (!EvaluateFloat(E->getArg(0), Result, Info) ||
         !EvaluatePointer(E->getArg(1), Pointer, Info))
       return false;
     llvm::RoundingMode RM = getActiveRoundingMode(Info, E);
     int FrexpExp;
-    Result = llvm::frexp(Result, FrexpExp, RM);
+    FrexpExp = ilogb(Result);
+    FrexpExp = FrexpExp == llvm::detail::IEEEFloat::IEK_Zero ? 0 : FrexpExp + 
1;
+    Result =  scalbn(Result, -FrexpExp, RM);
     return true;
   }
   case Builtin::BI__builtin_huge_val:
@@ -14651,6 +14654,7 @@ bool FloatExprEvaluator::VisitCallExpr(const CallExpr 
*E) {
 
   case Builtin::BIfmin:
   case Builtin::BIfminf:
+  case Builtin::BIfminl:
   case Builtin::BI__builtin_fmin:
   case Builtin::BI__builtin_fminf:
   case Builtin::BI__builtin_fminl:
diff --git a/clang/test/CodeGenCXX/constexpr-math.cpp 
b/clang/test/CodeGenCXX/constexpr-math.cpp
index ad7b6779a4ae0e..a48c312d05af0a 100644
--- a/clang/test/CodeGenCXX/constexpr-math.cpp
+++ b/clang/test/CodeGenCXX/constexpr-math.cpp
@@ -24,15 +24,17 @@ int func()
   constexpr float f5 = __builtin_fminf(NAN, -1);
   constexpr float f6 = __builtin_fminf(-INFINITY, 0);
   constexpr float f7 = __builtin_fminf(INFINITY, 0);
+  constexpr long double f8 = __builtin_fminl(123.456L, 789.012L);
 
   // 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 f9 = __builtin_frexp(123.45, &i);
+  constexpr double f10 = __builtin_frexp(0.0, &i);
+  constexpr double f11 = __builtin_frexp(-0.0, &i);
+  constexpr double f12 = __builtin_frexpf(NAN, &i);
+  constexpr double f13 = __builtin_frexpf(-NAN, &i);
   constexpr double f14 = __builtin_frexpf(INFINITY, &i);
+  constexpr double f15 = __builtin_frexpf(INFINITY, &i);
+  constexpr long double f16 = __builtin_frexpl(259.328L, &i);
 
   return 0;
 }
@@ -44,6 +46,7 @@ int func()
 // LNX: store float 0x7FF8000000000000, ptr {{.*}}
 // CHECK: store float -1.000000e+00, ptr {{.*}}
 // CHECK: store float 0xFFF0000000000000, ptr {{.*}}
+// CHECK: store double 1.234560e+02, ptr {{.*}}
 
 // CHECK: store double 0x3FEEDCCCCCCCCCCD, ptr {{.*}}
 // CHECK: store double 0.000000e+00, ptr {{.*}}
@@ -53,3 +56,4 @@ int func()
 // LNX: store double 0xFFF8000000000000, ptr {{.*}}
 // CHECK: store double 0x7FF0000000000000, ptr {{.*}}
 // CHECK: store double 0x7FF0000000000000, ptr {{.*}}
+// CHECK: store double 5.065000e-01, ptr {{.*}}
diff --git a/clang/test/SemaCXX/constexpr-math.cpp 
b/clang/test/SemaCXX/constexpr-math.cpp
index f51ea1bcaf7bad..24e5bf70e3535c 100644
--- a/clang/test/SemaCXX/constexpr-math.cpp
+++ b/clang/test/SemaCXX/constexpr-math.cpp
@@ -12,19 +12,6 @@
 #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;
 
@@ -32,26 +19,20 @@ int main() {
     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)));
+    static_assert(__builtin_fminf(NAN, -1) == -1, "");
+    static_assert(__builtin_fminf(+INFINITY, 0) == 0, "");
+    static_assert(__builtin_isinf(__builtin_fminf(-INFINITY, 0)), "");
+    static_assert(__builtin_isnan(__builtin_fminf(NAN,NAN)), "");
 
     // 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);
+    static_assert(__builtin_isnan(__builtin_frexp(NAN, &i)));
+    static_assert(__builtin_isnan(__builtin_frexp(-NAN, &i)));
+    static_assert(!__builtin_isfinite(__builtin_frexp(INFINITY, &i)));
+    static_assert(!__builtin_isfinite(__builtin_frexp(-INFINITY, &i)));
+
     return 0;
 }

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to