Skip to content

Commit 7086025

Browse files
author
Andy Kaylor
committed
[Dependence Analysis] Enable delinearization of fixed sized arrays
Patch by Artem Radzikhovskyy! Allow delinearization of fixed sized arrays if we can prove that the GEP indices do not overflow the array dimensions. The checks applied are similar to the ones that are used for delinearization of parametric size arrays. Make sure that the GEP indices are non-negative and that they are smaller than the range of that dimension. Changes Summary: - Updated the LIT tests with more exact values, as we are able to delinearize and apply more exact tests - profitability.ll - now able to delinearize in all cases, no need to use -da-disable-delinearization-checks flag and run the test twice - loop-interchange-optimization-remarks.ll - in one of the cases we are able to delinearize without using -da-disable-delinearization-checks - SimpleSIVNoValidityCheckFixedSize.ll - removed unnecessary "-da-disable-delinearization-checks" flag. Now can get the exact answer without it. - SimpleSIVNoValidityCheckFixedSize.ll and PreliminaryNoValidityCheckFixedSize.ll - made negative tests more explicit, in order to demonstrate the need for "-da-disable-delinearization-checks" flag Differential Revision: https://reviews.llvm.org/D101486
1 parent f13893f commit 7086025

9 files changed

+107
-51
lines changed

