https://github.com/ckoparkar updated https://github.com/llvm/llvm-project/pull/158048
>From 7665f0d152250b327b93a8aedc2ed9410e22277c Mon Sep 17 00:00:00 2001 From: Chaitanya Koparkar <ckopar...@gmail.com> Date: Thu, 11 Sep 2025 07:24:02 -0400 Subject: [PATCH 1/4] [Clang] Allow __builtin_fma/fmaf/fmal to be used in a constant expression --- clang/include/clang/Basic/Builtins.td | 2 +- clang/lib/AST/ByteCode/InterpBuiltin.cpp | 8 ++++++++ clang/lib/AST/ExprConstant.cpp | 12 ++++++++---- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 27639f06529cb..a22a6e68db83b 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -199,7 +199,7 @@ def FloorF16F128 : Builtin, F16F128MathTemplate { def FmaF16F128 : Builtin, F16F128MathTemplate { let Spellings = ["__builtin_fma"]; - let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions, Constexpr]; let Prototype = "T(T, T, T)"; } diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp index a0dcdace854b9..55baa4891bb32 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp @@ -3411,6 +3411,14 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call, case clang::X86::BI__builtin_ia32_pmuludq512: return interp__builtin_ia32_pmul(S, OpPC, Call, BuiltinID); + case Builtin::BIfma: + case Builtin::BIfmal: + case Builtin::BIfmaf: + case Builtin::BI__builtin_fma: + case Builtin::BI__builtin_fmal: + case Builtin::BI__builtin_fmaf: + case Builtin::BI__builtin_fmaf16: + case Builtin::BI__builtin_fmaf128: case Builtin::BI__builtin_elementwise_fma: return interp__builtin_elementwise_triop_fp( S, OpPC, Call, diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index ca930737474df..dbff682714342 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -16346,11 +16346,15 @@ bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) { return true; } + case Builtin::BIfma: + case Builtin::BIfmal: + case Builtin::BIfmaf: + case Builtin::BI__builtin_fma: + case Builtin::BI__builtin_fmal: + case Builtin::BI__builtin_fmaf: + case Builtin::BI__builtin_fmaf16: + case Builtin::BI__builtin_fmaf128: case Builtin::BI__builtin_elementwise_fma: { - if (!E->getArg(0)->isPRValue() || !E->getArg(1)->isPRValue() || - !E->getArg(2)->isPRValue()) { - return false; - } APFloat SourceY(0.), SourceZ(0.); if (!EvaluateFloat(E->getArg(0), Result, Info) || !EvaluateFloat(E->getArg(1), SourceY, Info) || >From c61e699ff10d9c43cf78de46b31ff5b76e3134a3 Mon Sep 17 00:00:00 2001 From: Chaitanya Koparkar <ckopar...@gmail.com> Date: Sat, 13 Sep 2025 09:06:20 -0400 Subject: [PATCH 2/4] Make all fma variants constexpr, add tests --- clang/include/clang/Basic/Builtins.td | 2 +- clang/test/AST/ByteCode/builtin-functions.cpp | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index a22a6e68db83b..956e76085a08f 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -3885,7 +3885,7 @@ def Floor : FPMathTemplate, LibBuiltin<"math.h"> { def Fma : FPMathTemplate, LibBuiltin<"math.h"> { let Spellings = ["fma"]; - let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions, Constexpr]; let Prototype = "T(T, T, T)"; let AddBuiltinPrefixedAlias = 1; } diff --git a/clang/test/AST/ByteCode/builtin-functions.cpp b/clang/test/AST/ByteCode/builtin-functions.cpp index f47bc49d9a1a8..961495bb2ad0a 100644 --- a/clang/test/AST/ByteCode/builtin-functions.cpp +++ b/clang/test/AST/ByteCode/builtin-functions.cpp @@ -1742,6 +1742,19 @@ namespace Invalid { // both-note {{in call to}} } +namespace Fma { + static_assert(__builtin_fma(2.0, 3.0, 4.0) == 10.0); + static_assert(__builtin_fma(200.0, 300.0, 400.0) == 60400.0); + static_assert(__builtin_fmal(2.0, 3.0, 4.0) == 10.0); + static_assert(__builtin_fmal(200.0, 300.0, 400.0) == 60400.0); + static_assert(__builtin_fmaf(2.0, 3.0, 4.0) == 10.0); + static_assert(__builtin_fmaf(200.0, 300.0, 400.0) == 60400.0); + static_assert(__builtin_fmaf16(2.0, 3.0, 4.0) == 10.0); + static_assert(__builtin_fmaf16(200.0, 300.0, 400.0) == 60416.0); + static_assert(__builtin_fmaf128(2.0, 3.0, 4.0) == 10.0); + static_assert(__builtin_fmaf128(200.0, 300.0, 400.0) == 60400.0); +} + #if __cplusplus >= 202002L namespace WithinLifetime { constexpr int a = 10; >From 0016026eb7e712eb3c41e290a272448e2996c15f Mon Sep 17 00:00:00 2001 From: Chaitanya Koparkar <ckopar...@gmail.com> Date: Sat, 13 Sep 2025 18:45:24 -0400 Subject: [PATCH 3/4] constexpr-cxx23-clang.pass.cpp tests --- .../libcxx/numerics/c.math/constexpr-cxx23-clang.pass.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-clang.pass.cpp b/libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-clang.pass.cpp index 3f17f21e8c108..dfa991201fb67 100644 --- a/libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-clang.pass.cpp +++ b/libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-clang.pass.cpp @@ -194,11 +194,19 @@ int main(int, char**) { ASSERT_NOT_CONSTEXPR_CXX23(std::fminf(1.0f, 0.0f) == 0.0f); ASSERT_NOT_CONSTEXPR_CXX23(std::fminl(1.0L, 0.0L) == 0.0L); +#if !__has_constexpr_builtin(__builtin_fma) ASSERT_NOT_CONSTEXPR_CXX23(std::fma(1.0f, 1.0f, 1.0f) == 2.0f); ASSERT_NOT_CONSTEXPR_CXX23(std::fma(1.0, 1.0, 1.0) == 2.0); ASSERT_NOT_CONSTEXPR_CXX23(std::fma(1.0L, 1.0L, 1.0L) == 2.0L); ASSERT_NOT_CONSTEXPR_CXX23(std::fmaf(1.0f, 1.0f, 1.0f) == 2.0f); ASSERT_NOT_CONSTEXPR_CXX23(std::fmal(1.0L, 1.0L, 1.0L) == 2.0L); +#else + ASSERT_CONSTEXPR_CXX23(std::fma(1.0f, 1.0f, 1.0f) == 2.0f); + ASSERT_CONSTEXPR_CXX23(std::fma(1.0, 1.0, 1.0) == 2.0); + ASSERT_CONSTEXPR_CXX23(std::fma(1.0L, 1.0L, 1.0L) == 2.0L); + ASSERT_CONSTEXPR_CXX23(std::fmaf(1.0f, 1.0f, 1.0f) == 2.0f); + ASSERT_CONSTEXPR_CXX23(std::fmal(1.0L, 1.0L, 1.0L) == 2.0L); +#endif ASSERT_NOT_CONSTEXPR_CXX23(std::fpclassify(-1.0f) == FP_NORMAL); ASSERT_NOT_CONSTEXPR_CXX23(std::fpclassify(-1.0) == FP_NORMAL); >From 33999a84488855eaf4547caf69e565e4cb63565a Mon Sep 17 00:00:00 2001 From: Chaitanya Koparkar <ckopar...@gmail.com> Date: Wed, 17 Sep 2025 06:19:00 -0400 Subject: [PATCH 4/4] Fix tests, not all fmas are constexpr yet --- .../test/libcxx/numerics/c.math/constexpr-cxx23-clang.pass.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-clang.pass.cpp b/libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-clang.pass.cpp index dfa991201fb67..e03a86f1f6f52 100644 --- a/libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-clang.pass.cpp +++ b/libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-clang.pass.cpp @@ -201,9 +201,7 @@ int main(int, char**) { ASSERT_NOT_CONSTEXPR_CXX23(std::fmaf(1.0f, 1.0f, 1.0f) == 2.0f); ASSERT_NOT_CONSTEXPR_CXX23(std::fmal(1.0L, 1.0L, 1.0L) == 2.0L); #else - ASSERT_CONSTEXPR_CXX23(std::fma(1.0f, 1.0f, 1.0f) == 2.0f); ASSERT_CONSTEXPR_CXX23(std::fma(1.0, 1.0, 1.0) == 2.0); - ASSERT_CONSTEXPR_CXX23(std::fma(1.0L, 1.0L, 1.0L) == 2.0L); ASSERT_CONSTEXPR_CXX23(std::fmaf(1.0f, 1.0f, 1.0f) == 2.0f); ASSERT_CONSTEXPR_CXX23(std::fmal(1.0L, 1.0L, 1.0L) == 2.0L); #endif _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits