[clang] Clang: Support minimumnum and maximumnum intrinsics (PR #96281)

YunQiang Su via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 14 00:00:32 PDT 2024


https://github.com/wzssyqa updated https://github.com/llvm/llvm-project/pull/96281

>From 98e909e0eff233c2ee3c5e7f3094e35004326bd0 Mon Sep 17 00:00:00 2001
From: YunQiang Su <syq at gcc.gnu.org>
Date: Fri, 21 Jun 2024 14:28:42 +0800
Subject: [PATCH 01/12] Clang: Support minimumnum and maximumnum intrinsics

We just introduce llvm.minimumnum and llvm.maximumnum intrinsics
support to llvm. Let's support them in Clang.

See: #93033
---
 clang/include/clang/Basic/Builtins.td         | 28 +++++++++++++++++++
 clang/lib/CodeGen/CGBuiltin.cpp               | 24 ++++++++++++++++
 .../Tooling/Inclusions/Stdlib/CSymbolMap.inc  |  6 ++++
 .../Inclusions/Stdlib/StdSymbolMap.inc        | 18 ++++++++++++
 clang/test/CodeGen/builtins.c                 | 18 ++++++++++++
 clang/test/CodeGen/math-libcalls.c            | 25 +++++++++++++++++
 6 files changed, 119 insertions(+)

diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index 7068473a0e12ac..a7e2ee30d9d732 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -215,6 +215,18 @@ def FminF16F128 : Builtin, F16F128MathTemplate {
   let Prototype = "T(T, T)";
 }
 
+def FmaximumNumF16F128 : Builtin, F16F128MathTemplate {
+  let Spellings = ["__builtin_fmaximum_num"];
+  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, Constexpr];
+  let Prototype = "T(T, T)";
+}
+
+def FminimumNumF16F128 : Builtin, F16F128MathTemplate {
+  let Spellings = ["__builtin_fminimum_num"];
+  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, Constexpr];
+  let Prototype = "T(T, T)";
+}
+
 def Atan2F128 : Builtin {
   let Spellings = ["__builtin_atan2f128"];
   let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions];
@@ -3728,6 +3740,22 @@ def Fmin : FPMathTemplate, LibBuiltin<"math.h"> {
   let OnlyBuiltinPrefixedAliasIsConstexpr = 1;
 }
 
+def FmaximumNum : FPMathTemplate, LibBuiltin<"math.h"> {
+  let Spellings = ["fmaximum_num"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "T(T, T)";
+  let AddBuiltinPrefixedAlias = 1;
+  let OnlyBuiltinPrefixedAliasIsConstexpr = 1;
+}
+
+def FminimumNum : FPMathTemplate, LibBuiltin<"math.h"> {
+  let Spellings = ["fminimum_num"];
+  let Attributes = [NoThrow, Const];
+  let Prototype = "T(T, T)";
+  let AddBuiltinPrefixedAlias = 1;
+  let OnlyBuiltinPrefixedAliasIsConstexpr = 1;
+}
+
 def Hypot : FPMathTemplate, LibBuiltin<"math.h"> {
   let Spellings = ["hypot"];
   let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions];
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 465afd04740d89..0988f090174817 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -2869,6 +2869,30 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
                                    Intrinsic::minnum,
                                    Intrinsic::experimental_constrained_minnum));
 
+    case Builtin::BIfmaximum_num:
+    case Builtin::BIfmaximum_numf:
+    case Builtin::BIfmaximum_numl:
+    case Builtin::BI__builtin_fmaximum_num:
+    case Builtin::BI__builtin_fmaximum_numf:
+    case Builtin::BI__builtin_fmaximum_numf16:
+    case Builtin::BI__builtin_fmaximum_numl:
+    case Builtin::BI__builtin_fmaximum_numf128:
+      return RValue::get(emitBinaryMaybeConstrainedFPBuiltin(
+          *this, E, Intrinsic::maximumnum,
+          Intrinsic::experimental_constrained_maximumnum));
+
+    case Builtin::BIfminimum_num:
+    case Builtin::BIfminimum_numf:
+    case Builtin::BIfminimum_numl:
+    case Builtin::BI__builtin_fminimum_num:
+    case Builtin::BI__builtin_fminimum_numf:
+    case Builtin::BI__builtin_fminimum_numf16:
+    case Builtin::BI__builtin_fminimum_numl:
+    case Builtin::BI__builtin_fminimum_numf128:
+      return RValue::get(emitBinaryMaybeConstrainedFPBuiltin(
+          *this, E, Intrinsic::minimumnum,
+          Intrinsic::experimental_constrained_minimumnum));
+
     // fmod() is a special-case. It maps to the frem instruction rather than an
     // LLVM intrinsic.
     case Builtin::BIfmod:
diff --git a/clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc b/clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc
index 463ce921f0672f..af2dcb632fbb64 100644
--- a/clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc
+++ b/clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc
@@ -475,6 +475,12 @@ SYMBOL(fmaxl, None, <math.h>)
 SYMBOL(fmin, None, <math.h>)
 SYMBOL(fminf, None, <math.h>)
 SYMBOL(fminl, None, <math.h>)
+SYMBOL(fmaximum_num, None, <math.h>)
+SYMBOL(fmaximum_numf, None, <math.h>)
+SYMBOL(fmaximum_numfl, None, <math.h>)
+SYMBOL(fminimum_num, None, <math.h>)
+SYMBOL(fminimum_numf, None, <math.h>)
+SYMBOL(fminimum_numl, None, <math.h>)
 SYMBOL(fmod, None, <math.h>)
 SYMBOL(fmodf, None, <math.h>)
 SYMBOL(fmodl, None, <math.h>)
diff --git a/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc b/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc
index b46bd2e4d7a4b5..442316ce8d4ff6 100644
--- a/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc
+++ b/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc
@@ -1295,6 +1295,24 @@ SYMBOL(fminf, None, <math.h>)
 SYMBOL(fminl, std::, <cmath>)
 SYMBOL(fminl, None, <cmath>)
 SYMBOL(fminl, None, <math.h>)
+SYMBOL(fmaximum_num, std::, <cmath>)
+SYMBOL(fmaximum_num, None, <cmath>)
+SYMBOL(fmaximum_num, None, <math.h>)
+SYMBOL(fmaximum_numf, std::, <cmath>)
+SYMBOL(fmaximum_numf, None, <cmath>)
+SYMBOL(fmaximum_numf, None, <math.h>)
+SYMBOL(fmaximum_numl, std::, <cmath>)
+SYMBOL(fmaximum_numl, None, <cmath>)
+SYMBOL(fmaximum_numl, None, <math.h>)
+SYMBOL(fminimum_num, std::, <cmath>)
+SYMBOL(fminimum_num, None, <cmath>)
+SYMBOL(fminimum_num, None, <math.h>)
+SYMBOL(fminimum_numf, std::, <cmath>)
+SYMBOL(fminimum_numf, None, <cmath>)
+SYMBOL(fminimum_numf, None, <math.h>)
+SYMBOL(fminimum_numl, std::, <cmath>)
+SYMBOL(fminimum_numl, None, <cmath>)
+SYMBOL(fminimum_numl, None, <math.h>)
 SYMBOL(fmod, std::, <cmath>)
 SYMBOL(fmod, None, <cmath>)
 SYMBOL(fmod, None, <math.h>)
