[llvm] [LV] Vectorize early exit loops with multiple exits. (PR #174864)

via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 9 06:46:35 PST 2026


github-actions[bot] wrote:

<!--LLVM CODE FORMAT COMMENT: {clang-format}-->


:warning: C/C++ code formatter, clang-format found issues in your code. :warning:

<details>
<summary>
You can test this locally with the following command:
</summary>

``````````bash
git-clang-format --diff origin/main HEAD --extensions cpp,h -- llvm/lib/Transforms/Vectorize/LoopVectorize.cpp llvm/lib/Transforms/Vectorize/VPlan.h llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp llvm/lib/Transforms/Vectorize/VPlanTransforms.h --diff_from_common_commit
``````````

:warning:
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing `origin/main` to the base branch/commit you want to compare against.
:warning:

</details>

<details>
<summary>
View the diff from clang-format here.
</summary>

``````````diff
diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index b2fa81846..954a473c8 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -4154,45 +4154,45 @@ void VPlanTransforms::handleUncountableEarlyExits(VPlan &Plan,
     }
   }
 
-    // Chain through exits: for each exit, check if its condition is true at
-    // the first active lane. If so, take that exit; otherwise, try the next.
-    // The last exit needs no check since it must be taken if all others fail.
-    //
-    // For 3 exits (cond.0, cond.1, cond.2), this creates:
-    //
-    // vector.early.exit.check:
-    //   EMIT vp<%combined> = or vp<%cond.0>, vp<%cond.1>, vp<%cond.2>
-    //   EMIT vp<%first.lane> = first-active-lane vp<%combined>
-    //   EMIT vp<%at.cond.0> = extract-lane vp<%first.lane>, vp<%cond.0>
-    //   EMIT branch-on-cond vp<%at.cond.0>
-    // Successor(s): vector.early.exit.0, vector.early.exit.check.0
-    //
-    // vector.early.exit.check.0:
-    //   EMIT vp<%at.cond.1> = extract-lane vp<%first.lane>, vp<%cond.1>
-    //   EMIT branch-on-cond vp<%at.cond.1>
-    // Successor(s): vector.early.exit.1, vector.early.exit.2
-    VPBasicBlock *CurrentBB = DispatchVPBB;
-    for (auto [I, Exit] : enumerate(ArrayRef(Exits).drop_back())) {
-      VPValue *LaneVal = DispatchBuilder.createNaryOp(
-          VPInstruction::ExtractLane, {FirstActiveLane, Exit.CondToExit},
-          DebugLoc::getUnknown(), "exit.cond.at.lane");
-
-      // For the last dispatch, branch directly to the last exit on false;
-      // otherwise, create a new check block.
-      bool IsLastDispatch = (I + 2 == Exits.size());
-      VPBasicBlock *FalseBB =
-          IsLastDispatch ? VectorEarlyExitVPBBs.back()
-                         : Plan.createVPBasicBlock(
-                               Twine("vector.early.exit.check.") + Twine(I));
-
-      DispatchBuilder.createNaryOp(VPInstruction::BranchOnCond, {LaneVal});
-      CurrentBB->setSuccessors({VectorEarlyExitVPBBs[I], FalseBB});
-      VectorEarlyExitVPBBs[I]->setPredecessors({CurrentBB});
-      FalseBB->setPredecessors({CurrentBB});
-
-      CurrentBB = FalseBB;
-      DispatchBuilder.setInsertPoint(CurrentBB);
-    }
+  // Chain through exits: for each exit, check if its condition is true at
+  // the first active lane. If so, take that exit; otherwise, try the next.
+  // The last exit needs no check since it must be taken if all others fail.
+  //
+  // For 3 exits (cond.0, cond.1, cond.2), this creates:
+  //
+  // vector.early.exit.check:
+  //   EMIT vp<%combined> = or vp<%cond.0>, vp<%cond.1>, vp<%cond.2>
+  //   EMIT vp<%first.lane> = first-active-lane vp<%combined>
+  //   EMIT vp<%at.cond.0> = extract-lane vp<%first.lane>, vp<%cond.0>
+  //   EMIT branch-on-cond vp<%at.cond.0>
+  // Successor(s): vector.early.exit.0, vector.early.exit.check.0
+  //
+  // vector.early.exit.check.0:
+  //   EMIT vp<%at.cond.1> = extract-lane vp<%first.lane>, vp<%cond.1>
+  //   EMIT branch-on-cond vp<%at.cond.1>
+  // Successor(s): vector.early.exit.1, vector.early.exit.2
+  VPBasicBlock *CurrentBB = DispatchVPBB;
+  for (auto [I, Exit] : enumerate(ArrayRef(Exits).drop_back())) {
+    VPValue *LaneVal = DispatchBuilder.createNaryOp(
+        VPInstruction::ExtractLane, {FirstActiveLane, Exit.CondToExit},
+        DebugLoc::getUnknown(), "exit.cond.at.lane");
+
+    // For the last dispatch, branch directly to the last exit on false;
+    // otherwise, create a new check block.
+    bool IsLastDispatch = (I + 2 == Exits.size());
+    VPBasicBlock *FalseBB =
+        IsLastDispatch ? VectorEarlyExitVPBBs.back()
+                       : Plan.createVPBasicBlock(
+                             Twine("vector.early.exit.check.") + Twine(I));
+
+    DispatchBuilder.createNaryOp(VPInstruction::BranchOnCond, {LaneVal});
+    CurrentBB->setSuccessors({VectorEarlyExitVPBBs[I], FalseBB});
+    VectorEarlyExitVPBBs[I]->setPredecessors({CurrentBB});
+    FalseBB->setPredecessors({CurrentBB});
+
+    CurrentBB = FalseBB;
+    DispatchBuilder.setInsertPoint(CurrentBB);
+  }
 
   // Replace the latch terminator with the new branching logic.
   auto *LatchExitingBranch = cast<VPInstruction>(LatchVPBB->getTerminator());

``````````

</details>


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


More information about the llvm-commits mailing list