Skip to content
Permalink
Browse files
Optimize pow(x,a)*pow(x,b) to pow(x, a+b) (same for FDiv)
  • Loading branch information
EgorBo committed May 15, 2020
1 parent 9295f35 commit 2b46c1438601b48c5d40eedce80aee0b14409384
Showing 1 changed file with 26 additions and 0 deletions.
@@ -419,6 +419,20 @@ Instruction *InstCombiner::visitFMul(BinaryOperator &I) {
if (match(Op0, m_FNeg(m_Value(X))) && match(Op1, m_FNeg(m_Value(Y))))
return BinaryOperator::CreateFMulFMF(X, Y, &I);

// pow(X, A) * pow(X, B) -> pow(X, A+B)
Value *A, *B;
if (I.hasAllowReassoc() && Op0->hasOneUse() && Op1->hasOneUse()) {
if (match(Op0, m_Intrinsic<Intrinsic::pow>(m_Value(X), m_Value(A))) &&
match(Op1, m_Intrinsic<Intrinsic::pow>(m_Value(Y), m_Value(B)))) {
if (X == Y) {
Value *AddAB = Builder.CreateFAddFMF(A, B, &I);
Value *Pow = Builder.CreateBinaryIntrinsic(Intrinsic::pow, X, AddAB,
cast<IntrinsicInst>(Op0));
return replaceInstUsesWith(I, Pow);
}
}
}

// -X * C --> X * -C
Constant *C;
if (match(Op0, m_FNeg(m_Value(X))) && match(Op1, m_Constant(C)))
@@ -1270,6 +1284,18 @@ Instruction *InstCombiner::visitFDiv(BinaryOperator &I) {
Res = B.CreateFDiv(ConstantFP::get(I.getType(), 1.0), Res);
return replaceInstUsesWith(I, Res);
}

// pow(X, A) / pow(X, B) -> pow(X, A-B)
Value *Y, *A, *B;
if (match(Op0, m_Intrinsic<Intrinsic::pow>(m_Value(X), m_Value(A))) &&
match(Op1, m_Intrinsic<Intrinsic::pow>(m_Value(Y), m_Value(B)))) {
if (X == Y) {
Value *SubAB = Builder.CreateFSubFMF(A, B, &I);
Value *Pow = Builder.CreateBinaryIntrinsic(Intrinsic::pow, X, SubAB,
cast<IntrinsicInst>(Op0));
return replaceInstUsesWith(I, Pow);
}
}
}

// -X / -Y -> X / Y

0 comments on commit 2b46c14

Please sign in to comment.