[llvm] 7e3d110 - [InstCombine] optimize powi(X, Y)/X with Ofast (#67236)

via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 20 18:01:45 PDT 2023


Author: zhongyunde 00443407
Date: 2023-10-21T08:56:14+08:00
New Revision: 7e3d1103e6e7a7fa9b5f50222732e734d171bc86

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

LOG: [InstCombine] optimize powi(X,Y)/X with Ofast (#67236)

Try to transform the powi(X, Y) / X into powi(X, Y-1) with Ofast.
For this case, when the Y is 3, then powi(X, 2) is replaced by X * X in
the further step.

Fixes https://github.com/llvm/llvm-project/pull/67216
Reviewed By: dtcxzyw, nikic, jcranmer-intel

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 518f8aa51c0cd29..bc784390c23be49 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -1780,6 +1780,21 @@ Instruction *InstCombinerImpl::visitFDiv(BinaryOperator &I) {
     return replaceInstUsesWith(I, Pow);
   }
 
+  // powi(X, Y) / X --> powi(X, Y-1)
+  // This is legal when (Y - 1) can't wraparound, in which case reassoc and nnan
+  // are required.
+  // TODO: Multi-use may be also better off creating Powi(x,y-1)
+  if (I.hasAllowReassoc() && I.hasNoNaNs() &&
+      match(Op0, m_OneUse(m_Intrinsic<Intrinsic::powi>(m_Specific(Op1),
+                                                       m_Value(Y)))) &&
+      willNotOverflowSignedSub(Y, ConstantInt::get(Y->getType(), 1), I)) {
+    Constant *NegOne = ConstantInt::getAllOnesValue(Y->getType());
+    Value *Y1 = Builder.CreateAdd(Y, NegOne);
+    Type *Types[] = {Op1->getType(), Y1->getType()};
+    Value *Pow = Builder.CreateIntrinsic(Intrinsic::powi, Types, {Op1, Y1}, &I);
+    return replaceInstUsesWith(I, Pow);
+  }
+
   return nullptr;
 }
 

diff  --git a/llvm/test/Transforms/InstCombine/powi.ll b/llvm/test/Transforms/InstCombine/powi.ll
index a596bba7b0e2150..89efbb6f4536113 100644
--- a/llvm/test/Transforms/InstCombine/powi.ll
+++ b/llvm/test/Transforms/InstCombine/powi.ll
@@ -262,8 +262,7 @@ define double @
diff erent_types_powi(double %x, i32 %y, i64 %z) {
 
 define double @fdiv_pow_powi(double %x) {
 ; CHECK-LABEL: @fdiv_pow_powi(
-; CHECK-NEXT:    [[P1:%.*]] = call double @llvm.powi.f64.i32(double [[X:%.*]], i32 3)
-; CHECK-NEXT:    [[DIV:%.*]] = fdiv reassoc nnan double [[P1]], [[X]]
+; CHECK-NEXT:    [[DIV:%.*]] = fmul reassoc nnan double [[X:%.*]], [[X]]
 ; CHECK-NEXT:    ret double [[DIV]]
 ;
   %p1 = call double @llvm.powi.f64.i32(double %x, i32 3)
@@ -273,8 +272,7 @@ define double @fdiv_pow_powi(double %x) {
 
 define float @fdiv_powf_powi(float %x) {
 ; CHECK-LABEL: @fdiv_powf_powi(
-; CHECK-NEXT:    [[P1:%.*]] = call float @llvm.powi.f32.i32(float [[X:%.*]], i32 100)
-; CHECK-NEXT:    [[DIV:%.*]] = fdiv reassoc nnan float [[P1]], [[X]]
+; CHECK-NEXT:    [[DIV:%.*]] = call reassoc nnan float @llvm.powi.f32.i32(float [[X:%.*]], i32 99)
 ; CHECK-NEXT:    ret float [[DIV]]
 ;
   %p1 = call float @llvm.powi.f32.i32(float %x, i32 100)


        


More information about the llvm-commits mailing list