@@ -611,6 +611,18 @@ Instruction *InstCombinerImpl::foldPowiReassoc(BinaryOperator &I) {
611
611
Y->getType () == Z->getType ())
612
612
return createPowiExpr (I, *this , X, Y, Z);
613
613
614
+ // powi(X, Y) / X --> powi(X, Y-1)
615
+ // This is legal when (Y - 1) can't wraparound, in which case reassoc and nnan
616
+ // are required.
617
+ // TODO: Multi-use may be also better off creating Powi(x,y-1)
618
+ if (I.hasAllowReassoc () && I.hasNoNaNs () &&
619
+ match (Op0, m_OneUse (m_Intrinsic<Intrinsic::powi>(m_Specific (Op1),
620
+ m_Value (Y)))) &&
621
+ willNotOverflowSignedSub (Y, ConstantInt::get (Y->getType (), 1 ), I)) {
622
+ Constant *NegOne = ConstantInt::getAllOnesValue (Y->getType ());
623
+ return createPowiExpr (I, *this , Op1, Y, NegOne);
624
+ }
625
+
614
626
return nullptr ;
615
627
}
616
628
@@ -1904,20 +1916,8 @@ Instruction *InstCombinerImpl::visitFDiv(BinaryOperator &I) {
1904
1916
return replaceInstUsesWith (I, Pow);
1905
1917
}
1906
1918
1907
- // powi(X, Y) / X --> powi(X, Y-1)
1908
- // This is legal when (Y - 1) can't wraparound, in which case reassoc and nnan
1909
- // are required.
1910
- // TODO: Multi-use may be also better off creating Powi(x,y-1)
1911
- if (I.hasAllowReassoc () && I.hasNoNaNs () &&
1912
- match (Op0, m_OneUse (m_Intrinsic<Intrinsic::powi>(m_Specific (Op1),
1913
- m_Value (Y)))) &&
1914
- willNotOverflowSignedSub (Y, ConstantInt::get (Y->getType (), 1 ), I)) {
1915
- Constant *NegOne = ConstantInt::getAllOnesValue (Y->getType ());
1916
- Value *Y1 = Builder.CreateAdd (Y, NegOne);
1917
- Type *Types[] = {Op1->getType (), Y1->getType ()};
1918
- Value *Pow = Builder.CreateIntrinsic (Intrinsic::powi, Types, {Op1, Y1}, &I);
1919
- return replaceInstUsesWith (I, Pow);
1920
- }
1919
+ if (Instruction *FoldedPowi = foldPowiReassoc (I))
1920
+ return FoldedPowi;
1921
1921
1922
1922
return nullptr ;
1923
1923
}
0 commit comments