[llvm] [LV] Fix unsafe canVectorizeWithIfConvert() checks (PR #203273)

via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 11 07:02:07 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-vectorizers

Author: Gaƫtan Bossu (gbossu)

<details>
<summary>Changes</summary>

When allowExtraAnalysis is true, we might not have a canonical loop form to work with. This fixes the code paths that can be reached in legality checks to support loops with e.g. multiple latches.

---
Full diff: https://github.com/llvm/llvm-project/pull/203273.diff


3 Files Affected:

- (modified) llvm/lib/Analysis/LoopAccessAnalysis.cpp (+3) 
- (modified) llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp (+4-3) 
- (added) llvm/test/Transforms/LoopVectorize/allowExtraAnalysis-invalid-cfg.ll (+34) 


``````````diff
diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
index 74f0fa8a954da..971d0842dfa91 100644
--- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -2962,7 +2962,10 @@ bool LoopAccessInfo::blockNeedsPredication(const BasicBlock *BB,
   assert(TheLoop->contains(BB) && "Unknown block used");
 
   // Blocks that do not dominate the latch need predication.
+  // Treat blocks in loops with no unique latch as always needing predication.
   const BasicBlock *Latch = TheLoop->getLoopLatch();
+  if (!Latch)
+    return true;
   return !DT->dominates(BB, Latch);
 }
 
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
index 214b5cff8a03a..69ca29885f384 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
@@ -1470,12 +1470,13 @@ bool LoopVectorizationLegality::canVectorizeWithIfConvert() {
             continue;
 
           auto *CurrI = dyn_cast<Instruction>(CurrV);
+          BasicBlock *LoopPred = TheLoop->getLoopPredecessor();
           if (!CurrI || !TheLoop->contains(CurrI)) {
             // If operands from outside the loop may be poison then Ptr may also
             // be poison.
-            if (!isGuaranteedNotToBePoison(CurrV, AC,
-                                           TheLoop->getLoopPredecessor()
-                                               ->getTerminator()
+            if (!LoopPred ||
+                !isGuaranteedNotToBePoison(CurrV, AC,
+                                           LoopPred->getTerminator()
                                                ->getIterator(),
                                            DT))
               return false;
diff --git a/llvm/test/Transforms/LoopVectorize/allowExtraAnalysis-invalid-cfg.ll b/llvm/test/Transforms/LoopVectorize/allowExtraAnalysis-invalid-cfg.ll
new file mode 100644
index 0000000000000..3b562ec67a26a
--- /dev/null
+++ b/llvm/test/Transforms/LoopVectorize/allowExtraAnalysis-invalid-cfg.ll
@@ -0,0 +1,34 @@
+; RUN: opt -S -passes=loop-vectorize -pass-remarks-output=%t.yaml < %s | FileCheck %s
+
+; Enabling remarks forces extra legality analysis on loops with unexpected CFG.
+; Ensure LV does not crash due to the loop having multiple latches.
+; A normal branch gets canonicalized to a unique latch before LV runs, so use
+; indirectbr to keep the invalid CFG shape.
+
+; CHECK-LABEL: define void @multiple_latches_indirectbr(
+define void @multiple_latches_indirectbr() {
+entry:
+  indirectbr ptr null, [label %loop]
+
+loop:
+  br i1 false, label %bb, label %loop
+
+bb:
+  br label %loop
+}
+
+; CHECK-LABEL: define void @multiple_latches_and_predecessors_indirectbr(
+define void @multiple_latches_and_predecessors_indirectbr() {
+entry:
+  indirectbr ptr null, [label %loop, label %side]
+
+side:
+  br label %loop
+
+loop:
+  %x = load i64, ptr null, align 8
+  br i1 false, label %back, label %loop
+
+back:
+  br label %loop
+}

``````````

</details>


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


More information about the llvm-commits mailing list