Skip to content

Commit 4f1db68

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 5048808 commit 4f1db68

File tree

3 files changed

+143
-2
lines changed

3 files changed

+143
-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
@@ -722,7 +722,10 @@ static AliasResult underlyingObjectsAlias(AAResults *AA,
722722
MemoryLocation::getBeforeOrAfter(LocA.Ptr, LocA.AATags);
723723
MemoryLocation LocBS =
724724
MemoryLocation::getBeforeOrAfter(LocB.Ptr, LocB.AATags);
725-
if (AA->isNoAlias(LocAS, LocBS))
725+
BatchAAResults BAA(*AA);
726+
BAA.enableCrossIterationMode();
727+
728+
if (BAA.isNoAlias(LocAS, LocBS))
726729
return AliasResult::NoAlias;
727730

728731
// Check the underlying objects are the same
@@ -743,7 +746,6 @@ static AliasResult underlyingObjectsAlias(AAResults *AA,
743746
return AliasResult::NoAlias;
744747
}
745748

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

0 commit comments

Comments
 (0)