Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions clang/include/clang/Basic/Builtins.td
Original file line number Diff line number Diff line change
Expand Up @@ -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)";
}

Expand Down Expand Up @@ -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;
}
Expand Down
8 changes: 8 additions & 0 deletions clang/lib/AST/ByteCode/InterpBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
12 changes: 8 additions & 4 deletions clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) ||
Expand Down
13 changes: 13 additions & 0 deletions clang/test/AST/ByteCode/builtin-functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,11 +194,17 @@ 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.0, 1.0, 1.0) == 2.0);
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);
Expand Down
Loading