llvm/lib/Analysis/DependenceAnalysis.cpp

Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3304,16 +3304,6 @@ bool DependenceInfo::tryDelinearizeFixedSize(
33043304
const SCEV *DstAccessFn, SmallVectorImpl<const SCEV *> &SrcSubscripts,
33053305
SmallVectorImpl<const SCEV *> &DstSubscripts) {
33063306

3307-
// In general we cannot safely assume that the subscripts recovered from GEPs
3308-
// are in the range of values defined for their corresponding array
3309-
// dimensions. For example some C language usage/interpretation make it
3310-
// impossible to verify this at compile-time. As such we give up here unless
3311-
// we can assume that the subscripts do not overlap into neighboring
3312-
// dimensions and that the number of dimensions matches the number of
3313-
// subscripts being recovered.
3314-
if (!DisableDelinearizationChecks)
3315-
return false;
3316-
33173307
Value *SrcPtr = getLoadStorePointerOperand(Src);
33183308
Value *DstPtr = getLoadStorePointerOperand(Dst);
33193309
const SCEVUnknown *SrcBase =
@@ -3352,22 +3342,55 @@ bool DependenceInfo::tryDelinearizeFixedSize(
33523342

33533343
// Check that for identical base pointers we do not miss index offsets
33543344
// that have been added before this GEP is applied.
3355-
if (SrcBasePtr == SrcBase->getValue() && DstBasePtr == DstBase->getValue()) {
3356-
assert(SrcSubscripts.size() == DstSubscripts.size() &&
3357-
SrcSubscripts.size() == SrcSizes.size() + 1 &&
3358-
"Expected equal number of entries in the list of sizes and "
3359-
"subscripts.");
3360-
LLVM_DEBUG({
3361-
dbgs() << "Delinearized subscripts of fixed-size array\n"
3362-
<< "SrcGEP:" << *SrcGEP << "\n"
3363-
<< "DstGEP:" << *DstGEP << "\n";
3364-
});
3365-
return true;
3345+
if (SrcBasePtr != SrcBase->getValue() || DstBasePtr != DstBase->getValue()) {
3346+
SrcSubscripts.clear();
3347+
DstSubscripts.clear();
3348+
return false;
33663349
}
33673350

3368-
SrcSubscripts.clear();
3369-
DstSubscripts.clear();
3370-
return false;
3351+
assert(SrcSubscripts.size() == DstSubscripts.size() &&
3352+
SrcSubscripts.size() == SrcSizes.size() + 1 &&
3353+
"Expected equal number of entries in the list of sizes and "
3354+
"subscripts.");
3355+
3356+
// In general we cannot safely assume that the subscripts recovered from GEPs
3357+
// are in the range of values defined for their corresponding array
3358+
// dimensions. For example some C language usage/interpretation make it
3359+
// impossible to verify this at compile-time. As such we can only delinearize
3360+
// iff the subscripts are positive and are less than the range of the
3361+
// dimension.
3362+
if (!DisableDelinearizationChecks) {
3363+
auto AllIndiciesInRange = [&](SmallVector<int, 4> &DimensionSizes,
3364+
SmallVectorImpl<const SCEV *> &Subscripts,
3365+
Value *Ptr) {
3366+
size_t SSize = Subscripts.size();
3367+
for (size_t I = 1; I < SSize; ++I) {
3368+
const SCEV *S = Subscripts[I];
3369+
if (!isKnownNonNegative(S, Ptr))
3370+
return false;
3371+
if (auto *SType = dyn_cast<IntegerType>(S->getType())) {
3372+
const SCEV *Range = SE->getConstant(
3373+
ConstantInt::get(SType, DimensionSizes[I - 1], false));
3374+
if (!isKnownLessThan(S, Range))
3375+
return false;
3376+
}
3377+
}
3378+
return true;
3379+
};
3380+
3381+
if (!AllIndiciesInRange(SrcSizes, SrcSubscripts, SrcPtr) ||
3382+
!AllIndiciesInRange(DstSizes, DstSubscripts, DstPtr)) {
3383+
SrcSubscripts.clear();
3384+
DstSubscripts.clear();
3385+
return false;
3386+
}
3387+
}
3388+
LLVM_DEBUG({
3389+
dbgs() << "Delinearized subscripts of fixed-size array\n"
3390+
<< "SrcGEP:" << *SrcGEP << "\n"
3391+
<< "DstGEP:" << *DstGEP << "\n";
3392+
});
3393+
return true;
33713394
}
33723395

33733396
bool DependenceInfo::tryDelinearizeParametricSize(

llvm/test/Analysis/DependenceAnalysis/Coupled.ll

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,8 @@ entry:
438438

439439
; CHECK-LABEL: couple11
440440
; CHECK: da analyze - none!
441-
; CHECK: da analyze - flow [=|<]!
441+
; CHECK: da analyze - flow [=|<] splitable!
442+
; CHECK: da analyze - split level = 1, iteration = 9!
442443
; CHECK: da analyze - confused!
443444
; CHECK: da analyze - none!
444445
; CHECK: da analyze - confused!
@@ -476,7 +477,8 @@ entry:
476477

477478
; CHECK-LABEL: couple12
478479
; CHECK: da analyze - none!
479-
; CHECK: da analyze - flow [<]!
480+
; CHECK: da analyze - flow [<] splitable!
481+
; CHECK: da analyze - split level = 1, iteration = 11!
480482
; CHECK: da analyze - confused!
481483
; CHECK: da analyze - none!
482484
; CHECK: da analyze - confused!

llvm/test/Analysis/DependenceAnalysis/Invariant.ll

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,20 @@
55
; Test for a bug, which caused an assert when an invalid
66
; SCEVAddRecExpr is created in addToCoefficient.
77

8+
; float foo (float g, float* rr[40]) {
9+
; float res= 0.0f;
10+
; for (int i = 0; i < 40; i += 5) {
11+
; for (int j = 0; j < 40; j += 5) {
12+
; float add = rr[j][j] + rr[i][j];
13+
; res = add > g? add : res;
14+
; }
15+
; }
16+
; return res;
17+
; }
18+
819
; CHECK-LABEL: foo
920
; CHECK: da analyze - consistent input [S 0]!
10-
; CHECK: da analyze - input [* *|<]!
21+
; CHECK: da analyze - input [* 0|<]!
1122
; CHECK: da analyze - none!
1223

1324
define float @foo(float %g, [40 x float]* %rr) nounwind {

llvm/test/Analysis/DependenceAnalysis/PreliminaryNoValidityCheckFixedSize.ll

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
; RUN: opt < %s -disable-output "-passes=print<da>" -aa-pipeline=basic-aa 2>&1 \
22
; RUN: -da-disable-delinearization-checks | FileCheck %s
3+
; RUN: opt < %s -disable-output "-passes=print<da>" -aa-pipeline=basic-aa 2>&1 \
4+
; RUN: | FileCheck --check-prefix=LIN %s
35

46
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
57
target triple = "x86_64-apple-macosx10.6.0"
@@ -25,6 +27,14 @@ entry:
2527
; CHECK: da analyze - confused!
2628
; CHECK: da analyze - output [* * *]!
2729

30+
; LIN-LABEL: p2
31+
; LIN: da analyze - output [* * *]!
32+
; LIN: da analyze - flow [* *|<]!
33+
; LIN: da analyze - confused!
34+
; LIN: da analyze - input [* * *]!
35+
; LIN: da analyze - confused!
36+
; LIN: da analyze - output [* * *]!
37+
2838
for.cond1.preheader.preheader: ; preds = %entry
2939
br label %for.cond1.preheader
3040

llvm/test/Analysis/DependenceAnalysis/Separability.ll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ define void @sep0([100 x [100 x i32]]* %A, i32* %B, i32 %n) nounwind uwtable ssp
1717
entry:
1818
br label %for.cond1.preheader
1919

20-
; CHECK: da analyze - output [= * * S]!
20+
; CHECK: da analyze - output [0 * * S]!
2121
; CHECK: da analyze - flow [* * * *|<]!
2222
; CHECK: da analyze - confused!
2323
; CHECK: da analyze - input [* * S *]!
@@ -92,7 +92,7 @@ define void @sep1([100 x [100 x i32]]* %A, i32* %B, i32 %n) nounwind uwtable ssp
9292
entry:
9393
br label %for.cond1.preheader
9494

95-
; CHECK: da analyze - output [= * * S]!
95+
; CHECK: da analyze - output [0 * * S]!
9696
; CHECK: da analyze - flow [* * * *|<]!
9797
; CHECK: da analyze - confused!
9898
; CHECK: da analyze - input [* * S *]!
@@ -166,10 +166,10 @@ define void @sep2([100 x [100 x [100 x i32]]]* %A, i32* %B, i32 %n) nounwind uwt
166166
entry:
167167
br label %for.cond1.preheader
168168

169-
; CHECK: da analyze - output [= S = =]!
170-
; CHECK: da analyze - flow [* * * <>]!
169+
; CHECK: da analyze - consistent output [0 S 0 0]!
170+
; CHECK: da analyze - flow [> * * -10]!
171171
; CHECK: da analyze - confused!
172-
; CHECK: da analyze - input [= * * *]!
172+
; CHECK: da analyze - input [0 * * 0]!
173173
; CHECK: da analyze - confused!
174174
; CHECK: da analyze - none!
175175

@@ -240,10 +240,10 @@ define void @sep3([100 x [100 x [100 x i32]]]* %A, i32* %B, i32 %n) nounwind uwt
240240
entry:
241241
br label %for.cond1.preheader
242242

243-
; CHECK: da analyze - output [= S = =]!
244-
; CHECK: da analyze - flow [* * * *|<]!
243+
; CHECK: da analyze - consistent output [0 S 0 0]!
244+
; CHECK: da analyze - flow [> * * *]!
245245
; CHECK: da analyze - confused!
246-
; CHECK: da analyze - input [= * * *]!
246+
; CHECK: da analyze - input [0 * * 0]!
247247
; CHECK: da analyze - confused!
248248
; CHECK: da analyze - none!
249249

llvm/test/Analysis/DependenceAnalysis/SimpleSIVNoValidityCheck.ll

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
; RUN: opt < %s -disable-output -passes="print<da>" \
22
; RUN: -da-disable-delinearization-checks 2>&1 | FileCheck %s
3-
; RUN: opt < %s -da -analyze -enable-new-pm=0 -da-disable-delinearization-checks | FileCheck %s
3+
; RUN: opt < %s -disable-output -passes="print<da>" \
4+
; RUN: 2>&1 | FileCheck --check-prefix=LIN %s
45

56
; CHECK-LABEL: t1
67
; CHECK: da analyze - none!
78
; CHECK: da analyze - consistent anti [1 -2]!
89
; CHECK: da analyze - none!
910

11+
; LIN-LABEL: t1
12+
; LIN: da analyze - input [* *]!
13+
; LIN: da analyze - anti [* *|<]!
14+
; LIN: da analyze - output [* *]!
15+
1016
;; void t1(int n, int m, int a[][m]) {
1117
;; for (int i = 0; i < n-1; ++i)
1218
;; for (int j = 2; j < m; ++j)
@@ -58,6 +64,11 @@ for.end14: ; preds = %entry, %for.inc12
5864
; CHECK: da analyze - consistent anti [1 -2 0 -3 2]!
5965
; CHECK: da analyze - none!
6066

67+
; LIN-LABEL: t2
68+
; LIN: da analyze - input [* * * * *]!
69+
; LIN: da analyze - anti [* * * * *|<]!
70+
; LIN: da analyze - output [* * * * *]!
71+
6172
;; void t2(int n, int m, int a[][n][n][n][m]) {
6273
;; for (int i1 = 0; i1 < n-1; ++i1)
6374
;; for (int i2 = 2; i2 < n; ++i2)
@@ -179,6 +190,11 @@ for.end50: ; preds = %entry, %for.inc48
179190
; CHECK: da analyze - consistent anti [1 -2]!
180191
; CHECK: da analyze - none!
181192

193+
; LIN-LABEL: t3
194+
; LIN: da analyze - input [* *]!
195+
; LIN: da analyze - anti [* *|<]!
196+
; LIN: da analyze - output [* *]!
197+
182198
;; // No sign or zero extension, but with compile-time unknown loop lower bound.
183199
;; void t3(unsigned long long n, unsigned long long m, unsigned long long lb, float a[][m]) {
184200
;; for (unsigned long long i = 0; i < n-1; ++i)

llvm/test/Analysis/DependenceAnalysis/SimpleSIVNoValidityCheckFixedSize.ll

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
; RUN: opt < %s -disable-output -passes="print<da>" \
2-
; RUN: -da-disable-delinearization-checks 2>&1 | FileCheck %s
3-
; RUN: opt < %s -da -analyze -enable-new-pm=0 -da-disable-delinearization-checks | FileCheck %s
1+
; RUN: opt < %s -disable-output -passes="print<da>" 2>&1 | FileCheck %s
2+
; RUN: opt < %s -da -analyze -enable-new-pm=0 | FileCheck %s
3+
4+
; Note: exact results can be achived even if
5+
; "-da-disable-delinearization-checks" is not used
46

57
; CHECK-LABEL: t1
68
; CHECK: da analyze - none!

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,12 +178,12 @@ for.body4: ; preds = %for.body4, %for.con
178178
br i1 %exitcond, label %for.body4, label %for.cond.loopexit
179179
}
180180

181-
; CHECK: --- !Missed
181+
; CHECK: --- !Passed
182182
; CHECK-NEXT: Pass: loop-interchange
183-
; CHECK-NEXT: Name: Dependence
183+
; CHECK-NEXT: Name: Interchanged
184184
; CHECK-NEXT: Function: test03
185185
; CHECK-NEXT: Args:
186-
; CHECK-NEXT: - String: Cannot interchange loops due to dependences.
186+
; CHECK-NEXT: - String: Loop interchanged with enclosing loop.
187187
; CHECK-NEXT: ...
188188

189189
; DELIN: --- !Passed

llvm/test/Transforms/LoopInterchange/profitability.ll

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,6 @@
22
; RUN: -pass-remarks=loop-interchange -pass-remarks-missed=loop-interchange
33
; RUN: FileCheck -input-file %t %s
44

5-
; RUN: opt < %s -loop-interchange -pass-remarks-output=%t -verify-dom-info -verify-loop-info \
6-
; RUN: -pass-remarks=loop-interchange -pass-remarks-missed=loop-interchange \
7-
; RUN: -da-disable-delinearization-checks
8-
; RUN: FileCheck --check-prefix=DELIN -input-file %t %s
9-
105
;; We test profitability model in these test cases.
116

127
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
@@ -21,12 +16,9 @@ target triple = "x86_64-unknown-linux-gnu"
2116
;; for(int j=1;j<100;j++)
2217
;; A[j][i] = A[j - 1][i] + B[j][i];
2318

24-
; CHECK: Name: Dependence
19+
; CHECK: Name: Interchanged
2520
; CHECK-NEXT: Function: interchange_01
2621

27-
; DELIN: Name: Interchanged
28-
; DELIN-NEXT: Function: interchange_01
29-
3022
define void @interchange_01() {
3123
entry:
3224
br label %for2.preheader

0 commit comments

Comments
 (0)