[llvm] [LoopInterchange] Add test for loop contains AnyOf reduction (NFC) (PR #202091)

via llvm-commits llvm-commits at lists.llvm.org
Sat Jun 6 16:07:57 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Ryotaro Kasuga (kasuga-fj)

<details>
<summary>Changes</summary>

This patch adds the test case raised in #<!-- -->202089. It also removes a duplicated test case in `reductions-non-wrapped-operations.ll`, which was wrong in the first place.

---
Full diff: https://github.com/llvm/llvm-project/pull/202091.diff


2 Files Affected:

- (added) llvm/test/Transforms/LoopInterchange/reduction-anyof.ll (+90) 
- (modified) llvm/test/Transforms/LoopInterchange/reductions-non-wrapped-operations.ll (-42) 


``````````diff
diff --git a/llvm/test/Transforms/LoopInterchange/reduction-anyof.ll b/llvm/test/Transforms/LoopInterchange/reduction-anyof.ll
new file mode 100644
index 0000000000000..9346e76db2a60
--- /dev/null
+++ b/llvm/test/Transforms/LoopInterchange/reduction-anyof.ll
@@ -0,0 +1,90 @@
+; 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
+
+; red = 0;
+; for (i = 0; i < 2; i++)
+;   for (j = 0; j < 2; j++)
+;     red = A[j][i] == 0 ? i + 1 : red;
+;
+; These loops must not be interchanged, because the reduction operation is not
+; associative. For example, consider `A` is as follows:
+;
+;   A = {{1, 0}, {0, 1}};
+;
+; In the original code, the final value of `red` is 2, but if the loops are
+; interchanged, the final value of `red` becomes 1.
+;
+; FIXME: The loops are now interchanged.
+;
+define i8 @reduce_anyof(ptr %A) {
+; CHECK-LABEL: define i8 @reduce_anyof(
+; CHECK-SAME: ptr [[A:%.*]]) {
+; CHECK-NEXT:  [[FOR_I_HEADER_PREHEADER:.*:]]
+; CHECK-NEXT:    br label %[[FOR_I_HEADER:.*]]
+; CHECK:       [[FOR_I_HEADER_PREHEADER1:.*]]:
+; CHECK-NEXT:    br label %[[FOR_I_HEADER1:.*]]
+; CHECK:       [[FOR_I_HEADER1]]:
+; CHECK-NEXT:    [[I:%.*]] = phi i64 [ [[I_INC:%.*]], %[[FOR_I_LATCH:.*]] ], [ 0, %[[FOR_I_HEADER_PREHEADER1]] ]
+; CHECK-NEXT:    [[RED:%.*]] = phi i8 [ [[SEL:%.*]], %[[FOR_I_LATCH]] ], [ [[RED_OUTER:%.*]], %[[FOR_I_HEADER_PREHEADER1]] ]
+; CHECK-NEXT:    [[ADD:%.*]] = add i64 [[I]], 1
+; CHECK-NEXT:    [[ADD8:%.*]] = trunc i64 [[ADD]] to i8
+; CHECK-NEXT:    br label %[[FOR_J_SPLIT1:.*]]
+; CHECK:       [[FOR_I_HEADER]]:
+; CHECK-NEXT:    br label %[[FOR_J:.*]]
+; CHECK:       [[FOR_J]]:
+; CHECK-NEXT:    [[J:%.*]] = phi i64 [ [[TMP2:%.*]], %[[FOR_J_SPLIT2:.*]] ], [ 0, %[[FOR_I_HEADER]] ]
+; CHECK-NEXT:    [[RED_OUTER]] = phi i8 [ [[RED_LCSSA:%.*]], %[[FOR_J_SPLIT2]] ], [ 0, %[[FOR_I_HEADER]] ]
+; CHECK-NEXT:    br label %[[FOR_I_HEADER_PREHEADER1]]
+; CHECK:       [[FOR_J_SPLIT1]]:
+; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x i8], ptr [[A]], i64 [[J]], i64 [[I]]
+; CHECK-NEXT:    [[LV:%.*]] = load i8, ptr [[ARRAYIDX]], align 4
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[LV]], 0
+; CHECK-NEXT:    [[SEL]] = select i1 [[CMP]], i8 [[ADD8]], i8 [[RED]]
+; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[J]], 1
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[TMP0]], 2
+; CHECK-NEXT:    br label %[[FOR_I_LATCH]]
+; CHECK:       [[FOR_J_SPLIT2]]:
+; CHECK-NEXT:    [[RED_LCSSA]] = phi i8 [ [[SEL]], %[[FOR_I_LATCH]] ]
+; CHECK-NEXT:    [[TMP2]] = add i64 [[J]], 1
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i64 [[TMP2]], 2
+; CHECK-NEXT:    br i1 [[TMP3]], label %[[FOR_J_SPLIT:.*]], label %[[FOR_J]]
+; CHECK:       [[FOR_I_LATCH]]:
+; CHECK-NEXT:    [[I_INC]] = add i64 [[I]], 1
+; CHECK-NEXT:    [[EC_I:%.*]] = icmp eq i64 [[I_INC]], 2
+; CHECK-NEXT:    br i1 [[EC_I]], label %[[FOR_J_SPLIT2]], label %[[FOR_I_HEADER1]]
+; CHECK:       [[FOR_J_SPLIT]]:
+; CHECK-NEXT:    [[RES:%.*]] = phi i8 [ [[RED_LCSSA]], %[[FOR_J_SPLIT2]] ]
+; CHECK-NEXT:    ret i8 [[RES]]
+;
+entry:
+  br label %for.i.header
+
+for.i.header:
+  %i = phi i64 [ 0, %entry ], [ %i.inc, %for.i.latch ]
+  %red.outer = phi i8 [ 0, %entry ], [ %red.lcssa, %for.i.latch ]
+  %add = add i64 %i, 1
+  %add8 = trunc i64 %add to i8
+  br label %for.j
+
+for.j:
+  %j = phi i64 [ 0, %for.i.header ], [ %j.inc, %for.j ]
+  %red = phi i8 [ %red.outer, %for.i.header ], [ %sel, %for.j ]
+  %arrayidx = getelementptr inbounds [2 x i8], ptr %A, i64 %j, i64 %i
+  %lv = load i8, ptr %arrayidx, align 4
+  %cmp = icmp eq i8 %lv, 0
+  %sel = select i1 %cmp, i8 %add8, i8 %red
+  %j.inc = add i64 %j, 1
+  %ec.j = icmp eq i64 %j.inc, 2
+  br i1 %ec.j, label %for.i.latch, label %for.j
+
+for.i.latch:
+  %red.lcssa = phi i8 [ %sel, %for.j ]
+  %i.inc = add i64 %i, 1
+  %ec.i = icmp eq i64 %i.inc, 2
+  br i1 %ec.i, label %exit, label %for.i.header
+
+exit:
+  %res = phi i8 [ %red.lcssa, %for.i.latch ]
+  ret i8 %res
+}
+
diff --git a/llvm/test/Transforms/LoopInterchange/reductions-non-wrapped-operations.ll b/llvm/test/Transforms/LoopInterchange/reductions-non-wrapped-operations.ll
index f5c6ad7889366..0d523d3edd113 100644
--- a/llvm/test/Transforms/LoopInterchange/reductions-non-wrapped-operations.ll
+++ b/llvm/test/Transforms/LoopInterchange/reductions-non-wrapped-operations.ll
@@ -291,45 +291,3 @@ for.i.latch:
 exit:
   ret void
 }