diff --git a/clang/test/CodeGen/builtins.c b/clang/test/CodeGen/builtins.c
index 6383a3c65e3750..2ac2cf44c4c771 100644
--- a/clang/test/CodeGen/builtins.c
+++ b/clang/test/CodeGen/builtins.c
@@ -353,6 +353,24 @@ void test_float_builtin_ops(float F, double D, long double LD) {
   resld = __builtin_fmaxl(LD, LD);
   // CHECK: call x86_fp80 @llvm.maxnum.f80
 
+  resf = __builtin_fminimum_numf(F, F);
+  // CHECK: call float @llvm.minimumnum.f32
+
+  resd = __builtin_fminimum_num(D, D);
+  // CHECK: call double @llvm.minimumnum.f64
+
+  resld = __builtin_fminimum_numl(LD, LD);
+  // CHECK: call x86_fp80 @llvm.minimumnum.f80
+
+  resf = __builtin_fmaximum_numf(F, F);
+  // CHECK: call float @llvm.maximumnum.f32
+
+  resd = __builtin_fmaximum_num(D, D);
+  // CHECK: call double @llvm.maximumnum.f64
+
+  resld = __builtin_fmaximum_numl(LD, LD);
+  // CHECK: call x86_fp80 @llvm.maximumnum.f80
+
   resf = __builtin_fabsf(F);
   // CHECK: call float @llvm.fabs.f32
 
diff --git a/clang/test/CodeGen/math-libcalls.c b/clang/test/CodeGen/math-libcalls.c
index 5b23a4a3faef36..9ba17baa3cd39a 100644
--- a/clang/test/CodeGen/math-libcalls.c
+++ b/clang/test/CodeGen/math-libcalls.c
@@ -372,6 +372,31 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
 // HAS_MAYTRAP: declare float @llvm.experimental.constrained.minnum.f32(
 // HAS_MAYTRAP: declare x86_fp80 @llvm.experimental.constrained.minnum.f80(
 
+  fmaximum_num(f,f);       fmaximum_numf(f,f);      fmaximum_numl(f,f);
+
+// NO__ERRNO: declare double @llvm.maximumnum.f64(double, double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.maximumnum.f32(float, float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.maximumnum.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @llvm.maximumnum.f64(double, double) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare float @llvm.maximumnum.f32(float, float) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare x86_fp80 @llvm.maximumnum.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_MAYTRAP: declare double @llvm.experimental.constrained.maximumnum.f64(
+// HAS_MAYTRAP: declare float @llvm.experimental.constrained.maximumnum.f32(
+// HAS_MAYTRAP: declare x86_fp80 @llvm.experimental.constrained.maximumnum.f80(
+
+  fminimum_num(f,f);       fminimum_numf(f,f);      fminimum_numl(f,f);
+
+// NO__ERRNO: declare double @llvm.minimumnum.f64(double, double) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare float @llvm.minimumnum.f32(float, float) [[READNONE_INTRINSIC]]
+// NO__ERRNO: declare x86_fp80 @llvm.minimumnum.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare double @llvm.minimumnum.f64(double, double) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare float @llvm.minimumnum.f32(float, float) [[READNONE_INTRINSIC]]
+// HAS_ERRNO: declare x86_fp80 @llvm.minimumnum.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
+// HAS_MAYTRAP: declare double @llvm.experimental.constrained.minimumnum.f64(
+// HAS_MAYTRAP: declare float @llvm.experimental.constrained.minimumnum.f32(
+// HAS_MAYTRAP: declare x86_fp80 @llvm.experimental.constrained.minimumnum.f80(
+
+
   hypot(f,f);      hypotf(f,f);     hypotl(f,f);
 
 // NO__ERRNO: declare double @hypot(double noundef, double noundef) [[READNONE]]

>From f1434432dc16878113f29bbab3107b8ddfc2bcff Mon Sep 17 00:00:00 2001
From: YunQiang Su <syq at gcc.gnu.org>
Date: Wed, 26 Jun 2024 13:33:26 +0800
Subject: [PATCH 02/12] Add ExprConstant support

---
 clang/lib/AST/ExprConstant.cpp            | 27 +++++++++++++++++++++++
 clang/test/Preprocessor/feature_tests.cpp |  4 +++-
 2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 70b223596d8b9b..e876fecfe8cb95 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -15310,6 +15310,33 @@ bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) {
       Result = RHS;
     return true;
   }
+
+  case Builtin::BI__builtin_fmaximum_num:
+  case Builtin::BI__builtin_fmaximum_numf:
+  case Builtin::BI__builtin_fmaximum_numl:
+  case Builtin::BI__builtin_fmaximum_numf16:
+  case Builtin::BI__builtin_fmaximum_numf128: {
+    APFloat RHS(0.);
+    if (!EvaluateFloat(E->getArg(0), Result, Info) ||
+        !EvaluateFloat(E->getArg(1), RHS, Info))
+      return false;
+    Result = maximumnum(Result, RHS);
+    return true;
+  }
+
+  case Builtin::BI__builtin_fminimum_num:
+  case Builtin::BI__builtin_fminimum_numf:
+  case Builtin::BI__builtin_fminimum_numl:
+  case Builtin::BI__builtin_fminimum_numf16:
+  case Builtin::BI__builtin_fminimum_numf128: {
+    APFloat RHS(0.);
+    if (!EvaluateFloat(E->getArg(0), Result, Info) ||
+        !EvaluateFloat(E->getArg(1), RHS, Info))
+      return false;
+    Result = minimumnum(Result, RHS);
+    return true;
+  }
+
   }
 }
 
diff --git a/clang/test/Preprocessor/feature_tests.cpp b/clang/test/Preprocessor/feature_tests.cpp
index 13e2a9a261b667..a6079817734133 100644
--- a/clang/test/Preprocessor/feature_tests.cpp
+++ b/clang/test/Preprocessor/feature_tests.cpp
@@ -58,7 +58,9 @@
 
 // Check __has_constexpr_builtin
 #if  !__has_constexpr_builtin(__builtin_fmax) || \
-     !__has_constexpr_builtin(__builtin_fmin)
+     !__has_constexpr_builtin(__builtin_fmin) || \
+     !__has_constexpr_builtin(__builtin_fmaximum_num) || \
+     !__has_constexpr_builtin(__builtin_fmaximum_num)
 #error Clang should have these constexpr builtins
 #endif
 

>From 03982c2604f8dc0a06ab782adf93d0ff042a8de8 Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Fri, 11 Oct 2024 14:04:49 +0800
Subject: [PATCH 03/12] remove experimental_constrained_minimumnum

