[clang] [Clang] Allow __builtin_fma/fmaf/fmal to be used in a constant expression (PR #158048)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Sep 13 08:28:04 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Chaitanya Koparkar (ckoparkar)
<details>
<summary>Changes</summary>
Fixes #<!-- -->154747.
---
Full diff: https://github.com/llvm/llvm-project/pull/158048.diff
4 Files Affected:
- (modified) clang/include/clang/Basic/Builtins.td (+2-2)
- (modified) clang/lib/AST/ByteCode/InterpBuiltin.cpp (+8)
- (modified) clang/lib/AST/ExprConstant.cpp (+8-4)
- (modified) clang/test/AST/ByteCode/builtin-functions.cpp (+13)
``````````diff
diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index 27639f06529cb..956e76085a08f 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)";
}
@@ -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/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) ||
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;
``````````
</details>
https://github.com/llvm/llvm-project/pull/158048
More information about the cfe-commits
mailing list