[llvm] [InstCombine] fold (Binop phi(a, b) phi(b, a)) -> (Binop a, b) while Binop is commutative. (PR #75765)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 21 03:42:21 PST 2023


================
@@ -1096,6 +1096,53 @@ Value *InstCombinerImpl::foldUsingDistributiveLaws(BinaryOperator &I) {
   return SimplifySelectsFeedingBinaryOp(I, LHS, RHS);
 }
 
+std::optional<std::pair<Value *, Value *>>
+InstCombinerImpl::matchSymmetricPhiNodesPair(PHINode *LHS, PHINode *RHS) {
+
+  if (LHS->getParent() != RHS->getParent())
+    return std::nullopt;
+
+  if (LHS->getNumIncomingValues() < 2)
+    return std::nullopt;
+
+  BasicBlock *B0 = LHS->getIncomingBlock(0);
+  Value *N1 = LHS->getIncomingValueForBlock(B0);
----------------
nikic wrote:

Using getIncomingValueForBlock() is inefficient for large phis (the function will be quadratic).

What you can do is add a check `if (!equal(LHS->blocks(), RHS->blocks()) return false;` and then just work on the incoming values ignoring the blocks.

InstCombine canonicalizes the block order for phis in the same block, so this check only guards against phi nodes that have no been canonicalized yet -- it will eventually succeed.

https://github.com/llvm/llvm-project/pull/75765


More information about the llvm-commits mailing list