[clang] 0bf525b - [clang-cl] Add _M_FP_* #defines for floating point modes

David Majnemer via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 22 13:04:47 PDT 2022


Author: David Majnemer
Date: 2022-08-22T20:04:35Z
New Revision: 0bf525bf902e3cd2072ddac82069f28e6d01fdc5

URL: https://github.com/llvm/llvm-project/commit/0bf525bf902e3cd2072ddac82069f28e6d01fdc5
DIFF: https://github.com/llvm/llvm-project/commit/0bf525bf902e3cd2072ddac82069f28e6d01fdc5.diff

LOG: [clang-cl] Add _M_FP_* #defines for floating point modes

This keeps clang compatible with MSVC defines for the FP environment.
These defines are used by the CRT and other libraries to interrogate
what to expect. Perhaps most importantly, they feed into the definition
of float_t and double_t which may result in ODR violations between MSVC
and clang.

Added: 
    

Modified: 
    clang/lib/Basic/Targets/OSTargets.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Basic/Targets/OSTargets.cpp b/clang/lib/Basic/Targets/OSTargets.cpp
index f2ed076039a0b..5c734024897cb 100644
--- a/clang/lib/Basic/Targets/OSTargets.cpp
+++ b/clang/lib/Basic/Targets/OSTargets.cpp
@@ -178,6 +178,54 @@ static void addVisualCDefines(const LangOptions &Opts, MacroBuilder &Builder) {
   if (!Opts.CharIsSigned)
     Builder.defineMacro("_CHAR_UNSIGNED");
 
+  // "The /fp:contract option allows the compiler to generate floating-point
+  // contractions [...]"
+  if (Opts.getDefaultFPContractMode() != LangOptions::FPModeKind::FPM_Off)
+    Builder.defineMacro("_M_FP_CONTRACT");
+
+  // "The /fp:except option generates code to ensures that any unmasked
+  // floating-point exceptions are raised at the exact point at which they
+  // occur, and that no other floating-point exceptions are raised."
+  if (Opts.getDefaultExceptionMode() ==
+      LangOptions::FPExceptionModeKind::FPE_Strict)
+    Builder.defineMacro("_M_FP_EXCEPT");
+
+  // "The /fp:fast option allows the compiler to reorder, combine, or simplify
+  // floating-point operations to optimize floating-point code for speed and
+  // space. The compiler may omit rounding at assignment statements,
+  // typecasts, or function calls. It may reorder operations or make algebraic
+  // transforms, for example, by use of associative and distributive laws. It
+  // may reorder code even if such transformations result in observably
+  // 
diff erent rounding behavior."
+  //
+  // "Under /fp:precise and /fp:strict, the compiler doesn't do any mathematical
+  // transformation unless the transformation is guaranteed to produce a bitwise
+  // identical result."
+  const bool any_imprecise_flags =
+      Opts.FastMath || Opts.FiniteMathOnly || Opts.UnsafeFPMath ||
+      Opts.AllowFPReassoc || Opts.NoHonorNaNs || Opts.NoHonorInfs ||
+      Opts.NoSignedZero || Opts.AllowRecip || Opts.ApproxFunc;
+
+  // "Under both /fp:precise and /fp:fast, the compiler generates code intended
+  // to run in the default floating-point environment."
+  //
+  // "[The] default floating point environment [...] sets the rounding mode
+  // to round to nearest."
+  if (Opts.getDefaultRoundingMode() ==
+      LangOptions::RoundingMode::NearestTiesToEven) {
+    if (any_imprecise_flags) {
+      Builder.defineMacro("_M_FP_FAST");
+    } else {
+      Builder.defineMacro("_M_FP_PRECISE");
+    }
+  } else if (!any_imprecise_flags && Opts.getDefaultRoundingMode() ==
+                                         LangOptions::RoundingMode::Dynamic) {
+    // "Under /fp:strict, the compiler generates code that allows the
+    // program to safely unmask floating-point exceptions, read or write
+    // floating-point status registers, or change rounding modes."
+    Builder.defineMacro("_M_FP_STRICT");
+  }
+
   // FIXME: POSIXThreads isn't exactly the option this should be defined for,
   //        but it works for now.
   if (Opts.POSIXThreads)


        


More information about the cfe-commits mailing list