Skip to content

Commit 2c3453a

Browse files
authored
[LoopInterchange] Bail out when finding a dependency with all * elements (llvm#149049)
If a direction vector with all `*` elements, like `[* * *]`, is present, it indicates that none of the loop pairs are legal to interchange. In such cases, continuing the analysis is meaningless. This patch introduces a check to detect such direction vectors and exits early when one is found. This slightly reduces compile time.
1 parent 833d5f0 commit 2c3453a

File tree

6 files changed

+74
-16
lines changed

6 files changed

+74
-16
lines changed

llvm/lib/Transforms/Scalar/LoopInterchange.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,17 @@ static bool populateDependencyMatrix(CharMatrix &DepMatrix, unsigned Level,
260260
Dep.push_back('I');
261261
}
262262

263+
// If all the elements of any direction vector have only '*', legality
264+
// can't be proven. Exit early to save compile time.
265+
if (all_of(Dep, [](char C) { return C == '*'; })) {
266+
ORE->emit([&]() {
267+
return OptimizationRemarkMissed(DEBUG_TYPE, "Dependence",
268+
L->getStartLoc(), L->getHeader())
269+
<< "All loops have dependencies in all directions.";
270+
});
271+
return false;
272+
}
273+
263274
// Test whether the dependency is forward or not.
264275
bool IsKnownForward = true;
265276
if (Src->getParent() != Dst->getParent()) {
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
; RUN: opt < %s -passes=loop-interchange -pass-remarks-output=%t \
2+
; RUN: -disable-output
3+
; RUN: FileCheck -input-file %t %s
4+
5+
; Check that loop interchange bails out early when finding a direction vector
6+
; with all '*' elements.
7+
;
8+
; for (int i = 0; i < 4; i++)
9+
; for (int j = 0; j < 4; j++)
10+
; A[i & val][j & val] = 0;
11+
12+
; CHECK: --- !Missed
13+
; CHECK-NEXT: Pass: loop-interchange
14+
; CHECK-NEXT: Name: Dependence
15+
; CHECK-NEXT: Function: f
16+
; CHECK-NEXT: Args:
17+
; CHECK-NEXT: - String: All loops have dependencies in all directions.
18+
; CHECK-NEXT: ...
19+
define void @f(ptr %A, i64 %val) {
20+
entry:
21+
br label %for.i.header
22+
23+
for.i.header:
24+
%i = phi i64 [ 0, %entry ], [ %i.next, %for.i.latch ]
25+
br label %for.j
26+
27+
for.j:
28+
%j = phi i64 [ 0, %for.i.header ], [ %j.next, %for.j ]
29+
%subscript.0 = and i64 %i, %val
30+
%subscript.1 = and i64 %j, %val
31+
%idx = getelementptr inbounds [4 x i8], ptr %A, i64 %subscript.0, i64 %subscript.1
32+
store i8 0, ptr %idx
33+
%j.next = add nuw nsw i64 %j, 1
34+
%exit.j = icmp eq i64 %j.next, 4
35+
br i1 %exit.j, label %for.i.latch, label %for.j
36+
37+
for.i.latch:
38+
%i.next = add nuw nsw i64 %i, 1
39+
%exit.i = icmp eq i64 %i.next, 4
40+
br i1 %exit.i, label %exit, label %for.i.header
41+
42+
exit:
43+
ret void
44+
}

llvm/test/Transforms/LoopInterchange/confused-dependence.ll

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
; REQUIRES: asserts
2-
; RUN: opt < %s -passes=loop-interchange -verify-dom-info -verify-loop-info \
3-
; RUN: -disable-output -debug 2>&1 | FileCheck %s
1+
; RUN: opt < %s -passes=loop-interchange -pass-remarks-output=%t \
2+
; RUN: -disable-output
3+
; RUN: FileCheck -input-file %t %s
44

55
;; In the following case, p0 and p1 may alias, so the direction vector must be [* *].
66
;;
@@ -10,9 +10,13 @@
1010
;; p0[4 * i + j] = p1[4 * j + i];
1111
;; }
1212

13-
; CHECK: Dependency matrix before interchange:
14-
; CHECK-NEXT: * *
15-
; CHECK-NEXT: Processing InnerLoopId = 1 and OuterLoopId = 0
13+
; CHECK: --- !Missed
14+
; CHECK-NEXT: Pass: loop-interchange
15+
; CHECK-NEXT: Name: Dependence
16+
; CHECK-NEXT: Function: may_alias
17+
; CHECK-NEXT: Args:
18+
; CHECK-NEXT: - String: All loops have dependencies in all directions.
19+
; CHECK-NEXT: ...
1620
define void @may_alias(ptr %p0, ptr %p1) {
1721
entry:
1822
br label %for.i.header

llvm/test/Transforms/LoopInterchange/legality-for-scalar-deps.ll

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@
2121
; CHECK-NEXT: Name: Dependence
2222
; CHECK-NEXT: Function: issue46867
2323
; CHECK-NEXT: Args:
24-
; CHECK-NEXT: - String: Cannot interchange loops due to dependences.
24+
; CHECK-NEXT: - String: All loops have dependencies in all directions.
2525
; CHECK: --- !Missed
2626
; CHECK-NEXT: Pass: loop-interchange
2727
; CHECK-NEXT: Name: Dependence
2828
; CHECK-NEXT: Function: issue46867
2929
; CHECK-NEXT: Args:
30-
; CHECK-NEXT: - String: Cannot interchange loops due to dependences.
30+
; CHECK-NEXT: - String: All loops have dependencies in all directions.
3131
define void @issue46867(ptr noundef captures(none) %s, i32 noundef %c, ptr noundef readonly captures(none) %ff) {
3232
entry:
3333
%tobool7.not = icmp eq i32 %c, 0
@@ -121,7 +121,7 @@ land.end:
121121
; CHECK-NEXT: Name: Dependence
122122
; CHECK-NEXT: Function: issue47401
123123
; CHECK-NEXT: Args:
124-
; CHECK-NEXT: - String: Cannot interchange loops due to dependences.
124+
; CHECK-NEXT: - String: All loops have dependencies in all directions.
125125
define void @issue47401(ptr noundef writeonly captures(none) %e, ptr noundef readonly captures(none) %bb) {
126126
entry:
127127
br label %for.cond1.preheader
@@ -175,7 +175,7 @@ land.end:
175175
; CHECK-NEXT: Name: Dependence
176176
; CHECK-NEXT: Function: issue47295
177177
; CHECK-NEXT: Args:
178-
; CHECK-NEXT: - String: Cannot interchange loops due to dependences.
178+
; CHECK-NEXT: - String: All loops have dependencies in all directions.
179179
define void @issue47295(ptr noundef captures(none) %f, ptr noundef writeonly captures(none) %cc) {
180180
entry:
181181
br label %for.cond1.preheader
@@ -221,7 +221,7 @@ for.body4:
221221
; CHECK-NEXT: Name: Dependence
222222
; CHECK-NEXT: Function: issue54176
223223
; CHECK-NEXT: Args:
224-
; CHECK-NEXT: - String: Cannot interchange loops due to dependences.
224+
; CHECK-NEXT: - String: All loops have dependencies in all directions.
225225
define void @issue54176(i32 noundef %n, i32 noundef %m, ptr noundef captures(none) %aa, ptr noundef readonly captures(none) %bb, ptr noundef writeonly captures(none) %cc) {
226226

227227
entry:

llvm/test/Transforms/LoopInterchange/loop-interchange-optimization-remarks.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ for.end19:
7171
; CHECK-NEXT: Name: Dependence
7272
; CHECK-NEXT: Function: test01
7373
; CHECK-NEXT: Args:
74-
; CHECK-NEXT: - String: Cannot interchange loops due to dependences.
74+
; CHECK-NEXT: - String: All loops have dependencies in all directions.
7575
; CHECK-NEXT: ...
7676

7777
; DELIN: --- !Analysis
@@ -147,7 +147,7 @@ define void @test02(i32 %k, i32 %N) {
147147
; CHECK-NEXT: Name: Dependence
148148
; CHECK-NEXT: Function: test02
149149
; CHECK-NEXT: Args:
150-
; CHECK-NEXT: - String: Cannot interchange loops due to dependences.
150+
; CHECK-NEXT: - String: All loops have dependencies in all directions.
151151
; CHECK-NEXT: ...
152152

153153
; DELIN: --- !Analysis
@@ -290,7 +290,7 @@ for.end17:
290290
; CHECK-NEXT: Name: Dependence
291291
; CHECK-NEXT: Function: test04
292292
; CHECK-NEXT: Args:
293-
; CHECK-NEXT: - String: Cannot interchange loops due to dependences.
293+
; CHECK-NEXT: - String: All loops have dependencies in all directions.
294294
; CHECK-NEXT: ...
295295

296296
; DELIN: --- !Missed

llvm/test/Transforms/LoopInterchange/unique-dep-matrix.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@
22
; RUN: opt < %s -passes=loop-interchange -S -debug 2>&1 | FileCheck %s
33

44
; CHECK: Dependency matrix before interchange:
5-
; CHECK-NEXT: * *
65
; CHECK-NEXT: = *
76
; CHECK-NEXT: < *
87
; CHECK-NEXT: Processing InnerLoopId
98

109
; This example is taken from github issue #54176
1110
;
12-
define void @foo(i32 noundef %n, i32 noundef %m, ptr nocapture noundef %aa, ptr nocapture noundef readonly %bb, ptr nocapture noundef writeonly %cc) {
11+
define void @foo(i32 noundef %n, i32 noundef %m, ptr nocapture noundef noalias %aa, ptr nocapture noundef readonly noalias %bb, ptr nocapture noundef writeonly noalias %cc) {
1312
entry:
1413
%arrayidx7 = getelementptr inbounds i8, ptr %aa, i64 512
1514
br label %for.cond1.preheader

0 commit comments

Comments
 (0)