---
 clang/lib/CodeGen/CGBuiltin.cpp    | 10 ++++------
 clang/test/CodeGen/math-libcalls.c | 12 ++++++------
 2 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 0988f090174817..c563f2618b42c8 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -2877,9 +2877,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
     case Builtin::BI__builtin_fmaximum_numf16:
     case Builtin::BI__builtin_fmaximum_numl:
     case Builtin::BI__builtin_fmaximum_numf128:
-      return RValue::get(emitBinaryMaybeConstrainedFPBuiltin(
-          *this, E, Intrinsic::maximumnum,
-          Intrinsic::experimental_constrained_maximumnum));
+      return RValue::get(
+          emitBuiltinWithOneOverloadedType<2>(*this, E, Intrinsic::maximumnum));
 
     case Builtin::BIfminimum_num:
     case Builtin::BIfminimum_numf:
@@ -2889,9 +2888,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
     case Builtin::BI__builtin_fminimum_numf16:
     case Builtin::BI__builtin_fminimum_numl:
     case Builtin::BI__builtin_fminimum_numf128:
-      return RValue::get(emitBinaryMaybeConstrainedFPBuiltin(
-          *this, E, Intrinsic::minimumnum,
-          Intrinsic::experimental_constrained_minimumnum));
+      return RValue::get(
+          emitBuiltinWithOneOverloadedType<2>(*this, E, Intrinsic::minimumnum));
 
     // fmod() is a special-case. It maps to the frem instruction rather than an
     // LLVM intrinsic.
diff --git a/clang/test/CodeGen/math-libcalls.c b/clang/test/CodeGen/math-libcalls.c
index 9ba17baa3cd39a..265619071c16e1 100644
--- a/clang/test/CodeGen/math-libcalls.c
+++ b/clang/test/CodeGen/math-libcalls.c
@@ -380,9 +380,9 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
 // HAS_ERRNO: declare double @llvm.maximumnum.f64(double, double) [[READNONE_INTRINSIC]]
 // HAS_ERRNO: declare float @llvm.maximumnum.f32(float, float) [[READNONE_INTRINSIC]]
 // HAS_ERRNO: declare x86_fp80 @llvm.maximumnum.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
-// HAS_MAYTRAP: declare double @llvm.experimental.constrained.maximumnum.f64(
-// HAS_MAYTRAP: declare float @llvm.experimental.constrained.maximumnum.f32(
-// HAS_MAYTRAP: declare x86_fp80 @llvm.experimental.constrained.maximumnum.f80(
+// HAS_MAYTRAP: declare double @llvm.maximumnum.f64(
+// HAS_MAYTRAP: declare float @llvm.maximumnum.f32(
+// HAS_MAYTRAP: declare x86_fp80 @llvm.maximumnum.f80(
 
   fminimum_num(f,f);       fminimum_numf(f,f);      fminimum_numl(f,f);
 
@@ -392,9 +392,9 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
 // HAS_ERRNO: declare double @llvm.minimumnum.f64(double, double) [[READNONE_INTRINSIC]]
 // HAS_ERRNO: declare float @llvm.minimumnum.f32(float, float) [[READNONE_INTRINSIC]]
 // HAS_ERRNO: declare x86_fp80 @llvm.minimumnum.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
-// HAS_MAYTRAP: declare double @llvm.experimental.constrained.minimumnum.f64(
-// HAS_MAYTRAP: declare float @llvm.experimental.constrained.minimumnum.f32(
-// HAS_MAYTRAP: declare x86_fp80 @llvm.experimental.constrained.minimumnum.f80(
+// HAS_MAYTRAP: declare double @llvm.minimumnum.f64(
+// HAS_MAYTRAP: declare float @llvm.minimumnum.f32(
+// HAS_MAYTRAP: declare x86_fp80 @llvm.minimumnum.f80(
 
 
   hypot(f,f);      hypotf(f,f);     hypotl(f,f);

>From 0329600b0133fd816d35065a6e43efbbccce2680 Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Fri, 11 Oct 2024 14:10:31 +0800
Subject: [PATCH 04/12] fix code style

---
 clang/lib/AST/ExprConstant.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index e876fecfe8cb95..51956c631786b5 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -15336,7 +15336,6 @@ bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) {
     Result = minimumnum(Result, RHS);
     return true;
   }
-
   }
 }
 

>From 783b396133ef2d364f7d7b5e4fc243507b426217 Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Fri, 11 Oct 2024 20:35:11 +0800
Subject: [PATCH 05/12] remove from StdSymbolMap.inc

---
 .../Tooling/Inclusions/Stdlib/CSymbolMap.inc   |  6 ------
 .../Tooling/Inclusions/Stdlib/StdSymbolMap.inc | 18 ------------------
 clang/test/CodeGen/math-libcalls.c             |  4 ++--
 3 files changed, 2 insertions(+), 26 deletions(-)

diff --git a/clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc b/clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc
index af2dcb632fbb64..463ce921f0672f 100644
--- a/clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc
+++ b/clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc
@@ -475,12 +475,6 @@ SYMBOL(fmaxl, None, <math.h>)
 SYMBOL(fmin, None, <math.h>)
 SYMBOL(fminf, None, <math.h>)
 SYMBOL(fminl, None, <math.h>)
-SYMBOL(fmaximum_num, None, <math.h>)
-SYMBOL(fmaximum_numf, None, <math.h>)
-SYMBOL(fmaximum_numfl, None, <math.h>)
-SYMBOL(fminimum_num, None, <math.h>)
-SYMBOL(fminimum_numf, None, <math.h>)
-SYMBOL(fminimum_numl, None, <math.h>)
 SYMBOL(fmod, None, <math.h>)
 SYMBOL(fmodf, None, <math.h>)
 SYMBOL(fmodl, None, <math.h>)
diff --git a/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc b/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc
index 442316ce8d4ff6..b46bd2e4d7a4b5 100644
--- a/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc
+++ b/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc
@@ -1295,24 +1295,6 @@ SYMBOL(fminf, None, <math.h>)
 SYMBOL(fminl, std::, <cmath>)
 SYMBOL(fminl, None, <cmath>)
 SYMBOL(fminl, None, <math.h>)
-SYMBOL(fmaximum_num, std::, <cmath>)
-SYMBOL(fmaximum_num, None, <cmath>)
-SYMBOL(fmaximum_num, None, <math.h>)
-SYMBOL(fmaximum_numf, std::, <cmath>)
-SYMBOL(fmaximum_numf, None, <cmath>)
-SYMBOL(fmaximum_numf, None, <math.h>)
-SYMBOL(fmaximum_numl, std::, <cmath>)
-SYMBOL(fmaximum_numl, None, <cmath>)
-SYMBOL(fmaximum_numl, None, <math.h>)
-SYMBOL(fminimum_num, std::, <cmath>)
-SYMBOL(fminimum_num, None, <cmath>)
-SYMBOL(fminimum_num, None, <math.h>)
-SYMBOL(fminimum_numf, std::, <cmath>)
-SYMBOL(fminimum_numf, None, <cmath>)
-SYMBOL(fminimum_numf, None, <math.h>)
-SYMBOL(fminimum_numl, std::, <cmath>)
-SYMBOL(fminimum_numl, None, <cmath>)
-SYMBOL(fminimum_numl, None, <math.h>)
 SYMBOL(fmod, std::, <cmath>)
 SYMBOL(fmod, None, <cmath>)
 SYMBOL(fmod, None, <math.h>)
