Ryotaro Kasuga e5a40fef50
[LoopInterchange] Update tests for reduction2mem (NFC) (#181629)
The current ongoing work on DependenceAnalysis will degrade its analysis
capability. As a result, some existing tests will start to fail, meaning
that those tests are no longer meaningful. To preserve their original
intent, they need to be updated so that DependenceAnalysis can still
analyze them accurately.
This patch updates the test cases for the reduction2mem feature in
LoopInterchange. Specifically, it replaces the loop bounds with constant
values, which should not alter the intent of the tests.
2026-02-24 11:31:13 +00:00

91 lines
4.8 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; NOTE: Support the reduction in the inner loop.
; RUN: opt < %s -passes="loop-interchange" -loop-interchange-reduction-to-mem -loop-interchange-profitabilities=ignore -S | FileCheck %s
; for (int i = 0; i < 100; i++) {
; r = 0;
; for (int j = 0; j < 100; j++)
; r = r + a[j][i] * b[j][i];
; s[i] = r;
; }
define void @func(ptr noalias readonly %a, ptr noalias readonly %b, ptr noalias writeonly %s) {
; CHECK-LABEL: define void @func(
; CHECK-SAME: ptr noalias readonly [[A:%.*]], ptr noalias readonly [[B:%.*]], ptr noalias writeonly [[S:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: br label %[[INNERLOOP_PREHEADER:.*]]
; CHECK: [[OUTERLOOPHEADER_PREHEADER:.*]]:
; CHECK-NEXT: br label %[[OUTERLOOP_HEADER:.*]]
; CHECK: [[OUTERLOOP_HEADER]]:
; CHECK-NEXT: [[INDEX_I:%.*]] = phi i64 [ [[I_NEXT:%.*]], %[[OUTERLOOP_LATCH:.*]] ], [ 0, %[[OUTERLOOPHEADER_PREHEADER]] ]
; CHECK-NEXT: [[ADDR_S:%.*]] = getelementptr inbounds nuw double, ptr [[S]], i64 [[INDEX_I]]
; CHECK-NEXT: [[ADDR_A:%.*]] = getelementptr inbounds nuw double, ptr [[A]], i64 [[INDEX_I]]
; CHECK-NEXT: [[ADDR_B:%.*]] = getelementptr inbounds nuw double, ptr [[B]], i64 [[INDEX_I]]
; CHECK-NEXT: br label %[[INNERLOOP_SPLIT1:.*]]
; CHECK: [[INNERLOOP_PREHEADER]]:
; CHECK-NEXT: br label %[[INNERLOOP:.*]]
; CHECK: [[INNERLOOP]]:
; CHECK-NEXT: [[INDEX_J:%.*]] = phi i64 [ [[J_NEXT:%.*]], %[[INNERLOOP_SPLIT:.*]] ], [ 0, %[[INNERLOOP_PREHEADER]] ]
; CHECK-NEXT: [[REDUCTION:%.*]] = phi double [ [[ADD_LCSSA:%.*]], %[[INNERLOOP_SPLIT]] ], [ 0.000000e+00, %[[INNERLOOP_PREHEADER]] ]
; CHECK-NEXT: [[FIRSTITER:%.*]] = phi i1 [ false, %[[INNERLOOP_SPLIT]] ], [ true, %[[INNERLOOP_PREHEADER]] ]
; CHECK-NEXT: br label %[[OUTERLOOPHEADER_PREHEADER]]
; CHECK: [[INNERLOOP_SPLIT1]]:
; CHECK-NEXT: [[TMP0:%.*]] = load double, ptr [[ADDR_S]], align 8
; CHECK-NEXT: [[NEW_VAR:%.*]] = select i1 [[FIRSTITER]], double 0.000000e+00, double [[TMP0]]
; CHECK-NEXT: [[ADDR_A_J_I:%.*]] = getelementptr inbounds nuw [100 x double], ptr [[ADDR_A]], i64 [[INDEX_J]]
; CHECK-NEXT: [[A_J_I:%.*]] = load double, ptr [[ADDR_A_J_I]], align 8
; CHECK-NEXT: [[ADDR_B_J_I:%.*]] = getelementptr inbounds nuw [100 x double], ptr [[ADDR_B]], i64 [[INDEX_J]]
; CHECK-NEXT: [[B_J_I:%.*]] = load double, ptr [[ADDR_B_J_I]], align 8
; CHECK-NEXT: [[MUL:%.*]] = fmul fast double [[B_J_I]], [[A_J_I]]
; CHECK-NEXT: [[ADD:%.*]] = fadd fast double [[MUL]], [[NEW_VAR]]
; CHECK-NEXT: store double [[ADD]], ptr [[ADDR_S]], align 8
; CHECK-NEXT: [[DEAD_J_NEXT:%.*]] = add nuw nsw i64 [[INDEX_J]], 1
; CHECK-NEXT: [[COND1:%.*]] = icmp eq i64 [[DEAD_J_NEXT]], 100
; CHECK-NEXT: br label %[[OUTERLOOP_LATCH]]
; CHECK: [[INNERLOOP_SPLIT]]:
; CHECK-NEXT: [[ADD_LCSSA]] = phi double [ [[ADD]], %[[OUTERLOOP_LATCH]] ]
; CHECK-NEXT: [[LCSSA:%.*]] = phi double [ [[ADD]], %[[OUTERLOOP_LATCH]] ]
; CHECK-NEXT: [[J_NEXT]] = add nuw nsw i64 [[INDEX_J]], 1
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i64 [[J_NEXT]], 100
; CHECK-NEXT: br i1 [[CMP1]], label %[[EXIT_LOOPEXIT:.*]], label %[[INNERLOOP]]
; CHECK: [[OUTERLOOP_LATCH]]:
; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i64 [[INDEX_I]], 1
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i64 [[I_NEXT]], 100
; CHECK-NEXT: br i1 [[CMP2]], label %[[INNERLOOP_SPLIT]], label %[[OUTERLOOP_HEADER]]
; CHECK: [[EXIT_LOOPEXIT]]:
; CHECK-NEXT: ret void
;
entry:
br label %outerloop_header
outerloop_header:
%index_i = phi i64 [ 0, %entry ], [ %index_i.next, %outerloop_latch ]
%addr_s = getelementptr inbounds nuw double, ptr %s, i64 %index_i
%invariant.gep.us = getelementptr inbounds nuw double, ptr %a, i64 %index_i
%invariant.gep32.us = getelementptr inbounds nuw double, ptr %b, i64 %index_i
br label %innerloop
innerloop:
%index_j = phi i64 [ 0, %outerloop_header ], [ %index_j.next, %innerloop ]
%reduction = phi double [ 0.000000e+00, %outerloop_header ], [ %add, %innerloop ]
%addr_a_j_i = getelementptr inbounds nuw [100 x double], ptr %invariant.gep.us, i64 %index_j
%0 = load double, ptr %addr_a_j_i, align 8
%addr_b_j_i = getelementptr inbounds nuw [100 x double], ptr %invariant.gep32.us, i64 %index_j
%1 = load double, ptr %addr_b_j_i, align 8
%mul = fmul fast double %1, %0
%add = fadd fast double %mul, %reduction
%index_j.next = add nuw nsw i64 %index_j, 1
%cond1 = icmp eq i64 %index_j.next, 100
br i1 %cond1, label %outerloop_latch, label %innerloop
outerloop_latch:
%lcssa = phi double [ %add, %innerloop ]
store double %lcssa, ptr %addr_s, align 8
%index_i.next = add nuw nsw i64 %index_i, 1
%cond2 = icmp eq i64 %index_i.next, 100
br i1 %cond2, label %exit, label %outerloop_header
exit:
ret void
}