From d2eccb2430fadfc0ee144d7c34a042494c68a9be Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Thu, 9 Apr 2015 15:03:23 +0000 Subject: [PATCH] Process the -freciprocal-math optimization flag (PR20912) The driver currently accepts but ignores the -freciprocal-math flag. This patch passes the flag through and enables 'arcp' fast-math-flag generation in IR. Note that this change does not actually enable the optimization for any target. The reassociation optimization that this flag specifies was implemented by http://reviews.llvm.org/D6334 : http://llvm.org/viewvc/llvm-project?view=revision&revision=222510 Because the optimization is done in the backend rather than IR, the backend must be modified to understand instruction-level fast-math-flags or a new function-level attribute must be created. Also note that -freciprocal-math is independent of any target-specific usage of reciprocal estimate hardware instructions. That requires its own flag ('-mrecip'). https://llvm.org/bugs/show_bug.cgi?id=20912 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@234493 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Driver/Options.td | 4 +++- include/clang/Frontend/CodeGenOptions.def | 3 ++- lib/CodeGen/CodeGenFunction.cpp | 3 +++ lib/Driver/Tools.cpp | 3 +++ lib/Frontend/CompilerInvocation.cpp | 1 + test/CodeGen/finite-math.c | 2 ++ test/Driver/fast-math.c | 15 +++++++++++++++ 7 files changed, 29 insertions(+), 2 deletions(-) diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index 4e1afbe4e9..45729cf0ab 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -561,7 +561,9 @@ def fno_unsafe_math_optimizations : Flag<["-"], "fno-unsafe-math-optimizations"> Group; def fassociative_math : Flag<["-"], "fassociative-math">, Group; def fno_associative_math : Flag<["-"], "fno-associative-math">, Group; -def freciprocal_math : Flag<["-"], "freciprocal-math">, Group; +def freciprocal_math : + Flag<["-"], "freciprocal-math">, Group, Flags<[CC1Option]>, + HelpText<"Allow division operations to be reassociated">; def fno_reciprocal_math : Flag<["-"], "fno-reciprocal-math">, Group; def ffinite_math_only : Flag<["-"], "ffinite-math-only">, Group, Flags<[CC1Option]>; def fno_finite_math_only : Flag<["-"], "fno-finite-math-only">, Group; diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def index 514716f361..188171b86e 100644 --- a/include/clang/Frontend/CodeGenOptions.def +++ b/include/clang/Frontend/CodeGenOptions.def @@ -81,7 +81,8 @@ CODEGENOPT(NoGlobalMerge , 1, 0) ///< Set when -mno-global-merge is enabled. CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enabled. CODEGENOPT(NoInfsFPMath , 1, 0) ///< Assume FP arguments, results not +-Inf. CODEGENOPT(NoSignedZeros , 1, 0) ///< Allow ignoring the signedness of FP zero -CODEGENOPT(NoInline , 1, 0) ///< Set when -fno-inline is enabled. +CODEGENOPT(ReciprocalMath , 1, 0) ///< Allow FP divisions to be reassociated. +CODEGENOPT(NoInline , 1, 0) ///< Set when -fno-inline is enabled. ///< Disables use of the inline keyword. CODEGENOPT(NoNaNsFPMath , 1, 0) ///< Assume FP arguments, results not NaN. CODEGENOPT(NoZeroInitializedInBSS , 1, 0) ///< -fno-zero-initialized-in-bss. diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index e59a50ee76..8401d722f4 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -70,6 +70,9 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext) if (CGM.getCodeGenOpts().NoSignedZeros) { FMF.setNoSignedZeros(); } + if (CGM.getCodeGenOpts().ReciprocalMath) { + FMF.setAllowReciprocal(); + } Builder.SetFastMathFlags(FMF); } diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index f0fc574bd0..9ebf681aab 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -3062,6 +3062,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (!SignedZeros) CmdArgs.push_back("-fno-signed-zeros"); + if (ReciprocalMath) + CmdArgs.push_back("-freciprocal-math"); + // Validate and pass through -fp-contract option. if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, options::OPT_fno_fast_math, diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 5d2cdae6e0..cd0a7c4640 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -451,6 +451,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Args.hasArg(OPT_cl_finite_math_only) || Args.hasArg(OPT_cl_fast_relaxed_math)); Opts.NoSignedZeros = Args.hasArg(OPT_fno_signed_zeros); + Opts.ReciprocalMath = Args.hasArg(OPT_freciprocal_math); Opts.NoZeroInitializedInBSS = Args.hasArg(OPT_mno_zero_initialized_in_bss); Opts.BackendOptions = Args.getAllArgValues(OPT_backend_option); Opts.NumRegisterParameters = getLastArgIntValue(Args, OPT_mregparm, 0, Diags); diff --git a/test/CodeGen/finite-math.c b/test/CodeGen/finite-math.c index fd8fcf6fad..8365b56fe5 100644 --- a/test/CodeGen/finite-math.c +++ b/test/CodeGen/finite-math.c @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -ffinite-math-only -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=FINITE // RUN: %clang_cc1 -fno-signed-zeros -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=NSZ +// RUN: %clang_cc1 -freciprocal-math -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=RECIP float f0, f1, f2; @@ -8,6 +9,7 @@ void foo(void) { // FINITE: fadd nnan ninf // NSZ: fadd nsz + // RECIP: fadd arcp f0 = f1 + f2; // CHECK: ret diff --git a/test/Driver/fast-math.c b/test/Driver/fast-math.c index bacd7fe4cb..24c30386da 100644 --- a/test/Driver/fast-math.c +++ b/test/Driver/fast-math.c @@ -40,6 +40,21 @@ // CHECK-NO-SIGNED-ZEROS-NO-FAST-MATH: "-cc1" // CHECK-NO-SIGNED-ZEROS-NO-FAST-MATH-NOT: "-fno-signed-zeros" // +// RUN: %clang -### -freciprocal-math -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RECIPROCAL-MATH %s +// CHECK-RECIPROCAL-MATH: "-cc1" +// CHECK-RECIPROCAL-MATH: "-freciprocal-math" +// +// RUN: %clang -### -fno-fast-math -freciprocal-math -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-NO-FAST-MATH-RECIPROCAL-MATH %s +// CHECK-NO-FAST-MATH-RECIPROCAL-MATH: "-cc1" +// CHECK-NO-FAST-MATH-RECIPROCAL-MATH: "-freciprocal-math" +// +// RUN: %clang -### -freciprocal-math -fno-fast-math -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RECIPROCAL-MATH-NO-FAST-MATH %s +// CHECK-RECIPROCAL-MATH-NO-FAST-MATH: "-cc1" +// CHECK-RECIPROCAL-MATH-NO-FAST-MATH-NOT: "-freciprocal-math" +// // RUN: %clang -### -fno-honor-nans -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NO-NANS %s // CHECK-NO-NANS: "-cc1" -- 2.50.1