diff --git a/clang/test/CodeGen/math-libcalls.c b/clang/test/CodeGen/math-libcalls.c
index 265619071c16e1..4217d615be7628 100644
--- a/clang/test/CodeGen/math-libcalls.c
+++ b/clang/test/CodeGen/math-libcalls.c
@@ -372,7 +372,7 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
 // HAS_MAYTRAP: declare float @llvm.experimental.constrained.minnum.f32(
 // HAS_MAYTRAP: declare x86_fp80 @llvm.experimental.constrained.minnum.f80(
 
-  fmaximum_num(f,f);       fmaximum_numf(f,f);      fmaximum_numl(f,f);
+  fmaximum_num(*d,*d);       fmaximum_numf(f,f);      fmaximum_numl(*l,*l);
 
 // NO__ERRNO: declare double @llvm.maximumnum.f64(double, double) [[READNONE_INTRINSIC]]
 // NO__ERRNO: declare float @llvm.maximumnum.f32(float, float) [[READNONE_INTRINSIC]]
@@ -384,7 +384,7 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
 // HAS_MAYTRAP: declare float @llvm.maximumnum.f32(
 // HAS_MAYTRAP: declare x86_fp80 @llvm.maximumnum.f80(
 
-  fminimum_num(f,f);       fminimum_numf(f,f);      fminimum_numl(f,f);
+  fminimum_num(*d,*d);       fminimum_numf(f,f);      fminimum_numl(*l,*l);
 
 // NO__ERRNO: declare double @llvm.minimumnum.f64(double, double) [[READNONE_INTRINSIC]]
 // NO__ERRNO: declare float @llvm.minimumnum.f32(float, float) [[READNONE_INTRINSIC]]

>From 9938086c048382e69ef56dfc1fc3308492df623d Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Fri, 11 Oct 2024 21:34:57 +0800
Subject: [PATCH 06/12] add constexpr evaluation and passes a int

---
 clang/test/CodeGen/builtins.c | 51 +++++++++++++++++++++++++++++++----
 1 file changed, 46 insertions(+), 5 deletions(-)

