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