Skip to content

Commit cd3d6d2

Browse files
committed
[DA] use alias analysis cross iteration mode
This patch fixes two bugs: #41488 #53942 The dependence analysis assumes that the base address of array accesses is invariant across loop iterations. In both bugs the base address evolves following loop iterations: the base address flip-flops between two different memory objects. The patch uses the cross iteration mode of alias analysis to disambiguate the base objects.
1 parent 81e2780 commit cd3d6d2

File tree

3 files changed

+166
-2
lines changed

3 files changed

+166
-2
lines changed

llvm/include/llvm/Analysis/AliasAnalysis.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,9 @@ class BatchAAResults {
660660
MemoryEffects getMemoryEffects(const CallBase *Call) {
661661
return AA.getMemoryEffects(Call, AAQI);
662662
}
663+
bool isNoAlias(const MemoryLocation &LocA, const MemoryLocation &LocB) {
664+
return alias(LocA, LocB) == AliasResult::NoAlias;
665+
}
663666
bool isMustAlias(const MemoryLocation &LocA, const MemoryLocation &LocB) {
664667
return alias(LocA, LocB) == AliasResult::MustAlias;
665668
}

llvm/lib/Analysis/DependenceAnalysis.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -723,7 +723,10 @@ static AliasResult underlyingObjectsAlias(AAResults *AA,
723723
MemoryLocation::getBeforeOrAfter(LocA.Ptr, LocA.AATags);
724724
MemoryLocation LocBS =
725725
MemoryLocation::getBeforeOrAfter(LocB.Ptr, LocB.AATags);
726-
if (AA->isNoAlias(LocAS, LocBS))
726+
BatchAAResults BAA(*AA);
727+
BAA.enableCrossIterationMode();
728+
729+
if (BAA.isNoAlias(LocAS, LocBS))
727730
return AliasResult::NoAlias;
728731

729732
// Check the underlying objects are the same
@@ -744,7 +747,6 @@ static AliasResult underlyingObjectsAlias(AAResults *AA,
744747
return AliasResult::NoAlias;
745748
}
746749

747-
748750
// Returns true if the load or store can be analyzed. Atomic and volatile
749751
// operations have properties which this analysis does not understand.
750752
static
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt < %s -disable-output "-passes=print<da>" -aa-pipeline=basic-aa 2>&1 \
3+
; RUN: | FileCheck %s
4+
5+
; Check that dependence analysis correctly handles flip-flop of base addresses.
6+
; Bug 41488 - https://github.com/llvm/llvm-project/issues/41488
7+
8+
define float @bug41488_test1(float %f) {
9+
; CHECK-LABEL: 'bug41488_test1'
10+
; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: %0 = load float, ptr %p, align 4
11+
; CHECK-NEXT: da analyze - input [*]!
12+
; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: store float %f, ptr %q, align 4
13+
; CHECK-NEXT: da analyze - confused!
14+
; CHECK-NEXT: Src: store float %f, ptr %q, align 4 --> Dst: store float %f, ptr %q, align 4
15+
; CHECK-NEXT: da analyze - output [*]!
16+
;
17+
entry:
18+
%g = alloca float, align 4
19+
%h = alloca float, align 4
20+
br label %for.body
21+
22+
for.body:
23+
%p = phi float* [ %g, %entry ], [ %q, %for.body ]
24+
%q = phi float* [ %h, %entry ], [ %p, %for.body ]
25+
%0 = load float, float* %p, align 4
26+
store float %f, float* %q, align 4
27+
%branch_cond = fcmp ugt float %0, 0.0
28+
br i1 %branch_cond, label %for.cond.cleanup, label %for.body
29+
30+
for.cond.cleanup:
31+
ret float %f
32+
}
33+
34+
define void @bug41488_test2(i32 %n) {
35+
; CHECK-LABEL: 'bug41488_test2'
36+
; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: %0 = load float, ptr %p, align 4
37+
; CHECK-NEXT: da analyze - input [*]!
38+
; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: store float 0.000000e+00, ptr %q, align 4
39+
; CHECK-NEXT: da analyze - confused!
40+
; CHECK-NEXT: Src: store float 0.000000e+00, ptr %q, align 4 --> Dst: store float 0.000000e+00, ptr %q, align 4
41+
; CHECK-NEXT: da analyze - output [*]!
42+
;
43+
entry:
44+
%g = alloca float, align 4
45+
%h = alloca float, align 4
46+
br label %for.body
47+
48+
for.body:
49+
%i = phi i32 [0, %entry ], [ %inc, %for.body ]
50+
%p = phi float* [ %g, %entry ], [ %q, %for.body ]
51+
%q = phi float* [ %h, %entry ], [ %p, %for.body ]
52+
%0 = load float, float* %p, align 4
53+
store float 0.0, float* %q, align 4
54+
%inc = add nuw i32 %i, 1
55+
%branch_cond = icmp ult i32 %i, %n
56+
br i1 %branch_cond, label %for.body, label %for.cond.cleanup
57+
58+
for.cond.cleanup:
59+
ret void
60+
}
61+
62+
; Bug 53942 - https://github.com/llvm/llvm-project/issues/53942
63+
64+
define void @bug53942_foo(i32 noundef %n, ptr noalias nocapture noundef writeonly %A, ptr noalias nocapture noundef %B) {
65+
; CHECK-LABEL: 'bug53942_foo'
66+
; CHECK-NEXT: Src: %.pre = load double, ptr %B, align 8 --> Dst: %.pre = load double, ptr %B, align 8
67+
; CHECK-NEXT: da analyze - consistent input [S]!
68+
; CHECK-NEXT: Src: %.pre = load double, ptr %B, align 8 --> Dst: store double %.pre, ptr %arrayidx2, align 8
69+
; CHECK-NEXT: da analyze - confused!
70+
; CHECK-NEXT: Src: store double %.pre, ptr %arrayidx2, align 8 --> Dst: store double %.pre, ptr %arrayidx2, align 8
71+
; CHECK-NEXT: da analyze - output [*]!
72+
;
73+
entry:
74+
%cmp8 = icmp sgt i32 %n, 1
75+
br i1 %cmp8, label %for.body.preheader, label %for.cond.cleanup
76+
77+
for.body.preheader: ; preds = %entry
78+
%wide.trip.count = zext nneg i32 %n to i64
79+
br label %for.body
80+
81+
for.cond.cleanup: ; preds = %for.body, %entry
82+
ret void
83+
84+
for.body: ; preds = %for.body.preheader, %for.body
85+
%indvars.iv = phi i64 [ 1, %for.body.preheader ], [ %indvars.iv.next, %for.body ]
86+
%ptr1.011 = phi ptr [ %A, %for.body.preheader ], [ %ptr2.09, %for.body ]
87+
%ptr2.09 = phi ptr [ %B, %for.body.preheader ], [ %ptr1.011, %for.body ]
88+
%.pre = load double, ptr %B, align 8
89+
%arrayidx2 = getelementptr inbounds double, ptr %ptr1.011, i64 %indvars.iv
90+
store double %.pre, ptr %arrayidx2, align 8
91+
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
92+
%exitcond.not = icmp eq i64 %indvars.iv.next, %wide.trip.count
93+
br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
94+
}
95+
96+
97+
; Bug 53942 - https://github.com/llvm/llvm-project/issues/53942
98+
99+
define void @bug53942_bar(i32 noundef %n, ptr noalias noundef %A, ptr noalias noundef %B) {
100+
; CHECK-LABEL: 'bug53942_bar'
101+
; CHECK-NEXT: Src: %0 = load double, ptr %arrayidx, align 8 --> Dst: %0 = load double, ptr %arrayidx, align 8
102+
; CHECK-NEXT: da analyze - input [*]!
103+
; CHECK-NEXT: Src: %0 = load double, ptr %arrayidx, align 8 --> Dst: store double %0, ptr %arrayidx8, align 8
104+
; CHECK-NEXT: da analyze - confused!
105+
; CHECK-NEXT: Src: store double %0, ptr %arrayidx8, align 8 --> Dst: store double %0, ptr %arrayidx8, align 8
106+
; CHECK-NEXT: da analyze - output [*]!
107+
;
108+
entry:
109+
br label %for.cond
110+
111+
for.cond: ; preds = %for.inc, %entry
112+
%i.0 = phi i32 [ 1, %entry ], [ %inc, %for.inc ]
113+
%cmp = icmp slt i32 %i.0, %n
114+
br i1 %cmp, label %for.body, label %for.cond.cleanup
115+
116+
for.cond.cleanup: ; preds = %for.cond
117+
br label %for.end
118+
119+
for.body: ; preds = %for.cond
120+
%and = and i32 %i.0, 2
121+
%tobool.not = icmp eq i32 %and, 0
122+
br i1 %tobool.not, label %cond.false, label %cond.true
123+
124+
cond.true: ; preds = %for.body
125+
br label %cond.end
126+
127+
cond.false: ; preds = %for.body
128+
br label %cond.end
129+
130+
cond.end: ; preds = %cond.false, %cond.true
131+
%cond = phi ptr [ %A, %cond.true ], [ %B, %cond.false ]
132+
%and1 = and i32 %i.0, 2
133+
%tobool2.not = icmp eq i32 %and1, 0
134+
br i1 %tobool2.not, label %cond.false4, label %cond.true3
135+
136+
cond.true3: ; preds = %cond.end
137+
br label %cond.end5
138+
139+
cond.false4: ; preds = %cond.end
140+
br label %cond.end5
141+
142+
cond.end5: ; preds = %cond.false4, %cond.true3
143+
%cond6 = phi ptr [ %B, %cond.true3 ], [ %A, %cond.false4 ]
144+
%sub = add nsw i32 %i.0, -1
145+
%idxprom = sext i32 %sub to i64
146+
%arrayidx = getelementptr inbounds double, ptr %cond6, i64 %idxprom
147+
%0 = load double, ptr %arrayidx, align 8
148+
%idxprom7 = zext nneg i32 %i.0 to i64
149+
%arrayidx8 = getelementptr inbounds double, ptr %cond, i64 %idxprom7
150+
store double %0, ptr %arrayidx8, align 8
151+
br label %for.inc
152+
153+
for.inc: ; preds = %cond.end5
154+
%inc = add nuw nsw i32 %i.0, 1
155+
br label %for.cond
156+
157+
for.end: ; preds = %for.cond.cleanup
158+
ret void
159+
}

0 commit comments

Comments
 (0)