[llvm] [VPlan] Sink recipes from the vector loop region in licm. (PR #168031)

Luke Lau via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 13 08:50:20 PST 2026


================
@@ -2547,6 +2547,69 @@ static void licm(VPlan &Plan) {
       R.moveBefore(*Preheader, Preheader->end());
     }
   }
+
+  // Collect dedicated exit blocks, which have only the loop region as
+  // predecessor.
+  // TODO: Sinking to non-dedicated exits is not supported yet, as it would
+  // require splitting the edge to create a dedicated exit block. Without this,
+  // the sunk instruction would incorrectly execute on paths entering the exit
+  // block from other predecessors.
+  SmallPtrSet<VPBasicBlock *, 2> DedicatedExits;
+  for (VPBlockBase *Succ : LoopRegion->getSuccessors()) {
+    auto *ExitBB = cast<VPBasicBlock>(Succ);
+    if (ExitBB->getSinglePredecessor() == LoopRegion)
+      DedicatedExits.insert(ExitBB);
+  }
+  if (DedicatedExits.empty())
+    return;
+
+  VPDominatorTree VPDT(Plan);
+  // Sink recipes with no users inside the vector loop region into a dedicated
+  // exit block.
+  // TODO: Extend to sink recipes from inner loops.
+  for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
+           vp_post_order_shallow(LoopRegion->getEntry()))) {
+    for (VPRecipeBase &R : make_early_inc_range(reverse(*VPBB))) {
+      if (cannotHoistOrSinkRecipe(R))
+        continue;
+
+      auto *Def = cast<VPSingleDefRecipe>(&R);
+      if (Def->getNumUsers() == 0)
+        continue;
+
+      SmallPtrSet<VPBasicBlock *, 2> UserBBs;
+      // Cannot sink the recipe if any user is defined in the same loop or in
+      // any nested inner loop region.
+      if (any_of(Def->users(), [&](VPUser *U) {
----------------
lukel97 wrote:

```suggestion
      if (any_of(Def->users(), [&UserBBs](VPUser *U) {
```

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


More information about the llvm-commits mailing list