[llvm] [VPlan] Convert EVL loops to variable-length stepping after dissolution (PR #147222)
Luke Lau via llvm-commits
llvm-commits at lists.llvm.org
Sat Jul 19 07:21:49 PDT 2025
================
@@ -2357,6 +2357,60 @@ bool VPlanTransforms::tryAddExplicitVectorLength(
return true;
}
+void VPlanTransforms::simplifyEVLIVs(VPlan &Plan) {
+ using namespace llvm::VPlanPatternMatch;
+ // Find EVL loop entries by locating VPEVLBasedIVPHIRecipe
+ // There should be only one EVL PHI in the entire plan
+ VPEVLBasedIVPHIRecipe *EVLPhi = nullptr;
+
+ for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
+ vp_depth_first_shallow(Plan.getEntry())))
+ for (VPRecipeBase &R : VPBB->phis())
+ if (auto *PhiR = dyn_cast<VPEVLBasedIVPHIRecipe>(&R)) {
+ assert(!EVLPhi && "Found multiple EVL PHIs. Only one expected");
+ EVLPhi = PhiR;
+ }
+
+ // Early return if no EVL PHI is found
+ if (!EVLPhi)
+ return;
+
+ VPBasicBlock *Entry = EVLPhi->getParent();
+ VPValue *EVLIncrement = EVLPhi->getBackedgeValue();
+
+ // Convert EVLPhi to concrete recipe.
+ auto *ScalarR =
+ VPBuilder(EVLPhi).createScalarPhi({EVLPhi->getStartValue(), EVLIncrement},
+ EVLPhi->getDebugLoc(), "evl.based.iv");
+ EVLPhi->replaceAllUsesWith(ScalarR);
+ EVLPhi->eraseFromParent();
+
+ // Find the latch-exiting block and convert to variable-length stepping.
+ // Before: (branch-on-count CanonicalIVInc, VectorTripCount)
+ // After: (branch-on-count EVLIVInc, TripCount)
+ auto Range =
+ VPBlockUtils::blocksOnly<VPBasicBlock>(vp_depth_first_shallow(Entry));
+ auto It = find_if(Range, [&Entry](VPBasicBlock *VPBB) {
+ return any_of(VPBB->successors(),
+ [&Entry](VPBlockBase *Succ) { return Succ == Entry; });
+ });
+ assert((It != Range.end()) && "LatchExiting is not found");
+ VPBasicBlock *LatchExiting = *It;
+ auto *LatchExitingBr = cast<VPInstruction>(LatchExiting->getTerminator());
+ VPValue *ScalarIVInc;
+ assert(LatchExitingBr &&
+ match(LatchExitingBr,
+ m_BranchOnCount(m_VPValue(ScalarIVInc),
+ m_Specific(&Plan.getVectorTripCount()))) &&
+ "Unexpected terminator in EVL loop");
----------------
lukel97 wrote:
I tried this PR out locally on SPEC CPU 2017 and hit this assertion building 502.gcc_r, it looks like sometimes the branch condition might be simplified?
```
WIDEN vp.store vp<%6>, ir<0>, vp<%4>
EMIT-SCALAR vp<%7> = zext vp<%4> to i64
EMIT vp<%index.evl.next> = add vp<%7>, vp<%evl.based.iv>
EMIT vp<%index.next> = add vp<%index>, vp<%0>
EMIT branch-on-cond ir<true>
Successor(s): middle.block, vector.body
...
Assertion failed: (LatchExitingBr && match(LatchExitingBr, m_BranchOnCount(m_VPValue(ScalarIVInc), m_Specific(&Plan.getVectorTripCount()))) && "Unexpected terminator in EVL loop"), function simplifyEVLIVs, file VPlanTransforms.cpp, line 2406.
```
Maybe we need to relax the assertion?
https://github.com/llvm/llvm-project/pull/147222
More information about the llvm-commits
mailing list