[InstCombine][SimplifyLibCalls] An extra sqrtf was produced because of transformation...
authorDaniil Seredkin <vdsered@gmail.com>
Wed, 10 Mar 2021 17:30:53 +0000 (12:30 -0500)
committerSanjay Patel <spatel@rotateright.com>
Wed, 10 Mar 2021 17:33:05 +0000 (12:33 -0500)
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

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

index 2816d49..c279d18 100644 (file)
@@ -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) {
index 2563b44..29fb034 100644 (file)
@@ -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:%.*]])