[llvm] r253521 - [SimplifyLibCalls] New trick: pow(x, 0.5) -> sqrt(x) under -ffast-math.

Davide Italiano via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 18 15:21:32 PST 2015


Author: davide
Date: Wed Nov 18 17:21:32 2015
New Revision: 253521

URL: http://llvm.org/viewvc/llvm-project?rev=253521&view=rev
Log:
[SimplifyLibCalls] New trick: pow(x, 0.5) -> sqrt(x) under -ffast-math.

Differential Revision:	http://reviews.llvm.org/D14466

Added:
    llvm/trunk/test/Transforms/InstCombine/pow-sqrt.ll
Modified:
    llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp

Modified: llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp?rev=253521&r1=253520&r2=253521&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp Wed Nov 18 17:21:32 2015
@@ -1096,6 +1096,8 @@ Value *LibCallSimplifier::optimizePow(Ca
                                   Callee->getAttributes());
   }
 
+  bool unsafeFPMath = canUseUnsafeFPMath(CI->getParent()->getParent());
+
   // pow(exp(x), y) -> exp(x*y)
   // pow(exp2(x), y) -> exp2(x * y)
   // We enable these only under fast-math. Besides rounding
@@ -1103,7 +1105,7 @@ Value *LibCallSimplifier::optimizePow(Ca
   // underflow behavior quite dramatically.
   // Example: x = 1000, y = 0.001.
   // pow(exp(x), y) = pow(inf, 0.001) = inf, whereas exp(x*y) = exp(1).
-  if (canUseUnsafeFPMath(CI->getParent()->getParent())) {
+  if (unsafeFPMath) {
     if (auto *OpC = dyn_cast<CallInst>(Op1)) {
       IRBuilder<>::FastMathFlagGuard Guard(B);
       FastMathFlags FMF;
@@ -1134,10 +1136,15 @@ Value *LibCallSimplifier::optimizePow(Ca
                       LibFunc::sqrtl) &&
       hasUnaryFloatFn(TLI, Op2->getType(), LibFunc::fabs, LibFunc::fabsf,
                       LibFunc::fabsl)) {
+
+    // In -ffast-math, pow(x, 0.5) -> sqrt(x).
+    if (unsafeFPMath)
+      return EmitUnaryFloatFnCall(Op1, TLI->getName(LibFunc::sqrt), B,
+                                  Callee->getAttributes());
+
     // Expand pow(x, 0.5) to (x == -infinity ? +infinity : fabs(sqrt(x))).
     // This is faster than calling pow, and still handles negative zero
     // and negative infinity correctly.
-    // TODO: In fast-math mode, this could be just sqrt(x).
     // TODO: In finite-only mode, this could be just fabs(sqrt(x)).
     Value *Inf = ConstantFP::getInfinity(CI->getType());
     Value *NegInf = ConstantFP::getInfinity(CI->getType(), true);

Added: llvm/trunk/test/Transforms/InstCombine/pow-sqrt.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/pow-sqrt.ll?rev=253521&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/pow-sqrt.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/pow-sqrt.ll Wed Nov 18 17:21:32 2015
@@ -0,0 +1,15 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+define double @mypow(double %x) #0 {
+entry:
+  %pow = call double @llvm.pow.f64(double %x, double 5.000000e-01)
+  ret double %pow
+}
+
+; CHECK-LABEL: define double @mypow(
+; CHECK:   %sqrt = call double @sqrt(double %x) #1
+; CHECK:   ret double %sqrt
+; CHECK: }
+
+declare double @llvm.pow.f64(double, double)
+attributes #0 = { "unsafe-fp-math"="true" }




More information about the llvm-commits mailing list