[llvm] [LoopInterchange] Add test for imperfect loop nest (NFC) (PR #201507)

Rohit Garg via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 9 23:00:05 PDT 2026


https://github.com/rohgarg-qual updated https://github.com/llvm/llvm-project/pull/201507

>From dffba54c20dd748a970f20c0c0a499ad19a10da4 Mon Sep 17 00:00:00 2001
From: rohgarg <rohgarg at qti.qualcomm.com>
Date: Wed, 3 Jun 2026 22:00:42 -0700
Subject: [PATCH] Add test for imperfect loop nest in LoopInterchange

---
 .../LoopInterchange/partially-perfect-loop.ll | 107 ++++++++++++++++++
 1 file changed, 107 insertions(+)
 create mode 100644 llvm/test/Transforms/LoopInterchange/partially-perfect-loop.ll

diff --git a/llvm/test/Transforms/LoopInterchange/partially-perfect-loop.ll b/llvm/test/Transforms/LoopInterchange/partially-perfect-loop.ll
new file mode 100644
index 0000000000000..7d72b4a7f1804
--- /dev/null
+++ b/llvm/test/Transforms/LoopInterchange/partially-perfect-loop.ll
@@ -0,0 +1,107 @@
+; 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 < %s | FileCheck %s
+;
+; for (i = 0; i < 64; i++) {
+;   for (j = 0; j < 64; j++)
+;     for (r = 0; r < 64; r++)
+;       A[j][r] = 0;
+;
+;   for (k = 0; k < 64; k++)
+;     for (l = 0; l < 64; l++)
+;       B[l][k] = 0;
+; }
+
+define void @f(ptr noalias %A, ptr noalias %B) {
+; CHECK-LABEL: define void @f(
+; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]]) {
+; CHECK-NEXT:  [[FOR_J_HEADER:.*]]:
+; CHECK-NEXT:    br label %[[FOR_R_HEADER_SPLIT1:.*]]
+; CHECK:       [[FOR_R_HEADER_SPLIT1]]:
+; CHECK-NEXT:    [[I:%.*]] = phi i64 [ 0, %[[FOR_J_HEADER]] ], [ [[I_NEXT:%.*]], %[[FOR_I_LATCH:.*]] ]
+; CHECK-NEXT:    br label %[[FOR_R_HEADER:.*]]
+; CHECK:       [[FOR_R_HEADER]]:
+; CHECK-NEXT:    [[J:%.*]] = phi i64 [ 0, %[[FOR_R_HEADER_SPLIT1]] ], [ [[J_NEXT:%.*]], %[[FOR_J_LATCH:.*]] ]
+; CHECK-NEXT:    br label %[[FOR_J_HEADER_PREHEADER:.*]]
+; CHECK:       [[FOR_J_HEADER_PREHEADER]]:
+; CHECK-NEXT:    [[R:%.*]] = phi i64 [ 0, %[[FOR_R_HEADER]] ], [ [[TMP0:%.*]], %[[FOR_J_HEADER_PREHEADER]] ]
+; CHECK-NEXT:    [[A_ELEMENT:%.*]] = getelementptr [64 x i8], ptr [[A]], i64 [[J]], i64 [[R]]
+; CHECK-NEXT:    store i8 0, ptr [[A_ELEMENT]], align 1
+; CHECK-NEXT:    [[TMP0]] = add i64 [[R]], 1
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[TMP0]], 64
+; CHECK-NEXT:    br i1 [[TMP1]], label %[[FOR_J_LATCH]], label %[[FOR_J_HEADER_PREHEADER]]
+; CHECK:       [[FOR_J_LATCH]]:
+; CHECK-NEXT:    [[J_NEXT]] = add i64 [[J]], 1
+; CHECK-NEXT:    [[J_DONE:%.*]] = icmp eq i64 [[J_NEXT]], 64
+; CHECK-NEXT:    br i1 [[J_DONE]], label %[[FOR_L_HEADER_PREHEADER:.*]], label %[[FOR_R_HEADER]]
+; CHECK:       [[FOR_L_HEADER_PREHEADER]]:
+; CHECK-NEXT:    br label %[[FOR_L_HEADER:.*]]
+; CHECK:       [[FOR_L_HEADER]]:
+; CHECK-NEXT:    [[K:%.*]] = phi i64 [ [[K_NEXT:%.*]], %[[FOR_K_LATCH:.*]] ], [ 0, %[[FOR_L_HEADER_PREHEADER]] ]
+; CHECK-NEXT:    br label %[[FOR_K_HEADER_PREHEADER:.*]]
+; CHECK:       [[FOR_K_HEADER_PREHEADER]]:
+; CHECK-NEXT:    [[L:%.*]] = phi i64 [ 0, %[[FOR_L_HEADER]] ], [ [[TMP2:%.*]], %[[FOR_K_HEADER_PREHEADER]] ]
+; CHECK-NEXT:    [[B_ELEMENT:%.*]] = getelementptr [64 x i8], ptr [[B]], i64 [[L]], i64 [[K]]
+; CHECK-NEXT:    store i8 0, ptr [[B_ELEMENT]], align 1
+; CHECK-NEXT:    [[TMP2]] = add i64 [[L]], 1
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i64 [[TMP2]], 64
+; CHECK-NEXT:    br i1 [[TMP3]], label %[[FOR_K_LATCH]], label %[[FOR_K_HEADER_PREHEADER]]
+; CHECK:       [[FOR_K_LATCH]]:
+; CHECK-NEXT:    [[K_NEXT]] = add i64 [[K]], 1
+; CHECK-NEXT:    [[K_DONE:%.*]] = icmp eq i64 [[K_NEXT]], 64
+; CHECK-NEXT:    br i1 [[K_DONE]], label %[[FOR_I_LATCH]], label %[[FOR_L_HEADER]]
+; CHECK:       [[FOR_I_LATCH]]:
+; CHECK-NEXT:    [[I_NEXT]] = add i64 [[I]], 1
+; CHECK-NEXT:    [[I_DONE:%.*]] = icmp eq i64 [[I_NEXT]], 64
+; CHECK-NEXT:    br i1 [[I_DONE]], label %[[EXIT:.*]], label %[[FOR_R_HEADER_SPLIT1]]
+; CHECK:       [[EXIT]]:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %for.i.header
+
+for.i.header:
+  %i = phi i64 [ 0, %entry ], [ %i.next, %for.i.latch ]
+  br label %for.j.header
+
+for.j.header:
+  %j = phi i64 [ 0, %for.i.header ], [ %j.next, %for.j.latch ]
+  br label %for.r.header
+
+for.r.header:
+  %r = phi i64 [ 0, %for.j.header ], [ %r.next, %for.r.header ]
+  %a.element = getelementptr [64 x i8], ptr %A, i64 %j, i64 %r
+  store i8 0, ptr %a.element
+  %r.next = add i64 %r, 1
+  %r.done = icmp eq i64 %r.next, 64
+  br i1 %r.done, label %for.j.latch, label %for.r.header
+
+for.j.latch:
+  %j.next = add i64 %j, 1
+  %j.done = icmp eq i64 %j.next, 64
+  br i1 %j.done, label %for.k.header, label %for.j.header
+
+for.k.header:
+  %k = phi i64 [ 0, %for.j.latch ], [ %k.next, %for.k.latch ]
+  br label %for.l.header
+
+for.l.header:
+  %l = phi i64 [ 0, %for.k.header ], [ %l.next, %for.l.header ]
+  %b.element = getelementptr [64 x i8], ptr %B, i64 %l, i64 %k
+  store i8 0, ptr %b.element
+  %l.next = add i64 %l, 1
+  %l.done = icmp eq i64 %l.next, 64
+  br i1 %l.done, label %for.k.latch, label %for.l.header
+
+for.k.latch:
+  %k.next = add i64 %k, 1
+  %k.done = icmp eq i64 %k.next, 64
+  br i1 %k.done, label %for.i.latch, label %for.k.header
+
+for.i.latch:
+  %i.next = add i64 %i, 1
+  %i.done = icmp eq i64 %i.next, 64
+  br i1 %i.done, label %exit, label %for.i.header
+
+exit:
+  ret void
+}



More information about the llvm-commits mailing list