[llvm] [LV] Fix unsafe canVectorizeWithIfConvert() checks (PR #203273)
Gaƫtan Bossu via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 11 07:01:09 PDT 2026
https://github.com/gbossu created https://github.com/llvm/llvm-project/pull/203273
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.
>From 59fc4a4129893f2c8a17a0571f10d57f3942a9c6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ga=C3=ABtan=20Bossu?= <gaetan.bossu at arm.com>
Date: Thu, 11 Jun 2026 13:22:52 +0000
Subject: [PATCH] [LV] Fix unsafe canVectorizeWithIfConvert() checks
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.
---
llvm/lib/Analysis/LoopAccessAnalysis.cpp | 3 ++
.../Vectorize/LoopVectorizationLegality.cpp | 7 ++--
.../allowExtraAnalysis-invalid-cfg.ll | 34 +++++++++++++++++++
3 files changed, 41 insertions(+), 3 deletions(-)
create mode 100644 llvm/test/Transforms/LoopVectorize/allowExtraAnalysis-invalid-cfg.ll
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
+}
More information about the llvm-commits
mailing list