[llvm] r339046 - [SLC] Fix shrinking of pow()

Evandro Menezes via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 6 12:40:17 PDT 2018


Author: evandro
Date: Mon Aug  6 12:40:17 2018
New Revision: 339046

URL: http://llvm.org/viewvc/llvm-project?rev=339046&view=rev
Log:
[SLC] Fix shrinking of pow()

Properly shrink `pow()` to `powf()` as a binary function and, when no other
simplification applies, do not discard it.

Differential revision: https://reviews.llvm.org/D50113

Modified:
    llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp
    llvm/trunk/test/Transforms/InstCombine/double-float-shrink-1.ll

Modified: llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp?rev=339046&r1=339045&r2=339046&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp Mon Aug  6 12:40:17 2018
@@ -965,12 +965,14 @@ static Value *valueHasFloatPrecision(Val
 
 /// Shrink double -> float functions.
 static Value *optimizeDoubleFP(CallInst *CI, IRBuilder<> &B,
-                               bool isBinary, bool doResultCheck = false) {
+                               bool isBinary, bool isPrecise = false) {
   if (!CI->getType()->isDoubleTy())
     return nullptr;
 
-  // Check if all the uses of the function are converted to float.
-  if (doResultCheck)
+  // If not all the uses of the function are converted to float, then bail out.
+  // This matters if the precision of the result is more important than the
+  // precision of the arguments.
+  if (isPrecise)
     for (User *U : CI->users()) {
       FPTruncInst *Cast = dyn_cast<FPTruncInst>(U);
       if (!Cast || !Cast->getType()->isFloatTy())
@@ -1022,14 +1024,14 @@ static Value *optimizeDoubleFP(CallInst
 
 /// Shrink double -> float for unary functions.
 static Value *optimizeUnaryDoubleFP(CallInst *CI, IRBuilder<> &B,
-                                    bool doResultCheck = false) {
-  return optimizeDoubleFP(CI, B, false, doResultCheck);
+                                    bool isPrecise = false) {
+  return optimizeDoubleFP(CI, B, false, isPrecise);
 }
 
 /// Shrink double -> float for binary functions.
 static Value *optimizeBinaryDoubleFP(CallInst *CI, IRBuilder<> &B,
-                                     bool doResultCheck = false) {
-  return optimizeDoubleFP(CI, B, true, doResultCheck);
+                                     bool isPrecise = false) {
+  return optimizeDoubleFP(CI, B, true, isPrecise);
 }
 
 // cabs(z) -> sqrt((creal(z)*creal(z)) + (cimag(z)*cimag(z)))
@@ -1150,14 +1152,16 @@ Value *LibCallSimplifier::optimizePow(Ca
   Value *Shrunk = nullptr;
   bool Ignored;
 
-  if (UnsafeFPShrink &&
-      Name == TLI->getName(LibFunc_pow) && hasFloatVersion(Name))
-    Shrunk = optimizeUnaryDoubleFP(Pow, B, true);
-
   // Propagate the math semantics from the call to any created instructions.
   IRBuilder<>::FastMathFlagGuard Guard(B);
   B.setFastMathFlags(Pow->getFastMathFlags());
 
+  // Shrink pow() to powf() if the arguments are single precision,
+  // unless the result is expected to be double precision.
+  if (UnsafeFPShrink &&
+      Name == TLI->getName(LibFunc_pow) && hasFloatVersion(Name))
+    Shrunk = optimizeBinaryDoubleFP(Pow, B, true);
+
   // Evaluate special cases related to the base.
 
   // pow(1.0, x) -> 1.0
@@ -1252,7 +1256,7 @@ Value *LibCallSimplifier::optimizePow(Ca
     if (!ExpoA.isInteger() ||
         ExpoA.compare
             (APFloat(ExpoA.getSemantics(), 32.0)) == APFloat::cmpGreaterThan)
-      return nullptr;
+      return Shrunk;
 
     // We will memoize intermediate products of the Addition Chain.
     Value *InnerChain[33] = {nullptr};
@@ -1270,7 +1274,7 @@ Value *LibCallSimplifier::optimizePow(Ca
     return FMul;
   }
 
-  return nullptr;
+  return Shrunk;
 }
 
 Value *LibCallSimplifier::optimizeExp2(CallInst *CI, IRBuilder<> &B) {

Modified: llvm/trunk/test/Transforms/InstCombine/double-float-shrink-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/double-float-shrink-1.ll?rev=339046&r1=339045&r2=339046&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/double-float-shrink-1.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/double-float-shrink-1.ll Mon Aug  6 12:40:17 2018
@@ -344,11 +344,9 @@ define double @logb_test2(float %f)   {
   ret double %call
 }
 
-; FIXME: Miscompile - we dropped the 2nd argument!
-
 define float @pow_test1(float %f, float %g)   {
 ; CHECK-LABEL: @pow_test1(
-; CHECK-NEXT:    [[POWF:%.*]] = call fast float @powf(float [[F:%.*]])
+; CHECK-NEXT:    [[POWF:%.*]] = call fast float @powf(float %f, float %g)
 ; CHECK-NEXT:    ret float [[POWF]]
 ;
   %df = fpext float %f to double
@@ -358,14 +356,10 @@ define float @pow_test1(float %f, float
   ret float %fr
 }
 
-; TODO: This should shrink?
-
 define double @pow_test2(float %f, float %g) {
 ; CHECK-LABEL: @pow_test2(
-; CHECK-NEXT:    [[DF:%.*]] = fpext float [[F:%.*]] to double
-; CHECK-NEXT:    [[DG:%.*]] = fpext float [[G:%.*]] to double
-; CHECK-NEXT:    [[CALL:%.*]] = call fast double @pow(double [[DF]], double [[DG]])
-; CHECK-NEXT:    ret double [[CALL]]
+; CHECK:         [[POW:%.*]] = call fast double @pow(double %df, double %dg)
+; CHECK-NEXT:    ret double [[POW]]
 ;
   %df = fpext float %f to double
   %dg = fpext float %g to double




More information about the llvm-commits mailing list