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: _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
