[llvm] a7cee55 - [InstCombine] fold fdiv with powi divisor (PR49147)

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 24 13:44:48 PST 2021


Author: Sanjay Patel
Date: 2021-02-24T16:44:36-05:00
New Revision: a7cee55762c6564de9dfc90985fe5c14cad7f9ee

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

LOG: [InstCombine] fold fdiv with powi divisor (PR49147)

This extends b40fde062c for the especially non-standard
powi pattern. We want to avoid being completely wrong
on the negation-of-int-min corner case, so I'm adding
an extra FMF check for 'ninf' assuming that gives us
the flexibility to handle that possibility.
https://llvm.org/PR49147

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
    llvm/test/Transforms/InstCombine/fdiv.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 5cfa9223fc36..e164a6122b70 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -1294,6 +1294,17 @@ static Instruction *foldFDivPowDivisor(BinaryOperator &I,
     Args.push_back(II->getArgOperand(0));
     Args.push_back(Builder.CreateFNegFMF(II->getArgOperand(1), &I));
     break;
+  case Intrinsic::powi:
+    // Require 'ninf' assuming that makes powi(X, -INT_MIN) acceptable.
+    // That is, X ** (huge negative number) is 0.0, ~1.0, or INF and so
+    // dividing by that is INF, ~1.0, or 0.0. Code that uses powi allows
+    // non-standard results, so this corner case should be acceptable if the
+    // code rules out INF values.
+    if (!I.hasNoInfs())
+      return nullptr;
+    Args.push_back(II->getArgOperand(0));
+    Args.push_back(Builder.CreateNeg(II->getArgOperand(1)));
+    break;
   case Intrinsic::exp:
   case Intrinsic::exp2:
     Args.push_back(Builder.CreateFNegFMF(II->getArgOperand(0), &I));

diff  --git a/llvm/test/Transforms/InstCombine/fdiv.ll b/llvm/test/Transforms/InstCombine/fdiv.ll
index 0028bf60b842..ff4fa2bf8ff4 100644
--- a/llvm/test/Transforms/InstCombine/fdiv.ll
+++ b/llvm/test/Transforms/InstCombine/fdiv.ll
@@ -865,8 +865,9 @@ define <2 x half> @exp2_recip(<2 x half> %x, <2 x half> %y) {
 
 define float @powi_divisor(float %x, i32 %y, float %z) {
 ; CHECK-LABEL: @powi_divisor(
-; CHECK-NEXT:    [[P:%.*]] = call float @llvm.powi.f32(float [[X:%.*]], i32 [[Y:%.*]])
-; CHECK-NEXT:    [[R:%.*]] = fdiv reassoc ninf arcp float [[Z:%.*]], [[P]]
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[Y:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = call reassoc ninf arcp float @llvm.powi.f32(float [[X:%.*]], i32 [[TMP1]])
+; CHECK-NEXT:    [[R:%.*]] = fmul reassoc ninf arcp float [[TMP2]], [[Z:%.*]]
 ; CHECK-NEXT:    ret float [[R]]
 ;
   %p = call float @llvm.powi.f32(float %x, i32 %y)
@@ -919,9 +920,9 @@ define float @powi_divisor_not_enough_fmf2(float %x, i32 %y, float %z) {
 
 define <2 x half> @powi_recip(<2 x half> %x, i32 %y) {
 ; CHECK-LABEL: @powi_recip(
-; CHECK-NEXT:    [[P:%.*]] = call <2 x half> @llvm.powi.v2f16(<2 x half> [[X:%.*]], i32 [[Y:%.*]])
-; CHECK-NEXT:    [[R:%.*]] = fdiv reassoc nnan ninf arcp <2 x half> <half 0xH3C00, half 0xH3C00>, [[P]]
-; CHECK-NEXT:    ret <2 x half> [[R]]
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[Y:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = call reassoc nnan ninf arcp <2 x half> @llvm.powi.v2f16(<2 x half> [[X:%.*]], i32 [[TMP1]])
+; CHECK-NEXT:    ret <2 x half> [[TMP2]]
 ;
   %p = call <2 x half> @llvm.powi.v2f16(<2 x half> %x, i32 %y)
   %r = fdiv reassoc arcp nnan ninf <2 x half> <half 1.0, half 1.0>, %p


        


More information about the llvm-commits mailing list