Skip to content

Commit 3ab0e49

Browse files
committed
[LoopInterchange] Bail out for Scalar Dependencies
This makes loop-interchange more pessimistic, but also more correct as we are not handling 'S' scalar dependencies correctly and have at least the following miscompiles related to that: [LoopInterchange] incorrect handling of scalar dependencies and dependence vectors starting with ">" #54176 [LoopInterchange] Interchange breaks program correctness #46867 [LoopInterchange] Loops should not interchanged due to dependencies #47259 [LoopInterchange] Loops should not interchanged due to control flow #47401 This should be a stopgap. We would like to get interchange enabled by default and thus prefer correctness over unsafe transforms, and later lift this restriction.
1 parent 408659c commit 3ab0e49

9 files changed

+98
-134
lines changed

llvm/lib/Transforms/Scalar/LoopInterchange.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,11 +187,19 @@ static void interChangeDependencies(CharMatrix &DepMatrix, unsigned FromIndx,
187187
// if the direction matrix, after the same permutation is applied to its
188188
// columns, has no ">" direction as the leftmost non-"=" direction in any row.
189189
static bool isLexicographicallyPositive(std::vector<char> &DV) {
190+
bool HasScalar = false;
191+
bool FirstPosScalar = true;
190192
for (unsigned char Direction : DV) {
193+
// FIXME: we reject scalar dependencies because we currently don't
194+
// handle them correctly. This makes the legality check more conservative
195+
// than needed, but is a stopgap to avoid miscompiles.
196+
if (Direction == 'S' && !FirstPosScalar)
197+
return false;
191198
if (Direction == '<')
192199
return true;
193200
if (Direction == '>' || Direction == '*')
194201
return false;
202+
FirstPosScalar = false;
195203
}
196204
return true;
197205
}

llvm/test/Transforms/LoopInterchange/gh54176-scalar-deps.ll

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,13 @@
2929
define dso_local i32 @test1(i1 %cond) {
3030
; CHECK-LABEL: define dso_local i32 @test1(
3131
; CHECK-SAME: i1 [[COND:%.*]]) {
32-
; CHECK-NEXT: [[FOR_PREHEADER:.*:]]
33-
; CHECK-NEXT: br label %[[INNERLOOP_PREHEADER:.*]]
34-
; CHECK: [[OUTERLOOP_PREHEADER:.*]]:
32+
; CHECK-NEXT: [[FOR_PREHEADER:.*]]:
3533
; CHECK-NEXT: br label %[[OUTERLOOP:.*]]
3634
; CHECK: [[OUTERLOOP]]:
37-
; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[INDVARS_IV_NEXT21_I:%.*]], %[[FOR_LATCH:.*]] ], [ 0, %[[OUTERLOOP_PREHEADER]] ]
38-
; CHECK-NEXT: br label %[[INNERLOOP_SPLIT:.*]]
39-
; CHECK: [[INNERLOOP_PREHEADER]]:
35+
; CHECK-NEXT: [[I:%.*]] = phi i64 [ 0, %[[FOR_PREHEADER]] ], [ [[INDVARS_IV_NEXT21_I:%.*]], %[[FOR_LATCH:.*]] ]
4036
; CHECK-NEXT: br label %[[INNERLOOP:.*]]
4137
; CHECK: [[INNERLOOP]]:
42-
; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[TMP0:%.*]], %[[IF_END_SPLIT:.*]] ], [ 0, %[[INNERLOOP_PREHEADER]] ]
43-
; CHECK-NEXT: br label %[[OUTERLOOP_PREHEADER]]
44-
; CHECK: [[INNERLOOP_SPLIT]]:
38+
; CHECK-NEXT: [[J:%.*]] = phi i64 [ 0, %[[OUTERLOOP]] ], [ [[TMP0:%.*]], %[[IF_END:.*]] ]
4539
; CHECK-NEXT: [[ARRAYIDX6_I:%.*]] = getelementptr inbounds [4 x [9 x i32]], ptr @f, i64 0, i64 [[J]], i64 [[I]]
4640
; CHECK-NEXT: [[I1:%.*]] = load i32, ptr [[ARRAYIDX6_I]], align 4
4741
; CHECK-NEXT: [[TOBOOL_I:%.*]] = icmp eq i32 [[I1]], 0
@@ -50,24 +44,20 @@ define dso_local i32 @test1(i1 %cond) {
5044
; CHECK-NEXT: store i32 3, ptr @g, align 4
5145
; CHECK-NEXT: br label %[[LAND_END]]
5246
; CHECK: [[LAND_END]]:
53-
; CHECK-NEXT: br i1 [[COND]], label %[[IF_END:.*]], label %[[IF_THEN:.*]]
47+
; CHECK-NEXT: br i1 [[COND]], label %[[IF_END]], label %[[IF_THEN:.*]]
5448
; CHECK: [[IF_THEN]]:
5549
; CHECK-NEXT: [[I2:%.*]] = load i32, ptr @g, align 4
5650
; CHECK-NEXT: [[INC_I:%.*]] = add i32 [[I2]], 1
5751
; CHECK-NEXT: store i32 [[INC_I]], ptr @g, align 4
5852
; CHECK-NEXT: br label %[[IF_END]]
5953
; CHECK: [[IF_END]]:
60-
; CHECK-NEXT: [[J_NEXT:%.*]] = add nuw nsw i64 [[J]], 1
61-
; CHECK-NEXT: [[EXITCOND_I:%.*]] = icmp eq i64 [[J_NEXT]], 3
62-
; CHECK-NEXT: br label %[[FOR_LATCH]]
63-
; CHECK: [[IF_END_SPLIT]]:
6454
; CHECK-NEXT: [[TMP0]] = add nuw nsw i64 [[J]], 1
6555
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[TMP0]], 3
66-
; CHECK-NEXT: br i1 [[TMP1]], label %[[EXIT:.*]], label %[[INNERLOOP]]
56+
; CHECK-NEXT: br i1 [[TMP1]], label %[[FOR_LATCH]], label %[[INNERLOOP]]
6757
; CHECK: [[FOR_LATCH]]:
6858
; CHECK-NEXT: [[INDVARS_IV_NEXT21_I]] = add nsw i64 [[I]], 1
6959
; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i64 [[I]], 2
70-
; CHECK-NEXT: br i1 [[CMP_I]], label %[[OUTERLOOP]], label %[[IF_END_SPLIT]]
60+
; CHECK-NEXT: br i1 [[CMP_I]], label %[[OUTERLOOP]], label %[[EXIT:.*]]
7161
; CHECK: [[EXIT]]:
7262
; CHECK-NEXT: [[I3:%.*]] = load i32, ptr @g, align 4
7363
; CHECK-NEXT: ret i32 [[I3]]
@@ -139,19 +129,13 @@ exit:
139129
define dso_local i32 @test2(i1 %cond) {
140130
; CHECK-LABEL: define dso_local i32 @test2(
141131
; CHECK-SAME: i1 [[COND:%.*]]) {
142-
; CHECK-NEXT: [[FOR_PREHEADER:.*:]]
143-
; CHECK-NEXT: br label %[[INNERLOOP_PREHEADER:.*]]
144-
; CHECK: [[OUTERLOOP_PREHEADER:.*]]:
132+
; CHECK-NEXT: [[FOR_PREHEADER:.*]]:
145133
; CHECK-NEXT: br label %[[OUTERLOOP:.*]]
146134
; CHECK: [[OUTERLOOP]]:
147-
; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[INDVARS_IV_NEXT21_I:%.*]], %[[FOR_LATCH:.*]] ], [ 0, %[[OUTERLOOP_PREHEADER]] ]
148-
; CHECK-NEXT: br label %[[INNERLOOP_SPLIT:.*]]
149-
; CHECK: [[INNERLOOP_PREHEADER]]:
135+
; CHECK-NEXT: [[I:%.*]] = phi i64 [ 0, %[[FOR_PREHEADER]] ], [ [[INDVARS_IV_NEXT21_I:%.*]], %[[FOR_LATCH:.*]] ]
150136
; CHECK-NEXT: br label %[[INNERLOOP:.*]]
151137
; CHECK: [[INNERLOOP]]:
152-
; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[TMP0:%.*]], %[[IF_END_SPLIT:.*]] ], [ 0, %[[INNERLOOP_PREHEADER]] ]
153-
; CHECK-NEXT: br label %[[OUTERLOOP_PREHEADER]]
154-
; CHECK: [[INNERLOOP_SPLIT]]:
138+
; CHECK-NEXT: [[J:%.*]] = phi i64 [ 0, %[[OUTERLOOP]] ], [ [[TMP0:%.*]], %[[IF_END:.*]] ]
155139
; CHECK-NEXT: [[ARRAYIDX6_I:%.*]] = getelementptr inbounds [4 x [9 x i32]], ptr @f, i64 0, i64 [[J]], i64 [[I]]
156140
; CHECK-NEXT: [[I1:%.*]] = load i32, ptr [[ARRAYIDX6_I]], align 4
157141
; CHECK-NEXT: [[TOBOOL_I:%.*]] = icmp eq i32 [[I1]], 0
@@ -160,24 +144,20 @@ define dso_local i32 @test2(i1 %cond) {
160144
; CHECK: [[LAND_RHS]]:
161145
; CHECK-NEXT: br label %[[LAND_END]]
162146
; CHECK: [[LAND_END]]:
163-
; CHECK-NEXT: br i1 [[COND]], label %[[IF_END:.*]], label %[[IF_THEN:.*]]
147+
; CHECK-NEXT: br i1 [[COND]], label %[[IF_END]], label %[[IF_THEN:.*]]
164148
; CHECK: [[IF_THEN]]:
165149
; CHECK-NEXT: [[I2:%.*]] = load i32, ptr @g, align 4
166150
; CHECK-NEXT: [[INC_I:%.*]] = add i32 [[I2]], 1
167151
; CHECK-NEXT: store i32 [[INC_I]], ptr @g, align 4
168152
; CHECK-NEXT: br label %[[IF_END]]
169153
; CHECK: [[IF_END]]:
170-
; CHECK-NEXT: [[J_NEXT:%.*]] = add nuw nsw i64 [[J]], 1
171-
; CHECK-NEXT: [[EXITCOND_I:%.*]] = icmp eq i64 [[J_NEXT]], 3
172-
; CHECK-NEXT: br label %[[FOR_LATCH]]
173-
; CHECK: [[IF_END_SPLIT]]:
174154
; CHECK-NEXT: [[TMP0]] = add nuw nsw i64 [[J]], 1
175155
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[TMP0]], 3
176-
; CHECK-NEXT: br i1 [[TMP1]], label %[[EXIT:.*]], label %[[INNERLOOP]]
156+
; CHECK-NEXT: br i1 [[TMP1]], label %[[FOR_LATCH]], label %[[INNERLOOP]]
177157
; CHECK: [[FOR_LATCH]]:
178158
; CHECK-NEXT: [[INDVARS_IV_NEXT21_I]] = add nsw i64 [[I]], 1
179159
; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i64 [[I]], 2
180-
; CHECK-NEXT: br i1 [[CMP_I]], label %[[OUTERLOOP]], label %[[IF_END_SPLIT]]
160+
; CHECK-NEXT: br i1 [[CMP_I]], label %[[OUTERLOOP]], label %[[EXIT:.*]]
181161
; CHECK: [[EXIT]]:
182162
; CHECK-NEXT: [[I3:%.*]] = load i32, ptr @g, align 4
183163
; CHECK-NEXT: ret i32 [[I3]]

