[clang] [Driver] Make ffp-model=fast honor non-finite-values, introduce ffp-model=aggressive (PR #100453)

Andy Kaylor via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 19 14:10:17 PDT 2024


https://github.com/andykaylor updated https://github.com/llvm/llvm-project/pull/100453

>From 59ac754b9a88037e2348f16e5dc7efbd437d65cb Mon Sep 17 00:00:00 2001
From: Andy Kaylor <andrew.kaylor at intel.com>
Date: Mon, 19 Aug 2024 13:41:40 -0700
Subject: [PATCH 1/5] Fix bug with -ffp-contract=fast-honor-pragmas

This fixes a problem which caused clang to assert in the Sema pragma
handling if it encountered "#pragma STDC FP_CONTRACT DEFAULT" when
compiling with the -ffp-contract=fast-honor-pragmas option.

This fixes https://github.com/llvm/llvm-project/issues/104830
---
 clang/lib/Sema/SemaAttr.cpp                   |   3 +-
 .../ffp-contract-fast-honor-pramga-option.cpp |  37 +++++
 .../ffp-contract-fhp-pragma-override.cpp      | 151 ++++++++++++++++++
 3 files changed, 189 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/CodeGen/ffp-contract-fast-honor-pramga-option.cpp
 create mode 100644 clang/test/CodeGen/ffp-contract-fhp-pragma-override.cpp

diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp
index b0c239678d0b01..a1724820472b59 100644
--- a/clang/lib/Sema/SemaAttr.cpp
+++ b/clang/lib/Sema/SemaAttr.cpp
@@ -1269,13 +1269,12 @@ void Sema::ActOnPragmaFPContract(SourceLocation Loc,
     NewFPFeatures.setAllowFPContractWithinStatement();
     break;
   case LangOptions::FPM_Fast:
+  case LangOptions::FPM_FastHonorPragmas:
     NewFPFeatures.setAllowFPContractAcrossStatement();
     break;
   case LangOptions::FPM_Off:
     NewFPFeatures.setDisallowFPContract();
     break;
-  case LangOptions::FPM_FastHonorPragmas:
-    llvm_unreachable("Should not happen");
   }
   FpPragmaStack.Act(Loc, Sema::PSK_Set, StringRef(), NewFPFeatures);
   CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
diff --git a/clang/test/CodeGen/ffp-contract-fast-honor-pramga-option.cpp b/clang/test/CodeGen/ffp-contract-fast-honor-pramga-option.cpp
new file mode 100644
index 00000000000000..c2c5daeae68331
--- /dev/null
+++ b/clang/test/CodeGen/ffp-contract-fast-honor-pramga-option.cpp
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -O3 -ffp-contract=fast-honor-pragmas -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
+
+float fp_contract_1(float a, float b, float c) {
+  // CHECK-LABEL: fp_contract_1fff(
+  // CHECK: fmul contract float
+  // CHECK: fadd contract float
+  return a * b + c;
+}
+
+float fp_contract_2(float a, float b, float c) {
+  // CHECK-LABEL: fp_contract_2fff(
+  // CHECK: fmul contract float
+  // CHECK: fsub contract float
+  return a * b - c;
+}
+
+void fp_contract_3(float *a, float b, float c) {
+  // CHECK-LABEL: fp_contract_3Pfff(
+  // CHECK: fmul contract float
+  // CHECK: fadd contract float
+  a[0] += b * c;
+}
+
+void fp_contract_4(float *a, float b, float c) {
+  // CHECK-LABEL: fp_contract_4Pfff(
+  // CHECK: fmul contract float
+  // CHECK: fsub contract float
+  a[0] -= b * c;
+}
+
+float fp_contract_5(float a, float b, float c) {
+  // CHECK-LABEL: fp_contract_5fff(
+  // CHECK: fmul contract float
+  // CHECK: fadd contract float
+  float t = a * b;
+  return t + c;
+}
\ No newline at end of file
diff --git a/clang/test/CodeGen/ffp-contract-fhp-pragma-override.cpp b/clang/test/CodeGen/ffp-contract-fhp-pragma-override.cpp
new file mode 100644
index 00000000000000..15d546b71abbe4
--- /dev/null
+++ b/clang/test/CodeGen/ffp-contract-fhp-pragma-override.cpp
@@ -0,0 +1,151 @@
+// RUN: %clang_cc1 -O3 -ffp-contract=fast-honor-pragmas -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
+
+float fp_contract_on_1(float a, float b, float c) {
+  // CHECK-LABEL: fp_contract_on_1fff(
+  // CHECK: call float @llvm.fmuladd.f32(float {{.*}}, float {{.*}}, float {{.*}})
+  #pragma STDC FP_CONTRACT ON
+  return a * b + c;
+}
+
+float fp_contract_on_2(float a, float b, float c) {
+  // CHECK-LABEL: fp_contract_on_2fff(
+  // CHECK: fmul float
+  // CHECK: fadd float
+  #pragma STDC FP_CONTRACT ON
+  float t = a * b;
+  return t + c;
+}
+
+float fp_contract_off_1(float a, float b, float c) {
+  // CHECK-LABEL: fp_contract_off_1fff(
+  // CHECK: fmul float
+  // CHECK: fadd float
+  #pragma STDC FP_CONTRACT OFF
+  return a * b + c;
+}
+
+float fp_contract_off_2(float a, float b, float c) {
+  // CHECK-LABEL: fp_contract_off_2fff(
+  // CHECK: fmul float
+  // CHECK: fadd float
+  #pragma STDC FP_CONTRACT OFF
+  float t = a * b;
+  return t + c;
+}
+
+float fp_contract_default_1(float a, float b, float c) {
+  // CHECK-LABEL: fp_contract_default_1fff(
+  // CHECK: fmul contract float
+  // CHECK: fadd contract float
+  #pragma STDC FP_CONTRACT DEFAULT
+  return a * b + c;
+}
+
+float fp_contract_default_2(float a, float b, float c) {
+  // CHECK-LABEL: fp_contract_default_2fff(
+  // CHECK: fmul contract float
+  // CHECK: fadd contract float
+  #pragma STDC FP_CONTRACT DEFAULT
+  float t = a * b;
+  return t + c;
+}
+
+float fp_contract_clang_on_1(float a, float b, float c) {
+  // CHECK-LABEL: fp_contract_clang_on_1fff(
+  // CHECK: call float @llvm.fmuladd.f32(float {{.*}}, float {{.*}}, float {{.*}})
+  #pragma clang fp contract(on)
+  return a * b + c;
+}
+
+float fp_contract_clang_on_2(float a, float b, float c) {
+  // CHECK-LABEL: fp_contract_clang_on_2fff(
+  // CHECK: fmul float
+  // CHECK: fadd float
+  #pragma clang fp contract(on)
+  float t = a * b;
+  return t + c;
+}
+
+float fp_contract_clang_off_1(float a, float b, float c) {
+  // CHECK-LABEL: fp_contract_clang_off_1fff(
+  // CHECK: fmul float
+  // CHECK: fadd float
+  #pragma clang fp contract(off)
+  return a * b + c;
+}
+
+float fp_contract_clang_off_2(float a, float b, float c) {
+  // CHECK-LABEL: fp_contract_clang_off_2fff(
+  // CHECK: fmul float
+  // CHECK: fadd float
+  #pragma clang fp contract(off)
+  float t = a * b;
+  return t + c;
+}
+
+float fp_contract_clang_fast_1(float a, float b, float c) {
+  // CHECK-LABEL: fp_contract_clang_fast_1fff(
+  // CHECK: fmul contract float
+  // CHECK: fadd contract float
+  #pragma clang fp contract(fast)
+  return a * b + c;
+}
+
+float fp_contract_clang_fast_2(float a, float b, float c) {
+  // CHECK-LABEL: fp_contract_clang_fast_2fff(
+  // CHECK: fmul contract float
+  // CHECK: fadd contract float
+  #pragma clang fp contract(fast)
+  float t = a * b;
+  return t + c;
+}
+
+#pragma STDC FP_CONTRACT ON
+
+float fp_contract_global_on_1(float a, float b, float c) {
+  // CHECK-LABEL: fp_contract_global_on_1fff(
+  // CHECK: call float @llvm.fmuladd.f32(float {{.*}}, float {{.*}}, float {{.*}})
+  return a * b + c;
+}
+
+float fp_contract_global_on_2(float a, float b, float c) {
+  // CHECK-LABEL: fp_contract_global_on_2fff(
+  // CHECK: fmul float
+  // CHECK: fadd float
+  float t = a * b;
+  return t + c;
+}
+
+#pragma STDC FP_CONTRACT OFF
+
+float fp_contract_global_off_1(float a, float b, float c) {
+  // CHECK-LABEL: fp_contract_global_off_1fff(
+  // CHECK: fmul float
+  // CHECK: fadd float
+  return a * b + c;
+}
+
+float fp_contract_global_off_2(float a, float b, float c) {
+  // CHECK-LABEL: fp_contract_global_off_2fff(
+  // CHECK: fmul float
+  // CHECK: fadd float
+  float t = a * b;
+  return t + c;
+}
+
+#pragma STDC FP_CONTRACT DEFAULT
+
+float fp_contract_global_default_1(float a, float b, float c) {
+  // CHECK-LABEL: fp_contract_global_default_1fff(
+  // CHECK: fmul contract float
+  // CHECK: fadd contract float
+  return a * b + c;
+}
+
+float fp_contract_global_default_2(float a, float b, float c) {
+  // CHECK-LABEL: fp_contract_global_default_2fff(
+  // CHECK: fmul contract float
+  // CHECK: fadd contract float
+  float t = a * b;
+  return t + c;
+}
\ No newline at end of file

>From 27e73993638296a3bb222235caeb02f65748d1e2 Mon Sep 17 00:00:00 2001
From: Andy Kaylor <andrew.kaylor at intel.com>
Date: Fri, 19 Apr 2024 15:34:03 -0700
Subject: [PATCH 2/5] [Driver] Introduce ffp-model=aggressive

This change modifies -ffp-model=fast to select options that more closely
match -funsafe-math-optimizations, and introduces a new model,
-ffp-model=aggressive which matches the existing behavior (except for a
minor change in the fp-contract behavior).

The primary motivation for this change is to make -ffp-model=fast more
user friendly, particularly in light of LLVM's aggressive optimizations
when -fno-honor-nans and -fno-honor-infinites are used.

This was previously proposed here:
https://discourse.llvm.org/t/making-ffp-model-fast-more-user-friendly/78402
---
 clang/docs/ReleaseNotes.rst           | 10 ++++++
 clang/docs/UsersManual.rst            | 45 ++++++++++++++------------
 clang/lib/Driver/ToolChain.cpp        |  2 +-
 clang/lib/Driver/ToolChains/Clang.cpp | 46 ++++++++++++++++-----------
 clang/test/CodeGen/ffp-model.c        | 35 +++++++++++++++-----
 clang/test/Driver/fp-model.c          |  4 +--
 6 files changed, 93 insertions(+), 49 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 249249971dec7c..fbf9489230e585 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -176,6 +176,16 @@ Modified Compiler Flags
 
 - The compiler flag `-fbracket-depth` default value is increased from 256 to 2048.
 
+- The ``-ffp-model`` option has been updated to enable a more limited set of
+  optimizations when the ``fast`` argument is used and to accept a new argument,
+  ``aggressive``. The behavior of ``-ffp-model=aggressive`` is mostly equivalent
+  to the previous behavior of ``-ffp-model=fast``. The updated
+  ``-ffp-model=fast`` behavior no longer assumes finite math only and uses a
+  the ``promoted`` algorithm for complex division when possible rather than the
+  less robust Smith algorithm. Both ``-ffp-model=fast`` and
+  ``-ffp-model=aggressive`` will now imply ``-ffp-contract=fast-honor-pragmas``
+  rather than ``-ffp-contract=fast``.
+
 Removed Compiler Flags
 -------------------------
 
diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst
index 64e991451bf703..d4eff29494439e 100644
--- a/clang/docs/UsersManual.rst
+++ b/clang/docs/UsersManual.rst
@@ -1452,28 +1452,30 @@ describes the various floating point semantic modes and the corresponding option
   "fhonor-infinities", "{on, off}"
   "fsigned-zeros", "{on, off}"
   "freciprocal-math", "{on, off}"
-  "allow_approximate_fns", "{on, off}"
+  "fallow-approximate-fns", "{on, off}"
   "fassociative-math", "{on, off}"
+  "fcomplex-arithmetic", "{basic, improved, full, promoted}"
 
 This table describes the option settings that correspond to the three
 floating point semantic models: precise (the default), strict, and fast.
 
 
 .. csv-table:: Floating Point Models
-  :header: "Mode", "Precise", "Strict", "Fast"
-  :widths: 25, 15, 15, 15
-
-  "except_behavior", "ignore", "strict", "ignore"
-  "fenv_access", "off", "on", "off"
-  "rounding_mode", "tonearest", "dynamic", "tonearest"
-  "contract", "on", "off", "fast"
-  "support_math_errno", "on", "on", "off"
-  "no_honor_nans", "off", "off", "on"
-  "no_honor_infinities", "off", "off", "on"
-  "no_signed_zeros", "off", "off", "on"
-  "allow_reciprocal", "off", "off", "on"
-  "allow_approximate_fns", "off", "off", "on"
-  "allow_reassociation", "off", "off", "on"
+  :header: "Mode", "Precise", "Strict", "Fast", "Aggressive"
+  :widths: 25, 25, 25, 25, 25
+
+  "except_behavior", "ignore", "strict", "ignore", "ignore"
+  "fenv_access", "off", "on", "off", "off"
+  "rounding_mode", "tonearest", "dynamic", "tonearest", "tonearest"
+  "contract", "on", "off", "fast-honor-pragmas", "fast-honor-pragmas"
+  "support_math_errno", "on", "on", "off", "off"
+  "no_honor_nans", "off", "off", "off", "on"
+  "no_honor_infinities", "off", "off", "off", "on"
+  "no_signed_zeros", "off", "off", "on", "on"
+  "allow_reciprocal", "off", "off", "on", "on"
+  "allow_approximate_fns", "off", "off", "on", "on"
+  "allow_reassociation", "off", "off", "on", "on"
+  "complex_arithmetic", "full", "full", "promoted", "basic"
 
 The ``-ffp-model`` option does not modify the ``fdenormal-fp-math``
 setting, but it does have an impact on whether ``crtfastmath.o`` is
@@ -1492,9 +1494,9 @@ for more details.
    * Floating-point math obeys regular algebraic rules for real numbers (e.g.
      ``+`` and ``*`` are associative, ``x/y == x * (1/y)``, and
      ``(a + b) * c == a * c + b * c``),
-   * Operands to floating-point operations are not equal to ``NaN`` and
-     ``Inf``, and
-   * ``+0`` and ``-0`` are interchangeable.
+   * No ``NaN`` or infinite values will be operands or results of
+     floating-point operations,
+   * ``+0`` and ``-0`` may be treated as interchangeable.
 
    ``-ffast-math`` also defines the ``__FAST_MATH__`` preprocessor
    macro. Some math libraries recognize this macro and change their behavior.
@@ -1753,7 +1755,7 @@ for more details.
    Specify floating point behavior. ``-ffp-model`` is an umbrella
    option that encompasses functionality provided by other, single
    purpose, floating point options.  Valid values are: ``precise``, ``strict``,
-   and ``fast``.
+   ``fast``, and ``aggressive``.
    Details:
 
    * ``precise`` Disables optimizations that are not value-safe on
@@ -1766,7 +1768,10 @@ for more details.
      ``STDC FENV_ACCESS``: by default ``FENV_ACCESS`` is disabled. This option
      setting behaves as though ``#pragma STDC FENV_ACCESS ON`` appeared at the
      top of the source file.
-   * ``fast`` Behaves identically to specifying both ``-ffast-math`` and
+   * ``fast`` Behaves identically to specifying ``-funsafe-math-optimizations``,
+     ``-fno-math-errno`` and ``-fcomplex-arithmetic=promoted``
+     ``ffp-contract=fast``
+   * ``aggressive`` Behaves identically to specifying both ``-ffast-math`` and
      ``ffp-contract=fast``
 
    Note: If your command line specifies multiple instances
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 0e8577b1115e38..c93c97146b6104 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -1366,7 +1366,7 @@ bool ToolChain::isFastMathRuntimeAvailable(const ArgList &Args,
       Default = false;
     if (A && A->getOption().getID() == options::OPT_ffp_model_EQ) {
       StringRef Model = A->getValue();
-      if (Model != "fast")
+      if (Model != "fast" && Model != "aggressive")
         Default = false;
     }
   }
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index a5a87db97e96b4..117667a76a7fd0 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -2919,9 +2919,19 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
   std::string GccRangeComplexOption = "";
 
   // Lambda to set fast-math options. This is also used by -ffp-model=fast
-  auto applyFastMath = [&]() {
-    HonorINFs = false;
-    HonorNaNs = false;
+  auto applyFastMath = [&](bool Aggressive) {
+    LangOptions::ComplexRangeKind NewRange;
+    if (Aggressive) {
+      HonorINFs = false;
+      HonorNaNs = false;
+      FPContract = "fast";
+      NewRange = LangOptions::ComplexRangeKind::CX_Basic;
+    } else {
+      HonorINFs = true;
+      HonorNaNs = true;
+      FPContract = "fast-honor-pragmas";
+      NewRange = LangOptions::ComplexRangeKind::CX_Promoted;
+    }
     MathErrno = false;
     AssociativeMath = true;
     ReciprocalMath = true;
@@ -2930,21 +2940,16 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
     TrappingMath = false;
     RoundingFPMath = false;
     FPExceptionBehavior = "";
-    // If fast-math is set then set the fp-contract mode to fast.
-    FPContract = "fast";
-    // ffast-math enables basic range rules for complex multiplication and
-    // division.
     // Warn if user expects to perform full implementation of complex
     // multiplication or division in the presence of nan or ninf flags.
-    if (Range == LangOptions::ComplexRangeKind::CX_Full ||
-        Range == LangOptions::ComplexRangeKind::CX_Improved ||
-        Range == LangOptions::ComplexRangeKind::CX_Promoted)
+    if (Range != NewRange)
       EmitComplexRangeDiag(
-          D, ComplexArithmeticStr(Range),
+          D,
           !GccRangeComplexOption.empty()
               ? GccRangeComplexOption
-              : ComplexArithmeticStr(LangOptions::ComplexRangeKind::CX_Basic));
-    Range = LangOptions::ComplexRangeKind::CX_Basic;
+              : ComplexArithmeticStr(Range),
+              ComplexArithmeticStr(NewRange));
+    Range = NewRange;
     SeenUnsafeMathModeOption = true;
   };
 
@@ -3072,8 +3077,8 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
       SignedZeros = true;
 
       StringRef Val = A->getValue();
-      if (OFastEnabled && Val != "fast") {
-        // Only -ffp-model=fast is compatible with OFast, ignore.
+      if (OFastEnabled && Val != "aggressive") {
+          // Only -ffp-model=aggressive is compatible with OFast, ignore.
         D.Diag(clang::diag::warn_drv_overriding_option)
             << Args.MakeArgString("-ffp-model=" + Val) << "-Ofast";
         break;
@@ -3085,10 +3090,15 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
             << Args.MakeArgString("-ffp-model=" + Val);
       if (Val == "fast") {
         FPModel = Val;
-        applyFastMath();
+        applyFastMath(false);
         // applyFastMath sets fp-contract="fast"
         LastFpContractOverrideOption = "-ffp-model=fast";
-      } else if (Val == "precise") {
+      } else if (Val.equals("aggressive")) {
+        FPModel = Val;
+        applyFastMath(true);
+        // applyFastMath sets fp-contract="fast"
+        LastFpContractOverrideOption = "-ffp-model=aggressive";
+      } else if (Val.equals("precise")) {
         FPModel = Val;
         FPContract = "on";
         LastFpContractOverrideOption = "-ffp-model=precise";
@@ -3280,7 +3290,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
         continue;
       [[fallthrough]];
     case options::OPT_ffast_math:
-      applyFastMath();
+      applyFastMath(true);
       if (A->getOption().getID() == options::OPT_Ofast)
         LastFpContractOverrideOption = "-Ofast";
       else
diff --git a/clang/test/CodeGen/ffp-model.c b/clang/test/CodeGen/ffp-model.c
index 4ed9b9dc0a780c..5516ccb218b03f 100644
--- a/clang/test/CodeGen/ffp-model.c
+++ b/clang/test/CodeGen/ffp-model.c
@@ -3,6 +3,9 @@
 // RUN: %clang -S -emit-llvm -fenable-matrix -ffp-model=fast %s -o - \
 // RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-FAST
 
+// RUN: %clang -S -emit-llvm -fenable-matrix -ffp-model=aggressive %s -o - \
+// RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-AGGRESSIVE
+
 // RUN: %clang -S -emit-llvm -fenable-matrix -ffp-model=precise %s -o - \
 // RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-PRECISE
 
@@ -20,9 +23,13 @@ float mymuladd(float x, float y, float z) {
   // CHECK: define{{.*}} float @mymuladd
   return x * y + z;
 
-  // CHECK-FAST: fmul fast float
+  // CHECK-AGGRESSIVE: fmul fast float
+  // CHECK-AGGRESSIVE: load float, ptr
+  // CHECK-AGGRESSIVE: fadd fast float
+
+  // CHECK-FAST: fmul reassoc nsz arcp contract afn float
   // CHECK-FAST: load float, ptr
-  // CHECK-FAST: fadd fast float
+  // CHECK-FAST: fadd reassoc nsz arcp contract afn float
 
   // CHECK-PRECISE: load float, ptr
   // CHECK-PRECISE: load float, ptr
@@ -54,9 +61,13 @@ void my_vec_muladd(v2f x, float y, v2f z, v2f *res) {
   // CHECK: define{{.*}}@my_vec_muladd
   *res = x * y + z;
 
-  // CHECK-FAST: fmul fast <2 x float>
+  // CHECK-AGGRESSIVE: fmul fast <2 x float>
+  // CHECK-AGGRESSIVE: load <2 x float>, ptr
+  // CHECK-AGGRESSIVE: fadd fast <2 x float>
+
+  // CHECK-FAST: fmul reassoc nsz arcp contract afn <2 x float>
   // CHECK-FAST: load <2 x float>, ptr
-  // CHECK-FAST: fadd fast <2 x float>
+  // CHECK-FAST: fadd reassoc nsz arcp contract afn <2 x float>
 
   // CHECK-PRECISE: load <2 x float>, ptr
   // CHECK-PRECISE: load float, ptr
@@ -88,9 +99,13 @@ void my_m21_muladd(m21f x, float y, m21f z, m21f *res) {
   // CHECK: define{{.*}}@my_m21_muladd
   *res = x * y + z;
 
-  // CHECK-FAST: fmul fast <2 x float>
+  // CHECK-AGGRESSIVE: fmul fast <2 x float>
+  // CHECK-AGGRESSIVE: load <2 x float>, ptr
+  // CHECK-AGGRESSIVE: fadd fast <2 x float>
+
+  // CHECK-FAST: fmul reassoc nsz arcp contract afn <2 x float>
   // CHECK-FAST: load <2 x float>, ptr
-  // CHECK-FAST: fadd fast <2 x float>
+  // CHECK-FAST: fadd reassoc nsz arcp contract afn <2 x float>
 
   // CHECK-PRECISE: load <2 x float>, ptr
   // CHECK-PRECISE: load float, ptr
@@ -122,9 +137,13 @@ void my_m22_muladd(m22f x, float y, m22f z, m22f *res) {
   // CHECK: define{{.*}}@my_m22_muladd
   *res = x * y + z;
 
-  // CHECK-FAST: fmul fast <4 x float>
+  // CHECK-AGGRESSIVE: fmul fast <4 x float>
+  // CHECK-AGGRESSIVE: load <4 x float>, ptr
+  // CHECK-AGGRESSIVE: fadd fast <4 x float>
+
+  // CHECK-FAST: fmul reassoc nsz arcp contract afn <4 x float>
   // CHECK-FAST: load <4 x float>, ptr
-  // CHECK-FAST: fadd fast <4 x float>
+  // CHECK-FAST: fadd reassoc nsz arcp contract afn <4 x float>
 
   // CHECK-PRECISE: load <4 x float>, ptr
   // CHECK-PRECISE: load float, ptr
diff --git a/clang/test/Driver/fp-model.c b/clang/test/Driver/fp-model.c
index 2348d4b41f43ab..d15dcad725a8f6 100644
--- a/clang/test/Driver/fp-model.c
+++ b/clang/test/Driver/fp-model.c
@@ -2,11 +2,11 @@
 // and other floating point options get a warning diagnostic.
 //
 
-// RUN: %clang -### -ffp-model=fast -ffp-contract=off -c %s 2>&1 \
+// RUN: %clang -### -ffp-model=aggressive -ffp-contract=off -c %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=WARN %s
 // WARN: warning: overriding '-ffp-model=fast' option with '-ffp-contract=off' [-Woverriding-option]
 
-// RUN: %clang -### -ffp-model=fast -ffp-contract=on -c %s 2>&1 \
+// RUN: %clang -### -ffp-model=aggressive -ffp-contract=on -c %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=WARN1 %s
 // WARN1: warning: overriding '-ffp-model=fast' option with '-ffp-contract=on' [-Woverriding-option]
 

>From 997e369855aa7df929b38d1300568f04922614ad Mon Sep 17 00:00:00 2001
From: Andy Kaylor <andrew.kaylor at intel.com>
Date: Wed, 24 Jul 2024 15:08:46 -0700
Subject: [PATCH 3/5] Apply complex range changes to all models and address
 review comments

---
 clang/docs/ReleaseNotes.rst           |  9 ++--
 clang/docs/UsersManual.rst            |  2 +-
 clang/lib/Driver/ToolChains/Clang.cpp | 35 ++++++------
 clang/test/Driver/fp-model.c          | 76 ++++++++++++++++++++-------
 4 files changed, 82 insertions(+), 40 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index fbf9489230e585..0f4cf8a234d9df 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -178,13 +178,12 @@ Modified Compiler Flags
 
 - The ``-ffp-model`` option has been updated to enable a more limited set of
   optimizations when the ``fast`` argument is used and to accept a new argument,
-  ``aggressive``. The behavior of ``-ffp-model=aggressive`` is mostly equivalent
+  ``aggressive``. The behavior of ``-ffp-model=aggressive`` is equivalent
   to the previous behavior of ``-ffp-model=fast``. The updated
-  ``-ffp-model=fast`` behavior no longer assumes finite math only and uses a
+  ``-ffp-model=fast`` behavior no longer assumes finite math only, uses
   the ``promoted`` algorithm for complex division when possible rather than the
-  less robust Smith algorithm. Both ``-ffp-model=fast`` and
-  ``-ffp-model=aggressive`` will now imply ``-ffp-contract=fast-honor-pragmas``
-  rather than ``-ffp-contract=fast``.
+  less basic (limited range) algorithm, and sets
+  ``-ffp-contract=fast-honor-pragmas`` rather than ``-ffp-contract=fast``.
 
 Removed Compiler Flags
 -------------------------
diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst
index d4eff29494439e..cd95b84eb6f863 100644
--- a/clang/docs/UsersManual.rst
+++ b/clang/docs/UsersManual.rst
@@ -1770,7 +1770,7 @@ for more details.
      top of the source file.
    * ``fast`` Behaves identically to specifying ``-funsafe-math-optimizations``,
      ``-fno-math-errno`` and ``-fcomplex-arithmetic=promoted``
-     ``ffp-contract=fast``
+     ``ffp-contract=fast-honor-pragmas``
    * ``aggressive`` Behaves identically to specifying both ``-ffast-math`` and
      ``ffp-contract=fast``
 
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 117667a76a7fd0..4cc88ddd2099f3 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -2918,19 +2918,30 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
   std::string ComplexRangeStr = "";
   std::string GccRangeComplexOption = "";
 
+  auto setComplexRange = [&](LangOptions::ComplexRangeKind NewRange) {
+    // Warn if user expects to perform full implementation of complex
+    // multiplication or division in the presence of nan or ninf flags.
+    if (Range != NewRange)
+      EmitComplexRangeDiag(D,
+                           !GccRangeComplexOption.empty()
+                               ? GccRangeComplexOption
+                               : ComplexArithmeticStr(Range),
+                           ComplexArithmeticStr(NewRange));
+    Range = NewRange;
+  };
+
   // Lambda to set fast-math options. This is also used by -ffp-model=fast
   auto applyFastMath = [&](bool Aggressive) {
-    LangOptions::ComplexRangeKind NewRange;
     if (Aggressive) {
       HonorINFs = false;
       HonorNaNs = false;
       FPContract = "fast";
-      NewRange = LangOptions::ComplexRangeKind::CX_Basic;
+      setComplexRange(LangOptions::ComplexRangeKind::CX_Basic);
     } else {
       HonorINFs = true;
       HonorNaNs = true;
       FPContract = "fast-honor-pragmas";
-      NewRange = LangOptions::ComplexRangeKind::CX_Promoted;
+      setComplexRange(LangOptions::ComplexRangeKind::CX_Promoted);
     }
     MathErrno = false;
     AssociativeMath = true;
@@ -2940,16 +2951,6 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
     TrappingMath = false;
     RoundingFPMath = false;
     FPExceptionBehavior = "";
-    // Warn if user expects to perform full implementation of complex
-    // multiplication or division in the presence of nan or ninf flags.
-    if (Range != NewRange)
-      EmitComplexRangeDiag(
-          D,
-          !GccRangeComplexOption.empty()
-              ? GccRangeComplexOption
-              : ComplexArithmeticStr(Range),
-              ComplexArithmeticStr(NewRange));
-    Range = NewRange;
     SeenUnsafeMathModeOption = true;
   };
 
@@ -3078,7 +3079,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
 
       StringRef Val = A->getValue();
       if (OFastEnabled && Val != "aggressive") {
-          // Only -ffp-model=aggressive is compatible with OFast, ignore.
+        // Only -ffp-model=aggressive is compatible with OFast, ignore.
         D.Diag(clang::diag::warn_drv_overriding_option)
             << Args.MakeArgString("-ffp-model=" + Val) << "-Ofast";
         break;
@@ -3093,15 +3094,16 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
         applyFastMath(false);
         // applyFastMath sets fp-contract="fast"
         LastFpContractOverrideOption = "-ffp-model=fast";
-      } else if (Val.equals("aggressive")) {
+      } else if (Val == "aggressive") {
         FPModel = Val;
         applyFastMath(true);
         // applyFastMath sets fp-contract="fast"
         LastFpContractOverrideOption = "-ffp-model=aggressive";
-      } else if (Val.equals("precise")) {
+      } else if (Val == "precise") {
         FPModel = Val;
         FPContract = "on";
         LastFpContractOverrideOption = "-ffp-model=precise";
+        setComplexRange(LangOptions::ComplexRangeKind::CX_Full);
       } else if (Val == "strict") {
         StrictFPModel = true;
         FPExceptionBehavior = "strict";
@@ -3110,6 +3112,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
         LastFpContractOverrideOption = "-ffp-model=strict";
         TrappingMath = true;
         RoundingFPMath = true;
+        setComplexRange(LangOptions::ComplexRangeKind::CX_Full);
       } else
         D.Diag(diag::err_drv_unsupported_option_argument)
             << A->getSpelling() << Val;
diff --git a/clang/test/Driver/fp-model.c b/clang/test/Driver/fp-model.c
index d15dcad725a8f6..44b073c7ac5c5f 100644
--- a/clang/test/Driver/fp-model.c
+++ b/clang/test/Driver/fp-model.c
@@ -4,11 +4,11 @@
 
 // RUN: %clang -### -ffp-model=aggressive -ffp-contract=off -c %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=WARN %s
-// WARN: warning: overriding '-ffp-model=fast' option with '-ffp-contract=off' [-Woverriding-option]
+// WARN: warning: overriding '-ffp-model=aggressive' option with '-ffp-contract=off' [-Woverriding-option]
 
 // RUN: %clang -### -ffp-model=aggressive -ffp-contract=on -c %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=WARN1 %s
-// WARN1: warning: overriding '-ffp-model=fast' option with '-ffp-contract=on' [-Woverriding-option]
+// WARN1: warning: overriding '-ffp-model=aggressive' option with '-ffp-contract=on' [-Woverriding-option]
 
 // RUN: %clang -### -ffp-model=strict -fassociative-math -c %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=WARN2 %s
@@ -74,9 +74,12 @@
 
 // RUN: %clang -### -Ofast -ffp-model=strict -c %s 2>&1 | FileCheck \
 // RUN:   --check-prefix=WARN12 %s
-// RUN: %clang -### -Werror -ffast-math -ffp-model=strict -c %s
 // WARN12: warning: overriding '-ffp-model=strict' option with '-Ofast'
 
+// RUN: %clang -### -ffast-math -ffp-model=strict -c %s 2>&1 | FileCheck \
+// RUN:   --check-prefix=WARN-CX-BASIC-TO-FULL %s
+// WARN-CX-BASIC-TO-FULL: warning: overriding '-fcomplex-arithmetic=basic' option with '-fcomplex-arithmetic=full'
+
 // RUN: %clang -### -ffp-model=strict -fapprox-func -c %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=WARN13 %s
 // WARN13: warning: overriding '-ffp-model=strict' option with '-fapprox-func' [-Woverriding-option]
@@ -109,20 +112,37 @@
 // CHECK-TRAP: "-cc1"
 // CHECK-TRAP: "-ffp-exception-behavior=strict"
 
+// RUN: %clang -### -nostdinc -ffp-model=aggressive -c %s 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-FPM-AGGR %s
+// CHECK-FPM-AGGR: "-cc1"
+// CHECK-FPM-AGGR: "-menable-no-infs"
+// CHECK-FPM-AGGR: "-menable-no-nans"
+// CHECK-FPM-AGGR: "-fapprox-func"
+// CHECK-FPM-AGGR: "-funsafe-math-optimizations"
+// CHECK-FPM-AGGR: "-fno-signed-zeros"
+// CHECK-FPM-AGGR: "-mreassociate"
+// CHECK-FPM-AGGR: "-freciprocal-math"
+// CHECK-FPM-AGGR: "-ffp-contract=fast"
+// CHECK-FPM-AGGR: "-fno-rounding-math"
+// CHECK-FPM-AGGR: "-ffast-math"
+// CHECK-FPM-AGGR: "-ffinite-math-only"
+// CHECK-FPM-AGGR: "-complex-range=basic"
+
 // RUN: %clang -### -nostdinc -ffp-model=fast -c %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-FPM-FAST %s
 // CHECK-FPM-FAST: "-cc1"
-// CHECK-FPM-FAST: "-menable-no-infs"
-// CHECK-FPM-FAST: "-menable-no-nans"
+// CHECK-FPM-FAST-NOT: "-menable-no-infs"
+// CHECK-FPM-FAST-NOT: "-menable-no-nans"
 // CHECK-FPM-FAST: "-fapprox-func"
 // CHECK-FPM-FAST: "-funsafe-math-optimizations"
 // CHECK-FPM-FAST: "-fno-signed-zeros"
 // CHECK-FPM-FAST: "-mreassociate"
 // CHECK-FPM-FAST: "-freciprocal-math"
-// CHECK-FPM-FAST: "-ffp-contract=fast"
+// CHECK-FPM-FAST: "-ffp-contract=fast-honor-pragmas"
 // CHECK-FPM-FAST: "-fno-rounding-math"
-// CHECK-FPM-FAST: "-ffast-math"
-// CHECK-FPM-FAST: "-ffinite-math-only"
+// CHECK-FPM-FAST-NOT: "-ffast-math"
+// CHECK-FPM-FAST-NOT: "-ffinite-math-only"
+// CHECK-FPM-FAST: "-complex-range=promoted"
 
 // RUN: %clang -### -nostdinc -ffp-model=precise -c %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-FPM-PRECISE %s
@@ -163,23 +183,41 @@
 // CHECK-FEB-IGNORE: "-fno-rounding-math"
 // CHECK-FEB-IGNORE: "-ffp-exception-behavior=ignore"
 
-// RUN: %clang -### -nostdinc -Werror -ffast-math -ffp-model=fast -c %s 2>&1 \
+// RUN: %clang -### -nostdinc -Werror -ffast-math -ffp-model=aggressive -c %s 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-FASTMATH-FPM-AGGR %s
+// CHECK-FASTMATH-FPM-AGGR: "-cc1"
+// CHECK-FASTMATH-FPM-AGGR: "-menable-no-infs"
+// CHECK-FASTMATH-FPM-AGGR: "-menable-no-nans"
+// CHECK-FASTMATH-FPM-AGGR: "-fapprox-func"
+// CHECK-FASTMATH-FPM-AGGR: "-funsafe-math-optimizations"
+// CHECK-FASTMATH-FPM-AGGR: "-fno-signed-zeros"
+// CHECK-FASTMATH-FPM-AGGR: "-mreassociate"
+// CHECK-FASTMATH-FPM-AGGR: "-freciprocal-math"
+// CHECK-FASTMATH-FPM-AGGR: "-ffp-contract=fast"
+// CHECK-FASTMATH-FPM-AGGR: "-fno-rounding-math"
+// CHECK-FASTMATH-FPM-AGGR: "-ffast-math"
+// CHECK-FASTMATH-FPM-AGGR: "-ffinite-math-only"
+// CHECK-FASTMATH-FPM-AGGR: "-complex-range=basic"
+
+// RUN: %clang -### -nostdinc -ffast-math -ffp-model=fast -c %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-FASTMATH-FPM-FAST %s
+// CHECK-FASTMATH-FPM-FAST: warning: overriding '-fcomplex-arithmetic=basic' option with '-fcomplex-arithmetic=promoted'
 // CHECK-FASTMATH-FPM-FAST: "-cc1"
-// CHECK-FASTMATH-FPM-FAST: "-menable-no-infs"
-// CHECK-FASTMATH-FPM-FAST: "-menable-no-nans"
+// CHECK-FASTMATH-FPM-FAST-NOT: "-menable-no-infs"
+// CHECK-FASTMATH-FPM-FAST-NOT: "-menable-no-nans"
 // CHECK-FASTMATH-FPM-FAST: "-fapprox-func"
 // CHECK-FASTMATH-FPM-FAST: "-funsafe-math-optimizations"
 // CHECK-FASTMATH-FPM-FAST: "-fno-signed-zeros"
 // CHECK-FASTMATH-FPM-FAST: "-mreassociate"
 // CHECK-FASTMATH-FPM-FAST: "-freciprocal-math"
-// CHECK-FASTMATH-FPM-FAST: "-ffp-contract=fast"
+// CHECK-FASTMATH-FPM-FAST: "-ffp-contract=fast-honor-pragmas"
 // CHECK-FASTMATH-FPM-FAST: "-fno-rounding-math"
-// CHECK-FASTMATH-FPM-FAST: "-ffast-math"
-// CHECK-FASTMATH-FPM-FAST: "-ffinite-math-only"
+// CHECK-FASTMATH-FPM-FAST-NOT: "-ffast-math"
+// CHECK-FASTMATH-FPM-FAST-NOT: "-ffinite-math-only"
+// CHECK-FASTMATH-FPM-FAST: "-complex-range=promoted"
 
-// RUN: %clang -### -nostdinc -Werror -ffast-math -ffp-model=precise -c %s 2>&1 \
-// RUN:   | FileCheck --check-prefix=CHECK-FASTMATH-FPM-PRECISE %s
+// RUN: %clang -### -nostdinc -ffast-math -ffp-model=precise -c %s 2>&1 \
+// RUN:   | FileCheck --check-prefixes=CHECK-FASTMATH-FPM-PRECISE,WARN-CX-BASIC-TO-FULL %s
 // CHECK-FASTMATH-FPM-PRECISE:     "-cc1"
 // CHECK-FASTMATH-FPM-PRECISE-NOT: "-menable-no-infs"
 // CHECK-FASTMATH-FPM-PRECISE-NOT: "-menable-no-nans"
@@ -192,9 +230,10 @@
 // CHECK-FASTMATH-FPM-PRECISE:     "-fno-rounding-math"
 // CHECK-FASTMATH-FPM-PRECISE-NOT: "-ffast-math"
 // CHECK-FASTMATH-FPM-PRECISE-NOT: "-ffinite-math-only"
+// CHECK-FASTMATH-FPM-PRECISE: "-complex-range=full"
 
-// RUN: %clang -### -nostdinc -Werror -ffast-math -ffp-model=strict -c %s 2>&1 \
-// RUN:   | FileCheck --check-prefix=CHECK-FASTMATH-FPM-STRICT %s
+// RUN: %clang -### -nostdinc -ffast-math -ffp-model=strict -c %s 2>&1 \
+// RUN:   | FileCheck --check-prefixes=CHECK-FASTMATH-FPM-STRICT,WARN-CX-BASIC-TO-FULL %s
 // CHECK-FASTMATH-FPM-STRICT:     "-cc1"
 // CHECK-FASTMATH-FPM-STRICT-NOT: "-menable-no-infs"
 // CHECK-FASTMATH-FPM-STRICT-NOT: "-menable-no-nans"
@@ -207,3 +246,4 @@
 // CHECK-FASTMATH-FPM-STRICT-NOT: "-fno-rounding-math"
 // CHECK-FASTMATH-FPM-STRICT-NOT: "-ffast-math"
 // CHECK-FASTMATH-FPM-STRICT-NOT: "-ffinite-math-only"
+// CHECK-FASTMATH-FPM-STRICT: "-complex-range=full"

>From 0aedabe16f721d4180478e33f5512b9ec98aa4e4 Mon Sep 17 00:00:00 2001
From: Andy Kaylor <andrew.kaylor at intel.com>
Date: Mon, 19 Aug 2024 11:25:01 -0700
Subject: [PATCH 4/5] Cleanup tests and comments based on review

---
 clang/lib/Driver/ToolChains/Clang.cpp |   4 +-
 clang/test/Driver/fp-model.c          | 116 +++++++++++++-------------
 2 files changed, 62 insertions(+), 58 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 4cc88ddd2099f3..c5aaf7b91cd7d9 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -2920,7 +2920,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
 
   auto setComplexRange = [&](LangOptions::ComplexRangeKind NewRange) {
     // Warn if user expects to perform full implementation of complex
-    // multiplication or division in the presence of nan or ninf flags.
+    // multiplication or division in the presence of nnan or ninf flags.
     if (Range != NewRange)
       EmitComplexRangeDiag(D,
                            !GccRangeComplexOption.empty()
@@ -3079,7 +3079,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
 
       StringRef Val = A->getValue();
       if (OFastEnabled && Val != "aggressive") {
-        // Only -ffp-model=aggressive is compatible with OFast, ignore.
+        // Only -ffp-model=aggressive is compatible with -OFast, ignore.
         D.Diag(clang::diag::warn_drv_overriding_option)
             << Args.MakeArgString("-ffp-model=" + Val) << "-Ofast";
         break;
diff --git a/clang/test/Driver/fp-model.c b/clang/test/Driver/fp-model.c
index 44b073c7ac5c5f..5088185311a069 100644
--- a/clang/test/Driver/fp-model.c
+++ b/clang/test/Driver/fp-model.c
@@ -6,6 +6,10 @@
 // RUN:   | FileCheck --check-prefix=WARN %s
 // WARN: warning: overriding '-ffp-model=aggressive' option with '-ffp-contract=off' [-Woverriding-option]
 
+// RUN: %clang -### -ffp-model=fast -ffp-contract=off -c %s 2>&1 \
+// RUN:   | FileCheck --check-prefix=WARN0 %s
+// WARN0: warning: overriding '-ffp-model=fast' option with '-ffp-contract=off' [-Woverriding-option]
+
 // RUN: %clang -### -ffp-model=aggressive -ffp-contract=on -c %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=WARN1 %s
 // WARN1: warning: overriding '-ffp-model=aggressive' option with '-ffp-contract=on' [-Woverriding-option]
@@ -100,61 +104,61 @@
 // RUN: %clang -### -c %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-NOROUND %s
 // CHECK-NOROUND: "-cc1"
-// CHECK-NOROUND: "-fno-rounding-math"
+// CHECK-NOROUND-SAME: "-fno-rounding-math"
 
 // RUN: %clang -### -frounding-math -c %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-ROUND --implicit-check-not ffp-exception-behavior=strict %s
 // CHECK-ROUND: "-cc1"
-// CHECK-ROUND: "-frounding-math"
+// CHECK-ROUND-SAME: "-frounding-math"
 
 // RUN: %clang -### -ftrapping-math -c %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-TRAP %s
 // CHECK-TRAP: "-cc1"
-// CHECK-TRAP: "-ffp-exception-behavior=strict"
+// CHECK-TRAP-SAME: "-ffp-exception-behavior=strict"
 
 // RUN: %clang -### -nostdinc -ffp-model=aggressive -c %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-FPM-AGGR %s
 // CHECK-FPM-AGGR: "-cc1"
-// CHECK-FPM-AGGR: "-menable-no-infs"
-// CHECK-FPM-AGGR: "-menable-no-nans"
-// CHECK-FPM-AGGR: "-fapprox-func"
-// CHECK-FPM-AGGR: "-funsafe-math-optimizations"
-// CHECK-FPM-AGGR: "-fno-signed-zeros"
-// CHECK-FPM-AGGR: "-mreassociate"
-// CHECK-FPM-AGGR: "-freciprocal-math"
-// CHECK-FPM-AGGR: "-ffp-contract=fast"
-// CHECK-FPM-AGGR: "-fno-rounding-math"
-// CHECK-FPM-AGGR: "-ffast-math"
-// CHECK-FPM-AGGR: "-ffinite-math-only"
-// CHECK-FPM-AGGR: "-complex-range=basic"
+// CHECK-FPM-AGGR-SAME: "-menable-no-infs"
+// CHECK-FPM-AGGR-SAME: "-menable-no-nans"
+// CHECK-FPM-AGGR-SAME: "-fapprox-func"
+// CHECK-FPM-AGGR-SAME: "-funsafe-math-optimizations"
+// CHECK-FPM-AGGR-SAME: "-fno-signed-zeros"
+// CHECK-FPM-AGGR-SAME: "-mreassociate"
+// CHECK-FPM-AGGR-SAME: "-freciprocal-math"
+// CHECK-FPM-AGGR-SAME: "-ffp-contract=fast"
+// CHECK-FPM-AGGR-SAME: "-fno-rounding-math"
+// CHECK-FPM-AGGR-SAME: "-ffast-math"
+// CHECK-FPM-AGGR-SAME: "-ffinite-math-only"
+// CHECK-FPM-AGGR-SAME: "-complex-range=basic"
 
 // RUN: %clang -### -nostdinc -ffp-model=fast -c %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-FPM-FAST %s
 // CHECK-FPM-FAST: "-cc1"
 // CHECK-FPM-FAST-NOT: "-menable-no-infs"
 // CHECK-FPM-FAST-NOT: "-menable-no-nans"
-// CHECK-FPM-FAST: "-fapprox-func"
-// CHECK-FPM-FAST: "-funsafe-math-optimizations"
-// CHECK-FPM-FAST: "-fno-signed-zeros"
-// CHECK-FPM-FAST: "-mreassociate"
-// CHECK-FPM-FAST: "-freciprocal-math"
-// CHECK-FPM-FAST: "-ffp-contract=fast-honor-pragmas"
-// CHECK-FPM-FAST: "-fno-rounding-math"
+// CHECK-FPM-FAST-SAME: "-fapprox-func"
+// CHECK-FPM-FAST-SAME: "-funsafe-math-optimizations"
+// CHECK-FPM-FAST-SAME: "-fno-signed-zeros"
+// CHECK-FPM-FAST-SAME: "-mreassociate"
+// CHECK-FPM-FAST-SAME: "-freciprocal-math"
+// CHECK-FPM-FAST-SAME: "-ffp-contract=fast-honor-pragmas"
+// CHECK-FPM-FAST-SAME: "-fno-rounding-math"
 // CHECK-FPM-FAST-NOT: "-ffast-math"
 // CHECK-FPM-FAST-NOT: "-ffinite-math-only"
-// CHECK-FPM-FAST: "-complex-range=promoted"
+// CHECK-FPM-FAST-SAME: "-complex-range=promoted"
 
 // RUN: %clang -### -nostdinc -ffp-model=precise -c %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-FPM-PRECISE %s
 // CHECK-FPM-PRECISE: "-cc1"
-// CHECK-FPM-PRECISE: "-ffp-contract=on"
-// CHECK-FPM-PRECISE: "-fno-rounding-math"
+// CHECK-FPM-PRECISE-SAME: "-ffp-contract=on"
+// CHECK-FPM-PRECISE-SAME: "-fno-rounding-math"
 
 // RUN: %clang -### -nostdinc -ffp-model=strict -c %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-FPM-STRICT %s
 // CHECK-FPM-STRICT: "-cc1"
-// CHECK-FPM-STRICT: "-frounding-math"
-// CHECK-FPM-STRICT: "-ffp-exception-behavior=strict"
+// CHECK-FPM-STRICT-SAME: "-frounding-math"
+// CHECK-FPM-STRICT-SAME: "-ffp-exception-behavior=strict"
 
 // RUN: %clang -### -nostdinc -ffp-model=strict -ffp-model=fast -c %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-NO-EXCEPT %s
@@ -168,14 +172,14 @@
 // RUN: %clang -### -nostdinc -ffp-exception-behavior=strict -c %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-FEB-STRICT %s
 // CHECK-FEB-STRICT: "-cc1"
-// CHECK-FEB-STRICT: "-fno-rounding-math"
-// CHECK-FEB-STRICT: "-ffp-exception-behavior=strict"
+// CHECK-FEB-STRICT-SAME: "-fno-rounding-math"
+// CHECK-FEB-STRICT-SAME: "-ffp-exception-behavior=strict"
 
 // RUN: %clang -### -nostdinc -ffp-exception-behavior=maytrap -c %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-FEB-MAYTRAP %s
 // CHECK-FEB-MAYTRAP: "-cc1"
-// CHECK-FEB-MAYTRAP: "-fno-rounding-math"
-// CHECK-FEB-MAYTRAP: "-ffp-exception-behavior=maytrap"
+// CHECK-FEB-MAYTRAP-SAME: "-fno-rounding-math"
+// CHECK-FEB-MAYTRAP-SAME: "-ffp-exception-behavior=maytrap"
 
 // RUN: %clang -### -nostdinc -ffp-exception-behavior=ignore -c %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-FEB-IGNORE %s
@@ -186,18 +190,18 @@
 // RUN: %clang -### -nostdinc -Werror -ffast-math -ffp-model=aggressive -c %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-FASTMATH-FPM-AGGR %s
 // CHECK-FASTMATH-FPM-AGGR: "-cc1"
-// CHECK-FASTMATH-FPM-AGGR: "-menable-no-infs"
-// CHECK-FASTMATH-FPM-AGGR: "-menable-no-nans"
-// CHECK-FASTMATH-FPM-AGGR: "-fapprox-func"
-// CHECK-FASTMATH-FPM-AGGR: "-funsafe-math-optimizations"
-// CHECK-FASTMATH-FPM-AGGR: "-fno-signed-zeros"
-// CHECK-FASTMATH-FPM-AGGR: "-mreassociate"
-// CHECK-FASTMATH-FPM-AGGR: "-freciprocal-math"
-// CHECK-FASTMATH-FPM-AGGR: "-ffp-contract=fast"
-// CHECK-FASTMATH-FPM-AGGR: "-fno-rounding-math"
-// CHECK-FASTMATH-FPM-AGGR: "-ffast-math"
-// CHECK-FASTMATH-FPM-AGGR: "-ffinite-math-only"
-// CHECK-FASTMATH-FPM-AGGR: "-complex-range=basic"
+// CHECK-FASTMATH-FPM-AGGR-SAME: "-menable-no-infs"
+// CHECK-FASTMATH-FPM-AGGR-SAME: "-menable-no-nans"
+// CHECK-FASTMATH-FPM-AGGR-SAME: "-fapprox-func"
+// CHECK-FASTMATH-FPM-AGGR-SAME: "-funsafe-math-optimizations"
+// CHECK-FASTMATH-FPM-AGGR-SAME: "-fno-signed-zeros"
+// CHECK-FASTMATH-FPM-AGGR-SAME: "-mreassociate"
+// CHECK-FASTMATH-FPM-AGGR-SAME: "-freciprocal-math"
+// CHECK-FASTMATH-FPM-AGGR-SAME: "-ffp-contract=fast"
+// CHECK-FASTMATH-FPM-AGGR-SAME: "-fno-rounding-math"
+// CHECK-FASTMATH-FPM-AGGR-SAME: "-ffast-math"
+// CHECK-FASTMATH-FPM-AGGR-SAME: "-ffinite-math-only"
+// CHECK-FASTMATH-FPM-AGGR-SAME: "-complex-range=basic"
 
 // RUN: %clang -### -nostdinc -ffast-math -ffp-model=fast -c %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-FASTMATH-FPM-FAST %s
@@ -205,16 +209,16 @@
 // CHECK-FASTMATH-FPM-FAST: "-cc1"
 // CHECK-FASTMATH-FPM-FAST-NOT: "-menable-no-infs"
 // CHECK-FASTMATH-FPM-FAST-NOT: "-menable-no-nans"
-// CHECK-FASTMATH-FPM-FAST: "-fapprox-func"
-// CHECK-FASTMATH-FPM-FAST: "-funsafe-math-optimizations"
-// CHECK-FASTMATH-FPM-FAST: "-fno-signed-zeros"
-// CHECK-FASTMATH-FPM-FAST: "-mreassociate"
-// CHECK-FASTMATH-FPM-FAST: "-freciprocal-math"
-// CHECK-FASTMATH-FPM-FAST: "-ffp-contract=fast-honor-pragmas"
-// CHECK-FASTMATH-FPM-FAST: "-fno-rounding-math"
+// CHECK-FASTMATH-FPM-FAST-SAME: "-fapprox-func"
+// CHECK-FASTMATH-FPM-FAST-SAME: "-funsafe-math-optimizations"
+// CHECK-FASTMATH-FPM-FAST-SAME: "-fno-signed-zeros"
+// CHECK-FASTMATH-FPM-FAST-SAME: "-mreassociate"
+// CHECK-FASTMATH-FPM-FAST-SAME: "-freciprocal-math"
+// CHECK-FASTMATH-FPM-FAST-SAME: "-ffp-contract=fast-honor-pragmas"
+// CHECK-FASTMATH-FPM-FAST-SAME: "-fno-rounding-math"
 // CHECK-FASTMATH-FPM-FAST-NOT: "-ffast-math"
 // CHECK-FASTMATH-FPM-FAST-NOT: "-ffinite-math-only"
-// CHECK-FASTMATH-FPM-FAST: "-complex-range=promoted"
+// CHECK-FASTMATH-FPM-FAST-SAME: "-complex-range=promoted"
 
 // RUN: %clang -### -nostdinc -ffast-math -ffp-model=precise -c %s 2>&1 \
 // RUN:   | FileCheck --check-prefixes=CHECK-FASTMATH-FPM-PRECISE,WARN-CX-BASIC-TO-FULL %s
@@ -226,11 +230,11 @@
 // CHECK-FASTMATH-FPM-PRECISE-NOT: "-fno-signed-zeros"
 // CHECK-FASTMATH-FPM-PRECISE-NOT: "-mreassociate"
 // CHECK-FASTMATH-FPM-PRECISE-NOT: "-freciprocal-math"
-// CHECK-FASTMATH-FPM-PRECISE:     "-ffp-contract=on"
-// CHECK-FASTMATH-FPM-PRECISE:     "-fno-rounding-math"
+// CHECK-FASTMATH-FPM-PRECISE-SAME:     "-ffp-contract=on"
+// CHECK-FASTMATH-FPM-PRECISE-SAME:     "-fno-rounding-math"
 // CHECK-FASTMATH-FPM-PRECISE-NOT: "-ffast-math"
 // CHECK-FASTMATH-FPM-PRECISE-NOT: "-ffinite-math-only"
-// CHECK-FASTMATH-FPM-PRECISE: "-complex-range=full"
+// CHECK-FASTMATH-FPM-PRECISE-SAME: "-complex-range=full"
 
 // RUN: %clang -### -nostdinc -ffast-math -ffp-model=strict -c %s 2>&1 \
 // RUN:   | FileCheck --check-prefixes=CHECK-FASTMATH-FPM-STRICT,WARN-CX-BASIC-TO-FULL %s
@@ -242,8 +246,8 @@
 // CHECK-FASTMATH-FPM-STRICT-NOT: "-fno-signed-zeros"
 // CHECK-FASTMATH-FPM-STRICT-NOT: "-mreassociate"
 // CHECK-FASTMATH-FPM-STRICT-NOT: "-freciprocal-math"
-// CHECK-FASTMATH-FPM-STRICT:     "-ffp-contract=off"
+// CHECK-FASTMATH-FPM-STRICT-SAME:     "-ffp-contract=off"
 // CHECK-FASTMATH-FPM-STRICT-NOT: "-fno-rounding-math"
 // CHECK-FASTMATH-FPM-STRICT-NOT: "-ffast-math"
 // CHECK-FASTMATH-FPM-STRICT-NOT: "-ffinite-math-only"
-// CHECK-FASTMATH-FPM-STRICT: "-complex-range=full"
+// CHECK-FASTMATH-FPM-STRICT-SAME: "-complex-range=full"

>From 9a4ea8881d94516d8005987f87b3627f2f1fa185 Mon Sep 17 00:00:00 2001
From: Andy Kaylor <andrew.kaylor at intel.com>
Date: Mon, 19 Aug 2024 11:33:05 -0700
Subject: [PATCH 5/5] Remove fp-contract changes, defer to a future PR

---
 clang/docs/ReleaseNotes.rst           | 5 ++---
 clang/docs/UsersManual.rst            | 4 ++--
 clang/lib/Driver/ToolChains/Clang.cpp | 3 +--
 clang/test/Driver/fp-model.c          | 4 ++--
 4 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 0f4cf8a234d9df..e3fac712de4662 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -180,10 +180,9 @@ Modified Compiler Flags
   optimizations when the ``fast`` argument is used and to accept a new argument,
   ``aggressive``. The behavior of ``-ffp-model=aggressive`` is equivalent
   to the previous behavior of ``-ffp-model=fast``. The updated
-  ``-ffp-model=fast`` behavior no longer assumes finite math only, uses
+  ``-ffp-model=fast`` behavior no longer assumes finite math only and uses
   the ``promoted`` algorithm for complex division when possible rather than the
-  less basic (limited range) algorithm, and sets
-  ``-ffp-contract=fast-honor-pragmas`` rather than ``-ffp-contract=fast``.
+  less basic (limited range) algorithm.
 
 Removed Compiler Flags
 -------------------------
diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst
index cd95b84eb6f863..d19b77ae40b0d7 100644
--- a/clang/docs/UsersManual.rst
+++ b/clang/docs/UsersManual.rst
@@ -1467,7 +1467,7 @@ floating point semantic models: precise (the default), strict, and fast.
   "except_behavior", "ignore", "strict", "ignore", "ignore"
   "fenv_access", "off", "on", "off", "off"
   "rounding_mode", "tonearest", "dynamic", "tonearest", "tonearest"
-  "contract", "on", "off", "fast-honor-pragmas", "fast-honor-pragmas"
+  "contract", "on", "off", "fast", "fast"
   "support_math_errno", "on", "on", "off", "off"
   "no_honor_nans", "off", "off", "off", "on"
   "no_honor_infinities", "off", "off", "off", "on"
@@ -1770,7 +1770,7 @@ for more details.
      top of the source file.
    * ``fast`` Behaves identically to specifying ``-funsafe-math-optimizations``,
      ``-fno-math-errno`` and ``-fcomplex-arithmetic=promoted``
-     ``ffp-contract=fast-honor-pragmas``
+     ``ffp-contract=fast``
    * ``aggressive`` Behaves identically to specifying both ``-ffast-math`` and
      ``ffp-contract=fast``
 
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index c5aaf7b91cd7d9..168d3e3f63bfe2 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -2935,12 +2935,10 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
     if (Aggressive) {
       HonorINFs = false;
       HonorNaNs = false;
-      FPContract = "fast";
       setComplexRange(LangOptions::ComplexRangeKind::CX_Basic);
     } else {
       HonorINFs = true;
       HonorNaNs = true;
-      FPContract = "fast-honor-pragmas";
       setComplexRange(LangOptions::ComplexRangeKind::CX_Promoted);
     }
     MathErrno = false;
@@ -2951,6 +2949,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
     TrappingMath = false;
     RoundingFPMath = false;
     FPExceptionBehavior = "";
+    FPContract = "fast";
     SeenUnsafeMathModeOption = true;
   };
 
diff --git a/clang/test/Driver/fp-model.c b/clang/test/Driver/fp-model.c
index 5088185311a069..6f17d4aeb1ef57 100644
--- a/clang/test/Driver/fp-model.c
+++ b/clang/test/Driver/fp-model.c
@@ -142,7 +142,7 @@
 // CHECK-FPM-FAST-SAME: "-fno-signed-zeros"
 // CHECK-FPM-FAST-SAME: "-mreassociate"
 // CHECK-FPM-FAST-SAME: "-freciprocal-math"
-// CHECK-FPM-FAST-SAME: "-ffp-contract=fast-honor-pragmas"
+// CHECK-FPM-FAST-SAME: "-ffp-contract=fast"
 // CHECK-FPM-FAST-SAME: "-fno-rounding-math"
 // CHECK-FPM-FAST-NOT: "-ffast-math"
 // CHECK-FPM-FAST-NOT: "-ffinite-math-only"
@@ -214,7 +214,7 @@
 // CHECK-FASTMATH-FPM-FAST-SAME: "-fno-signed-zeros"
 // CHECK-FASTMATH-FPM-FAST-SAME: "-mreassociate"
 // CHECK-FASTMATH-FPM-FAST-SAME: "-freciprocal-math"
-// CHECK-FASTMATH-FPM-FAST-SAME: "-ffp-contract=fast-honor-pragmas"
+// CHECK-FASTMATH-FPM-FAST-SAME: "-ffp-contract=fast"
 // CHECK-FASTMATH-FPM-FAST-SAME: "-fno-rounding-math"
 // CHECK-FASTMATH-FPM-FAST-NOT: "-ffast-math"
 // CHECK-FASTMATH-FPM-FAST-NOT: "-ffinite-math-only"



More information about the cfe-commits mailing list