[clang] dce6002 - [Clang][Codegen] Move floating point math intrinsic check to separate function [NFC] (#168198)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 19 04:54:22 PST 2025
Author: Hendrik Hübner
Date: 2025-11-19T07:54:18-05:00
New Revision: dce60025c1ae5c6c00885b49e496b29dffc03c8b
URL: https://github.com/llvm/llvm-project/commit/dce60025c1ae5c6c00885b49e496b29dffc03c8b
DIFF: https://github.com/llvm/llvm-project/commit/dce60025c1ae5c6c00885b49e496b29dffc03c8b.diff
LOG: [Clang][Codegen] Move floating point math intrinsic check to separate function [NFC] (#168198)
This PR moves the code that checks whether an LLVM intrinsic should be
generated instead of a call to floating point math functions to a
separate function. This simplifies `EmitBuiltinExpr` in `CGBuiltin.cpp`
and will allow us to reuse the logic in ClangIR.
Added:
Modified:
clang/include/clang/Basic/Builtins.h
clang/lib/Basic/Builtins.cpp
clang/lib/CodeGen/CGBuiltin.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h
index 3a5e31de2bc50..324e0deb241ab 100644
--- a/clang/include/clang/Basic/Builtins.h
+++ b/clang/include/clang/Basic/Builtins.h
@@ -19,6 +19,7 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringTable.h"
+#include "llvm/TargetParser/Triple.h"
#include <cstring>
// VC++ defines 'alloca' as an object-like macro, which interferes with our
@@ -405,6 +406,22 @@ class Context {
return strchr(getAttributesString(ID), 'g') != nullptr;
}
+ /// Determine whether we can generate LLVM intrinsics for the given
+ /// builtin ID, based on whether it has side effects such as setting errno.
+ ///
+ /// \param BuiltinID The builtin ID to check.
+ /// \param Trip The target triple.
+ /// \param ErrnoOverwritten Indicates whether the errno setting behavior
+ /// has been overwritten via '#pragma float_control(precise, on/off)'.
+ /// \param MathErrnoEnabled Indicates whether math-errno is enabled on
+ /// command line.
+ /// \param HasOptNoneAttr True iff 'attribute__((optnone))' is used.
+ /// \param IsOptimizationEnabled True iff the optimization level is not 'O0'.
+ bool shouldGenerateFPMathIntrinsic(unsigned BuiltinID, llvm::Triple Trip,
+ std::optional<bool> ErrnoOverwritten,
+ bool MathErrnoEnabled, bool HasOptNoneAttr,
+ bool IsOptimizationEnabled) const;
+
const char *getRequiredFeatures(unsigned ID) const;
unsigned getRequiredVectorWidth(unsigned ID) const;
diff --git a/clang/lib/Basic/Builtins.cpp b/clang/lib/Basic/Builtins.cpp
index acd98fe84adf5..e477da34fd5e0 100644
--- a/clang/lib/Basic/Builtins.cpp
+++ b/clang/lib/Basic/Builtins.cpp
@@ -197,6 +197,96 @@ static bool builtinIsSupported(const llvm::StringTable &Strings,
return true;
}
+static bool isBuiltinConstForTriple(unsigned BuiltinID, llvm::Triple Trip) {
+ // There's a special case with the fma builtins where they are always const
+ // if the target environment is GNU or the target is OS is Windows and we're
+ // targeting the MSVCRT.dll environment.
+ // FIXME: This list can be become outdated. Need to find a way to get it some
+ // other way.
+ switch (BuiltinID) {
+ case Builtin::BI__builtin_fma:
+ case Builtin::BI__builtin_fmaf:
+ case Builtin::BI__builtin_fmal:
+ case Builtin::BI__builtin_fmaf16:
+ case Builtin::BIfma:
+ case Builtin::BIfmaf:
+ case Builtin::BIfmal: {
+ if (Trip.isGNUEnvironment() || Trip.isOSMSVCRT())
+ return true;
+ break;
+ }
+ default:
+ break;
+ }
+
+ return false;
+}
+
+bool Builtin::Context::shouldGenerateFPMathIntrinsic(
+ unsigned BuiltinID, llvm::Triple Trip, std::optional<bool> ErrnoOverwritten,
+ bool MathErrnoEnabled, bool HasOptNoneAttr,
+ bool IsOptimizationEnabled) const {
+
+ // True if we are compiling at -O2 and errno has been disabled
+ // using the '#pragma float_control(precise, off)', and
+ // attribute opt-none hasn't been seen.
+ bool ErrnoOverridenToFalseWithOpt = ErrnoOverwritten.has_value() &&
+ !ErrnoOverwritten.value() &&
+ !HasOptNoneAttr && IsOptimizationEnabled;
+
+ // There are LLVM math intrinsics/instructions corresponding to math library
+ // functions except the LLVM op will never set errno while the math library
+ // might. Also, math builtins have the same semantics as their math library
+ // twins. Thus, we can transform math library and builtin calls to their
+ // LLVM counterparts if the call is marked 'const' (known to never set errno).
+ // In case FP exceptions are enabled, the experimental versions of the
+ // intrinsics model those.
+ bool ConstAlways =
+ isConst(BuiltinID) || isBuiltinConstForTriple(BuiltinID, Trip);
+
+ bool ConstWithoutErrnoAndExceptions =
+ isConstWithoutErrnoAndExceptions(BuiltinID);
+ bool ConstWithoutExceptions = isConstWithoutExceptions(BuiltinID);
+
+ // ConstAttr is enabled in fast-math mode. In fast-math mode, math-errno is
+ // disabled.
+ // Math intrinsics are generated only when math-errno is disabled. Any pragmas
+ // or attributes that affect math-errno should prevent or allow math
+ // intrinsics to be generated. Intrinsics are generated:
+ // 1- In fast math mode, unless math-errno is overriden
+ // via '#pragma float_control(precise, on)', or via an
+ // 'attribute__((optnone))'.
+ // 2- If math-errno was enabled on command line but overriden
+ // to false via '#pragma float_control(precise, off))' and
+ // 'attribute__((optnone))' hasn't been used.
+ // 3- If we are compiling with optimization and errno has been disabled
+ // via '#pragma float_control(precise, off)', and
+ // 'attribute__((optnone))' hasn't been used.
+
+ bool ConstWithoutErrnoOrExceptions =
+ ConstWithoutErrnoAndExceptions || ConstWithoutExceptions;
+ bool GenerateIntrinsics =
+ (ConstAlways && !HasOptNoneAttr) ||
+ (!MathErrnoEnabled &&
+ !(ErrnoOverwritten.has_value() && ErrnoOverwritten.value()) &&
+ !HasOptNoneAttr);
+ if (!GenerateIntrinsics) {
+ GenerateIntrinsics =
+ ConstWithoutErrnoOrExceptions && !ConstWithoutErrnoAndExceptions;
+ if (!GenerateIntrinsics)
+ GenerateIntrinsics =
+ ConstWithoutErrnoOrExceptions &&
+ (!MathErrnoEnabled &&
+ !(ErrnoOverwritten.has_value() && ErrnoOverwritten.value()) &&
+ !HasOptNoneAttr);
+ if (!GenerateIntrinsics)
+ GenerateIntrinsics =
+ ConstWithoutErrnoOrExceptions && ErrnoOverridenToFalseWithOpt;
+ }
+
+ return GenerateIntrinsics;
+}
+
/// initializeBuiltins - Mark the identifiers for all the builtins with their
/// appropriate builtin ID # and mark any non-portable builtin identifiers as
/// such.
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 93f691e4c2267..3079f8ab7229e 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -2640,84 +2640,14 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
// fast-math which implies math-errno.
bool OptNone = CurFuncDecl && CurFuncDecl->hasAttr<OptimizeNoneAttr>();
- // True if we are compiling at -O2 and errno has been disabled
- // using the '#pragma float_control(precise, off)', and
- // attribute opt-none hasn't been seen.
- bool ErrnoOverridenToFalseWithOpt =
- ErrnoOverriden.has_value() && !ErrnoOverriden.value() && !OptNone &&
- CGM.getCodeGenOpts().OptimizationLevel != 0;
-
- // There are LLVM math intrinsics/instructions corresponding to math library
- // functions except the LLVM op will never set errno while the math library
- // might. Also, math builtins have the same semantics as their math library
- // twins. Thus, we can transform math library and builtin calls to their
- // LLVM counterparts if the call is marked 'const' (known to never set errno).
- // In case FP exceptions are enabled, the experimental versions of the
- // intrinsics model those.
- bool ConstAlways =
- getContext().BuiltinInfo.isConst(BuiltinID);
-
- // There's a special case with the fma builtins where they are always const
- // if the target environment is GNU or the target is OS is Windows and we're
- // targeting the MSVCRT.dll environment.
- // FIXME: This list can be become outdated. Need to find a way to get it some
- // other way.
- switch (BuiltinID) {
- case Builtin::BI__builtin_fma:
- case Builtin::BI__builtin_fmaf:
- case Builtin::BI__builtin_fmal:
- case Builtin::BI__builtin_fmaf16:
- case Builtin::BIfma:
- case Builtin::BIfmaf:
- case Builtin::BIfmal: {
- auto &Trip = CGM.getTriple();
- if (Trip.isGNUEnvironment() || Trip.isOSMSVCRT())
- ConstAlways = true;
- break;
- }
- default:
- break;
- }
+ bool IsOptimizationEnabled = CGM.getCodeGenOpts().OptimizationLevel != 0;
+
+ bool GenerateFPMathIntrinsics =
+ getContext().BuiltinInfo.shouldGenerateFPMathIntrinsic(
+ BuiltinID, CGM.getTriple(), ErrnoOverriden, getLangOpts().MathErrno,
+ OptNone, IsOptimizationEnabled);
- bool ConstWithoutErrnoAndExceptions =
- getContext().BuiltinInfo.isConstWithoutErrnoAndExceptions(BuiltinID);
- bool ConstWithoutExceptions =
- getContext().BuiltinInfo.isConstWithoutExceptions(BuiltinID);
-
- // ConstAttr is enabled in fast-math mode. In fast-math mode, math-errno is
- // disabled.
- // Math intrinsics are generated only when math-errno is disabled. Any pragmas
- // or attributes that affect math-errno should prevent or allow math
- // intrinsics to be generated. Intrinsics are generated:
- // 1- In fast math mode, unless math-errno is overriden
- // via '#pragma float_control(precise, on)', or via an
- // 'attribute__((optnone))'.
- // 2- If math-errno was enabled on command line but overriden
- // to false via '#pragma float_control(precise, off))' and
- // 'attribute__((optnone))' hasn't been used.
- // 3- If we are compiling with optimization and errno has been disabled
- // via '#pragma float_control(precise, off)', and
- // 'attribute__((optnone))' hasn't been used.
-
- bool ConstWithoutErrnoOrExceptions =
- ConstWithoutErrnoAndExceptions || ConstWithoutExceptions;
- bool GenerateIntrinsics =
- (ConstAlways && !OptNone) ||
- (!getLangOpts().MathErrno &&
- !(ErrnoOverriden.has_value() && ErrnoOverriden.value()) && !OptNone);
- if (!GenerateIntrinsics) {
- GenerateIntrinsics =
- ConstWithoutErrnoOrExceptions && !ConstWithoutErrnoAndExceptions;
- if (!GenerateIntrinsics)
- GenerateIntrinsics =
- ConstWithoutErrnoOrExceptions &&
- (!getLangOpts().MathErrno &&
- !(ErrnoOverriden.has_value() && ErrnoOverriden.value()) && !OptNone);
- if (!GenerateIntrinsics)
- GenerateIntrinsics =
- ConstWithoutErrnoOrExceptions && ErrnoOverridenToFalseWithOpt;
- }
- if (GenerateIntrinsics) {
+ if (GenerateFPMathIntrinsics) {
switch (BuiltinIDIfNoAsmLabel) {
case Builtin::BIacos:
case Builtin::BIacosf:
More information about the cfe-commits
mailing list