[llvm] 6801950 - [InstCombine] For pow(x, +/-0.5), stop falling into pow(x, 1.5), etc. case

Hubert Tong via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 22 11:23:44 PDT 2020


Author: Hubert Tong
Date: 2020-09-22T14:23:32-04:00
New Revision: 6801950192ff4f6d60c822fc721354f34e609e7a

URL: https://github.com/llvm/llvm-project/commit/6801950192ff4f6d60c822fc721354f34e609e7a
DIFF: https://github.com/llvm/llvm-project/commit/6801950192ff4f6d60c822fc721354f34e609e7a.diff

LOG: [InstCombine] For pow(x, +/-0.5), stop falling into pow(x, 1.5), etc. case

The current code for handling pow(x, y) where y is an integer plus 0.5
is not explicitly guarded against attempting to transform the case where
abs(y) is exactly 0.5.

The latter case is meant to be handled by `replacePowWithSqrt`. Indeed,
if the pow(x, integer+0.5) case proceeds past a certain point, it will
hit an assertion by attempting to form pow(x, 0) using `getPow`.

This patch adds an explicit check to prevent attempting the
pow(x, integer+0.5) transformation on pow(x, +/-0.5) as suggested during
the review of D87877. This has the effect of retaining the shrinking of
`pow` to `powf` when the `sqrt` libcall cannot be formed.

Reviewed By: spatel

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

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 60b7da7e64fe..c4eff0795d12 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -1722,7 +1722,8 @@ Value *LibCallSimplifier::optimizePow(CallInst *Pow, IRBuilderBase &B) {
 
   // pow(x, n) -> x * x * x * ...
   const APFloat *ExpoF;
-  if (AllowApprox && match(Expo, m_APFloat(ExpoF))) {
+  if (AllowApprox && match(Expo, m_APFloat(ExpoF)) &&
+      !ExpoF->isExactlyValue(0.5) && !ExpoF->isExactlyValue(-0.5)) {
     // We limit to a max of 7 multiplications, thus the maximum exponent is 32.
     // If the exponent is an integer+0.5 we generate a call to sqrt and an
     // additional fmul.

diff  --git a/llvm/test/Transforms/InstCombine/pow-4.ll b/llvm/test/Transforms/InstCombine/pow-4.ll
index 23cc2d801a16..2563b4435fcb 100644
--- a/llvm/test/Transforms/InstCombine/pow-4.ll
+++ b/llvm/test/Transforms/InstCombine/pow-4.ll
@@ -234,6 +234,24 @@ define <4 x float> @test_simplify_3_5(<4 x float> %x) {
   ret <4 x float> %1
 }
 
+; (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]]
+;
+; NOSQRT-LABEL: @shrink_pow_libcall_half(
+; NOSQRT-NEXT:    [[SQRTF:%.*]] = call fast float @sqrtf(float [[X:%.*]])
+; NOSQRT-NEXT:    ret float [[SQRTF]]
+;
+  %dx = fpext float %x to double
+  %call = call fast double @pow(double %dx, double 0.5)
+  %fr = fptrunc double %call to float
+  ret float %fr
+}
+
 ; Make sure that -0.0 exponent is always simplified.
 
 define double @PR43233(double %x) {


        


More information about the llvm-commits mailing list