[llvm] [LoopInterchange] Add test for IR modification stops partway (PR #205562)
Ryotaro Kasuga via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 25 09:16:50 PDT 2026
https://github.com/kasuga-fj updated https://github.com/llvm/llvm-project/pull/205562
>From 76222bb97968107bac9fa5d469a62997dae87f61 Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <kasuga.ryotaro at fujitsu.com>
Date: Wed, 24 Jun 2026 12:53:55 +0000
Subject: [PATCH 1/2] [LoopInterchange] Add test for IR modification stops
partway
---
.../lib/Transforms/Scalar/LoopInterchange.cpp | 5 +-
.../LoopInterchange/transform-stop-partway.ll | 88 +++++++++++++++++++
2 files changed, 92 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/Transforms/LoopInterchange/transform-stop-partway.ll
diff --git a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
index e9e77b7a48963..392912486705c 100644
--- a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
@@ -2487,8 +2487,11 @@ bool LoopInterchangeTransform::adjustLoopBranches() {
Instruction *OuterLoopPredecessorBI = OuterLoopPredecessor->getTerminator();
BasicBlock *InnerLoopHeaderSuccessor = InnerLoopHeader->getUniqueSuccessor();
- if (!InnerLoopHeaderSuccessor)
+ if (!InnerLoopHeaderSuccessor) {
+ LLVM_DEBUG(
+ dbgs() << "Inner loop header does not have a unique successor\n");
return false;
+ }
// Adjust Loop Preheader and headers.
// The branches in the outer loop predecessor and the outer loop header can
diff --git a/llvm/test/Transforms/LoopInterchange/transform-stop-partway.ll b/llvm/test/Transforms/LoopInterchange/transform-stop-partway.ll
new file mode 100644
index 0000000000000..74aefe9c8c74c
--- /dev/null
+++ b/llvm/test/Transforms/LoopInterchange/transform-stop-partway.ll
@@ -0,0 +1,88 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=loop-interchange -loop-interchange-profitabilities=ignore -debug-only=loop-interchange -S 2>&1 | FileCheck %s
+; REQUIRES: asserts
+
+; This test shows a case where the IR‑transformation phase of loop interchange
+; can fail partway. As a result, the final output becomes a partially
+; transformed IR. The IR‑transformation phase must not stop partway; in such
+; cases, the entire process should bail out early during the legality‑check
+; phase.
+
+; CHECK: Inner loop header does not have a unique successor
+
+define void @f(i1 %cond, ptr %A) {
+; CHECK-LABEL: define void @f(
+; CHECK-SAME: i1 [[COND:%.*]], ptr [[A:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br label %[[OUTER_HEADER_PREHEADER:.*]]
+; CHECK: [[OUTER_HEADER_PREHEADER]]:
+; CHECK-NEXT: br label %[[OUTER_HEADER:.*]]
+; CHECK: [[OUTER_HEADER]]:
+; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_INC:%.*]], %[[OUTER_LATCH:.*]] ], [ 0, %[[OUTER_HEADER_PREHEADER]] ]
+; CHECK-NEXT: br label %[[INNER_HEADER_PREHEADER:.*]]
+; CHECK: [[INNER_HEADER_PREHEADER]]:
+; CHECK-NEXT: br label %[[INNER_HEADER:.*]]
+; CHECK: [[INNER_HEADER]]:
+; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[TMP0:%.*]], %[[INNER_LATCH_SPLIT:.*]] ], [ 0, %[[INNER_HEADER_PREHEADER]] ]
+; CHECK-NEXT: br i1 [[COND]], label %[[INNER_BODY_0:.*]], label %[[INNER_BODY_1:.*]]
+; CHECK: [[INNER_BODY_0]]:
+; CHECK-NEXT: br label %[[INNER_LATCH:.*]]
+; CHECK: [[INNER_BODY_1]]:
+; CHECK-NEXT: br label %[[INNER_LATCH]]
+; CHECK: [[INNER_LATCH]]:
+; CHECK-NEXT: [[GEP:%.*]] = getelementptr [42 x i8], ptr [[A]], i64 [[J]], i64 [[I]]
+; CHECK-NEXT: store i8 1, ptr [[GEP]], align 1
+; CHECK-NEXT: [[J_INC:%.*]] = add i64 [[J]], 1
+; CHECK-NEXT: [[EC_J:%.*]] = icmp eq i64 [[J_INC]], 42
+; CHECK-NEXT: br label %[[INNER_LATCH_SPLIT]]
+; CHECK: [[INNER_LATCH_SPLIT]]:
+; CHECK-NEXT: [[TMP0]] = add i64 [[J]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[TMP0]], 42
+; CHECK-NEXT: br i1 [[TMP1]], label %[[INNER_EXIT:.*]], label %[[INNER_HEADER]]
+; CHECK: [[BB2:.*:]]
+; CHECK-NEXT: unreachable
+; CHECK: [[INNER_EXIT]]:
+; CHECK-NEXT: br label %[[OUTER_LATCH]]
+; CHECK: [[OUTER_LATCH]]:
+; CHECK-NEXT: [[I_INC]] = add i64 [[I]], 1
+; CHECK-NEXT: [[EC_I:%.*]] = icmp eq i64 [[I_INC]], 42
+; CHECK-NEXT: br i1 [[EC_I]], label %[[EXIT:.*]], label %[[OUTER_HEADER]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
+entry:
+ br label %outer.header
+
+outer.header:
+ %i = phi i64 [ 0, %entry ], [ %i.inc, %outer.latch ]
+ br label %inner.header
+
+inner.header:
+ %j = phi i64 [ 0, %outer.header ], [ %j.inc, %inner.latch ]
+ br i1 %cond, label %inner.body.0, label %inner.body.1
+
+inner.body.0:
+ br label %inner.latch
+
+inner.body.1:
+ br label %inner.latch
+
+inner.latch:
+ %gep = getelementptr [42 x i8], ptr %A, i64 %j, i64 %i
+ store i8 1, ptr %gep
+ %j.inc = add i64 %j, 1
+ %ec.j = icmp eq i64 %j.inc, 42
+ br i1 %ec.j, label %inner.exit, label %inner.header
+ br label %inner.latch
+
+inner.exit:
+ br label %outer.latch
+
+outer.latch:
+ %i.inc = add i64 %i, 1
+ %ec.i = icmp eq i64 %i.inc, 42
+ br i1 %ec.i, label %exit, label %outer.header
+
+exit:
+ ret void
+}
>From fa059dae03a5fa9c5a7a585a62fdb9d14c22f747 Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <kasuga.ryotaro at fujitsu.com>
Date: Fri, 26 Jun 2026 01:16:00 +0900
Subject: [PATCH 2/2] address review
---
llvm/lib/Transforms/Scalar/LoopInterchange.cpp | 2 ++
.../Transforms/LoopInterchange/transform-stop-partway.ll | 7 ++++---
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
index 392912486705c..96a4e4d54c6f8 100644
--- a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
@@ -2487,6 +2487,8 @@ bool LoopInterchangeTransform::adjustLoopBranches() {
Instruction *OuterLoopPredecessorBI = OuterLoopPredecessor->getTerminator();
BasicBlock *InnerLoopHeaderSuccessor = InnerLoopHeader->getUniqueSuccessor();
+
+ // FIXME: IR modification should not stop partway through.
if (!InnerLoopHeaderSuccessor) {
LLVM_DEBUG(
dbgs() << "Inner loop header does not have a unique successor\n");
diff --git a/llvm/test/Transforms/LoopInterchange/transform-stop-partway.ll b/llvm/test/Transforms/LoopInterchange/transform-stop-partway.ll
index 74aefe9c8c74c..71a6693b7d25d 100644
--- a/llvm/test/Transforms/LoopInterchange/transform-stop-partway.ll
+++ b/llvm/test/Transforms/LoopInterchange/transform-stop-partway.ll
@@ -4,9 +4,10 @@
; This test shows a case where the IR‑transformation phase of loop interchange
; can fail partway. As a result, the final output becomes a partially
-; transformed IR. The IR‑transformation phase must not stop partway; in such
-; cases, the entire process should bail out early during the legality‑check
-; phase.
+; transformed IR.
+;
+; FIXME: The IR‑transformation phase must not stop partway; in such cases, the
+; entire process should bail out early during the legality‑check phase.
; CHECK: Inner loop header does not have a unique successor
More information about the llvm-commits
mailing list