[llvm] 7c49f3c - [InstCombine][SimplifyLibCalls] An extra sqrtf was produced because of transformations in optimizePow function

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 10 09:33:15 PST 2021


Author: Daniil Seredkin
Date: 2021-03-10T12:33:05-05:00
New Revision: 7c49f3c75be95401b089cab75bb71a71020b350d

URL: https://github.com/llvm/llvm-project/commit/7c49f3c75be95401b089cab75bb71a71020b350d
DIFF: https://github.com/llvm/llvm-project/commit/7c49f3c75be95401b089cab75bb71a71020b350d.diff

LOG: [InstCombine][SimplifyLibCalls] An extra sqrtf was produced because of transformations in optimizePow function

See: https://bugs.llvm.org/show_bug.cgi?id=47613

There was an extra sqrt call because shrinking emitted a new powf and at the same time optimizePow replaces the previous pow with sqrt and as the result we have two instructions that will be in worklist of InstCombie despite the fact that %powf is not used by anyone (it is alive because of errno).

As the result we have two instructions:

  %powf = call fast float @powf(float %x, float 5.000000e-01)
  %sqrt = call fast double @sqrt(double %dx)

%powf will be converted to %sqrtf on a later iteration.

As a quick fix for that I moved shrinking to the end of optimizePow so that pow is replaced with sqrt at first that allows not to emit a new shrunk powf.

Differential Revision: https://reviews.llvm.org/D98235

Added: 
    

Modified: 
    llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
    llvm/test/Transforms/InstCombine/pow-4.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index 2816d49d163f..c279d18043c0 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -1704,20 +1704,12 @@ Value *LibCallSimplifier::optimizePow(CallInst *Pow, IRBuilderBase &B) {
   StringRef Name = Callee->getName();
   Type *Ty = Pow->getType();
   Module *M = Pow->getModule();
-  Value *Shrunk = nullptr;
   bool AllowApprox = Pow->hasApproxFunc();
   bool Ignored;
 
   // Propagate the math semantics from the call to any created instructions.
   IRBuilderBase::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
@@ -1818,7 +1810,15 @@ Value *LibCallSimplifier::optimizePow(CallInst *Pow, IRBuilderBase &B) {
       return createPowWithIntegerExponent(Base, ExpoI, M, B);
   }
 
-  return Shrunk;
+  // 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)) {
+    if (Value *Shrunk = optimizeBinaryDoubleFP(Pow, B, true))
+      return Shrunk;
+  }
+
+  return nullptr;
 }
 
 Value *LibCallSimplifier::optimizeExp2(CallInst *CI, IRBuilderBase &B) {

diff  --git a/llvm/test/Transforms/InstCombine/pow-4.ll b/llvm/test/Transforms/InstCombine/pow-4.ll
index 2563b4435fcb..29fb034fbe33 100644
--- a/llvm/test/Transforms/InstCombine/pow-4.ll
+++ b/llvm/test/Transforms/InstCombine/pow-4.ll
@@ -1,7 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt -instcombine -S < %s                        | FileCheck %s --check-prefixes=CHECK,SQRT
 ; RUN: opt -instcombine -S < %s -disable-builtin sqrt  | FileCheck %s --check-prefixes=CHECK,NOSQRT
-
 declare double @llvm.pow.f64(double, double)
 declare float @llvm.pow.f32(float, float)
 declare <2 x double> @llvm.pow.v2f64(<2 x double>, <2 x double>)
@@ -235,12 +234,10 @@ define <4 x float> @test_simplify_3_5(<4 x float> %x) {
 }
 
 ; (float)pow((double)(float)x, 0.5)
-; FIXME: One call to `sqrtf` would suffice (PR47613).
 define float @shrink_pow_libcall_half(float %x) {
 ; SQRT-LABEL: @shrink_pow_libcall_half(
-; SQRT-NEXT:    [[SQRTF:%.*]] = call fast float @sqrtf(float [[X:%.*]])
-; SQRT-NEXT:    [[SQRTF1:%.*]] = call fast float @sqrtf(float [[X]])
-; SQRT-NEXT:    ret float [[SQRTF1]]
+; SQRT-NEXT:    [[SQRTF:%.*]] = call fast float @sqrtf(float [[X]])
+; SQRT-NEXT:    ret float [[SQRTF]]
 ;
 ; NOSQRT-LABEL: @shrink_pow_libcall_half(
 ; NOSQRT-NEXT:    [[SQRTF:%.*]] = call fast float @sqrtf(float [[X:%.*]])


        


More information about the llvm-commits mailing list