[llvm] [InstCombine] fold (Binop phi(a, b) phi(b, a)) -> (Binop a, b) while Binop is commutative. (PR #75765)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 18 00:30:15 PST 2023
================
@@ -1096,6 +1096,50 @@ Value *InstCombinerImpl::foldUsingDistributiveLaws(BinaryOperator &I) {
return SimplifySelectsFeedingBinaryOp(I, LHS, RHS);
}
+bool InstCombinerImpl::matchSymmetricPhiNodesPair(PHINode *LHS, PHINode *RHS) {
+
+ if (LHS->getNumOperands() != 2 || RHS->getNumOperands() != 2)
+ return false;
+
+ BasicBlock *B0 = LHS->getIncomingBlock(0);
+ BasicBlock *B1 = LHS->getIncomingBlock(1);
+
+ bool RHSContainB0 = RHS->getBasicBlockIndex(B0) != -1;
+ bool RHSContainB1 = RHS->getBasicBlockIndex(B1) != -1;
+
+ if (!RHSContainB0 || !RHSContainB1)
+ return false;
+
+ Value *N1 = LHS->getIncomingValueForBlock(B0);
+ Value *N2 = LHS->getIncomingValueForBlock(B1);
+ Value *N3 = RHS->getIncomingValueForBlock(B0);
+ Value *N4 = RHS->getIncomingValueForBlock(B1);
+
+ return N1 == N4 && N2 == N3;
+}
+
+Value *InstCombinerImpl::SimplifyPhiCommutativeBinaryOp(BinaryOperator &I,
+ Value *Op0,
+ Value *Op1) {
+ assert(I.isCommutative() && "Instruction Should be commutative");
+
+ PHINode *LHS = dyn_cast<PHINode>(Op0);
+ PHINode *RHS = dyn_cast<PHINode>(Op1);
+
+ if (!LHS || !RHS)
+ return nullptr;
+
+ if (matchSymmetricPhiNodesPair(LHS, RHS)) {
+ Value *BI = Builder.CreateBinOp(I.getOpcode(), LHS->getIncomingValue(0),
+ LHS->getIncomingValue(1));
+ if (auto *BO = dyn_cast<BinaryOperator>(BI))
+ BO->copyIRFlags(&I);
----------------
dtcxzyw wrote:
Could you please add some tests with IR flag propagation (e.g., nowrap flags and fast-math flags)?
https://github.com/llvm/llvm-project/pull/75765
More information about the llvm-commits
mailing list