[clang] [Clang][Codegen] Move floating point math intrinsic check to separate function [NFC] (PR #168198)
Hendrik Hübner via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 18 03:46:21 PST 2025
https://github.com/HendrikHuebner updated https://github.com/llvm/llvm-project/pull/168198
>From 93bc9344bfe1c5eeedddbd6b24398cc81b13b168 Mon Sep 17 00:00:00 2001
From: hhuebner <hendrik.huebner18 at gmail.com>
Date: Sat, 15 Nov 2025 12:04:42 +0100
Subject: [PATCH 1/2] Move GenerateIntrinsic to separate function
---
clang/include/clang/Basic/Builtins.h | 19 ++++++
clang/lib/Basic/Builtins.cpp | 88 ++++++++++++++++++++++++++++
clang/lib/CodeGen/CGBuiltin.cpp | 83 ++------------------------
3 files changed, 113 insertions(+), 77 deletions(-)
diff --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h
index 3a5e31de2bc50..9dc97f7d73f82 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,24 @@ 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..4c653e6af42ae 100644
--- a/clang/lib/Basic/Builtins.cpp
+++ b/clang/lib/Basic/Builtins.cpp
@@ -197,6 +197,94 @@ 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 0a2ea416e5e4d..d80becb40be8a 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -2640,84 +2640,13 @@ 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:
>From 451cde386ae653d580c54c3c7fcd563b82ee0844 Mon Sep 17 00:00:00 2001
From: hhuebner <hendrik.huebner18 at gmail.com>
Date: Sat, 15 Nov 2025 12:06:54 +0100
Subject: [PATCH 2/2] format
---
clang/include/clang/Basic/Builtins.h | 6 ++----
clang/lib/Basic/Builtins.cpp | 28 +++++++++++++++-------------
clang/lib/CodeGen/CGBuiltin.cpp | 7 ++++---
3 files changed, 21 insertions(+), 20 deletions(-)
diff --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h
index 9dc97f7d73f82..324e0deb241ab 100644
--- a/clang/include/clang/Basic/Builtins.h
+++ b/clang/include/clang/Basic/Builtins.h
@@ -417,11 +417,9 @@ class Context {
/// 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,
+ bool shouldGenerateFPMathIntrinsic(unsigned BuiltinID, llvm::Triple Trip,
std::optional<bool> ErrnoOverwritten,
- bool MathErrnoEnabled,
- bool HasOptNoneAttr,
+ bool MathErrnoEnabled, bool HasOptNoneAttr,
bool IsOptimizationEnabled) const;
const char *getRequiredFeatures(unsigned ID) const;
diff --git a/clang/lib/Basic/Builtins.cpp b/clang/lib/Basic/Builtins.cpp
index 4c653e6af42ae..e477da34fd5e0 100644
--- a/clang/lib/Basic/Builtins.cpp
+++ b/clang/lib/Basic/Builtins.cpp
@@ -222,19 +222,17 @@ static bool isBuiltinConstForTriple(unsigned BuiltinID, llvm::Triple Trip) {
return false;
}
-bool Builtin::Context::shouldGenerateFPMathIntrinsic(unsigned BuiltinID,
- llvm::Triple Trip,
- std::optional<bool> ErrnoOverwritten,
- bool MathErrnoEnabled,
- bool HasOptNoneAttr,
- bool IsOptimizationEnabled) const {
+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;
+ 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
@@ -243,9 +241,11 @@ bool Builtin::Context::shouldGenerateFPMathIntrinsic(unsigned BuiltinID,
// 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 ConstAlways =
+ isConst(BuiltinID) || isBuiltinConstForTriple(BuiltinID, Trip);
- bool ConstWithoutErrnoAndExceptions = isConstWithoutErrnoAndExceptions(BuiltinID);
+ bool ConstWithoutErrnoAndExceptions =
+ isConstWithoutErrnoAndExceptions(BuiltinID);
bool ConstWithoutExceptions = isConstWithoutExceptions(BuiltinID);
// ConstAttr is enabled in fast-math mode. In fast-math mode, math-errno is
@@ -268,7 +268,8 @@ bool Builtin::Context::shouldGenerateFPMathIntrinsic(unsigned BuiltinID,
bool GenerateIntrinsics =
(ConstAlways && !HasOptNoneAttr) ||
(!MathErrnoEnabled &&
- !(ErrnoOverwritten.has_value() && ErrnoOverwritten.value()) && !HasOptNoneAttr);
+ !(ErrnoOverwritten.has_value() && ErrnoOverwritten.value()) &&
+ !HasOptNoneAttr);
if (!GenerateIntrinsics) {
GenerateIntrinsics =
ConstWithoutErrnoOrExceptions && !ConstWithoutErrnoAndExceptions;
@@ -276,7 +277,8 @@ bool Builtin::Context::shouldGenerateFPMathIntrinsic(unsigned BuiltinID,
GenerateIntrinsics =
ConstWithoutErrnoOrExceptions &&
(!MathErrnoEnabled &&
- !(ErrnoOverwritten.has_value() && ErrnoOverwritten.value()) && !HasOptNoneAttr);
+ !(ErrnoOverwritten.has_value() && ErrnoOverwritten.value()) &&
+ !HasOptNoneAttr);
if (!GenerateIntrinsics)
GenerateIntrinsics =
ConstWithoutErrnoOrExceptions && ErrnoOverridenToFalseWithOpt;
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index d80becb40be8a..ce6eae98a0b30 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -2642,9 +2642,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
bool IsOptimizationEnabled = CGM.getCodeGenOpts().OptimizationLevel != 0;
- bool GenerateFPMathIntrinsics = getContext().BuiltinInfo.shouldGenerateFPMathIntrinsic(
- BuiltinID, CGM.getTriple(), ErrnoOverriden,
- getLangOpts().MathErrno, OptNone, IsOptimizationEnabled);
+ bool GenerateFPMathIntrinsics =
+ getContext().BuiltinInfo.shouldGenerateFPMathIntrinsic(
+ BuiltinID, CGM.getTriple(), ErrnoOverriden, getLangOpts().MathErrno,
+ OptNone, IsOptimizationEnabled);
if (GenerateFPMathIntrinsics) {
switch (BuiltinIDIfNoAsmLabel) {
More information about the cfe-commits
mailing list