[llvm] [VPlan] Create epilogue minimum iteration check in VPlan. (PR #157545)
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 24 10:53:23 PDT 2025
================
@@ -9813,6 +9724,98 @@ static void fixScalarResumeValuesFromBypass(BasicBlock *BypassBlock, Loop *L,
}
}
+/// Connect the epilogue vector loop generated for \p Plan to the main vector
+/// loop, updating branches from the iteration and runtime checks, as well as
+/// updating various phis. \p InstsToMove contains instructions that need to be
+/// moved to the vector preheader.
+static void connectEpilogueVectorLoop(
+ VPlan &Plan, Loop *L, EpilogueLoopVectorizationInfo &EPI, DominatorTree *DT,
+ LoopVectorizationLegality &LVL,
+ DenseMap<const SCEV *, Value *> &ExpandedSCEVs, GeneratedRTChecks &Checks,
+ ArrayRef<Instruction *> InstsToMove) {
+ BasicBlock *AdditionalBypassBlock =
+ cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
+ BasicBlock *VecEpilogueIterationCountCheck = AdditionalBypassBlock;
+
+ BasicBlock *LoopVectorPreHeader =
+ cast<BranchInst>(VecEpilogueIterationCountCheck->getTerminator())
+ ->getSuccessor(1);
+ // Adjust the control flow taking the state info from the main loop
+ // vectorization into account.
+ assert(EPI.MainLoopIterationCountCheck && EPI.EpilogueIterationCountCheck &&
+ "expected this to be saved from the previous pass.");
+ DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
+ EPI.MainLoopIterationCountCheck->getTerminator()->replaceUsesOfWith(
+ VecEpilogueIterationCountCheck, LoopVectorPreHeader);
+
+ DTU.applyUpdates({{DominatorTree::Delete, EPI.MainLoopIterationCountCheck,
+ VecEpilogueIterationCountCheck},
+ {DominatorTree::Insert, EPI.MainLoopIterationCountCheck,
+ LoopVectorPreHeader}});
+
+ BasicBlock *ScalarPH =
+ cast<VPIRBasicBlock>(Plan.getScalarPreheader())->getIRBasicBlock();
+ EPI.EpilogueIterationCountCheck->getTerminator()->replaceUsesOfWith(
+ VecEpilogueIterationCountCheck, ScalarPH);
+ DTU.applyUpdates(
+ {{DominatorTree::Delete, EPI.EpilogueIterationCountCheck,
+ VecEpilogueIterationCountCheck},
+ {DominatorTree::Insert, EPI.EpilogueIterationCountCheck, ScalarPH}});
+
+ // Adjust the terminators of runtime check blocks and phis using them.
+ BasicBlock *SCEVCheckBlock = Checks.getSCEVChecks().second;
+ BasicBlock *MemCheckBlock = Checks.getMemRuntimeChecks().second;
+ if (SCEVCheckBlock) {
+ SCEVCheckBlock->getTerminator()->replaceUsesOfWith(
+ VecEpilogueIterationCountCheck, ScalarPH);
+ DTU.applyUpdates({{DominatorTree::Delete, SCEVCheckBlock,
+ VecEpilogueIterationCountCheck},
+ {DominatorTree::Insert, SCEVCheckBlock, ScalarPH}});
+ }
+ if (MemCheckBlock) {
+ MemCheckBlock->getTerminator()->replaceUsesOfWith(
+ VecEpilogueIterationCountCheck, ScalarPH);
+ DTU.applyUpdates(
+ {{DominatorTree::Delete, MemCheckBlock, VecEpilogueIterationCountCheck},
+ {DominatorTree::Insert, MemCheckBlock, ScalarPH}});
+ }
+
+ // The vec.epilog.iter.check block may contain Phi nodes from inductions
+ // or reductions which merge control-flow from the latch block and the
+ // middle block. Update the incoming values here and move the Phi into the
+ // preheader.
+ SmallVector<PHINode *, 4> PhisInBlock(
+ llvm::make_pointer_range(VecEpilogueIterationCountCheck->phis()));
+
+ for (PHINode *Phi : PhisInBlock) {
+ Phi->moveBefore(LoopVectorPreHeader->getFirstNonPHIIt());
+ Phi->replaceIncomingBlockWith(
+ VecEpilogueIterationCountCheck->getSinglePredecessor(),
+ VecEpilogueIterationCountCheck);
+
+ // If the phi doesn't have an incoming value from the
+ // EpilogueIterationCountCheck, we are done. Otherwise remove the
+ // incoming value and also those from other check blocks. This is needed
+ // for reduction phis only.
+ if (none_of(Phi->blocks(), [&](BasicBlock *IncB) {
+ return EPI.EpilogueIterationCountCheck == IncB;
+ }))
+ continue;
+ Phi->removeIncomingValue(EPI.EpilogueIterationCountCheck);
+ if (SCEVCheckBlock)
+ Phi->removeIncomingValue(SCEVCheckBlock);
+ if (MemCheckBlock)
+ Phi->removeIncomingValue(MemCheckBlock);
+ }
+
+ auto IP = LoopVectorPreHeader->getFirstNonPHIIt();
+ for (auto *I : InstsToMove)
+ I->moveBefore(IP);
+
----------------
fhahn wrote:
Added,thanks
https://github.com/llvm/llvm-project/pull/157545
More information about the llvm-commits
mailing list