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

Reply via email to