Skip to content

Commit 456ec1c

Browse files
authored
[LoopInterchange] Remove 'S' Scalar Dependencies (#119345)
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 patch does no longer insert the "S" dependency/direction into the dependency matrix, so a dependency is never "S". We seem to have forgotten what the exact meaning is of this dependency type, and don't see why it should be treated differently. We prefer correctness over incorrect and more aggressive results. I.e., this prevents the miscompiles at the expense of handling less cases, i.e. making interchange more pessimistic. However, some of the cases that are now rejected for dependence analysis reasons, were rejected before too but for other reasons (e.g. profitability). So at least for the llvm regression tests, the number of regression are very reasonable. This should be a stopgap. We would like to get interchange enabled by default and thus prefer correctness over unsafe transforms, and later see if we can get solve the regressions.
1 parent 1c5b122 commit 456ec1c

13 files changed

+91
-30
lines changed

llvm/lib/Transforms/Scalar/LoopInterchange.cpp

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -136,23 +136,17 @@ static bool populateDependencyMatrix(CharMatrix &DepMatrix, unsigned Level,
136136
unsigned Levels = D->getLevels();
137137
char Direction;
138138
for (unsigned II = 1; II <= Levels; ++II) {
139-
if (D->isScalar(II)) {
140-
Direction = 'S';
141-
Dep.push_back(Direction);
142-
} else {
143-
unsigned Dir = D->getDirection(II);
144-
if (Dir == Dependence::DVEntry::LT ||
145-
Dir == Dependence::DVEntry::LE)
146-
Direction = '<';
147-
else if (Dir == Dependence::DVEntry::GT ||
148-
Dir == Dependence::DVEntry::GE)
149-
Direction = '>';
150-
else if (Dir == Dependence::DVEntry::EQ)
151-
Direction = '=';
152-
else
153-
Direction = '*';
154-
Dep.push_back(Direction);
155-
}
139+
unsigned Dir = D->getDirection(II);
140+
if (Dir == Dependence::DVEntry::LT || Dir == Dependence::DVEntry::LE)
141+
Direction = '<';
142+
else if (Dir == Dependence::DVEntry::GT ||
143+
Dir == Dependence::DVEntry::GE)
144+
Direction = '>';
145+
else if (Dir == Dependence::DVEntry::EQ)
146+
Direction = '=';
147+
else
148+
Direction = '*';
149+
Dep.push_back(Direction);
156150
}
157151
while (Dep.size() != Level) {
158152
Dep.push_back('I');

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
; Remove 'S' Scalar Dependencies #119345
2+
; Scalar dependencies are not handled correctly, so they were removed to avoid
3+
; miscompiles. The loop nest in this test case used to be interchanged, but it's
4+
; no longer triggering. XFAIL'ing this test to indicate that this test should
5+
; interchanged if scalar deps are handled correctly.
6+
;
7+
; XFAIL: *
8+
19
; RUN: opt < %s -passes=loop-interchange -pass-remarks-output=%t -disable-output
210
; RUN: FileCheck -input-file %t %s
311

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22
; RUN: -verify-dom-info -verify-loop-info -verify-loop-lcssa 2>&1 | FileCheck -check-prefix=IR %s
33
; RUN: FileCheck --input-file=%t %s
44

5-
; Inner loop only reductions are not supported currently. See discussion at
6-
; D53027 for more information on the required checks.
5+
; Both tests should be rejected as interchange candidates. For now, they are
6+
; rejected for dependence analysis reasons, but that's because support for 'S'
7+
; scalar dependencies was removed. When that is properly, the inner loop only
8+
; reductions should still not be supported currently, see discussion at D53027
9+
; for more information on the required checks.
710

811
@A = common global [500 x [500 x i32]] zeroinitializer
912
@X = common global i32 0
@@ -18,7 +21,7 @@
1821

1922
; CHECK: --- !Missed
2023
; CHECK-NEXT: Pass: loop-interchange
21-
; CHECK-NEXT: Name: UnsupportedPHI
24+
; CHECK-NEXT: Name: Dependence
2225
; CHECK-NEXT: Function: reduction_01
2326

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

7275
; CHECK: --- !Missed
7376
; CHECK-NEXT: Pass: loop-interchange
74-
; CHECK-NEXT: Name: UnsupportedPHIOuter
77+
; CHECK-NEXT: Name: Dependence
7578
; CHECK-NEXT: Function: reduction_03
7679

7780
; IR-LABEL: @reduction_03(

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
; Remove 'S' Scalar Dependencies #119345
2+
; Scalar dependencies are not handled correctly, so they were removed to avoid
3+
; miscompiles. The loop nest in this test case used to be interchanged, but it's
4+
; no longer triggering. XFAIL'ing this test to indicate that this test should
5+
; interchanged if scalar deps are handled correctly.
6+
;
7+
; XFAIL: *
8+
19
; RUN: opt < %s -passes=loop-interchange -verify-dom-info -verify-loop-info -pass-remarks-output=%t -disable-output
210
; RUN: FileCheck -input-file %t %s
311

llvm/test/Transforms/LoopInterchange/interchange-flow-dep-outer.ll

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
; Remove 'S' Scalar Dependencies #119345
2+
; Scalar dependencies are not handled correctly, so they were removed to avoid
3+
; miscompiles. The loop nest in this test case used to be interchanged, but it's
4+
; no longer triggering. XFAIL'ing this test to indicate that this test should
5+
; interchanged if scalar deps are handled correctly.
6+
;
7+
; XFAIL: *
8+
19
; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -verify-dom-info -verify-loop-info -pass-remarks-output=%t -disable-output
210
; RUN: FileCheck -input-file %t %s
311

llvm/test/Transforms/LoopInterchange/lcssa.ll

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
; Remove 'S' Scalar Dependencies #119345
2+
; Scalar dependencies are not handled correctly, so they were removed to avoid
3+
; miscompiles. The loop nest in this test case used to be interchanged, but it's
4+
; no longer triggering. XFAIL'ing this test to indicate that this test should
5+
; interchanged if scalar deps are handled correctly.
6+
;
7+
; XFAIL: *
8+
19
; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -pass-remarks-missed='loop-interchange' -verify-loop-lcssa -pass-remarks-output=%t -S
210
; RUN: FileCheck --input-file %t --check-prefix REMARK %s
311

@@ -177,7 +185,7 @@ for.end16: ; preds = %for.exit
177185
}
178186

179187
; PHI node in inner latch with multiple predecessors.
180-
; REMARK: Interchanged
188+
; REMARK: Interchanged
181189
; REMARK-NEXT: lcssa_05
182190

183191
define void @lcssa_05(ptr %ptr, i1 %arg) {
@@ -222,7 +230,7 @@ for.end16: ; preds = %for.exit
222230
ret void
223231
}
224232

225-
; REMARK: UnsupportedExitPHI
233+
; REMARK: UnsupportedExitPHI
226234
; REMARK-NEXT: lcssa_06
227235

228236
define void @lcssa_06(ptr %ptr, ptr %ptr1, i1 %arg) {

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
; Remove 'S' Scalar Dependencies #119345
2+
; Scalar dependencies are not handled correctly, so they were removed to avoid
3+
; miscompiles. The loop nest in this test case used to be interchanged, but it's
4+
; no longer triggering. XFAIL'ing this test to indicate that this test should
5+
; interchanged if scalar deps are handled correctly.
6+
;
7+
; XFAIL: *
8+
19
; RUN: opt -passes=loop-interchange -cache-line-size=64 -verify-dom-info -verify-loop-info -verify-loop-lcssa %s -pass-remarks-output=%t -disable-output
210
; RUN: FileCheck -input-file %t %s
311

llvm/test/Transforms/LoopInterchange/pr43176-move-to-new-latch.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@
1414

1515
; CHECK: --- !Missed
1616
; CHECK-NEXT: Pass: loop-interchange
17-
; CHECK-NEXT: Name: InterchangeNotProfitable
17+
; CHECK-NEXT: Name: Dependence
1818
; CHECK-NEXT: Function: test1
1919
; CHECK-NEXT: Args:
20-
; CHECK-NEXT: - String: Interchanging loops is not considered to improve cache locality nor vectorization.
20+
; CHECK-NEXT: - String: Cannot interchange loops due to dependences.
2121

2222
define void @test1() {
2323
entry:
@@ -54,10 +54,10 @@ for.cond.for.end5_crit_edge: ; preds = %for.inc3
5454

5555
; CHECK: --- !Missed
5656
; CHECK-NEXT: Pass: loop-interchange
57-
; CHECK-NEXT: Name: InterchangeNotProfitable
57+
; CHECK-NEXT: Name: Dependence
5858
; CHECK-NEXT: Function: test2
5959
; CHECK-NEXT: Args:
60-
; CHECK-NEXT: - String: Interchanging loops is not considered to improve cache locality nor vectorization.
60+
; CHECK-NEXT: - String: Cannot interchange loops due to dependences.
6161

6262
define void @test2() {
6363
entry:

llvm/test/Transforms/LoopInterchange/pr43797-lcssa-for-multiple-outer-loop-blocks.ll

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
; Remove 'S' Scalar Dependencies #119345
2+
; Scalar dependencies are not handled correctly, so they were removed to avoid
3+
; miscompiles. The loop nest in this test case used to be interchanged, but it's
4+
; no longer triggering. XFAIL'ing this test to indicate that this test should
5+
; interchanged if scalar deps are handled correctly.
6+
;
7+
; XFAIL: *
8+
19
; RUN: opt -passes=loop-interchange -cache-line-size=64 -verify-loop-lcssa %s -pass-remarks-output=%t -disable-output
210
; RUN: FileCheck -input-file %t %s
311

llvm/test/Transforms/LoopInterchange/profitability.ll

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
; Remove 'S' Scalar Dependencies #119345
2+
; Scalar dependencies are not handled correctly, so they were removed to avoid
3+
; miscompiles. The loop nest in this test case used to be interchanged, but it's
4+
; no longer triggering. XFAIL'ing this test to indicate that this test should
5+
; interchanged if scalar deps are handled correctly.
6+
;
7+
; XFAIL: *
8+
19
; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -pass-remarks-output=%t -verify-dom-info -verify-loop-info \
210
; RUN: -pass-remarks=loop-interchange -pass-remarks-missed=loop-interchange
311
; RUN: FileCheck -input-file %t %s

llvm/test/Transforms/LoopInterchange/reductions-across-inner-and-outer-loop.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ for1.loopexit: ; preds = %for1.inc
153153
; Check that we do not interchange if reduction is stored in an invariant address inside inner loop
154154
; REMARKS: --- !Missed
155155
; REMARKS-NEXT: Pass: loop-interchange
156-
; REMARKS-NEXT: Name: UnsupportedPHIOuter
156+
; REMARKS-NEXT: Name: Dependence
157157
; REMARKS-NEXT: Function: test4
158158

159159
define i64 @test4(ptr %Arr, ptr %dst) {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33

44
; CHECK: Dependency matrix before interchange:
55
; CHECK-NEXT: I I
6-
; CHECK-NEXT: = S
7-
; CHECK-NEXT: < S
6+
; CHECK-NEXT: = *
7+
; CHECK-NEXT: < *
88
; CHECK-NEXT: Processing InnerLoopId
99

1010
; This example is taken from github issue #54176

llvm/test/Transforms/LoopInterchange/vector-gep-operand.ll

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
; Remove 'S' Scalar Dependencies #119345
2+
; Scalar dependencies are not handled correctly, so they were removed to avoid
3+
; miscompiles. The loop nest in this test case used to be interchanged, but it's
4+
; no longer triggering. XFAIL'ing this test to indicate that this test should
5+
; interchanged if scalar deps are handled correctly.
6+
;
7+
; XFAIL: *
8+
19
; RUN: opt -passes=loop-interchange -cache-line-size=64 -loop-interchange-threshold=-10 %s -pass-remarks-output=%t -disable-output
210
; RUN: FileCheck -input-file %t %s
311

0 commit comments

Comments
 (0)