[llvm] [LV] Support tail-folded epilogue loops (PR #208764)
David Sherwood via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 21 04:05:20 PDT 2026
================
@@ -5384,12 +5420,113 @@ void LoopVectorizationPlanner::plan(ElementCount UserVF, unsigned UserIC) {
CM->collectNonVectorizedAndSetWideningDecisions(VF);
}
- buildVPlans(*VPlan1, ElementCount::getFixed(1), MaxFactors.FixedVF);
- buildVPlans(*VPlan1, ElementCount::getScalable(1), MaxFactors.ScalableVF);
+ buildVPlans(*VPlan1, ElementCount::getFixed(1), MaxFactors.FixedVF, *CM);
+ buildVPlans(*VPlan1, ElementCount::getScalable(1), MaxFactors.ScalableVF,
+ *CM);
LLVM_DEBUG(printPlans(dbgs()));
}
+bool LoopVectorizationPlanner::planForEpilogueTF() {
+ EpilogueLowering EpilogueTailLoweringStatus =
+ getEpilogueTailLowering(*CM, OrigLoop, ORE, *Legal, Config.getHints());
+ if (EpilogueTailLoweringStatus !=
+ EpilogueLowering::CM_EpilogueNotNeededFoldTail)
+ return false;
+ LLVM_DEBUG(dbgs() << "LV: epilogue tail-folding is enabled\n");
+
+ bool UseInterleaved = TTI.enableInterleavedAccessVectorization();
+ if (EnableInterleavedMemAccesses.getNumOccurrences() > 0)
+ UseInterleaved = EnableInterleavedMemAccesses;
+
+ EpilogueTfIAI = std::make_unique<InterleavedAccessInfo>(
+ PSE, OrigLoop, DT, LI, Legal->getLAI(), Config.OptForSize);
+ if (UseInterleaved)
+ EpilogueTfIAI->analyzeInterleaving(useMaskedInterleavedAccesses(TTI));
+ LoopVectorizationCostModel EpilogueTfCM(
+ EpilogueTailLoweringStatus, OrigLoop, PSE, LI, Legal, TTI, TLI, CM->AC,
+ ORE, CM->GetBFI, CM->TheFunction, *EpilogueTfIAI, Config);
+
+ assert(EpilogueTfCM.preferTailFoldedLoop() &&
+ "Epilogue tail-folding is expected to be enabled");
+
+ LLVM_DEBUG(dbgs() << "LV: plan for tail-folded epilogue\n");
+
+ EpilogueTfCM.ValuesToIgnore.insert_range(CM->ValuesToIgnore);
+ EpilogueTfCM.VecValuesToIgnore.insert_range(CM->VecValuesToIgnore);
+
+ FixedScalableVFPair MaxFactors =
+ EpilogueTfCM.computeMaxVF(EpilogueVectorizationForceVF, /*UserIC*/ 1);
+ if (!MaxFactors || !EpilogueTfCM.foldTailByMasking()) {
+ // Cases that should not to be vectorized or tail-folded.
+ reportVectorizationInfo("This case of epilogue loop can't be tail-folded",
+ "InvalidTailFoldedEpilogue", ORE, OrigLoop);
+ return false;
+ }
+
+ auto VPlan1 = tryToBuildVPlan1(EpilogueTfCM);
+
+ // If we're here, the main loop's initial VPlan was built successfully.
+ // Building one for the tail-folded loop should therefore also succeed, since
+ // nothing tail-folding-specific happens yet at this point. Still check below
+ // to catch any unexpected failure.
+ if (!VPlan1) {
+ reportVectorizationInfo(
+ "Failed to build initial tail-folded epilogue VPlan",
+ "InvalidTailFoldedEpilogue", ORE, OrigLoop);
+ assert(false && "Failed to build initial tail-folded epilogue VPlan");
+ return false;
+ }
+
+ if (!useMaskedInterleavedAccesses(TTI)) {
+ LLVM_DEBUG(
+ dbgs() << "LV: Invalidate all interleaved groups due to fold-tail by "
+ "masking which requires masked-interleaved support.\n");
+ if (EpilogueTfCM.InterleaveInfo.invalidateGroups())
+ // Invalidating interleave groups also requires invalidating all decisions
+ // based on them, which includes widening decisions and uniform and scalar
+ // values.
+ EpilogueTfCM.invalidateCostModelingDecisions();
+ }
+ Legal->prepareToFoldTailByMasking();
+
+ // Collect the instructions (and their associated costs) that will be more
+ // profitable to scalarize.
+ EpilogueTfCM.collectNonVectorizedAndSetWideningDecisions(
+ EpilogueVectorizationForceVF);
+
+ size_t NumPlansBefore = VPlans.size();
+ buildVPlans(*VPlan1, EpilogueVectorizationForceVF,
+ EpilogueVectorizationForceVF, EpilogueTfCM);
+
+ // Check that a Vplan is successfully built:
+ if (VPlans.size() == NumPlansBefore) {
+ reportVectorizationInfo("Failed to build tail-folded epilogue VPlan",
+ "InvalidTailFoldedEpilogue", ORE, OrigLoop);
+ return false;
+ }
+ if (VPlans.back()->getSingleVF() != EpilogueVectorizationForceVF ||
+ !VPlans.back()->hasTailFolded()) {
+ reportVectorizationInfo(
+ "Failed to build a valid tail-folded epilogue VPlan",
----------------
david-arm wrote:
Is there a test for this? I looked for a remark or debug message in a test, but couldn't find one.
https://github.com/llvm/llvm-project/pull/208764
More information about the llvm-commits
mailing list