[llvm] [InstCombine] Fold dependent IVs (PR #81151)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 20 07:45:47 PST 2024


================
@@ -1378,6 +1378,58 @@ static Value *simplifyUsingControlFlow(InstCombiner &Self, PHINode &PN,
   return nullptr;
 }
 
+// Fold  iv = phi(start, iv.next = iv2.next op start)
+// where iv2 = phi(iv2.start, iv2.next = iv2 + iv2.step)
+// and   iv2.start op start = start
+// to    iv = iv2 op start
+static Value *foldDependentIVs(PHINode &PN, IRBuilderBase &Builder) {
+  BasicBlock *BB = PN.getParent();
+  if (PN.getNumIncomingValues() != 2)
+    return nullptr;
+
+  Value *Start;
+  Instruction *IvNext;
+  BinaryOperator *Iv2Next;
+  auto MatchOuterIV = [&](Value *V1, Value *V2) {
+    if (match(V2, m_c_BinOp(m_Specific(V1), m_BinOp(Iv2Next))) ||
+        match(V2, m_GEP(m_Specific(V1), m_BinOp(Iv2Next)))) {
+      Start = V1;
+      IvNext = cast<Instruction>(V2);
+      return true;
+    }
+    return false;
+  };
+
+  if (!MatchOuterIV(PN.getIncomingValue(0), PN.getIncomingValue(1)) &&
+      !MatchOuterIV(PN.getIncomingValue(1), PN.getIncomingValue(0)))
+    return nullptr;
+
+  PHINode *Iv2;
+  Value *Iv2Start, *Iv2Step;
+  if (!matchSimpleRecurrence(Iv2Next, Iv2, Iv2Start, Iv2Step) ||
+      Iv2->getParent() != BB)
+    return nullptr;
+
+  auto *BO = dyn_cast<BinaryOperator>(IvNext);
+  Constant *Identity =
+      BO ? ConstantExpr::getBinOpIdentity(BO->getOpcode(), Iv2Start->getType())
+         : Constant::getNullValue(Iv2Start->getType());
+  if (Iv2Start != Identity)
+    return nullptr;
+
+  Builder.SetInsertPoint(&*BB, BB->getFirstInsertionPt());
+  if (!BO) {
+    auto *GEP = cast<GEPOperator>(IvNext);
+    return Builder.CreateGEP(GEP->getSourceElementType(), Start, Iv2, "",
+                             cast<GEPOperator>(IvNext)->isInBounds());
+  }
+
+  assert(BO->isCommutative() && "Must be commutative");
+  Value *Res = Builder.CreateBinOp(BO->getOpcode(), Start, Iv2);
----------------
dtcxzyw wrote:

```suggestion
  Value *Res = Builder.CreateBinOp(BO->getOpcode(), Iv2, Start);
```
`Start` is likely to be a constant.



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


More information about the llvm-commits mailing list