[PATCH] D145223: [InstCombine] Combine binary operator of two phi node
luxufan via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 3 00:57:50 PST 2023
StephenFan created this revision.
StephenFan added reviewers: nikic, spatel.
Herald added a subscriber: hiraditya.
Herald added a project: All.
StephenFan requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
Combine binary operator of two phi node if there is at least one
specific constant value in phi0 and phi1's incoming values for each
same incoming block and this specific constant value can be used
to do optimization for specific binary operator.
For example:
%phi0 = phi i32 [0, %bb0], [%i, %bb1]
%phi1 = phi i32 [%j, %bb0], [0, %bb1]
%add = add i32 %phi0, %phi1
==>
%add = phi i32 [%j, %bb0], [%i, %bb1]
Fixes: https://github.com/llvm/llvm-project/issues/61137
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D145223
Files:
llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
llvm/test/Transforms/InstCombine/add.ll
Index: llvm/test/Transforms/InstCombine/add.ll
===================================================================
--- llvm/test/Transforms/InstCombine/add.ll
+++ llvm/test/Transforms/InstCombine/add.ll
@@ -2952,9 +2952,7 @@
; CHECK: if.then:
; CHECK-NEXT: br label [[IF_END]]
; CHECK: if.end:
-; CHECK-NEXT: [[X:%.*]] = phi i32 [ 0, [[IF_THEN]] ], [ [[J:%.*]], [[ENTRY:%.*]] ]
-; CHECK-NEXT: [[Y:%.*]] = phi i32 [ [[I:%.*]], [[IF_THEN]] ], [ 0, [[ENTRY]] ]
-; CHECK-NEXT: [[ADD:%.*]] = add i32 [[Y]], [[X]]
+; CHECK-NEXT: [[ADD:%.*]] = phi i32 [ [[I:%.*]], [[IF_THEN]] ], [ [[J:%.*]], [[ENTRY:%.*]] ]
; CHECK-NEXT: ret i32 [[ADD]]
;
entry:
Index: llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -1294,7 +1294,7 @@
auto *Phi0 = dyn_cast<PHINode>(BO.getOperand(0));
auto *Phi1 = dyn_cast<PHINode>(BO.getOperand(1));
if (!Phi0 || !Phi1 || !Phi0->hasOneUse() || !Phi1->hasOneUse() ||
- Phi0->getNumOperands() != 2 || Phi1->getNumOperands() != 2)
+ Phi0->getNumOperands() != Phi1->getNumOperands())
return nullptr;
// TODO: Remove the restriction for binop being in the same block as the phis.
@@ -1302,6 +1302,47 @@
BO.getParent() != Phi1->getParent())
return nullptr;
+ // Fold if there is at least one specific constant values in phi0 or phi1's
+ // incoming value that comes from the same block and this specific constant
+ // value can be used to do optimization for specific binary operator.
+ // For example:
+ // %phi0 = phi i32 [0, %bb0], [%i, %bb1]
+ // %phi1 = phi i32 [%j, %bb0], [0, %bb1]
+ // %add = add i32 %phi0, %phi1
+ // ==>
+ // %add = phi i32 [%j, %bb0], [%i, %bb1]
+ // TODO: Support other binary operators
+ if (BO.getOpcode() == Instruction::Add) {
+ llvm::SmallVector<Value *, 4> NewIncomingValues;
+ if (all_of(llvm::zip(Phi0->operands(), Phi1->operands()),
+ [&](std::tuple<llvm::Use &, llvm::Use &> T) {
+ auto &Phi0Use = std::get<0>(T);
+ auto &Phi1Use = std::get<1>(T);
+ if (Phi0->getIncomingBlock(Phi0Use) !=
+ Phi1->getIncomingBlock(Phi1Use))
+ return false;
+ if (match(Phi0Use.get(), m_Zero()))
+ NewIncomingValues.push_back(Phi1Use.get());
+ else if (match(Phi1Use.get(), m_Zero()))
+ NewIncomingValues.push_back(Phi0Use.get());
+ else
+ return false;
+ return true;
+ })) {
+ PHINode *NewPhi =
+ PHINode::Create(Phi0->getType(), Phi0->getNumOperands());
+ assert(NewIncomingValues.size() == Phi0->getNumOperands() &&
+ "The number of collected incoming values should equal the number "
+ "of the original PHINode operands!");
+ for (unsigned I = 0; I < Phi0->getNumOperands(); I++)
+ NewPhi->addIncoming(NewIncomingValues[I], Phi0->getIncomingBlock(I));
+ return NewPhi;
+ }
+ }
+
+ if (Phi0->getNumOperands() != 2 || Phi1->getNumOperands() != 2)
+ return nullptr;
+
// Match a pair of incoming constants for one of the predecessor blocks.
BasicBlock *ConstBB, *OtherBB;
Constant *C0, *C1;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D145223.502074.patch
Type: text/x-patch
Size: 3430 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230303/bdb3c5cf/attachment.bin>
More information about the llvm-commits
mailing list