llvm/test/Transforms/LoopInterchange/inner-only-reductions.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
; CHECK: --- !Missed
2020
; CHECK-NEXT: Pass: loop-interchange
21-
; CHECK-NEXT: Name: UnsupportedPHI
21+
; CHECK-NEXT: Name: Dependence
2222
; CHECK-NEXT: Function: reduction_01
2323

2424
; IR-LABEL: @reduction_01(
@@ -71,7 +71,7 @@ for.end8: ; preds = %for.cond1.for.inc6_
7171

7272
; CHECK: --- !Missed
7373
; CHECK-NEXT: Pass: loop-interchange
74-
; CHECK-NEXT: Name: UnsupportedPHIOuter
74+
; CHECK-NEXT: Name: UnsupportedPHIOuter
7575
; CHECK-NEXT: Function: reduction_03
7676

7777
; IR-LABEL: @reduction_03(

llvm/test/Transforms/LoopInterchange/innermost-latch-uses-values-in-middle-header.ll

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,20 @@ define void @innermost_latch_uses_values_in_middle_header() {
2828
; CHECK: [[INNERMOST_HEADER_PREHEADER]]:
2929
; CHECK-NEXT: br label %[[INNERMOST_HEADER:.*]]
3030
; CHECK: [[INNERMOST_HEADER]]:
31-
; CHECK-NEXT: [[INDVAR_INNERMOST:%.*]] = phi i64 [ [[TMP1:%.*]], %[[INNERMOST_LATCH_SPLIT:.*]] ], [ 4, %[[INNERMOST_HEADER_PREHEADER]] ]
31+
; CHECK-NEXT: [[INDVAR_INNERMOST:%.*]] = phi i64 [ [[TMP3:%.*]], %[[INNERMOST_LATCH_SPLIT:.*]] ], [ 4, %[[INNERMOST_HEADER_PREHEADER]] ]
3232
; CHECK-NEXT: br label %[[MIDDLE_HEADER_PREHEADER]]
3333
; CHECK: [[INNERMOST_BODY]]:
3434
; CHECK-NEXT: [[ARRAYIDX9_I:%.*]] = getelementptr inbounds [1 x [6 x i32]], ptr @d, i64 0, i64 [[INDVAR_INNERMOST]], i64 [[INDVAR_MIDDLE]]
3535
; CHECK-NEXT: store i32 0, ptr [[ARRAYIDX9_I]], align 4
3636
; CHECK-NEXT: br label %[[INNERMOST_LATCH:.*]]
3737
; CHECK: [[INNERMOST_LATCH]]:
38-
; CHECK-NEXT: [[INDVAR_INNERMOST_NEXT:%.*]] = add nsw i64 [[INDVAR_INNERMOST]], 1
39-
; CHECK-NEXT: [[TOBOOL5_I:%.*]] = icmp eq i64 [[INDVAR_INNERMOST_NEXT]], [[INDVAR_MIDDLE_WIDE]]
38+
; CHECK-NEXT: [[TMP1:%.*]] = add nsw i64 [[INDVAR_INNERMOST]], 1
39+
; CHECK-NEXT: [[TOBOOL5_I:%.*]] = icmp eq i64 [[TMP1]], [[INDVAR_MIDDLE_WIDE]]
4040
; CHECK-NEXT: br label %[[MIDDLE_LATCH]]
4141
; CHECK: [[INNERMOST_LATCH_SPLIT]]:
4242
; CHECK-NEXT: [[INDVAR_MIDDLE_WIDE_LCSSA:%.*]] = phi i64 [ [[INDVAR_MIDDLE_WIDE]], %[[MIDDLE_LATCH]] ]
43-
; CHECK-NEXT: [[TMP1]] = add nsw i64 [[INDVAR_INNERMOST]], 1
44-
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], [[INDVAR_MIDDLE_WIDE_LCSSA]]
43+
; CHECK-NEXT: [[TMP3]] = add nsw i64 [[INDVAR_INNERMOST]], 1
44+
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP3]], [[INDVAR_MIDDLE_WIDE_LCSSA]]
4545
; CHECK-NEXT: br i1 [[TMP2]], label %[[OUTERMOST_LATCH_LOOPEXIT:.*]], label %[[INNERMOST_HEADER]]
4646
; CHECK: [[MIDDLE_LATCH]]:
4747
; CHECK-NEXT: [[INDVAR_MIDDLE_NEXT]] = add nsw i64 [[INDVAR_MIDDLE]], -1

