[llvm-branch-commits] [llvm] [LoopInterchange] Add a test for simple profitable case (NFC) (PR #181990)

Ryotaro Kasuga via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Feb 18 03:12:23 PST 2026


https://github.com/kasuga-fj updated https://github.com/llvm/llvm-project/pull/181990

>From 9d7ca79c275f7abb77c6e295f104d36b3de763d2 Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <kasuga.ryotaro at fujitsu.com>
Date: Tue, 17 Feb 2026 09:27:42 +0000
Subject: [PATCH] [LoopInterchange] Add a test for simple profitable case (NFC)

---
 .../profitability-instorder.ll                | 180 ++++++++++++++++++
 1 file changed, 180 insertions(+)
 create mode 100644 llvm/test/Transforms/LoopInterchange/profitability-instorder.ll

diff --git a/llvm/test/Transforms/LoopInterchange/profitability-instorder.ll b/llvm/test/Transforms/LoopInterchange/profitability-instorder.ll
new file mode 100644
index 0000000000000..97f8f90f1159f
--- /dev/null
+++ b/llvm/test/Transforms/LoopInterchange/profitability-instorder.ll
@@ -0,0 +1,180 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=loop-interchange -loop-interchange-profitabilities=instorder -S | FileCheck %s
+
+; for (i = 0; i < 10; i++)
+;   for (j = 0; j < 10; j++)
+;     A[i + 100*j] = 0;
+;
+; The above loop should be interchanged in terms of locality of reference.
+;
+define void @profitable(ptr %A) {
+; CHECK-LABEL: define void @profitable(
+; CHECK-SAME: ptr [[A:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[LOOP_I_HEADER:.*]]
+; CHECK:       [[LOOP_I_HEADER]]:
+; CHECK-NEXT:    [[I:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[I_INC:%.*]], %[[LOOP_I_LATCH:.*]] ]
+; CHECK-NEXT:    br label %[[LOOP_J:.*]]
+; CHECK:       [[LOOP_J]]:
+; CHECK-NEXT:    [[J:%.*]] = phi i64 [ 0, %[[LOOP_I_HEADER]] ], [ [[J_INC:%.*]], %[[LOOP_J]] ]
+; CHECK-NEXT:    [[MUL:%.*]] = mul i64 [[J]], 100
+; CHECK-NEXT:    [[OFFSET:%.*]] = add i64 [[I]], [[MUL]]
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[OFFSET]]
+; CHECK-NEXT:    store i8 0, ptr [[GEP]], align 1
+; CHECK-NEXT:    [[J_INC]] = add i64 [[J]], 1
+; CHECK-NEXT:    [[EC_J:%.*]] = icmp eq i64 [[J_INC]], 10
+; CHECK-NEXT:    br i1 [[EC_J]], label %[[LOOP_I_LATCH]], label %[[LOOP_J]]
+; CHECK:       [[LOOP_I_LATCH]]:
+; CHECK-NEXT:    [[I_INC]] = add i64 [[I]], 1
+; CHECK-NEXT:    [[EC_I:%.*]] = icmp eq i64 [[I_INC]], 10
+; CHECK-NEXT:    br i1 [[EC_I]], label %[[EXIT:.*]], label %[[LOOP_I_HEADER]]
+; CHECK:       [[EXIT]]:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %loop.i.header
+
+loop.i.header:
+  %i = phi i64 [ 0, %entry ], [ %i.inc, %loop.i.latch ]
+  br label %loop.j
+
+loop.j:
+  %j = phi i64 [ 0, %loop.i.header ], [ %j.inc, %loop.j ]
+  %mul = mul i64 %j, 100
+  %offset = add i64 %i, %mul
+  %gep = getelementptr inbounds i8, ptr %A, i64 %offset
+  store i8 0, ptr %gep
+  %j.inc = add i64 %j, 1
+  %ec.j = icmp eq i64 %j.inc, 10
+  br i1 %ec.j, label %loop.i.latch, label %loop.j
+
+loop.i.latch:
+  %i.inc = add i64 %i, 1
+  %ec.i = icmp eq i64 %i.inc, 10
+  br i1 %ec.i, label %exit, label %loop.i.header
+
+exit:
+  ret void
+}
+
+; for (i = 0; i < 10; i++)
+;   for (j = 0; j < 10; j++)
+;     A[i + 100*(9-j)] = 0;
+;
+; The above loop should be interchanged in terms of locality of reference.
+;
+define void @profitable_neg_step(ptr %A) {
+; CHECK-LABEL: define void @profitable_neg_step(
+; CHECK-SAME: ptr [[A:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[LOOP_I_HEADER:.*]]
+; CHECK:       [[LOOP_I_HEADER]]:
+; CHECK-NEXT:    [[I:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[I_INC:%.*]], %[[LOOP_I_LATCH:.*]] ]
+; CHECK-NEXT:    br label %[[LOOP_J:.*]]
+; CHECK:       [[LOOP_J]]:
+; CHECK-NEXT:    [[J:%.*]] = phi i64 [ 0, %[[LOOP_I_HEADER]] ], [ [[J_INC:%.*]], %[[LOOP_J]] ]
+; CHECK-NEXT:    [[J_REV:%.*]] = sub i64 9, [[J]]
+; CHECK-NEXT:    [[MUL:%.*]] = mul i64 [[J_REV]], 100
+; CHECK-NEXT:    [[OFFSET:%.*]] = add i64 [[I]], [[MUL]]
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[OFFSET]]
+; CHECK-NEXT:    store i8 0, ptr [[GEP]], align 1
+; CHECK-NEXT:    [[J_INC]] = add i64 [[J]], 1
+; CHECK-NEXT:    [[EC_J:%.*]] = icmp eq i64 [[J_INC]], 10
+; CHECK-NEXT:    br i1 [[EC_J]], label %[[LOOP_I_LATCH]], label %[[LOOP_J]]
+; CHECK:       [[LOOP_I_LATCH]]:
+; CHECK-NEXT:    [[I_INC]] = add i64 [[I]], 1
+; CHECK-NEXT:    [[EC_I:%.*]] = icmp eq i64 [[I_INC]], 10
+; CHECK-NEXT:    br i1 [[EC_I]], label %[[EXIT:.*]], label %[[LOOP_I_HEADER]]
+; CHECK:       [[EXIT]]:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %loop.i.header
+
+loop.i.header:
+  %i = phi i64 [ 0, %entry ], [ %i.inc, %loop.i.latch ]
+  br label %loop.j
+
+loop.j:
+  %j = phi i64 [ 0, %loop.i.header ], [ %j.inc, %loop.j ]
+  %j.rev = sub i64 9, %j
+  %mul = mul i64 %j.rev, 100
+  %offset = add i64 %i, %mul
+  %gep = getelementptr inbounds i8, ptr %A, i64 %offset
+  store i8 0, ptr %gep
+  %j.inc = add i64 %j, 1
+  %ec.j = icmp eq i64 %j.inc, 10
+  br i1 %ec.j, label %loop.i.latch, label %loop.j
+
+loop.i.latch:
+  %i.inc = add i64 %i, 1
+  %ec.i = icmp eq i64 %i.inc, 10
+  br i1 %ec.i, label %exit, label %loop.i.header
+
+exit:
+  ret void
+}
+
+; for (i = 0; i < 10; i++)
+;   for (j = 0; j < 10; j++)
+;     A[100*i + j] = 0;
+;
+; The above loop should NOT be interchanged in terms of locality of reference.
+;
+define void @unprofitable(ptr %A) {
+; CHECK-LABEL: define void @unprofitable(
+; CHECK-SAME: ptr [[A:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    br label %[[LOOP_J_PREHEADER:.*]]
+; CHECK:       [[LOOP_I_HEADER_PREHEADER:.*]]:
+; CHECK-NEXT:    br label %[[LOOP_I_HEADER:.*]]
+; CHECK:       [[LOOP_I_HEADER]]:
+; CHECK-NEXT:    [[I:%.*]] = phi i64 [ [[I_INC:%.*]], %[[LOOP_I_LATCH:.*]] ], [ 0, %[[LOOP_I_HEADER_PREHEADER]] ]
+; CHECK-NEXT:    [[MUL:%.*]] = mul i64 [[I]], 100
+; CHECK-NEXT:    br label %[[LOOP_J_SPLIT1:.*]]
+; CHECK:       [[LOOP_J_PREHEADER]]:
+; CHECK-NEXT:    br label %[[LOOP_J:.*]]
+; CHECK:       [[LOOP_J]]:
+; CHECK-NEXT:    [[J:%.*]] = phi i64 [ [[TMP0:%.*]], %[[LOOP_J_SPLIT:.*]] ], [ 0, %[[LOOP_J_PREHEADER]] ]
+; CHECK-NEXT:    br label %[[LOOP_I_HEADER_PREHEADER]]
+; CHECK:       [[LOOP_J_SPLIT1]]:
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [1 x i8], ptr [[A]], i64 [[J]], i64 [[MUL]]
+; CHECK-NEXT:    store i8 0, ptr [[GEP]], align 1
+; CHECK-NEXT:    [[J_INC:%.*]] = add i64 [[J]], 1
+; CHECK-NEXT:    [[EC_J:%.*]] = icmp eq i64 [[J_INC]], 10
+; CHECK-NEXT:    br label %[[LOOP_I_LATCH]]
+; CHECK:       [[LOOP_J_SPLIT]]:
+; CHECK-NEXT:    [[TMP0]] = add i64 [[J]], 1
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[TMP0]], 10
+; CHECK-NEXT:    br i1 [[TMP1]], label %[[EXIT:.*]], label %[[LOOP_J]]
+; CHECK:       [[LOOP_I_LATCH]]:
+; CHECK-NEXT:    [[I_INC]] = add i64 [[I]], 1
+; CHECK-NEXT:    [[EC_I:%.*]] = icmp eq i64 [[I_INC]], 10
+; CHECK-NEXT:    br i1 [[EC_I]], label %[[LOOP_J_SPLIT]], label %[[LOOP_I_HEADER]]
+; CHECK:       [[EXIT]]:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %loop.i.header
+
+loop.i.header:
+  %i = phi i64 [ 0, %entry ], [ %i.inc, %loop.i.latch ]
+  %mul = mul i64 %i, 100
+  br label %loop.j
+
+loop.j:
+  %j = phi i64 [ 0, %loop.i.header ], [ %j.inc, %loop.j ]
+  %gep = getelementptr inbounds [1 x i8], ptr %A, i64 %j, i64 %mul
+  store i8 0, ptr %gep
+  %j.inc = add i64 %j, 1
+  %ec.j = icmp eq i64 %j.inc, 10
+  br i1 %ec.j, label %loop.i.latch, label %loop.j
+
+loop.i.latch:
+  %i.inc = add i64 %i, 1
+  %ec.i = icmp eq i64 %i.inc, 10
+  br i1 %ec.i, label %exit, label %loop.i.header
+
+exit:
+  ret void
+}



More information about the llvm-branch-commits mailing list