[llvm] [VPlan] Move tail folding out of VPlanPredicator. NFC (PR #176143)
Andrei Elovikov via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 5 10:13:11 PST 2026
================
@@ -964,6 +964,82 @@ void VPlanTransforms::createLoopRegions(VPlan &Plan) {
TopRegion->getEntryBasicBlock()->setName("vector.body");
}
+void VPlanTransforms::foldTailByMasking(VPlan &Plan) {
+ assert(Plan.getExitBlocks().size() == 1 &&
+ "only a single-exit block is supported currently");
+ assert(Plan.getExitBlocks().front()->getSinglePredecessor() ==
+ Plan.getMiddleBlock() &&
+ "the exit block must have middle block as single predecessor");
+
+ VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
+ VPBasicBlock *Header = LoopRegion->getEntryBasicBlock();
+
+ Header->splitAt(Header->getFirstNonPhi());
+
+ // Create the header mask, insert it in the header and branch on it.
+ auto *IV =
+ new VPWidenCanonicalIVRecipe(Header->getParent()->getCanonicalIV());
+ VPBuilder Builder(Header, Header->getFirstNonPhi());
+ Builder.insert(IV);
+ VPValue *BTC = Plan.getOrCreateBackedgeTakenCount();
+ VPValue *HeaderMask = Builder.createICmp(CmpInst::ICMP_ULE, IV, BTC);
+ Builder.createNaryOp(VPInstruction::BranchOnCond, HeaderMask);
+
+ VPBasicBlock *Latch = LoopRegion->getExitingBasicBlock();
+ VPValue *IVInc;
+ [[maybe_unused]] bool TermBranchOnCount =
+ match(Latch->getTerminator(),
+ m_BranchOnCount(m_VPValue(IVInc),
+ m_Specific(&Plan.getVectorTripCount())));
+ assert(TermBranchOnCount &&
+ match(IVInc, m_Add(m_Specific(LoopRegion->getCanonicalIV()),
+ m_Specific(&Plan.getVFxUF()))) &&
+ std::next(IVInc->getDefiningRecipe()->getIterator()) ==
+ Latch->getTerminator()->getIterator() &&
+ "Unexpected canonical iv increment");
+
+ // Split the latch at the IV update, and branch to it from the header mask.
+ VPBasicBlock *LatchSplit =
+ Latch->splitAt(IVInc->getDefiningRecipe()->getIterator());
+ VPBlockUtils::connectBlocks(Header, LatchSplit);
+
+ // Insert phis for any values in the predicated body that are used outside.
+ Builder.setInsertPoint(LatchSplit, LatchSplit->begin());
+ for (VPBasicBlock *VPBB : {Header, Plan.getMiddleBlock()}) {
+ for (VPRecipeBase &R : *VPBB) {
----------------
eas wrote:
> Probably it suffices to just iterate through those?
Maybe check that in the verifier?
https://github.com/llvm/llvm-project/pull/176143
More information about the llvm-commits
mailing list