llvm/test/Transforms/LoopInterchange/lcssa.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ for.end16: ; preds = %for.exit
177177
}
178178

179179
; PHI node in inner latch with multiple predecessors.
180-
; REMARK: Interchanged
180+
; REMARK: Dependence
181181
; REMARK-NEXT: lcssa_05
182182

183183
define void @lcssa_05(ptr %ptr) {
@@ -222,7 +222,7 @@ for.end16: ; preds = %for.exit
222222
ret void
223223
}
224224

225-
; REMARK: UnsupportedExitPHI
225+
; REMARK: Dependence
226226
; REMARK-NEXT: lcssa_06
227227

228228
define void @lcssa_06(ptr %ptr, ptr %ptr1) {

llvm/test/Transforms/LoopInterchange/outer-header-jump-to-inner-latch.ll

Lines changed: 59 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
12
; RUN: opt -passes=loop-interchange -cache-line-size=64 -verify-dom-info -verify-loop-info -verify-loop-lcssa -S %s | FileCheck %s
23

34
@b = global [3 x [5 x [8 x i16]]] [[5 x [8 x i16]] zeroinitializer, [5 x [8 x i16]] [[8 x i16] zeroinitializer, [8 x i16] [i16 0, i16 0, i16 0, i16 6, i16 1, i16 6, i16 0, i16 0], [8 x i16] zeroinitializer, [8 x i16] zeroinitializer, [8 x i16] zeroinitializer], [5 x [8 x i16]] zeroinitializer], align 2
@@ -21,44 +22,37 @@
2122
;; }
2223