-
-
-; Check that interchanging the loops is legal for the any-of reduction.
-;
-; int any_of = 0;
-; for (int i = 0; i < 2; i++)
-;   for (int j = 0; j < 2; j++)
-;     any_of = (A[j][i] == 42) ? 1 : any_of;
-
-; CHECK:      --- !Pass
-; CHECK-NEXT: Pass:            loop-interchange
-; CHECK-NEXT: Name:            Interchanged
-; CHECK-NEXT: Function:        reduction_anyof
-define void @reduction_anyof(ptr %A) {
-entry:
-  br label %for.i.header
-
-for.i.header:
-  %i = phi i32 [ 0, %entry ], [ %i.inc, %for.i.latch ]
-  %anyof.i = phi i32 [ 0, %entry ], [ %anyof.i.lcssa, %for.i.latch ]
-  br label %for.j
-
-for.j:
-  %j = phi i32 [ 0, %for.i.header ], [ %j.inc, %for.j ]
-  %anyof.j = phi i32 [ %anyof.i, %for.i.header ], [ %anyof.j.next, %for.j ]
-  %idx = getelementptr inbounds [2 x [2 x i32]], ptr %A, i32 0, i32 %j, i32 %i
-  %a = load i32, ptr %idx, align 4
-  %cmp = icmp eq i32 %a, 42
-  %anyof.j.next = select i1 %cmp, i32 1, i32 %anyof.j
-  %j.inc = add i32 %j, 1
-  %cmp.j = icmp slt i32 %j.inc, 2
-  br i1 %cmp.j, label %for.j, label %for.i.latch
-
-for.i.latch:
-  %anyof.i.lcssa = phi i32 [ %anyof.j.next, %for.j ]
-  %i.inc = add i32 %i, 1
-  %cmp.i = icmp slt i32 %i.inc, 2
-  br i1 %cmp.i, label %for.i.header, label %exit
-
-exit:
-  ret void
-}

``````````

</details>


https://github.com/llvm/llvm-project/pull/202091


More information about the llvm-commits mailing list