[clang] Option control afn flag
authorMasoud Ataei <msd.ataei@gmail.com>
Fri, 8 Oct 2021 18:26:14 +0000 (14:26 -0400)
committerMasoud Ataei <msd.ataei@gmail.com>
Fri, 8 Oct 2021 18:26:14 +0000 (14:26 -0400)
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
clang/include/clang/Driver/Options.td
clang/lib/CodeGen/BackendUtil.cpp
clang/lib/CodeGen/CGCall.cpp
clang/lib/Driver/ToolChains/Clang.cpp
clang/test/CodeGen/afn-flag-test.c [new file with mode: 0644]
clang/test/Driver/fast-math.c
llvm/include/llvm/Target/TargetOptions.h

index f025028c1721d31a2f38e93de5b05329af46c2b0..30da581c6770038c1f26f7bc553afea3e7023129 100644 (file)
@@ -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**
index 5a87f1276d1f34056ab982896195cb6c059588a6..9b0d0dfb7628c53586f4b4f155c695b8f6975fac 100644 (file)
@@ -1764,8 +1764,11 @@ defm reciprocal_math : BoolFOption<"reciprocal-math",
   PosFlag<SetTrue, [CC1Option], "Allow division operations to be reassociated",
           [menable_unsafe_fp_math.KeyPath]>,
   NegFlag<SetFalse>>;
-def fapprox_func : Flag<["-"], "fapprox-func">, Group<f_Group>, Flags<[CC1Option, NoDriverOption]>,
-  MarshallingInfoFlag<LangOpts<"ApproxFunc">>, ImpliedByAnyOf<[menable_unsafe_fp_math.KeyPath]>;
+defm approx_func : BoolFOption<"approx-func", LangOpts<"ApproxFunc">, DefaultFalse,
+   PosFlag<SetTrue, [CC1Option], "Allow certain math function calls to be replaced "
+           "with an approximately equivalent calculation",
+           [menable_unsafe_fp_math.KeyPath]>,
+   NegFlag<SetFalse>>;
 defm finite_math_only : BoolFOption<"finite-math-only",
   LangOpts<"FiniteMathOnly">, DefaultFalse,
   PosFlag<SetTrue, [CC1Option], "", [cl_finite_math_only.KeyPath, ffast_math.KeyPath]>,
index 99e33b227f792c5fdb85f30f8bdab38fce6a35ba..76f6985d5cfa3c99e45ab45a3d1bac6c323232fb 100644 (file)
@@ -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<llvm::BasicBlockSection>(CodeGenOpts.BBSections)
index 70966c9e7b357dff95958020a90f5d1e5c717f20..af5f519c6fced89223a340c8294555ed2e4cd180 100644 (file)
@@ -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)
index c636c25a1dc817ae21d9b005f2fa11e6e761e207..f1771d4fa35d2d29dce4329098371f2c4cc34be6 100644 (file)
@@ -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 (file)
index 0000000..f948fc0
--- /dev/null
@@ -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" {{.*}}
+}
index d6c82add799cd6ea81124ba98ded184563e69dc6..8d293c2ea01ffb72634503df756f5d3b9edb7df7 100644 (file)
 // 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"
index 11f9296f900ca080aed82fd151fd3edaf04ec16d..912f6d1c153a70edbcbb99333e23a9de190d6334 100644 (file)
@@ -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