diff --git a/clang/test/CodeGen/builtins.c b/clang/test/CodeGen/builtins.c
index 2ac2cf44c4c771..eda6c67fdad00c 100644
--- a/clang/test/CodeGen/builtins.c
+++ b/clang/test/CodeGen/builtins.c
@@ -69,6 +69,13 @@ int main(void) {
   P(issignaling, (1.));
   P(isfpclass, (1., 1));
 
+  Q(fmaximum_num, (1.0, 2.0));
+  Q(fmaximum_numf, (1.0, 2.0));
+  Q(fmaximum_numl, (1.0, 2.0));
+  Q(fminimum_num, (1.0, 2.0));
+  Q(fminimum_numf, (1.0, 2.0));
+  Q(fminimum_numl, (1.0, 2.0));
+
   // Bitwise & Numeric Functions
 
   P(abs, (N));
@@ -305,7 +312,7 @@ void test_float_builtins(__fp16 *H, float F, double D, long double LD) {
 }
 
 // CHECK-LABEL: define{{.*}} void @test_float_builtin_ops
-void test_float_builtin_ops(float F, double D, long double LD) {
+void test_float_builtin_ops(float F, double D, long double LD, int I) {
   volatile float resf;
   volatile double resd;
   volatile long double resld;
@@ -356,20 +363,54 @@ void test_float_builtin_ops(float F, double D, long double LD) {
   resf = __builtin_fminimum_numf(F, F);
   // CHECK: call float @llvm.minimumnum.f32
 
+  resf = __builtin_fminimum_numf(I, I);
+  // CHECK: sitofp i32 {{%[0-9]+}} to float
+  // CHECK: sitofp i32 {{%[0-9]+}} to float
+  // CHECK: call float @llvm.minimumnum.f32
+
+  resf = __builtin_fminimum_numf(1.0, 2.0);
+  // CHECK: store volatile float 1.000000e+00, ptr %resf
+
   resd = __builtin_fminimum_num(D, D);
   // CHECK: call double @llvm.minimumnum.f64
 
-  resld = __builtin_fminimum_numl(LD, LD);
-  // CHECK: call x86_fp80 @llvm.minimumnum.f80
+  resd = __builtin_fminimum_num(I, I);
+  // CHECK: sitofp i32 {{%[0-9]+}} to double
+  // CHECK: sitofp i32 {{%[0-9]+}} to double
+  // CHECK: call double @llvm.minimumnum.f64
+
+  resd = __builtin_fminimum_num(1.0, 2.0);
+  // CHECK: store volatile double 1.000000e+00, ptr %resd
+
+  //FIXME: __builtin_fminimum_numl is not supported well yet.
+  resld = __builtin_fminimum_numl(1.0, 2.0);
+  // CHECK: store volatile x86_fp80 0xK3FFF8000000000000000, ptr %resld, align 16
 
   resf = __builtin_fmaximum_numf(F, F);
   // CHECK: call float @llvm.maximumnum.f32
 
+  resf = __builtin_fmaximum_numf(I, I);
+  // CHECK: sitofp i32 {{%[0-9]+}} to float
+  // CHECK: sitofp i32 {{%[0-9]+}} to float
+  // CHECK: call float @llvm.maximumnum.f32
+
+  resf = __builtin_fmaximum_numf(1.0, 2.0);
+  // CHECK: store volatile float 2.000000e+00, ptr %resf
+
   resd = __builtin_fmaximum_num(D, D);
   // CHECK: call double @llvm.maximumnum.f64
 
-  resld = __builtin_fmaximum_numl(LD, LD);
-  // CHECK: call x86_fp80 @llvm.maximumnum.f80
+  resd = __builtin_fmaximum_num(I, I);
+  // CHECK: sitofp i32 {{%[0-9]+}} to double
+  // CHECK: sitofp i32 {{%[0-9]+}} to double
+  // CHECK: call double @llvm.maximumnum.f64
+
+  resd = __builtin_fmaximum_num(1.0, 2.0);
+  // CHECK: store volatile double 2.000000e+00, ptr %resd
+
+  //FIXME: __builtin_fmaximum_numl is not supported well yet.
+  resld = __builtin_fmaximum_numl(1.0, 2.0);
+  // CHECK: store volatile x86_fp80 0xK40008000000000000000, ptr %resld, align 16
 
   resf = __builtin_fabsf(F);
   // CHECK: call float @llvm.fabs.f32

>From 9c8d2378a16359463b65012febbbab387c8c16af Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Fri, 11 Oct 2024 21:39:18 +0800
Subject: [PATCH 07/12] fix typo in clang/test/Preprocessor/feature_tests.cpp

---
 clang/test/Preprocessor/feature_tests.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/Preprocessor/feature_tests.cpp b/clang/test/Preprocessor/feature_tests.cpp
index a6079817734133..3bda3db70ed0da 100644
--- a/clang/test/Preprocessor/feature_tests.cpp
+++ b/clang/test/Preprocessor/feature_tests.cpp
@@ -60,7 +60,7 @@
 #if  !__has_constexpr_builtin(__builtin_fmax) || \
      !__has_constexpr_builtin(__builtin_fmin) || \
      !__has_constexpr_builtin(__builtin_fmaximum_num) || \
-     !__has_constexpr_builtin(__builtin_fmaximum_num)
+     !__has_constexpr_builtin(__builtin_fminimum_num)
 #error Clang should have these constexpr builtins
 #endif
 

>From 7f60acb29788ee01b874f1d057656ef6a73efedd Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Fri, 11 Oct 2024 22:21:03 +0800
Subject: [PATCH 08/12] add constexpr evaluation tests in Sema

---
 .../Sema/constant-builtins-fmaximum-num.cpp   | 55 +++++++++++++++++++
 .../Sema/constant-builtins-fminimum-num.cpp   | 55 +++++++++++++++++++
 2 files changed, 110 insertions(+)
 create mode 100644 clang/test/Sema/constant-builtins-fmaximum-num.cpp
 create mode 100644 clang/test/Sema/constant-builtins-fminimum-num.cpp

diff --git a/clang/test/Sema/constant-builtins-fmaximum-num.cpp b/clang/test/Sema/constant-builtins-fmaximum-num.cpp
new file mode 100644
index 00000000000000..7a5425bbbe0637
--- /dev/null
+++ b/clang/test/Sema/constant-builtins-fmaximum-num.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s
+// FIXME: %clang_cc1 -std=c++17 -fsyntax-only -verify -fexperimental-new-constant-interpreter %s
+// expected-no-diagnostics
+
+constexpr double NaN = __builtin_nan("");
+constexpr double Inf = __builtin_inf();
+constexpr double NegInf = -__builtin_inf();
+
+#define FMAXIMUMNUM_TEST_SIMPLE(T, FUNC)                           \
+    static_assert(T(6.7890) == FUNC(T(1.2345), T(6.7890))); \
+    static_assert(T(6.7890) == FUNC(T(6.7890), T(1.2345)));
+
+#define FMAXIMUMNUM_TEST_NAN(T, FUNC)                          \
+    static_assert(Inf == FUNC(NaN, Inf));               \
+    static_assert(NegInf == FUNC(NegInf, NaN));         \
+    static_assert(0.0 == FUNC(NaN, 0.0));               \
+    static_assert(-0.0 == FUNC(-0.0, NaN));             \
+    static_assert(T(-1.2345) == FUNC(NaN, T(-1.2345))); \
+    static_assert(T(1.2345) == FUNC(T(1.2345), NaN));   \
+    static_assert(__builtin_isnan(FUNC(NaN, NaN)));
+
+#define FMAXIMUMNUM_TEST_INF(T, FUNC)                  \
+    static_assert(Inf == FUNC(NegInf, Inf));    \
+    static_assert(Inf == FUNC(Inf, 0.0));       \
+    static_assert(Inf == FUNC(-0.0, Inf));      \
+    static_assert(Inf == FUNC(Inf, T(1.2345))); \
+    static_assert(Inf == FUNC(T(-1.2345), Inf));
+
+#define FMAXIMUMNUM_TEST_NEG_INF(T, FUNC)                         \
+    static_assert(Inf == FUNC(Inf, NegInf));               \
+    static_assert(0.0 == FUNC(NegInf, 0.0));               \
+    static_assert(-0.0 == FUNC(-0.0, NegInf));             \
+    static_assert(T(-1.2345) == FUNC(NegInf, T(-1.2345))); \
+    static_assert(T(1.2345) == FUNC(T(1.2345), NegInf));
+
+#define FMAXIMUMNUM_TEST_BOTH_ZERO(T, FUNC)       \
+    static_assert(__builtin_copysign(1.0, FUNC(0.0, 0.0)) == 1.0);  \
+    static_assert(__builtin_copysign(1.0, FUNC(-0.0, 0.0)) == 1.0);  \
+    static_assert(__builtin_copysign(1.0, FUNC(0.0, -0.0)) == 1.0);  \
+    static_assert(__builtin_copysign(1.0, FUNC(-0.0, -0.0)) == -1.0);
+
+#define LIST_FMAXIMUMNUM_TESTS(T, FUNC) \
+    FMAXIMUMNUM_TEST_SIMPLE(T, FUNC)    \
+    FMAXIMUMNUM_TEST_NAN(T, FUNC)       \
+    FMAXIMUMNUM_TEST_INF(T, FUNC)       \
+    FMAXIMUMNUM_TEST_NEG_INF(T, FUNC)   \
+    FMAXIMUMNUM_TEST_BOTH_ZERO(T, FUNC)
+
+LIST_FMAXIMUMNUM_TESTS(double, __builtin_fmaximum_num)
+LIST_FMAXIMUMNUM_TESTS(float, __builtin_fmaximum_numf)
+LIST_FMAXIMUMNUM_TESTS((long double), __builtin_fmaximum_numl)
+LIST_FMAXIMUMNUM_TESTS(__fp16, __builtin_fmaximum_numf16)
+#ifdef __FLOAT128__
+LIST_FMAXIMUMNUM_TESTS(__float128, __builtin_fmaximum_numf128)
+#endif
diff --git a/clang/test/Sema/constant-builtins-fminimum-num.cpp b/clang/test/Sema/constant-builtins-fminimum-num.cpp
new file mode 100644
index 00000000000000..062db4ef130559
--- /dev/null
+++ b/clang/test/Sema/constant-builtins-fminimum-num.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s
+// FIXME: %clang_cc1 -std=c++17 -fsyntax-only -verify -fexperimental-new-constant-interpreter %s
+// expected-no-diagnostics
+
+constexpr double NaN = __builtin_nan("");
+constexpr double Inf = __builtin_inf();
+constexpr double NegInf = -__builtin_inf();
+
+#define FMAXIMUMNUM_TEST_SIMPLE(T, FUNC)                           \
+    static_assert(T(1.2345) == FUNC(T(1.2345), T(6.7890))); \
+    static_assert(T(1.2345) == FUNC(T(6.7890), T(1.2345)));
+
+#define FMAXIMUMNUM_TEST_NAN(T, FUNC)                          \
+    static_assert(Inf == FUNC(NaN, Inf));               \
+    static_assert(NegInf == FUNC(NegInf, NaN));         \
+    static_assert(0.0 == FUNC(NaN, 0.0));               \
+    static_assert(-0.0 == FUNC(-0.0, NaN));             \
+    static_assert(T(-1.2345) == FUNC(NaN, T(-1.2345))); \
+    static_assert(T(1.2345) == FUNC(T(1.2345), NaN));   \
+    static_assert(__builtin_isnan(FUNC(NaN, NaN)));
+
+#define FMAXIMUMNUM_TEST_INF(T, FUNC)                        \
+    static_assert(NegInf == FUNC(NegInf, Inf));       \
+    static_assert(0.0 == FUNC(Inf, 0.0));             \
+    static_assert(-0.0 == FUNC(-0.0, Inf));           \
+    static_assert(T(1.2345) == FUNC(Inf, T(1.2345))); \
+    static_assert(T(-1.2345) == FUNC(T(-1.2345), Inf));
+
+#define FMAXIMUMNUM_TEST_NEG_INF(T, FUNC)                     \
+    static_assert(NegInf == FUNC(Inf, NegInf));        \
+    static_assert(NegInf == FUNC(NegInf, 0.0));        \
+    static_assert(NegInf == FUNC(-0.0, NegInf));       \
+    static_assert(NegInf == FUNC(NegInf, T(-1.2345))); \
+    static_assert(NegInf == FUNC(T(1.2345), NegInf));
+
+#define FMAXIMUMNUM_TEST_BOTH_ZERO(T, FUNC)                                 \
+    static_assert(__builtin_copysign(1.0, FUNC(0.0, 0.0)) == 1.0);   \
+    static_assert(__builtin_copysign(1.0, FUNC(-0.0, 0.0)) == -1.0); \
+    static_assert(__builtin_copysign(1.0, FUNC(0.0, -0.0)) == -1.0); \
+    static_assert(__builtin_copysign(1.0, FUNC(-0.0, -0.0)) == -1.0);
+
+#define LIST_FMAXIMUMNUM_TESTS(T, FUNC) \
+    FMAXIMUMNUM_TEST_SIMPLE(T, FUNC)    \
+    FMAXIMUMNUM_TEST_NAN(T, FUNC)       \
+    FMAXIMUMNUM_TEST_INF(T, FUNC)       \
+    FMAXIMUMNUM_TEST_NEG_INF(T, FUNC)   \
+    FMAXIMUMNUM_TEST_BOTH_ZERO(T, FUNC)
+
+LIST_FMAXIMUMNUM_TESTS(double, __builtin_fminimum_num)
+LIST_FMAXIMUMNUM_TESTS(float, __builtin_fminimum_numf)
+LIST_FMAXIMUMNUM_TESTS((long double), __builtin_fminimum_numl)
+LIST_FMAXIMUMNUM_TESTS(__fp16, __builtin_fminimum_numf16)
+#ifdef __FLOAT128__
+LIST_FMAXIMUMNUM_TESTS(__float128, __builtin_fminimum_numf128)
+#endif

>From 9ebfa54591f134c42049c1337022a28241343975 Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Fri, 11 Oct 2024 22:38:49 +0800
Subject: [PATCH 09/12] add invalid arguments type test

---
 .../CodeGen/fmaxfmin-invalid-arguments-type.c | 33 +++++++++++++++++++
 1 file changed, 33 insertions(+)
 create mode 100644 clang/test/CodeGen/fmaxfmin-invalid-arguments-type.c

diff --git a/clang/test/CodeGen/fmaxfmin-invalid-arguments-type.c b/clang/test/CodeGen/fmaxfmin-invalid-arguments-type.c
new file mode 100644
index 00000000000000..3da41b40b40697
--- /dev/null
+++ b/clang/test/CodeGen/fmaxfmin-invalid-arguments-type.c
@@ -0,0 +1,33 @@
+// RUN: not %clang_cc1 -triple x86_64 %s -fsyntax-only -verify 2>&1 | FileCheck %s --check-prefix=CHECK-ERR
+
+float fminimum_numf (float, float);
+double fminimum_num (double, double);
+long double fminimum_numl (long double, long double);
+float fmaximum_numf (float, float);
+double fmaximum_num (double, double);
+long double fmaximum_numl (long double, long double);
+
+// CHECK-ERR: passing 'char *' to parameter of incompatible type 'float'
+float fmin1(char *a, char *b) {
+        return fminimum_numf(a, b);
+}
+// CHECK-ERR: passing 'char *' to parameter of incompatible type 'double'
+float fmin2(char *a, char *b) {
+        return fminimum_num(a, b);
+}
+// CHECK-ERR: passing 'char *' to parameter of incompatible type 'long double'
+float fmin3(char *a, char *b) {
+        return fminimum_numl(a, b);
+}
+// CHECK-ERR: passing 'char *' to parameter of incompatible type 'float'
+float fmax1(char *a, char *b) {
+        return fmaximum_numf(a, b);
+}
+// CHECK-ERR: passing 'char *' to parameter of incompatible type 'double'
+float fmax2(char *a, char *b) {
+        return fmaximum_num(a, b);
+}
+// CHECK-ERR: passing 'char *' to parameter of incompatible type 'long double'
+float fmax3(char *a, char *b) {
+        return fmaximum_numl(a, b);
+}

>From 38fcfdf5bbc3ee4caff3476875f84fd330a4b843 Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Fri, 11 Oct 2024 22:42:19 +0800
Subject: [PATCH 10/12] fix typo in
 clang/test/Sema/constant-builtins-fminimum-num.cpp

---
 .../Sema/constant-builtins-fminimum-num.cpp   | 34 +++++++++----------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/clang/test/Sema/constant-builtins-fminimum-num.cpp b/clang/test/Sema/constant-builtins-fminimum-num.cpp
index 062db4ef130559..92e8c2b59efb90 100644
--- a/clang/test/Sema/constant-builtins-fminimum-num.cpp
+++ b/clang/test/Sema/constant-builtins-fminimum-num.cpp
@@ -6,11 +6,11 @@ constexpr double NaN = __builtin_nan("");
 constexpr double Inf = __builtin_inf();
 constexpr double NegInf = -__builtin_inf();
 
-#define FMAXIMUMNUM_TEST_SIMPLE(T, FUNC)                           \
+#define FMINIMUMNUM_TEST_SIMPLE(T, FUNC)                           \
     static_assert(T(1.2345) == FUNC(T(1.2345), T(6.7890))); \
     static_assert(T(1.2345) == FUNC(T(6.7890), T(1.2345)));
 
-#define FMAXIMUMNUM_TEST_NAN(T, FUNC)                          \
+#define FMINIMUMNUM_TEST_NAN(T, FUNC)                          \
     static_assert(Inf == FUNC(NaN, Inf));               \
     static_assert(NegInf == FUNC(NegInf, NaN));         \
     static_assert(0.0 == FUNC(NaN, 0.0));               \
@@ -19,37 +19,37 @@ constexpr double NegInf = -__builtin_inf();
     static_assert(T(1.2345) == FUNC(T(1.2345), NaN));   \
     static_assert(__builtin_isnan(FUNC(NaN, NaN)));
 
-#define FMAXIMUMNUM_TEST_INF(T, FUNC)                        \
+#define FMINIMUMNUM_TEST_INF(T, FUNC)                        \
     static_assert(NegInf == FUNC(NegInf, Inf));       \
     static_assert(0.0 == FUNC(Inf, 0.0));             \
     static_assert(-0.0 == FUNC(-0.0, Inf));           \
     static_assert(T(1.2345) == FUNC(Inf, T(1.2345))); \
     static_assert(T(-1.2345) == FUNC(T(-1.2345), Inf));
 
-#define FMAXIMUMNUM_TEST_NEG_INF(T, FUNC)                     \
+#define FMINIMUMNUM_TEST_NEG_INF(T, FUNC)                     \
     static_assert(NegInf == FUNC(Inf, NegInf));        \
     static_assert(NegInf == FUNC(NegInf, 0.0));        \
     static_assert(NegInf == FUNC(-0.0, NegInf));       \
     static_assert(NegInf == FUNC(NegInf, T(-1.2345))); \
     static_assert(NegInf == FUNC(T(1.2345), NegInf));
 
-#define FMAXIMUMNUM_TEST_BOTH_ZERO(T, FUNC)                                 \
+#define FMINIMUMNUM_TEST_BOTH_ZERO(T, FUNC)                                 \
     static_assert(__builtin_copysign(1.0, FUNC(0.0, 0.0)) == 1.0);   \
     static_assert(__builtin_copysign(1.0, FUNC(-0.0, 0.0)) == -1.0); \
     static_assert(__builtin_copysign(1.0, FUNC(0.0, -0.0)) == -1.0); \
     static_assert(__builtin_copysign(1.0, FUNC(-0.0, -0.0)) == -1.0);
 
-#define LIST_FMAXIMUMNUM_TESTS(T, FUNC) \
-    FMAXIMUMNUM_TEST_SIMPLE(T, FUNC)    \
-    FMAXIMUMNUM_TEST_NAN(T, FUNC)       \
-    FMAXIMUMNUM_TEST_INF(T, FUNC)       \
-    FMAXIMUMNUM_TEST_NEG_INF(T, FUNC)   \
-    FMAXIMUMNUM_TEST_BOTH_ZERO(T, FUNC)
-
-LIST_FMAXIMUMNUM_TESTS(double, __builtin_fminimum_num)
-LIST_FMAXIMUMNUM_TESTS(float, __builtin_fminimum_numf)
-LIST_FMAXIMUMNUM_TESTS((long double), __builtin_fminimum_numl)
-LIST_FMAXIMUMNUM_TESTS(__fp16, __builtin_fminimum_numf16)
+#define LIST_FMINIMUMNUM_TESTS(T, FUNC) \
+    FMINIMUMNUM_TEST_SIMPLE(T, FUNC)    \
+    FMINIMUMNUM_TEST_NAN(T, FUNC)       \
+    FMINIMUMNUM_TEST_INF(T, FUNC)       \
+    FMINIMUMNUM_TEST_NEG_INF(T, FUNC)   \
+    FMINIMUMNUM_TEST_BOTH_ZERO(T, FUNC)
+
+LIST_FMINIMUMNUM_TESTS(double, __builtin_fminimum_num)
+LIST_FMINIMUMNUM_TESTS(float, __builtin_fminimum_numf)
+LIST_FMINIMUMNUM_TESTS((long double), __builtin_fminimum_numl)
+LIST_FMINIMUMNUM_TESTS(__fp16, __builtin_fminimum_numf16)
 #ifdef __FLOAT128__
-LIST_FMAXIMUMNUM_TESTS(__float128, __builtin_fminimum_numf128)
+LIST_FMINIMUMNUM_TESTS(__float128, __builtin_fminimum_numf128)
 #endif

>From 9c821fbc1a734d643552879d458831b39d1d0feb Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Sat, 12 Oct 2024 13:35:16 +0800
Subject: [PATCH 11/12] clang/test/CodeGen/math-libcalls.c: use common prefix

---
 clang/test/CodeGen/math-libcalls.c | 35 ++++++++++--------------------
 1 file changed, 11 insertions(+), 24 deletions(-)

diff --git a/clang/test/CodeGen/math-libcalls.c b/clang/test/CodeGen/math-libcalls.c
index 4217d615be7628..2226212eca94ee 100644
--- a/clang/test/CodeGen/math-libcalls.c
+++ b/clang/test/CodeGen/math-libcalls.c
@@ -1,8 +1,8 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-implicit-function-declaration -w -o - -emit-llvm %s | FileCheck %s --check-prefix=NO__ERRNO
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-implicit-function-declaration -w -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-implicit-function-declaration -w -o - -emit-llvm -disable-llvm-passes -O2 %s | FileCheck %s --check-prefix=NO__ERRNO
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-implicit-function-declaration -w -o - -emit-llvm -disable-llvm-passes -O2 -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-implicit-function-declaration -w -o - -emit-llvm -ffp-exception-behavior=maytrap %s | FileCheck %s --check-prefix=HAS_MAYTRAP
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-implicit-function-declaration -w -o - -emit-llvm %s | FileCheck %s --check-prefixes=COMMON,NO__ERRNO
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-implicit-function-declaration -w -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefixes=COMMON,HAS_ERRNO
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-implicit-function-declaration -w -o - -emit-llvm -disable-llvm-passes -O2 %s | FileCheck %s --check-prefixes=COMMON,NO__ERRNO
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-implicit-function-declaration -w -o - -emit-llvm -disable-llvm-passes -O2 -fmath-errno %s | FileCheck %s --check-prefixes=COMMON,HAS_ERRNO
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-implicit-function-declaration -w -o - -emit-llvm -ffp-exception-behavior=maytrap %s | FileCheck %s --check-prefixes=COMMON,HAS_MAYTRAP
 // RUN: %clang_cc1 -triple x86_64-unknown-unknown-gnu -Wno-implicit-function-declaration -w -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO_GNU
 // RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -Wno-implicit-function-declaration -w -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO_WIN
 
@@ -374,28 +374,15 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
 
   fmaximum_num(*d,*d);       fmaximum_numf(f,f);      fmaximum_numl(*l,*l);
 
-// NO__ERRNO: declare double @llvm.maximumnum.f64(double, double) [[READNONE_INTRINSIC]]
-// NO__ERRNO: declare float @llvm.maximumnum.f32(float, float) [[READNONE_INTRINSIC]]
-// NO__ERRNO: declare x86_fp80 @llvm.maximumnum.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
-// HAS_ERRNO: declare double @llvm.maximumnum.f64(double, double) [[READNONE_INTRINSIC]]
-// HAS_ERRNO: declare float @llvm.maximumnum.f32(float, float) [[READNONE_INTRINSIC]]
-// HAS_ERRNO: declare x86_fp80 @llvm.maximumnum.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
-// HAS_MAYTRAP: declare double @llvm.maximumnum.f64(
-// HAS_MAYTRAP: declare float @llvm.maximumnum.f32(
-// HAS_MAYTRAP: declare x86_fp80 @llvm.maximumnum.f80(
+// COMMON: declare double @llvm.maximumnum.f64(double, double) [[READNONE_INTRINSIC]]
+// COMMON: declare float @llvm.maximumnum.f32(float, float) [[READNONE_INTRINSIC]]
+// COMMON: declare x86_fp80 @llvm.maximumnum.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
 
   fminimum_num(*d,*d);       fminimum_numf(f,f);      fminimum_numl(*l,*l);
 
-// NO__ERRNO: declare double @llvm.minimumnum.f64(double, double) [[READNONE_INTRINSIC]]
-// NO__ERRNO: declare float @llvm.minimumnum.f32(float, float) [[READNONE_INTRINSIC]]
-// NO__ERRNO: declare x86_fp80 @llvm.minimumnum.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
-// HAS_ERRNO: declare double @llvm.minimumnum.f64(double, double) [[READNONE_INTRINSIC]]
-// HAS_ERRNO: declare float @llvm.minimumnum.f32(float, float) [[READNONE_INTRINSIC]]
-// HAS_ERRNO: declare x86_fp80 @llvm.minimumnum.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
-// HAS_MAYTRAP: declare double @llvm.minimumnum.f64(
-// HAS_MAYTRAP: declare float @llvm.minimumnum.f32(
-// HAS_MAYTRAP: declare x86_fp80 @llvm.minimumnum.f80(
-
+// COMMON: declare double @llvm.minimumnum.f64(double, double) [[READNONE_INTRINSIC]]
+// COMMON: declare float @llvm.minimumnum.f32(float, float) [[READNONE_INTRINSIC]]
+// COMMON: declare x86_fp80 @llvm.minimumnum.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]]
 
   hypot(f,f);      hypotf(f,f);     hypotl(f,f);
 

>From fe51305f0f5be23b0a1b95ac8e3755d3f001e6e1 Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Mon, 14 Oct 2024 14:59:53 +0800
Subject: [PATCH 12/12] test constant snan

---
 clang/test/Sema/constant-builtins-fmaximum-num.cpp | 14 ++++++++++++++
 clang/test/Sema/constant-builtins-fminimum-num.cpp | 14 ++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/clang/test/Sema/constant-builtins-fmaximum-num.cpp b/clang/test/Sema/constant-builtins-fmaximum-num.cpp
index 7a5425bbbe0637..206be5d407654c 100644
--- a/clang/test/Sema/constant-builtins-fmaximum-num.cpp
+++ b/clang/test/Sema/constant-builtins-fmaximum-num.cpp
@@ -3,6 +3,7 @@
 // expected-no-diagnostics
 
 constexpr double NaN = __builtin_nan("");
+constexpr double SNaN = __builtin_nans("");
 constexpr double Inf = __builtin_inf();
 constexpr double NegInf = -__builtin_inf();
 
@@ -10,6 +11,18 @@ constexpr double NegInf = -__builtin_inf();
     static_assert(T(6.7890) == FUNC(T(1.2345), T(6.7890))); \
     static_assert(T(6.7890) == FUNC(T(6.7890), T(1.2345)));
 
+#define FMAXIMUMNUM_TEST_SNAN(T, FUNC)                          \
+    static_assert(Inf == FUNC(SNaN, Inf));               \
+    static_assert(NegInf == FUNC(NegInf, SNaN));         \
+    static_assert(0.0 == FUNC(SNaN, 0.0));               \
+    static_assert(-0.0 == FUNC(-0.0, SNaN));             \
+    static_assert(T(-1.2345) == FUNC(SNaN, T(-1.2345))); \
+    static_assert(T(1.2345) == FUNC(T(1.2345), SNaN));   \
+    static_assert(__builtin_isnan(FUNC(SNaN, SNaN)));    \
+    static_assert(__builtin_isnan(FUNC(NaN, SNaN)));    \
+    static_assert(!__builtin_issignaling(FUNC(SNaN, SNaN)));  \
+    static_assert(!__builtin_issignaling(FUNC(NaN, SNaN)));
+
 #define FMAXIMUMNUM_TEST_NAN(T, FUNC)                          \
     static_assert(Inf == FUNC(NaN, Inf));               \
     static_assert(NegInf == FUNC(NegInf, NaN));         \
@@ -42,6 +55,7 @@ constexpr double NegInf = -__builtin_inf();
 #define LIST_FMAXIMUMNUM_TESTS(T, FUNC) \
     FMAXIMUMNUM_TEST_SIMPLE(T, FUNC)    \
     FMAXIMUMNUM_TEST_NAN(T, FUNC)       \
+    FMAXIMUMNUM_TEST_SNAN(T, FUNC)       \
     FMAXIMUMNUM_TEST_INF(T, FUNC)       \
     FMAXIMUMNUM_TEST_NEG_INF(T, FUNC)   \
     FMAXIMUMNUM_TEST_BOTH_ZERO(T, FUNC)
diff --git a/clang/test/Sema/constant-builtins-fminimum-num.cpp b/clang/test/Sema/constant-builtins-fminimum-num.cpp
index 92e8c2b59efb90..7ec7427dba72b9 100644
--- a/clang/test/Sema/constant-builtins-fminimum-num.cpp
+++ b/clang/test/Sema/constant-builtins-fminimum-num.cpp
@@ -3,6 +3,7 @@
 // expected-no-diagnostics
 
 constexpr double NaN = __builtin_nan("");
+constexpr double SNaN = __builtin_nans("");
 constexpr double Inf = __builtin_inf();
 constexpr double NegInf = -__builtin_inf();
 
@@ -19,6 +20,18 @@ constexpr double NegInf = -__builtin_inf();
     static_assert(T(1.2345) == FUNC(T(1.2345), NaN));   \
     static_assert(__builtin_isnan(FUNC(NaN, NaN)));
 
+#define FMINIMUMNUM_TEST_SNAN(T, FUNC)                          \
+    static_assert(Inf == FUNC(SNaN, Inf));               \
+    static_assert(NegInf == FUNC(NegInf, SNaN));         \
+    static_assert(0.0 == FUNC(SNaN, 0.0));               \
+    static_assert(-0.0 == FUNC(-0.0, SNaN));             \
+    static_assert(T(-1.2345) == FUNC(SNaN, T(-1.2345))); \
+    static_assert(T(1.2345) == FUNC(T(1.2345), SNaN));   \
+    static_assert(__builtin_isnan(FUNC(SNaN, SNaN)));    \
+    static_assert(__builtin_isnan(FUNC(NaN, SNaN)));    \
+    static_assert(!__builtin_issignaling(FUNC(SNaN, SNaN)));  \
+    static_assert(!__builtin_issignaling(FUNC(NaN, SNaN)));
+
 #define FMINIMUMNUM_TEST_INF(T, FUNC)                        \
     static_assert(NegInf == FUNC(NegInf, Inf));       \
     static_assert(0.0 == FUNC(Inf, 0.0));             \
@@ -42,6 +55,7 @@ constexpr double NegInf = -__builtin_inf();
 #define LIST_FMINIMUMNUM_TESTS(T, FUNC) \
     FMINIMUMNUM_TEST_SIMPLE(T, FUNC)    \
     FMINIMUMNUM_TEST_NAN(T, FUNC)       \
+    FMINIMUMNUM_TEST_SNAN(T, FUNC)      \
     FMINIMUMNUM_TEST_INF(T, FUNC)       \
     FMINIMUMNUM_TEST_NEG_INF(T, FUNC)   \
     FMINIMUMNUM_TEST_BOTH_ZERO(T, FUNC)



More information about the cfe-commits mailing list