2324
define void @test1() {
24-
;CHECK-LABEL: @test1(
25-
;CHECK: entry:
26-
;CHECK-NEXT: br label [[FOR_COND1_PREHEADER:%.*]]
27-
;CHECK: for.body.preheader:
28-
;CHECK-NEXT: br label [[FOR_BODY:%.*]]
29-
;CHECK: for.body:
30-
;CHECK-NEXT: [[INDVARS_IV22:%.*]] = phi i64 [ [[INDVARS_IV_NEXT23:%.*]], [[FOR_INC8:%.*]] ], [ 0, [[FOR_BODY_PREHEADER:%.*]] ]
31-
;CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[INDVARS_IV22:%.*]], 0
32-
;CHECK-NEXT: br i1 [[TOBOOL]], label [[FOR_BODY3_SPLIT1:%.*]], label [[FOR_BODY3_SPLIT:%.*]]
33-
;CHECK: for.cond1.preheader:
34-
;CHECK-NEXT: br label [[FOR_BODY3:%.*]]
35-
;CHECK: for.body3:
36-
;CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[FOR_COND1_PREHEADER]] ], [ %3, [[FOR_BODY3_SPLIT]] ]
37-
;CHECK-NEXT: br label [[FOR_BODY_PREHEADER]]
38-
;CHECK: for.body3.split1:
39-
;CHECK-NEXT: [[TMP0:%.*]] = add nuw nsw i64 [[INDVARS_IV22]], 5
40-
;CHECK-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [3 x [5 x [8 x i16]]], ptr @b, i64 0, i64 [[INDVARS_IV]], i64 [[INDVARS_IV]], i64 [[TMP0]]
41-
;CHECK-NEXT: [[TMP1:%.*]] = load i16, ptr [[ARRAYIDX7]]
42-
;CHECK-NEXT: [[CONV:%.*]] = sext i16 [[TMP1]] to i32
43-
;CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr @a
44-
;CHECK-NEXT: [[TMP_OR:%.*]] = or i32 [[TMP2]], [[CONV]]
45-
;CHECK-NEXT: store i32 [[TMP_OR]], ptr @a
46-
;CHECK-NEXT: [[INDVARS_IV_NEXT:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 1
47-
;CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], 3
48-
;CHECK-NEXT: br label [[FOR_INC8_LOOPEXIT:%.*]]
49-
;CHECK: for.body3.split:
50-
;CHECK-NEXT: [[TMP3:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 1
51-
;CHECK-NEXT: [[TMP4:%.*]] = icmp ne i64 [[TMP3]], 3
52-
;CHECK-NEXT: br i1 %4, label [[FOR_BODY3]], label [[FOR_END10:%.*]]
53-
;CHECK: for.inc8.loopexit:
54-
;CHECK-NEXT: br label [[FOR_INC8]]
55-
;CHECK: for.inc8:
56-
;CHECK-NEXT: [[INDVARS_IV_NEXT23]] = add nuw nsw i64 [[INDVARS_IV22]], 1
57-
;CHECK-NEXT: [[EXITCOND25:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT23]], 3
58-
;CHECK-NEXT: br i1 [[EXITCOND25]], label [[FOR_BODY]], label [[FOR_BODY3_SPLIT]]
59-
;CHECK: for.end10:
60-
;CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr @a
61-
;CHECK-NEXT: ret void
25+
; CHECK-LABEL: define void @test1() {
26+
; CHECK-NEXT: [[ENTRY:.*]]:
27+
; CHECK-NEXT: br label %[[FOR_BODY:.*]]
28+
; CHECK: [[FOR_BODY]]:
29+
; CHECK-NEXT: [[INDVARS_IV22:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INDVARS_IV_NEXT23:%.*]], %[[FOR_INC8:.*]] ]
30+
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[INDVARS_IV22]], 0
31+
; CHECK-NEXT: br i1 [[TOBOOL]], label %[[FOR_COND1_PREHEADER:.*]], label %[[FOR_INC8]]
32+
; CHECK: [[FOR_COND1_PREHEADER]]:
33+
; CHECK-NEXT: br label %[[FOR_BODY3:.*]]
34+
; CHECK: [[FOR_BODY3]]:
35+
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[FOR_COND1_PREHEADER]] ], [ [[TMP3:%.*]], %[[FOR_BODY3]] ]
36+
; CHECK-NEXT: [[TMP0:%.*]] = add nuw nsw i64 [[INDVARS_IV22]], 5
37+
; CHECK-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [3 x [5 x [8 x i16]]], ptr @b, i64 0, i64 [[INDVARS_IV]], i64 [[INDVARS_IV]], i64 [[TMP0]]
38+
; CHECK-NEXT: [[TMP1:%.*]] = load i16, ptr [[ARRAYIDX7]], align 2
39+
; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[TMP1]] to i32
40+
; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr @a, align 4
41+
; CHECK-NEXT: [[TMP_OR:%.*]] = or i32 [[TMP2]], [[CONV]]
42+
; CHECK-NEXT: store i32 [[TMP_OR]], ptr @a, align 4
43+
; CHECK-NEXT: [[TMP3]] = add nuw nsw i64 [[INDVARS_IV]], 1
44+
; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i64 [[TMP3]], 3
45+
; CHECK-NEXT: br i1 [[TMP4]], label %[[FOR_BODY3]], label %[[FOR_INC8_LOOPEXIT:.*]]
46+
; CHECK: [[FOR_INC8_LOOPEXIT]]:
47+
; CHECK-NEXT: br label %[[FOR_INC8]]
48+
; CHECK: [[FOR_INC8]]:
49+
; CHECK-NEXT: [[INDVARS_IV_NEXT23]] = add nuw nsw i64 [[INDVARS_IV22]], 1
50+
; CHECK-NEXT: [[EXITCOND25:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT23]], 3
51+
; CHECK-NEXT: br i1 [[EXITCOND25]], label %[[FOR_BODY]], label %[[FOR_END10:.*]]
52+
; CHECK: [[FOR_END10]]:
53+
; CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr @a, align 4
54+
; CHECK-NEXT: ret void
55+
;
6256

