Skip to content

Commit 1752b9e

Browse files
committed
[InstCombine] create a helper function foldPowiReassoc, NFC
1 parent 0985202 commit 1752b9e

File tree

2 files changed

+41
-21
lines changed

2 files changed

+41
-21
lines changed

llvm/lib/Transforms/InstCombine/InstCombineInternal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
9898
Instruction *visitSub(BinaryOperator &I);
9999
Instruction *visitFSub(BinaryOperator &I);
100100
Instruction *visitMul(BinaryOperator &I);
101+
Instruction *foldPowiReassoc(BinaryOperator &I);
101102
Instruction *foldFMulReassoc(BinaryOperator &I);
102103
Instruction *visitFMul(BinaryOperator &I);
103104
Instruction *visitURem(BinaryOperator &I);

llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,44 @@ Instruction *InstCombinerImpl::foldFPSignBitOps(BinaryOperator &I) {
571571
return nullptr;
572572
}
573573

574+
Instruction *InstCombinerImpl::foldPowiReassoc(BinaryOperator &I) {
575+
Value *X, *Y, *Z;
576+
auto createPowiExpr = [](BinaryOperator &I, InstCombinerImpl &IC, Value *X,
577+
Value *Y, Value *Z) {
578+
Value *YZ;
579+
InstCombiner::BuilderTy &Builder = IC.Builder;
580+
581+
if (auto *C = dyn_cast<ConstantInt>(Z)) {
582+
if (C->isOne())
583+
YZ = Builder.CreateAdd(Y, ConstantInt::get(Y->getType(), 1));
584+
} else
585+
YZ = Builder.CreateAdd(Y, Z);
586+
587+
auto *NewPow = Builder.CreateIntrinsic(
588+
Intrinsic::powi, {X->getType(), YZ->getType()}, {X, YZ}, &I);
589+
return IC.replaceInstUsesWith(I, NewPow);
590+
};
591+
592+
// powi(X, Y) * X --> powi(X, Y+1)
593+
// X * powi(X, Y) --> powi(X, Y+1)
594+
if (match(&I, m_c_FMul(m_OneUse(m_Intrinsic<Intrinsic::powi>(m_Value(X),
595+
m_Value(Y))),
596+
m_Deferred(X))) &&
597+
willNotOverflowSignedAdd(Y, ConstantInt::get(Y->getType(), 1), I))
598+
return createPowiExpr(I, *this, X, Y, ConstantInt::get(Y->getType(), 1));
599+
600+
// powi(x, y) * powi(x, z) -> powi(x, y + z)
601+
Value *Op0 = I.getOperand(0);
602+
Value *Op1 = I.getOperand(1);
603+
if (I.isOnlyUserOfAnyOperand() &&
604+
match(Op0, m_Intrinsic<Intrinsic::powi>(m_Value(X), m_Value(Y))) &&
605+
match(Op1, m_Intrinsic<Intrinsic::powi>(m_Specific(X), m_Value(Z))) &&
606+
Y->getType() == Z->getType())
607+
return createPowiExpr(I, *this, X, Y, Z);
608+
609+
return nullptr;
610+
}
611+
574612
Instruction *InstCombinerImpl::foldFMulReassoc(BinaryOperator &I) {
575613
Value *Op0 = I.getOperand(0);
576614
Value *Op1 = I.getOperand(1);
@@ -683,17 +721,8 @@ Instruction *InstCombinerImpl::foldFMulReassoc(BinaryOperator &I) {
683721
return replaceInstUsesWith(I, Pow);
684722
}
685723

686-
// powi(X, Y) * X --> powi(X, Y+1)
687-
// X * powi(X, Y) --> powi(X, Y+1)
688-
if (match(&I, m_c_FMul(m_OneUse(m_Intrinsic<Intrinsic::powi>(m_Value(X),
689-
m_Value(Y))),
690-
m_Deferred(X))) &&
691-
willNotOverflowSignedAdd(Y, ConstantInt::get(Y->getType(), 1), I)) {
692-
auto *Y1 = Builder.CreateAdd(Y, ConstantInt::get(Y->getType(), 1));
693-
auto *NewPow = Builder.CreateIntrinsic(
694-
Intrinsic::powi, {X->getType(), Y1->getType()}, {X, Y1}, &I);
695-
return replaceInstUsesWith(I, NewPow);
696-
}
724+
if (Instruction *FoldedPowi = foldPowiReassoc(I))
725+
return FoldedPowi;
697726

698727
if (I.isOnlyUserOfAnyOperand()) {
699728
// pow(X, Y) * pow(X, Z) -> pow(X, Y + Z)
@@ -711,16 +740,6 @@ Instruction *InstCombinerImpl::foldFMulReassoc(BinaryOperator &I) {
711740
return replaceInstUsesWith(I, NewPow);
712741
}
713742

714-
// powi(x, y) * powi(x, z) -> powi(x, y + z)
715-
if (match(Op0, m_Intrinsic<Intrinsic::powi>(m_Value(X), m_Value(Y))) &&
716-
match(Op1, m_Intrinsic<Intrinsic::powi>(m_Specific(X), m_Value(Z))) &&
717-
Y->getType() == Z->getType()) {
718-
auto *YZ = Builder.CreateAdd(Y, Z);
719-
auto *NewPow = Builder.CreateIntrinsic(
720-
Intrinsic::powi, {X->getType(), YZ->getType()}, {X, YZ}, &I);
721-
return replaceInstUsesWith(I, NewPow);
722-
}
723-
724743
// exp(X) * exp(Y) -> exp(X + Y)
725744
if (match(Op0, m_Intrinsic<Intrinsic::exp>(m_Value(X))) &&
726745
match(Op1, m_Intrinsic<Intrinsic::exp>(m_Value(Y)))) {

0 commit comments

Comments
 (0)