[llvm] [VPlan] Untie tail folding from optimizeInductionLiveOutUsers. NFC (PR #207984)

Luke Lau via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 23 03:23:33 PDT 2026


================
@@ -1012,31 +1012,55 @@ optimizeLatchExitInductionUser(VPlan &Plan, VPValue *Op,
 
 void VPlanTransforms::optimizeInductionLiveOutUsers(
     VPlan &Plan, PredicatedScalarEvolution &PSE) {
-  // Compute end values for all inductions.
+  // Compute the value inductions at two points:
+  // - when exiting the loop from the latch, at trip-count iterations.
+  // - when resuming at the scalar preheader, at vector trip-count iterations.
   VPRegionBlock *VectorRegion = Plan.getVectorLoopRegion();
   auto *VectorPH = cast<VPBasicBlock>(VectorRegion->getSinglePredecessor());
   VPBuilder VectorPHBuilder(VectorPH, VectorPH->begin());
-  DenseMap<VPValue *, VPValue *> EndValues;
-  VPValue *ResumeTC =
-      Plan.hasTailFolded() ? Plan.getTripCount() : &Plan.getVectorTripCount();
+  DenseMap<VPValue *, VPValue *> LatchExitValues, ResumeValues;
   for (auto &Phi : VectorRegion->getEntryBasicBlock()->phis()) {
     auto *WideIV = dyn_cast<VPWidenInductionRecipe>(&Phi);
     if (!WideIV)
       continue;
-    if (VPValue *EndValue =
-            tryToComputeEndValueForInduction(WideIV, VectorPHBuilder, ResumeTC))
-      EndValues[WideIV] = EndValue;
+    if (VPValue *EndValue = tryToComputeEndValueForInduction(
+            WideIV, VectorPHBuilder, Plan.getTripCount()))
+      LatchExitValues[WideIV] = EndValue;
+    if (VPValue *EndValue = tryToComputeEndValueForInduction(
+            WideIV, VectorPHBuilder, &Plan.getVectorTripCount()))
+      ResumeValues[WideIV] = EndValue;
   }
 
   VPBasicBlock *MiddleVPBB = Plan.getMiddleBlock();
+  VPBasicBlock *LatchExitVPBB = nullptr;
+  // Try and find the latch exit from MiddleVPBB.
+  if (Plan.isExitBlock(MiddleVPBB->getSuccessors()[0])) {
----------------
lukel97 wrote:

I believe so, in an early exit VPlan the early exits are connected to the check block, not the middle block, so the middle block should still link to the original exit, e.g.:

```
    EMIT branch-on-two-conds vp<[[ANY_OF]]>, vp<[[CMP]]>
  No successors
}
Successor(s): vector.early.exit.check, middle.block

middle.block:
  EMIT vp<%cmp.n> = icmp eq ir<67>, vp<[[VTC]]>
  EMIT branch-on-cond vp<%cmp.n>
Successor(s): ir-bb<exit>, scalar.ph

vector.early.exit.check:
  EMIT vp<%first.active.lane> = first-active-lane vp<[[OR]]>
  EMIT vp<%exit.cond.at.lane> = extract-lane vp<%first.active.lane>, ir<%cmp1>
  EMIT branch-on-cond vp<%exit.cond.at.lane>
Successor(s): vector.early.exit.0, vector.early.exit.1

vector.early.exit.1:
Successor(s): ir-bb<exit>

vector.early.exit.0:
  EMIT vp<[[FIRST_ACTIVE:%.+]]> = first-active-lane vp<[[OR]]>
  EMIT vp<[[FINAL_IV:%.+]]> = add vp<[[CAN_IV]]>, vp<[[FIRST_ACTIVE]]>
Successor(s): ir-bb<exit>
```

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


More information about the llvm-commits mailing list