6357
entry:
6458
br label %for.body
@@ -118,45 +112,45 @@ for.end10: ; preds = %for.inc8
118112
;; }
119113

120114
define void @test2() {
121-
; CHECK-LABEL: @test2(
122-
; CHECK-NEXT: entry:
123-
; CHECK-NEXT: br label [[OUTERMOST_HEADER:%.*]]
124-
; CHECK: outermost.header:
125-
; CHECK-NEXT: [[INDVAR_OUTERMOST:%.*]] = phi i32 [ 10, [[ENTRY:%.*]] ], [ [[INDVAR_OUTERMOST_NEXT:%.*]], [[OUTERMOST_LATCH:%.*]] ]
115+
; CHECK-LABEL: define void @test2() {
116+
; CHECK-NEXT: [[ENTRY:.*]]:
117+
; CHECK-NEXT: br label %[[OUTERMOST_HEADER:.*]]
118+
; CHECK: [[OUTERMOST_HEADER]]:
119+
; CHECK-NEXT: [[INDVAR_OUTERMOST:%.*]] = phi i32 [ 10, %[[ENTRY]] ], [ [[INDVAR_OUTERMOST_NEXT:%.*]], %[[OUTERMOST_LATCH:.*]] ]
126120
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr @a, align 4
127121
; CHECK-NEXT: [[TOBOOL71_I:%.*]] = icmp eq i32 [[TMP0]], 0
128-
; CHECK-NEXT: br label [[INNERMOST_PREHEADER:%.*]]
129-
; CHECK: middle.header.preheader:
130-
; CHECK-NEXT: br label [[MIDDLE_HEADER:%.*]]
131-
; CHECK: middle.header:
132-
; CHECK-NEXT: [[INDVAR_MIDDLE:%.*]] = phi i64 [ [[INDVAR_MIDDLE_NEXT:%.*]], [[MIDDLE_LATCH:%.*]] ], [ 4, [[MIDDLE_HEADER_PREHEADER:%.*]] ]
133-
; CHECK-NEXT: br i1 [[TOBOOL71_I]], label [[INNERMOST_BODY_SPLIT1:%.*]], label [[INNERMOST_BODY_SPLIT:%.*]]
134-
; CHECK: innermost.preheader:
135-
; CHECK-NEXT: br label [[INNERMOST_BODY:%.*]]
136-
; CHECK: innermost.body:
137-
; CHECK-NEXT: [[INDVAR_INNERMOST:%.*]] = phi i64 [ [[TMP1:%.*]], [[INNERMOST_BODY_SPLIT]] ], [ 4, [[INNERMOST_PREHEADER]] ]
138-
; CHECK-NEXT: br label [[MIDDLE_HEADER_PREHEADER]]
139-
; CHECK: innermost.body.split1:
122+
; CHECK-NEXT: br label %[[INNERMOST_PREHEADER:.*]]
123+
; CHECK: [[MIDDLE_HEADER_PREHEADER:.*]]:
124+
; CHECK-NEXT: br label %[[MIDDLE_HEADER:.*]]
125+
; CHECK: [[MIDDLE_HEADER]]:
126+
; CHECK-NEXT: [[INDVAR_MIDDLE:%.*]] = phi i64 [ [[INDVAR_MIDDLE_NEXT:%.*]], %[[MIDDLE_LATCH:.*]] ], [ 4, %[[MIDDLE_HEADER_PREHEADER]] ]
127+
; CHECK-NEXT: br i1 [[TOBOOL71_I]], label %[[INNERMOST_BODY_SPLIT1:.*]], label %[[INNERMOST_BODY_SPLIT:.*]]
128+
; CHECK: [[INNERMOST_PREHEADER]]:
129+
; CHECK-NEXT: br label %[[INNERMOST_BODY:.*]]
130+
; CHECK: [[INNERMOST_BODY]]:
131+
; CHECK-NEXT: [[INDVAR_INNERMOST:%.*]] = phi i64 [ [[TMP1:%.*]], %[[INNERMOST_BODY_SPLIT]] ], [ 4, %[[INNERMOST_PREHEADER]] ]
132+
; CHECK-NEXT: br label %[[MIDDLE_HEADER_PREHEADER]]
133+
; CHECK: [[INNERMOST_BODY_SPLIT1]]:
140134
; CHECK-NEXT: [[ARRAYIDX9_I:%.*]] = getelementptr inbounds [1 x [6 x i32]], ptr @d, i64 0, i64 [[INDVAR_INNERMOST]], i64 [[INDVAR_MIDDLE]]
141135
; CHECK-NEXT: store i32 0, ptr [[ARRAYIDX9_I]], align 4
142136
; CHECK-NEXT: [[INDVAR_INNERMOST_NEXT:%.*]] = add nsw i64 [[INDVAR_INNERMOST]], -1
143137
; CHECK-NEXT: [[TOBOOL5_I:%.*]] = icmp eq i64 [[INDVAR_INNERMOST_NEXT]], 0
144-
; CHECK-NEXT: br label [[MIDDLE_LATCH_LOOPEXIT:%.*]]
145-
; CHECK: innermost.body.split:
138+
; CHECK-NEXT: br label %[[INNERMOST_LOOPEXIT:.*]]
139+
; CHECK: [[INNERMOST_BODY_SPLIT]]:
146140
; CHECK-NEXT: [[TMP1]] = add nsw i64 [[INDVAR_INNERMOST]], -1
147141
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 0
148-
; CHECK-NEXT: br i1 [[TMP2]], label [[OUTERMOST_LATCH]], label [[INNERMOST_BODY]]
149-
; CHECK: innermost.loopexit:
150-
; CHECK-NEXT: br label [[MIDDLE_LATCH]]
151-
; CHECK: middle.latch:
142+
; CHECK-NEXT: br i1 [[TMP2]], label %[[OUTERMOST_LATCH]], label %[[INNERMOST_BODY]]
143+
; CHECK: [[INNERMOST_LOOPEXIT]]:
144+
; CHECK-NEXT: br label %[[MIDDLE_LATCH]]
145+
; CHECK: [[MIDDLE_LATCH]]:
152146
; CHECK-NEXT: [[INDVAR_MIDDLE_NEXT]] = add nsw i64 [[INDVAR_MIDDLE]], -1
153147
; CHECK-NEXT: [[TOBOOL2_I:%.*]] = icmp eq i64 [[INDVAR_MIDDLE_NEXT]], 0
154-
; CHECK-NEXT: br i1 [[TOBOOL2_I]], label [[INNERMOST_BODY_SPLIT]], label [[MIDDLE_HEADER]]
155-
; CHECK: outermost.latch:
148+
; CHECK-NEXT: br i1 [[TOBOOL2_I]], label %[[INNERMOST_BODY_SPLIT]], label %[[MIDDLE_HEADER]]
149+
; CHECK: [[OUTERMOST_LATCH]]:
156150
; CHECK-NEXT: [[INDVAR_OUTERMOST_NEXT]] = add nsw i32 [[INDVAR_OUTERMOST]], -5
157151
; CHECK-NEXT: [[TOBOOL_I:%.*]] = icmp eq i32 [[INDVAR_OUTERMOST_NEXT]], 0
158-
; CHECK-NEXT: br i1 [[TOBOOL_I]], label [[OUTERMOST_EXIT:%.*]], label [[OUTERMOST_HEADER]]
159-
; CHECK: outermost.exit:
152+
; CHECK-NEXT: br i1 [[TOBOOL_I]], label %[[OUTERMOST_EXIT:.*]], label %[[OUTERMOST_HEADER]]
153+
; CHECK: [[OUTERMOST_EXIT]]:
160154
; CHECK-NEXT: ret void
161155
;
162156

llvm/test/Transforms/LoopInterchange/profitability.ll

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -pass-remarks-output=%t -verify-dom-info -verify-loop-info \
2-
; RUN: -pass-remarks=loop-interchange -pass-remarks-missed=loop-interchange
2+
; RUN: -pass-remarks=loop-interchange -pass-remarks-missed=loop-interchange -S
33
; RUN: FileCheck -input-file %t %s
44

55
; RUN: opt < %s -passes=loop-interchange,loop-interchange -cache-line-size=64 \
@@ -174,23 +174,15 @@ for.end12:
174174
;; for(int i=1;i<100;i++)
175175
;; for(int j=1;j<100;j++)
176176
;; A[j][0] = A[j][0] + B[j][i];
177+
;
178+
; FIXME
177179

178-
; CHECK: Name: Interchanged
180+
; CHECK: Name: Dependence
179181
; CHECK-NEXT: Function: interchange_05
180182

181-
; PROFIT-LABEL: --- !Passed
182-
; PROFIT-NEXT: Pass: loop-interchange
183-
; PROFIT-NEXT: Name: Interchanged
184-
; PROFIT-LABEL: Function: interchange_05
185-
; PROFIT-NEXT: Args:
186-
; PROFIT-NEXT: - String: Loop interchanged with enclosing loop.
187-
; PROFIT-NEXT: ...
188-
; PROFIT: --- !Missed
189-
; PROFIT-NEXT: Pass: loop-interchange
190-
; PROFIT-NEXT: Name: InterchangeNotProfitable
191-
; PROFIT-NEXT: Function: interchange_05
183+
; PROFIT: Function: interchange_05
192184
; PROFIT-NEXT: Args:
193-
; PROFIT-NEXT: - String: Interchanging loops is not considered to improve cache locality nor vectorization.
185+
; PROFIT-NEXT: - String: Cannot interchange loops due to dependences
194186
; PROFIT-NEXT: ...
195187
define void @interchange_05() {
196188
entry:

0 commit comments

Comments
 (0)