Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -741,7 +741,7 @@ HelpText<"Treat source input files as Objective-C inputs">; def O : Joined<["-"], "O">, Group, Flags<[CC1Option,FC1Option]>; def O_flag : Flag<["-"], "O">, Flags<[CC1Option,FC1Option]>, Alias, AliasArgs<["1"]>; -def Ofast : Joined<["-"], "Ofast">, Group, Flags<[CC1Option]>; +def Ofast : Joined<["-"], "Ofast">, Group, Flags<[CC1Option, FlangOption]>; def P : Flag<["-"], "P">, Flags<[CC1Option,FlangOption,FC1Option]>, Group, HelpText<"Disable linemarker output in -E mode">, MarshallingInfoNegativeFlag>; @@ -1603,7 +1603,7 @@ MarshallingInfoEnum, "FPE_Default">; defm fast_math : BoolFOption<"fast-math", LangOpts<"FastMath">, DefaultFalse, - PosFlag, NegFlag>; defm math_errno : BoolFOption<"math-errno", Index: clang/lib/Driver/ToolChains/Flang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Flang.cpp +++ clang/lib/Driver/ToolChains/Flang.cpp @@ -150,12 +150,45 @@ case options::OPT_fno_reciprocal_math: ReciprocalMath = false; break; + case options::OPT_Ofast: + [[fallthrough]]; + case options::OPT_ffast_math: + HonorINFs = false; + HonorNaNs = false; + AssociativeMath = true; + ReciprocalMath = true; + ApproxFunc = true; + SignedZeros = false; + FPContract = "fast"; + break; + case options::OPT_fno_fast_math: + HonorINFs = true; + HonorNaNs = true; + AssociativeMath = false; + ReciprocalMath = false; + ApproxFunc = false; + SignedZeros = true; + // FPContract = fast is the default anyway + // -fno-fast-math should undo -ffast-math so I return FPContract to the + // default anyway. It is important to check it is "fast" so that + // --ffp-contract=off -fno-fast-math doesn't lead to -ffp-contract=fast + if (FPContract == "fast") + FPContract = ""; + break; } // If we handled this option claim it A->claim(); } + if (!HonorINFs && !HonorNaNs && AssociativeMath && ReciprocalMath && + ApproxFunc && !SignedZeros && + (FPContract == "fast" || FPContract == "")) { + CmdArgs.push_back("-ffast-math"); + // No need to specify the other flags: + return; + } + if (!FPContract.empty()) CmdArgs.push_back(Args.MakeArgString("-ffp-contract=" + FPContract)); @@ -266,6 +299,8 @@ if (A->getOption().matches(options::OPT_O4)) { CmdArgs.push_back("-O3"); D.Diag(diag::warn_O4_is_O3); + } else if (A->getOption().matches(options::OPT_Ofast)) { + CmdArgs.push_back("-O3"); } else { A->render(Args, CmdArgs); } Index: flang/include/flang/Common/MathOptionsBase.def =================================================================== --- flang/include/flang/Common/MathOptionsBase.def +++ flang/include/flang/Common/MathOptionsBase.def @@ -38,4 +38,7 @@ /// Allow division operations to be reassociated ENUM_MATHOPT(ReciprocalMath, unsigned, 1, 0) +/// Allow aggressive, lossy floating-point optimizations (umbrella flag) +ENUM_MATHOPT(FastMath, unsigned, 1, 0) + #undef ENUM_MATHOPT Index: flang/include/flang/Frontend/LangOptions.def =================================================================== --- flang/include/flang/Frontend/LangOptions.def +++ flang/include/flang/Frontend/LangOptions.def @@ -34,6 +34,8 @@ LANGOPT(AssociativeMath, 1, false) /// Allow division operations to be reassociated LANGOPT(ReciprocalMath, 1, false) +/// Allow aggressive, lossy floating-point optimizations (umbrella flag) +LANGOPT(FastMath, 1, false) #undef LANGOPT #undef ENUM_LANGOPT Index: flang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- flang/lib/Frontend/CompilerInvocation.cpp +++ flang/lib/Frontend/CompilerInvocation.cpp @@ -735,6 +735,19 @@ opts.ReciprocalMath = true; } + if (const llvm::opt::Arg *a = + args.getLastArg(clang::driver::options::OPT_ffast_math)) { + diags.Report(diagUnimplemented) << a->getOption().getName(); + opts.FastMath = true; + opts.NoHonorInfs = true; + opts.NoHonorNaNs = true; + opts.AssociativeMath = true; + opts.ReciprocalMath = true; + opts.ApproxFunc = true; + opts.NoSignedZeros = true; + opts.setFPContractMode(LangOptions::FPM_Fast); + } + return true; } @@ -965,5 +978,6 @@ .setApproxFunc(langOptions.ApproxFunc) .setNoSignedZeros(langOptions.NoSignedZeros) .setAssociativeMath(langOptions.AssociativeMath) - .setReciprocalMath(langOptions.ReciprocalMath); + .setReciprocalMath(langOptions.ReciprocalMath) + .setFastMath(langOptions.FastMath); } Index: flang/lib/Optimizer/Builder/FIRBuilder.cpp =================================================================== --- flang/lib/Optimizer/Builder/FIRBuilder.cpp +++ flang/lib/Optimizer/Builder/FIRBuilder.cpp @@ -621,6 +621,9 @@ if (options.getReciprocalMath()) { arithFMF = arithFMF | mlir::arith::FastMathFlags::arcp; } + if (options.getFastMath()) { + arithFMF = arithFMF | mlir::arith::FastMathFlags::fast; + } setFastMathFlags(arithFMF); } Index: flang/test/Driver/driver-help-hidden.f90 =================================================================== --- flang/test/Driver/driver-help-hidden.f90 +++ flang/test/Driver/driver-help-hidden.f90 @@ -29,6 +29,7 @@ ! CHECK-NEXT: -fdefault-double-8 Set the default double precision kind to an 8 byte wide type ! CHECK-NEXT: -fdefault-integer-8 Set the default integer kind to an 8 byte wide type ! CHECK-NEXT: -fdefault-real-8 Set the default real kind to an 8 byte wide type +! CHECK-NEXT: -ffast-math Allow aggressive, lossy floating-point optimizations ! CHECK-NEXT: -ffixed-form Process source files in fixed form ! CHECK-NEXT: -ffixed-line-length= ! CHECK-NEXT: Use as character line width in fixed mode Index: flang/test/Driver/driver-help.f90 =================================================================== --- flang/test/Driver/driver-help.f90 +++ flang/test/Driver/driver-help.f90 @@ -29,6 +29,7 @@ ! HELP-NEXT: -fdefault-double-8 Set the default double precision kind to an 8 byte wide type ! HELP-NEXT: -fdefault-integer-8 Set the default integer kind to an 8 byte wide type ! HELP-NEXT: -fdefault-real-8 Set the default real kind to an 8 byte wide type +! HELP-NEXT: -ffast-math Allow aggressive, lossy floating-point optimizations ! HELP-NEXT: -ffixed-form Process source files in fixed form ! HELP-NEXT: -ffixed-line-length= ! HELP-NEXT: Use as character line width in fixed mode @@ -108,6 +109,7 @@ ! HELP-FC1-NEXT: -fdefault-double-8 Set the default double precision kind to an 8 byte wide type ! HELP-FC1-NEXT: -fdefault-integer-8 Set the default integer kind to an 8 byte wide type ! HELP-FC1-NEXT: -fdefault-real-8 Set the default real kind to an 8 byte wide type +! HELP-FC1-NEXT: -ffast-math Allow aggressive, lossy floating-point optimizations ! HELP-FC1-NEXT: -ffixed-form Process source files in fixed form ! HELP-FC1-NEXT: -ffixed-line-length= ! HELP-FC1-NEXT: Use as character line width in fixed mode Index: flang/test/Driver/fast_math.f90 =================================================================== --- /dev/null +++ flang/test/Driver/fast_math.f90 @@ -0,0 +1,51 @@ +! Test for correct forwarding of fast-math flags from the compiler driver to the +! frontend driver + +! -Ofast => -ffast-math -O3 +! RUN: %flang -Ofast -fsyntax-only -### %s -o %t 2>&1 \ +! RUN: | FileCheck --check-prefix=CHECK-OFAST %s +! CHECK-OFAST: -ffast-math +! CHECK-OFAST: -O3 + +! -Ofast -fno-fast-math => -O3 +! RUN: %flang -Ofast -fno-fast-math -fsyntax-only -### %s -o %t 2>&1 \ +! RUN: | FileCheck --check-prefix=CHECK-OFAST-NO-FAST %s +! CHECK-OFAST-NO-FAST-NOT: -ffast-math +! CHECK-OFAST-NO-FAST: -O3 + +! -ffast-math => -ffast-math +! RUN: %flang -ffast-math -fsyntax-only -### %s -o %t 2>&1 \ +! RUN: | FileCheck --check-prefix=CHECK-FFAST %s +! CHECK-FFAST: -ffast-math + +! (component flags) => -ffast-math +! RUN: %flang -fsyntax-only -### %s -o %t \ +! RUN: -fno-honor-infinities \ +! RUN: -fno-honor-nans \ +! RUN: -fassociative-math \ +! RUN: -freciprocal-math \ +! RUN: -fapprox-func \ +! RUN: -fno-signed-zeros \ +! RUN: -ffp-contract=fast \ +! RUN: 2>&1 | FileCheck --check-prefix=CHECK-FROM-COMPS %s +! CHECK-FROM-COMPS: -ffast-math + +! -ffast-math (followed by an alteration) => (component flags) +! RUN: %flang -ffast-math -fhonor-infinities -fsyntax-only -### %s -o %t 2>&1 \ +! RUN: | FileCheck --check-prefix=CHECK-TO-COMPS %s +! CHECK-TO-COMPS: -ffp-contract=fast +! CHECK-TO-COMPS: -menable-no-nans +! CHECK-TO-COMPS: -fapprox-func +! CHECK-TO-COMPS: -fno-signed-zeros +! CHECK-TO-COMPS: -mreassociate +! CHECK-TO-COMPS: -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: | FileCheck --check-prefix=CHECK-CONTRACT %s +! CHECK-CONTRACT: -ffp-contract=off + +! check for frontend driver warning +! RUN: %flang_fc1 -ffast-math -fsyntax-only %s -o %t 2>&1 \ +! RUN: | FileCheck --check-prefix=CHECK-WARN %s +! CHECK-WARN: ffast-math is not currently implemented Index: flang/test/Driver/frontend-forwarding.f90 =================================================================== --- flang/test/Driver/frontend-forwarding.f90 +++ flang/test/Driver/frontend-forwarding.f90 @@ -9,7 +9,6 @@ ! RUN: -flarge-sizes \ ! RUN: -fconvert=little-endian \ ! RUN: -ffp-contract=fast \ -! RUN: -fno-honor-infinities \ ! RUN: -fno-honor-nans \ ! RUN: -fapprox-func \ ! RUN: -fno-signed-zeros \ @@ -27,7 +26,6 @@ ! CHECK: "-fdefault-real-8" ! CHECK: "-flarge-sizes" ! CHECK: "-ffp-contract=fast" -! CHECK: "-menable-no-infs" ! CHECK: "-menable-no-nans" ! CHECK: "-fapprox-func" ! CHECK: "-fno-signed-zeros" Index: flang/test/Lower/fast-math-arithmetic.f90 =================================================================== --- flang/test/Lower/fast-math-arithmetic.f90 +++ flang/test/Lower/fast-math-arithmetic.f90 @@ -6,6 +6,7 @@ ! RUN: %flang_fc1 -emit-fir -mreassociate -ffp-contract=off %s -o - 2>&1 | FileCheck --check-prefixes=REASSOC,ALL %s ! RUN: %flang_fc1 -emit-fir -freciprocal-math -ffp-contract=off %s -o - 2>&1 | FileCheck --check-prefixes=ARCP,ALL %s ! RUN: %flang_fc1 -emit-fir -ffp-contract=fast -menable-no-infs -menable-no-nans -fapprox-func -fno-signed-zeros -mreassociate -freciprocal-math %s -o - 2>&1 | FileCheck --check-prefixes=FAST,ALL %s +! RUN: %flang_fc1 -emit-fir -ffast-math %s -o - 2>&1 | FileCheck --check-prefixes=FAST,ALL %s ! ALL-LABEL: func.func @_QPtest subroutine test(x)