[llvm] [LV] Support tail-folded epilogue loops (PR #208764)

David Sherwood via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 7 06:56:41 PDT 2026


================
@@ -7847,6 +7962,39 @@ static void connectEpilogueVectorLoop(VPlan &EpiPlan, Loop *L,
   for (PHINode &Phi : make_early_inc_range(VecEpiloguePreHeader->phis()))
     if (Phi.use_empty())
       Phi.eraseFromParent();
+
+  if (IsEpilogueTFEnabled) {
+    // The epilogue vector loop is tail-folded, so it can safely handle
+    // any remaining trip count, including zero, via masking.
+    // vec.epilog.iter.check's own min-iters check was therefore built with a
+    // compile-time-known-false condition (see
+    // addMinimumVectorEpilogueIterationCheck) that never needs to bail out to
+    // a scalar remainder. Fold it into an unconditional branch into the
+    // vector epilogue preheader.
+    auto *Br =
+        cast<CondBrInst>(VecEpilogueIterationCountCheck->getTerminator());
+    [[maybe_unused]] auto *CondC = dyn_cast<ConstantInt>(Br->getCondition());
+    assert(CondC && CondC->isZero() &&
+           "expected vec.epilog.iter.check's branch condition to be a "
+           "compile-time false constant when the epilogue is tail-folded");
+    BasicBlock *DeadSucc = Br->getSuccessor(0);
+    UncondBrInst::Create(VecEpiloguePreHeader, Br->getIterator());
+    Br->eraseFromParent();
+    DTU.applyUpdates(
+        {{DominatorTree::Delete, VecEpilogueIterationCountCheck, DeadSucc}});
+
+    if (!SCEVCheckBlock && !MemCheckBlock) {
----------------
david-arm wrote:

OK, but is this code actually required for functional correctness? I would expect us to still be able to generate correct, but inoptimal, code. It adds quite a lot of extra complication to the PR, especially when in future I would expect this sort of thing to be cleaned up anyway.

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


More information about the llvm-commits mailing list