[flang-commits] [flang] 5d27e3a - [Flang][Driver] Override -ffast-math floating point contraction with -ffp-contract= (#213574)
via flang-commits
flang-commits at lists.llvm.org
Tue Aug 11 17:00:04 PDT 2026
Author: Shunsuke Watanabe
Date: 2026-08-12T08:59:55+09:00
New Revision: 5d27e3a28f23ed73507d681b5f0cb96ab5f5d3f3
URL: https://github.com/llvm/llvm-project/commit/5d27e3a28f23ed73507d681b5f0cb96ab5f5d3f3
DIFF: https://github.com/llvm/llvm-project/commit/5d27e3a28f23ed73507d681b5f0cb96ab5f5d3f3.diff
LOG: [Flang][Driver] Override -ffast-math floating point contraction with -ffp-contract= (#213574)
This patch allows overriding the floating point contract settings
implied by -ffast-math by explicitly specifying -ffp-contract=. The
final floating point contract mode follows the usual last-flag-wins
behavior. In addition, -fno-fast-math only cancels the effects of
-ffast-math and preserves any explicitly specified -ffp-contract=
setting.
A warning is emitted when an explicit -ffp-contract= option overrides
the floating point contract mode implied by -ffast-math.
This behavior is consistent with Clang.
Added:
Modified:
clang/lib/Driver/ToolChains/Flang.cpp
flang/test/Driver/fast-math.f90
Removed:
################################################################################
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index b2d709afcb4e2..a48e41159f367 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -894,6 +894,8 @@ void Flang::addOffloadOptions(Compilation &C, const InputInfoList &Inputs,
static void addFloatingPointOptions(const Driver &D, const ArgList &Args,
ArgStringList &CmdArgs) {
StringRef FPContract;
+ StringRef LastSeenFfpContractOption;
+ StringRef LastFpContractOverrideOption;
bool HonorINFs = true;
bool HonorNaNs = true;
bool ApproxFunc = false;
@@ -904,23 +906,6 @@ static void addFloatingPointOptions(const Driver &D, const ArgList &Args,
StringRef LastComplexRangeOption;
LangOptions::ComplexRangeKind Range = LangOptions::ComplexRangeKind::CX_None;
- if (const Arg *A = Args.getLastArg(options::OPT_ffp_contract)) {
- const StringRef Val = A->getValue();
- if (Val == "fast" || Val == "off") {
- FPContract = Val;
- } else if (Val == "on") {
- // Warn instead of error because users might have makefiles written for
- // gfortran (which accepts -ffp-contract=on)
- D.Diag(diag::warn_drv_unsupported_option_for_flang)
- << Val << A->getOption().getName() << "off";
- FPContract = "off";
- } else
- // Clang's "fast-honor-pragmas" option is not supported because it is
- // non-standard
- D.Diag(diag::err_drv_unsupported_option_argument)
- << A->getSpelling() << Val;
- }
-
for (const Arg *A : Args) {
auto optId = A->getOption().getID();
switch (optId) {
@@ -983,6 +968,32 @@ static void addFloatingPointOptions(const Driver &D, const ArgList &Args,
case options::OPT_fno_reciprocal_math:
ReciprocalMath = false;
break;
+ case options::OPT_ffp_contract: {
+ StringRef Val = A->getValue();
+ if (Val == "fast" || Val == "off") {
+ if (Val != FPContract && LastFpContractOverrideOption != "") {
+ D.Diag(clang::diag::warn_drv_overriding_option)
+ << LastFpContractOverrideOption
+ << Args.MakeArgString("-ffp-contract=" + Val);
+ }
+ FPContract = Val;
+ LastSeenFfpContractOption = Val;
+ } else if (Val == "on") {
+ // Warn instead of error because users might have makefiles written for
+ // gfortran (which accepts -ffp-contract=on)
+ D.Diag(diag::warn_drv_unsupported_option_for_flang)
+ << Val << A->getOption().getName() << "off";
+ FPContract = "off";
+ LastSeenFfpContractOption = "off";
+ } else {
+ // Clang's "fast-honor-pragmas" option is not supported because it is
+ // non-standard
+ D.Diag(diag::err_drv_unsupported_option_argument)
+ << A->getSpelling() << Val;
+ }
+ LastFpContractOverrideOption = "";
+ break;
+ }
case options::OPT_Ofast:
[[fallthrough]];
case options::OPT_ffast_math:
@@ -993,6 +1004,10 @@ static void addFloatingPointOptions(const Driver &D, const ArgList &Args,
ApproxFunc = true;
SignedZeros = false;
FPContract = "fast";
+ if (A->getOption().getID() == options::OPT_Ofast)
+ LastFpContractOverrideOption = "-Ofast";
+ else
+ LastFpContractOverrideOption = "-ffast-math";
setComplexRange(D, A->getSpelling(),
LangOptions::ComplexRangeKind::CX_Basic,
LastComplexRangeOption, Range);
@@ -1005,13 +1020,17 @@ static void addFloatingPointOptions(const Driver &D, const ArgList &Args,
ApproxFunc = false;
SignedZeros = true;
// -fno-fast-math should undo -ffast-math so I return FPContract to the
- // default. It is important to check it is "fast" (the default) so that
- // --ffp-contract=off -fno-fast-math --> -ffp-contract=off
- if (FPContract == "fast")
+ // default. If -ffp-contract= was explicitly specified, restore the
+ // user-requested value from LastSeenFfpContractOption so that
+ // -ffp-contract=off -fno-fast-math --> -ffp-contract=off
+ if (LastSeenFfpContractOption != "")
+ FPContract = LastSeenFfpContractOption;
+ else
FPContract = "";
setComplexRange(D, A->getSpelling(),
LangOptions::ComplexRangeKind::CX_None,
LastComplexRangeOption, Range);
+ LastFpContractOverrideOption = "";
break;
}
diff --git a/flang/test/Driver/fast-math.f90 b/flang/test/Driver/fast-math.f90
index 22e339dc8ace9..39c36863b9463 100644
--- a/flang/test/Driver/fast-math.f90
+++ b/flang/test/Driver/fast-math.f90
@@ -2,24 +2,24 @@
! frontend driver
! Check warning message for Ofast deprecation
-! RUN: %flang -Ofast -### %s -o %t 2>&1 | FileCheck %s
+! RUN: %flang -Ofast -### %s 2>&1 | FileCheck %s
! CHECK: warning: argument '-Ofast' is deprecated; use '-O3 -ffast-math -fstack-arrays -fno-protect-parens' for the same behavior, or '-O3 -fstack-arrays' to enable only conforming optimizations [-Wdeprecated-ofast]
! -Ofast => -ffast-math -O3 -fstack-arrays
-! RUN: %flang -Ofast -fsyntax-only -### %s -o %t 2>&1 \
+! RUN: %flang -Ofast -fsyntax-only -### %s 2>&1 \
! RUN: | FileCheck --check-prefix=CHECK-OFAST %s
! CHECK-OFAST: -fc1
! CHECK-OFAST-SAME: -ffast-math
! CHECK-OFAST-SAME: -fstack-arrays
! CHECK-OFAST-SAME: -O3
-! RUN: %flang -fstack-arrays -fsyntax-only -### %s -o %t 2>&1 \
+! RUN: %flang -fstack-arrays -fsyntax-only -### %s 2>&1 \
! RUN: | FileCheck --check-prefix=CHECK-STACK-ARRAYS %s
! CHECK-STACK-ARRAYS: -fc1
! CHECK-STACK-ARRAYS-SAME: -fstack-arrays
! -Ofast -fno-fast-math => -O3 -fstack-arrays
-! RUN: %flang -Ofast -fno-fast-math -fsyntax-only -### %s -o %t 2>&1 \
+! RUN: %flang -Ofast -fno-fast-math -fsyntax-only -### %s 2>&1 \
! RUN: | FileCheck --check-prefix=CHECK-OFAST-NO-FAST %s
! CHECK-OFAST-NO-FAST: -fc1
! CHECK-OFAST-NO-FAST-NOT: -ffast-math
@@ -27,7 +27,7 @@
! CHECK-OFAST-NO-FAST-SAME: -O3
! -Ofast -fno-stack-arrays -> -O3 -ffast-math
-! RUN: %flang -Ofast -fno-stack-arrays -fsyntax-only -### %s -o %t 2>&1 \
+! RUN: %flang -Ofast -fno-stack-arrays -fsyntax-only -### %s 2>&1 \
! RUN: | FileCheck --check-prefix=CHECK-OFAST-NO-SA %s
! CHECK-OFAST-NO-SA: -fc1
! CHECK-OFAST-NO-SA-SAME: -ffast-math
@@ -35,13 +35,13 @@
! CHECK-OFAST-NO-SA-SAME: -O3
! -ffast-math => -ffast-math
-! RUN: %flang -ffast-math -fsyntax-only -### %s -o %t 2>&1 \
+! RUN: %flang -ffast-math -fsyntax-only -### %s 2>&1 \
! RUN: | FileCheck --check-prefix=CHECK-FFAST %s
! CHECK-FFAST: -fc1
! CHECK-FFAST-SAME: -ffast-math
! (component flags) => -ffast-math
-! RUN: %flang -fsyntax-only -### %s -o %t \
+! RUN: %flang -fsyntax-only -### %s \
! RUN: -fno-honor-infinities \
! RUN: -fno-honor-nans \
! RUN: -fassociative-math \
@@ -54,7 +54,7 @@
! CHECK-FROM-COMPS-SAME: -ffast-math
! -ffast-math (followed by an alteration) => (component flags)
-! RUN: %flang -ffast-math -fhonor-infinities -fsyntax-only -### %s -o %t 2>&1 \
+! RUN: %flang -ffast-math -fhonor-infinities -fsyntax-only -### %s 2>&1 \
! RUN: | FileCheck --check-prefix=CHECK-TO-COMPS %s
! CHECK-TO-COMPS: -fc1
! CHECK-TO-COMPS-SAME: -ffp-contract=fast
@@ -64,16 +64,57 @@
! CHECK-TO-COMPS-SAME: -mreassociate
! CHECK-TO-COMPS-SAME: -freciprocal-math
+! Check if -ffast-math component flags can be disabled
+! RUN: %flang -ffast-math \
+! RUN: -ffp-contract=off \
+! RUN: -fhonor-infinities \
+! RUN: -fhonor-nans \
+! RUN: -fno-approx-func \
+! RUN: -fsigned-zeros \
+! RUN: -fno-associative-math \
+! RUN: -fno-reciprocal-math \
+! RUN: -fsyntax-only -### %s 2>&1 \
+! RUN: | FileCheck --check-prefix=CHECK-TO-COMPS-DIS %s
+! CHECK-TO-COMPS-DIS: warning: overriding '-ffast-math' option with '-ffp-contract=off' [-Woverriding-option]
+! CHECK-TO-COMPS-DIS: -fc1
+! CHECK-TO-COMPS-DIS-SAME: -ffp-contract=off
+! CHECK-TO-COMPS-DIS-NOT: -menable-no-infs
+! CHECK-TO-COMPS-DIS-NOT: -menable-no-nans
+! CHECK-TO-COMPS-DIS-NOT: -fapprox-func
+! CHECK-TO-COMPS-DIS-NOT: -fno-signed-zeros
+! CHECK-TO-COMPS-DIS-NOT: -mreassociate
+! CHECK-TO-COMPS-DIS-NOT: -freciprocal-math
+
! Check that -fno-fast-math doesn't clobber -ffp-contract
-! RUN: %flang -ffp-contract=off -fno-fast-math -fsyntax-only -### %s -o %t 2>&1 \
+! RUN: %flang -ffp-contract=off -fno-fast-math -fsyntax-only -### %s 2>&1 \
! RUN: | FileCheck --check-prefix=CHECK-CONTRACT %s
! CHECK-CONTRACT: -fc1
! CHECK-CONTRACT-SAME: -ffp-contract=off
+! Check that -fno-fast-math only disables -ffast-math.
+! RUN: %flang -ffp-contract=off -ffast-math -fno-fast-math -fsyntax-only -### %s 2>&1 \
+! RUN: | FileCheck --check-prefix=CHECK-CONTRACT-NOFAST %s
+! CHECK-CONTRACT-NOFAST: -fc1
+! CHECK-CONTRACT-NOFAST-SAME: -ffp-contract=off
+
+! Check that no warning is emitted after -fno-fast-math.
+! RUN: %flang -ffast-math -fno-fast-math -ffp-contract=off -fsyntax-only -### %s 2>&1 \
+! RUN: | FileCheck --check-prefix=CHECK-NOFAST-CONTRACT %s
+! CHECK-NOFAST-CONTRACT-NOT: warning: overriding '-ffast-math' option with '-ffp-contract=off' [-Woverriding-option]
+! CHECK-NOFAST-CONTRACT: -fc1
+! CHECK-NOFAST-CONTRACT-SAME: -ffp-contract=off
+
+! Check that -Ofast is overridden.
+! RUN: %flang -Ofast -ffp-contract=off -fsyntax-only -### %s 2>&1 \
+! RUN: | FileCheck --check-prefix=CHECK-OFAST-CONTRACT %s
+! CHECK-OFAST-CONTRACT: warning: overriding '-Ofast' option with '-ffp-contract=off' [-Woverriding-option]
+! CHECK-OFAST-CONTRACT: -fc1
+! CHECK-OFAST-CONTRACT-SAME: -ffp-contract=off
+
! Check that -ffast-math causes us to link to crtfastmath.o
! UNSUPPORTED: system-windows
! UNSUPPORTED: target=powerpc{{.*}}
-! RUN: %flang -ffast-math -### %s -o %t 2>&1 \
+! RUN: %flang -ffast-math -### %s 2>&1 \
! RUN: --target=x86_64-unknown-linux -no-pie \
! RUN: --sysroot=%S/../../../clang/test/Driver/Inputs/basic_linux_tree \
! RUN: | FileCheck --check-prefix=CHECK-CRT %s
More information about the flang-commits
mailing list