[llvm] [VPlan] Make CanIV part of region. (PR #144803)

via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 10 05:12:54 PDT 2025


================
@@ -894,18 +902,37 @@ void VPRegionBlock::print(raw_ostream &O, const Twine &Indent,
 
 void VPRegionBlock::dissolveToCFGLoop() {
   auto *Header = cast<VPBasicBlock>(getEntry());
-  if (auto *CanIV = dyn_cast<VPCanonicalIVPHIRecipe>(&Header->front())) {
-    assert(this == getPlan()->getVectorLoopRegion() &&
-           "Canonical IV must be in the entry of the top-level loop region");
-    auto *ScalarR = VPBuilder(CanIV).createScalarPhi(
-        {CanIV->getStartValue(), CanIV->getBackedgeValue()},
-        CanIV->getDebugLoc(), "index");
+  auto *ExitingLatch = cast<VPBasicBlock>(getExiting());
+  if (CanIV && CanIV->getNumUsers() > 0) {
+    auto *ExitingTerm = ExitingLatch->getTerminator();
+    VPInstruction *CanIVInc = nullptr;
+    for (VPUser *U : CanIV->users()) {
+      if (match(U, m_Add(m_VPValue(), m_Specific(&getPlan()->getVFxUF())))) {
+        CanIVInc = cast<VPInstruction>(U);
+      }
+    }
+    if (!CanIVInc) {
+      VPValue *Count;
+      if (match(ExitingLatch->getTerminator(),
+                m_BranchOnCount(m_VPValue(Count), m_VPValue())))
+        CanIVInc = cast<VPInstruction>(Count);
+    }
+    if (!CanIVInc) {
+      CanIVInc = VPBuilder(ExitingTerm)
+                     .createOverflowingOp(
+                         Instruction::Add, {CanIV, &getPlan()->getVFxUF()},
+                         {CanIV->hasNoUnsignedWrap(), false},
+                         ExitingTerm->getDebugLoc(), "index.next");
+    }
+    auto *ScalarR = VPBuilder(Header, Header->begin())
+                        .createScalarPhi({CanIV->getStartValue(), CanIVInc},
+                                         CanIV->getDebugLoc(), "index");
     CanIV->replaceAllUsesWith(ScalarR);
-    CanIV->eraseFromParent();
+    if (ExitingTerm->getOperand(0) == ScalarR)
+      ExitingTerm->setOperand(0, CanIVInc);
----------------
ayalz wrote:

Worth explaining what kind of terminator is being fixed here; perhaps better to have it use CanIVInc instead of CanIV via replaceUsesWithIf(), before replacing CanIV with ScalarR.

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


More information about the llvm-commits mailing list