[clang] [clang] Make __builtin_exp and __builtin_expf constexpr. (PR #199808)
via cfe-commits
cfe-commits at lists.llvm.org
Tue May 26 19:52:15 PDT 2026
https://github.com/lntue updated https://github.com/llvm/llvm-project/pull/199808
>From b88013594ab6ed7939edd3d296b51fa0976bd1ad Mon Sep 17 00:00:00 2001
From: Tue Ly <lntue.h at gmail.com>
Date: Wed, 27 May 2026 01:56:13 +0000
Subject: [PATCH 1/2] [clang] Make __builtin_exp and __builtin_expf constexpr.
This is step 3 in https://discourse.llvm.org/t/rfc-make-clang-builtin-math-functions-constexpr-with-llvm-libc-to-support-c-23-constexpr-math-functions/86450
---
clang/include/clang/Basic/Builtins.td | 9 ++++++++-
clang/lib/AST/ByteCode/InterpBuiltin.cpp | 17 ++++++++++++++++-
clang/lib/AST/ExprConstant.cpp | 13 +++++++++++++
clang/test/Preprocessor/feature_tests.cpp | 4 +++-
clang/test/Sema/constant-builtins-exp.cpp | 19 +++++++++++++++++++
5 files changed, 59 insertions(+), 3 deletions(-)
create mode 100644 clang/test/Sema/constant-builtins-exp.cpp
diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index 84799929cee87..0c1c12fcb5788 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -166,7 +166,14 @@ def ErfcF128 : Builtin {
let Prototype = "__float128(__float128)";
}
-def ExpF16F128 : Builtin, F16F128MathTemplate {
+def BIExp : Builtin, Template<["float", "double"], ["f", ""]> {
+ let Spellings = ["__builtin_exp"];
+ let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, Constexpr];
+ let Prototype = "T(T)";
+}
+
+def ExpF16F128 : Builtin, Template<["long double", "_Float16", "__float128"],
+ ["l", "f16", "f128"]> {
let Spellings = ["__builtin_exp"];
let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions];
let Prototype = "T(T)";
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 8a53ae0937782..9ecc23ac5c9aa 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -706,6 +706,13 @@ static bool interp__builtin_fpclassify(InterpState &S, CodePtr OpPC,
return true;
}
+static bool interp__builtin_exp(InterpState &S, CodePtr OpPC,
+ const InterpFrame *Frame) {
+ APFloat Result = exp(S.Stk.peek<Floating>().getAPFloat());
+ S.Stk.push<Floating>(Floating(Result));
+ return true;
+}
+
static inline Floating abs(InterpState &S, const Floating &In) {
if (!In.isNegative())
return In;
@@ -4488,7 +4495,15 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
case Builtin::BI__builtin_copysignf128:
return interp__builtin_copysign(S, OpPC, Frame);
- case Builtin::BI__builtin_fmin:
+ case Builtin::BI__builtin_exp:
+ case Builtin::BI__builtin_expf:
+ return interp__builtin_exp(S, OpPC, Frame);
+ case Builtin::BI__builtin_expl:
+ case Builtin::BI__builtin_expf16:
+ case Builtin::BI__builtin_expf128:
+ return false
+
+ case Builtin::BI__builtin_fmin:
case Builtin::BI__builtin_fminf:
case Builtin::BI__builtin_fminl:
case Builtin::BI__builtin_fminf16:
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 0522d6f1dc944..54cd1dbc937c0 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -19948,6 +19948,19 @@ bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) {
return true;
}
+ case Builtin::BI__builtin_exp:
+ case Builtin::BI__builtin_expf: {
+ APFloat Input(0.);
+ if (!EvaluateFloat(E->getArg(0), Input, Info))
+ return false;
+ Result = exp(Input);
+ return true;
+ }
+ case Builtin::BI__builtin_expl:
+ case Builtin::BI__builtin_expf16:
+ case Builtin::BI__builtin_expf128:
+ return false;
+
case Builtin::BI__builtin_fmax:
case Builtin::BI__builtin_fmaxf:
case Builtin::BI__builtin_fmaxl:
diff --git a/clang/test/Preprocessor/feature_tests.cpp b/clang/test/Preprocessor/feature_tests.cpp
index 029f446113af4..b49376a14644f 100644
--- a/clang/test/Preprocessor/feature_tests.cpp
+++ b/clang/test/Preprocessor/feature_tests.cpp
@@ -60,7 +60,9 @@
#if !__has_constexpr_builtin(__builtin_fmax) || \
!__has_constexpr_builtin(__builtin_fmin) || \
!__has_constexpr_builtin(__builtin_fmaximum_num) || \
- !__has_constexpr_builtin(__builtin_fminimum_num)
+ !__has_constexpr_builtin(__builtin_fminimum_num) || \
+ !__has_constexpr_builtin(__builtin_exp) || \
+ !__has_constexpr_builtin(__builtin_expf)
#error Clang should have these constexpr builtins
#endif
diff --git a/clang/test/Sema/constant-builtins-exp.cpp b/clang/test/Sema/constant-builtins-exp.cpp
new file mode 100644
index 0000000000000..215d2c2765961
--- /dev/null
+++ b/clang/test/Sema/constant-builtins-exp.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify -fexperimental-new-constant-interpreter %s
+// expected-no-diagnostics
+
+constexpr float InfFloat = __builtin_inff();
+constexpr float NegInfFloat = -__builtin_inff();
+
+static_assert(InfFloat == __builtin_expf(InfFloat));
+static_assert(0.0f == __builtin_expf(NegInfFloat));
+static_assert(1.0f == __builtin_expf(0.0f));
+static_assert(0x1.5bf0a8p1f == __builtin_expf(1.0f));
+
+constexpr double InfDouble = __builtin_inf();
+constexpr double NegInfDouble = -__builtin_inf();
+
+static_assert(InfDouble == __builtin_exp(InfDouble));
+static_assert(0.0 == __builtin_exp(NegInfDouble));
+static_assert(1.0 == __builtin_exp(0.0));
+static_assert(0x1.5bf0a8b145769p1 == __builtin_exp(1.0));
>From 101f7614419f4031b747b871dd772a7511fd0b93 Mon Sep 17 00:00:00 2001
From: Tue Ly <lntue.h at gmail.com>
Date: Wed, 27 May 2026 02:51:36 +0000
Subject: [PATCH 2/2] Remove float and double from Exp in Builtins.td.
---
clang/include/clang/Basic/Builtins.td | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index 0c1c12fcb5788..686a67bee1fcb 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4134,7 +4134,7 @@ def Erfc : FPMathTemplate, LibBuiltin<"math.h"> {
let AddBuiltinPrefixedAlias = 1;
}
-def Exp : FPMathTemplate, LibBuiltin<"math.h"> {
+def Exp : Template<["long double", "l"]>, LibBuiltin<"math.h"> {
let Spellings = ["exp"];
let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions];
let Prototype = "T(T)";
More information about the cfe-commits
mailing list