From b0f68791f0ad867118497daf6aa23f9a71500012 Mon Sep 17 00:00:00 2001 From: Masoud Ataei Date: Fri, 8 Oct 2021 14:26:14 -0400 Subject: [PATCH] [clang] Option control afn flag Clang option to set/unset afn fast-math flag. Differential: https://reviews.llvm.org/D106191 Reviewd with: aaron.ballman, erichkeane, and others --- clang/docs/UsersManual.rst | 11 +++++++++++ clang/include/clang/Driver/Options.td | 7 +++++-- clang/lib/CodeGen/BackendUtil.cpp | 1 + clang/lib/CodeGen/CGCall.cpp | 2 ++ clang/lib/Driver/ToolChains/Clang.cpp | 6 ++++++ clang/test/CodeGen/afn-flag-test.c | 14 ++++++++++++++ clang/test/Driver/fast-math.c | 5 +++++ llvm/include/llvm/Target/TargetOptions.h | 8 +++++++- 8 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 clang/test/CodeGen/afn-flag-test.c diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index f025028c1721..30da581c6770 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -1386,6 +1386,17 @@ are listed below. If both ``-fno-honor-infinities`` and ``-fno-honor-nans`` are used, has the same effect as specifying ``-ffinite-math-only``. +.. _opt_fapprox-func: + +**-f[no-]approx-func** + + Allow certain math function calls (such as ``log``, ``sqrt``, ``pow``, etc) + to be replaced with an approximately equivalent set of instructions + or alternative math function calls. For example, a ``pow(x, 0.25)`` + may be replaced with ``sqrt(sqrt(x))``, despite being an inexact result + in cases where ``x`` is ``-0.0`` or ``-inf``. + Defaults to ``-fno-approx-func``. + .. _opt_fsigned-zeros: **-f[no-]signed-zeros** diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 5a87f1276d1f..9b0d0dfb7628 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1764,8 +1764,11 @@ defm reciprocal_math : BoolFOption<"reciprocal-math", PosFlag, NegFlag>; -def fapprox_func : Flag<["-"], "fapprox-func">, Group, Flags<[CC1Option, NoDriverOption]>, - MarshallingInfoFlag>, ImpliedByAnyOf<[menable_unsafe_fp_math.KeyPath]>; +defm approx_func : BoolFOption<"approx-func", LangOpts<"ApproxFunc">, DefaultFalse, + PosFlag, + NegFlag>; defm finite_math_only : BoolFOption<"finite-math-only", LangOpts<"FiniteMathOnly">, DefaultFalse, PosFlag, diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 99e33b227f79..76f6985d5cfa 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -539,6 +539,7 @@ static bool initTargetOptions(DiagnosticsEngine &Diags, Options.NoNaNsFPMath = LangOpts.NoHonorNaNs; Options.NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS; Options.UnsafeFPMath = LangOpts.UnsafeFPMath; + Options.ApproxFuncFPMath = LangOpts.ApproxFunc; Options.BBSections = llvm::StringSwitch(CodeGenOpts.BBSections) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 70966c9e7b35..af5f519c6fce 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1848,6 +1848,8 @@ void CodeGenModule::getDefaultFunctionAttributes(StringRef Name, FuncAttrs.addAttribute("no-infs-fp-math", "true"); if (LangOpts.NoHonorNaNs) FuncAttrs.addAttribute("no-nans-fp-math", "true"); + if (LangOpts.ApproxFunc) + FuncAttrs.addAttribute("approx-func-fp-math", "true"); if (LangOpts.UnsafeFPMath) FuncAttrs.addAttribute("unsafe-fp-math", "true"); if (CodeGenOpts.SoftFloat) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index c636c25a1dc8..f1771d4fa35d 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -2614,6 +2614,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, // LLVM flags based on the final state. bool HonorINFs = true; bool HonorNaNs = true; + bool ApproxFunc = false; // -fmath-errno is the default on some platforms, e.g. BSD-derived OSes. bool MathErrno = TC.IsMathErrnoDefault(); bool AssociativeMath = false; @@ -2718,6 +2719,8 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, case options::OPT_fno_honor_infinities: HonorINFs = false; break; case options::OPT_fhonor_nans: HonorNaNs = true; break; case options::OPT_fno_honor_nans: HonorNaNs = false; break; + case options::OPT_fapprox_func: ApproxFunc = true; break; + case options::OPT_fno_approx_func: ApproxFunc = false; break; case options::OPT_fmath_errno: MathErrno = true; break; case options::OPT_fno_math_errno: MathErrno = false; break; case options::OPT_fassociative_math: AssociativeMath = true; break; @@ -2913,6 +2916,9 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, if (!HonorNaNs) CmdArgs.push_back("-menable-no-nans"); + if (ApproxFunc) + CmdArgs.push_back("-fapprox-func"); + if (MathErrno) CmdArgs.push_back("-fmath-errno"); diff --git a/clang/test/CodeGen/afn-flag-test.c b/clang/test/CodeGen/afn-flag-test.c new file mode 100644 index 000000000000..f948fc068ba2 --- /dev/null +++ b/clang/test/CodeGen/afn-flag-test.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -fapprox-func %s -emit-llvm -o - | FileCheck --check-prefix=CHECK-AFN %s +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck --check-prefix=CHECK-NO-AFN %s + +extern double exp(double); +double afn_option_test(double x) { + return exp(x); + // CHECK-LABEL: define{{.*}} double @afn_option_test(double %x) #0 { + + // CHECK-AFN: %{{.*}} = call afn double @{{.*}}exp{{.*}}(double %{{.*}}) + // CHECK-AFN: attributes #0 ={{.*}} "approx-func-fp-math"="true" {{.*}} + + // CHECK-NO-AFN: %{{.*}} = call double @{{.*}}exp{{.*}}(double %{{.*}}) + // CHECK-NO-AFN-NOT: attributes #0 ={{.*}} "approx-func-fp-math"="true" {{.*}} +} diff --git a/clang/test/Driver/fast-math.c b/clang/test/Driver/fast-math.c index d6c82add799c..8d293c2ea01f 100644 --- a/clang/test/Driver/fast-math.c +++ b/clang/test/Driver/fast-math.c @@ -70,6 +70,11 @@ // CHECK-NO-NANS-NO-FAST-MATH: "-cc1" // CHECK-NO-NANS-NO-FAST-MATH-NOT: "-menable-no-nans" // +// RUN: %clang -### -fapprox-func -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-APPROX-FUNC %s +// CHECK-APPROX-FUNC: "-cc1" +// CHECK-APPROX-FUNC: "-fapprox-func" +// // RUN: %clang -### -fmath-errno -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-MATH-ERRNO %s // CHECK-MATH-ERRNO: "-cc1" diff --git a/llvm/include/llvm/Target/TargetOptions.h b/llvm/include/llvm/Target/TargetOptions.h index 11f9296f900c..912f6d1c153a 100644 --- a/llvm/include/llvm/Target/TargetOptions.h +++ b/llvm/include/llvm/Target/TargetOptions.h @@ -126,7 +126,7 @@ namespace llvm { TargetOptions() : UnsafeFPMath(false), NoInfsFPMath(false), NoNaNsFPMath(false), NoTrappingFPMath(true), NoSignedZerosFPMath(false), - EnableAIXExtendedAltivecABI(false), + ApproxFuncFPMath(false), EnableAIXExtendedAltivecABI(false), HonorSignDependentRoundingFPMathOption(false), NoZerosInBSS(false), GuaranteedTailCallOpt(false), StackSymbolOrdering(true), EnableFastISel(false), EnableGlobalISel(false), UseInitArray(false), @@ -183,6 +183,12 @@ namespace llvm { /// argument or result as insignificant. unsigned NoSignedZerosFPMath : 1; + /// ApproxFuncFPMath - This flag is enabled when the + /// -enable-approx-func-fp-math is specified on the command line. This + /// specifies that optimizations are allowed to substitute math functions + /// with approximate calculations + unsigned ApproxFuncFPMath : 1; + /// EnableAIXExtendedAltivecABI - This flag returns true when -vec-extabi is /// specified. The code generator is then able to use both volatile and /// nonvolitle vector registers. When false, the code generator only uses