[llvm] [IVDesc] Check loop-preheader for loop-legality when pass-remarks enabled (PR #166310)

via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 2 04:26:57 PST 2026


https://github.com/ParkHanbum updated https://github.com/llvm/llvm-project/pull/166310

>From f919b68db1e9932fa30ea461bdf918b16f5ff31a Mon Sep 17 00:00:00 2001
From: Hanbum Park <kese111 at gmail.com>
Date: Mon, 3 Nov 2025 23:33:37 +0900
Subject: [PATCH 1/3] [IVDesc] Check loop-preheader for loop-legality when
 pass-remarks enabled

When `-pass-remarks=loop-vectorize` is specified, the subsequent
logic is executed to display detailed debug messages even
if no PreHeader exists in the loop.

Therefore, an assert occurs when the `getLoopPreHeader()` function
is called. This commit resolves that issue.

Fixed: #165377
---
 llvm/lib/Analysis/IVDescriptors.cpp           | 10 +++++++-
 .../loop-legality-checks-remarks.ll           | 24 +++++++++++++++++++
 2 files changed, 33 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/Transforms/LoopVectorize/loop-legality-checks-remarks.ll

diff --git a/llvm/lib/Analysis/IVDescriptors.cpp b/llvm/lib/Analysis/IVDescriptors.cpp
index 3946a7ce8b8f6..28be9ef5fe27f 100644
--- a/llvm/lib/Analysis/IVDescriptors.cpp
+++ b/llvm/lib/Analysis/IVDescriptors.cpp
@@ -282,7 +282,9 @@ bool RecurrenceDescriptor::AddReductionVar(
 
   // Obtain the reduction start value from the value that comes from the loop
   // preheader.
-  Value *RdxStart = Phi->getIncomingValueForBlock(TheLoop->getLoopPreheader());
+  Value *RdxStart;
+  if (TheLoop->getLoopPreheader())
+    RdxStart = Phi->getIncomingValueForBlock(TheLoop->getLoopPreheader());
 
   // ExitInstruction is the single value which is used outside the loop.
   // We only allow for a single reduction value to be used outside the loop.
@@ -649,6 +651,9 @@ bool RecurrenceDescriptor::AddReductionVar(
   collectCastInstrs(TheLoop, ExitInstruction, RecurrenceType, CastInsts,
                     MinWidthCastToRecurrenceType);
 
+  if (!RdxStart)
+    return false;
+
   // We found a reduction var if we have reached the original phi node and we
   // only have a single instruction with out-of-loop users.
 
@@ -1690,6 +1695,9 @@ bool InductionDescriptor::isInductionPHI(
   assert(Phi->getParent() == TheLoop->getHeader() &&
          "Invalid Phi node, not present in loop header");
 
+  if (!TheLoop->getLoopPreheader())
+    return false;
+
   Value *StartValue =
       Phi->getIncomingValueForBlock(TheLoop->getLoopPreheader());
 
diff --git a/llvm/test/Transforms/LoopVectorize/loop-legality-checks-remarks.ll b/llvm/test/Transforms/LoopVectorize/loop-legality-checks-remarks.ll
new file mode 100644
index 0000000000000..9e51b42266c1e
--- /dev/null
+++ b/llvm/test/Transforms/LoopVectorize/loop-legality-checks-remarks.ll
@@ -0,0 +1,24 @@
+; RUN: opt < %s -passes=loop-vectorize -pass-remarks=loop-vectorize -debug -disable-output 2>&1 | FileCheck %s
+; REQUIRES: asserts
+
+; Make sure LV legal bails out when the loop doesn't have a legal pre-header.
+; CHECK-LABEL: 'not_exist_preheader'
+; CHECK: LV: Not vectorizing: Loop doesn't have a legal pre-header.
+define void @not_exist_preheader(ptr %dst, ptr %arg) nounwind uwtable {
+entry:
+  indirectbr ptr %arg, [label %0, label %loop]
+
+0:
+  unreachable
+
+loop:
+  %iv = phi i32 [0, %entry], [%iv.next, %loop]
+  %gep = getelementptr inbounds i32, ptr %dst, i32 %iv
+  store i32 0, ptr %gep, align 4
+  %iv.next = add i32 %iv, 1
+  %cmp = icmp slt i32 %iv.next, 4
+  br i1 %cmp, label %loop, label %exit
+
+exit:
+  ret void
+}

>From f0bbe898c83f2658475661dac215608f1e3155fa Mon Sep 17 00:00:00 2001
From: Hanbum Park <kese111 at gmail.com>
Date: Mon, 2 Feb 2026 21:25:46 +0900
Subject: [PATCH 2/3] rename unreachable block

---
 .../Transforms/LoopVectorize/loop-legality-checks-remarks.ll  | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/test/Transforms/LoopVectorize/loop-legality-checks-remarks.ll b/llvm/test/Transforms/LoopVectorize/loop-legality-checks-remarks.ll
index 9e51b42266c1e..beb07a1083331 100644
--- a/llvm/test/Transforms/LoopVectorize/loop-legality-checks-remarks.ll
+++ b/llvm/test/Transforms/LoopVectorize/loop-legality-checks-remarks.ll
@@ -6,9 +6,9 @@
 ; CHECK: LV: Not vectorizing: Loop doesn't have a legal pre-header.
 define void @not_exist_preheader(ptr %dst, ptr %arg) nounwind uwtable {
 entry:
-  indirectbr ptr %arg, [label %0, label %loop]
+  indirectbr ptr %arg, [label %exit.0, label %loop]
 
-0:
+exit.0:
   unreachable
 
 loop:

>From b76f10bf52f89207f57fe4fd1b5801e170ba11e1 Mon Sep 17 00:00:00 2001
From: Hanbum Park <kese111 at gmail.com>
Date: Mon, 2 Feb 2026 21:26:42 +0900
Subject: [PATCH 3/3] remove unreachable use instead ret

---
 .../Transforms/LoopVectorize/loop-legality-checks-remarks.ll    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/test/Transforms/LoopVectorize/loop-legality-checks-remarks.ll b/llvm/test/Transforms/LoopVectorize/loop-legality-checks-remarks.ll
index beb07a1083331..bd2231d9e47b1 100644
--- a/llvm/test/Transforms/LoopVectorize/loop-legality-checks-remarks.ll
+++ b/llvm/test/Transforms/LoopVectorize/loop-legality-checks-remarks.ll
@@ -9,7 +9,7 @@ entry:
   indirectbr ptr %arg, [label %exit.0, label %loop]
 
 exit.0:
-  unreachable
+  ret void
 
 loop:
   %iv = phi i32 [0, %entry], [%iv.next, %loop]



More information about the llvm-commits mailing list