1; RUN: opt < %s -phi-values -basic-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
2; RUN: opt < %s -aa-pipeline=basic-aa -passes='require<phi-values>,aa-eval' -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
3target 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"
4target triple = "x86_64-unknown-linux-gnu"
5
6; rdar://7282591
7
8@X = common global i32 0
9@Y = common global i32 0
10@Z = common global i32 0
11
12; CHECK-LABEL: foo
13; CHECK:  NoAlias: i32* %P, i32* @Z
14
15define void @foo(i32 %cond) nounwind {
16entry:
17  %"alloca point" = bitcast i32 0 to i32
18  %tmp = icmp ne i32 %cond, 0
19  br i1 %tmp, label %bb, label %bb1
20
21bb:
22  br label %bb2
23
24bb1:
25  br label %bb2
26
27bb2:
28  %P = phi i32* [ @X, %bb ], [ @Y, %bb1 ]
29  %tmp1 = load i32, i32* @Z, align 4
30  store i32 123, i32* %P, align 4
31  %tmp2 = load i32, i32* @Z, align 4
32  br label %return
33
34return:
35  ret void
36}
37
38; Pointers can vary in between iterations of loops.
39; PR18068
40
41; CHECK-LABEL: pr18068
42; CHECK: MayAlias: i32* %0, i32* %arrayidx5
43; CHECK: NoAlias: i32* %arrayidx13, i32* %arrayidx5
44
45define i32 @pr18068(i32* %jj7, i32* %j) {
46entry:
47  %oa5 = alloca [100 x i32], align 16
48  br label %codeRepl
49
50codeRepl:
51  %0 = phi i32* [ %arrayidx13, %for.body ], [ %j, %entry ]
52  %targetBlock = call i1 @cond(i32* %jj7)
53  br i1 %targetBlock, label %for.body, label %bye
54
55for.body:
56  %1 = load i32, i32* %jj7, align 4
57  %idxprom4 = zext i32 %1 to i64
58  %arrayidx5 = getelementptr inbounds [100 x i32], [100 x i32]* %oa5, i64 0, i64 %idxprom4
59  %2 = load i32, i32* %arrayidx5, align 4
60  %sub6 = sub i32 %2, 6
61  store i32 %sub6, i32* %arrayidx5, align 4
62  ; %0 and %arrayidx5 can alias! It is not safe to DSE the above store.
63  %3 = load i32, i32* %0, align 4
64  store i32 %3, i32* %arrayidx5, align 4
65  %sub11 = add i32 %1, -1
66  %idxprom12 = zext i32 %sub11 to i64
67  %arrayidx13 = getelementptr inbounds [100 x i32], [100 x i32]* %oa5, i64 0, i64 %idxprom12
68  call void @inc(i32* %jj7)
69  br label %codeRepl
70
71bye:
72  %.reload = load i32, i32* %jj7, align 4
73  ret i32 %.reload
74}
75
76declare i1 @cond(i32*)
77
78declare void @inc(i32*)
79
80
81; When we have a chain of phis in nested loops we should recognise if there's
82; actually only one underlying value.
83; CHECK-LABEL: loop_phi_chain
84; CHECK: NoAlias: i32* %val1, i32* @Y
85; CHECK: NoAlias: i32* %val2, i32* @Y
86; CHECK: NoAlias: i32* %val3, i32* @Y
87define void @loop_phi_chain(i32 %a, i32 %b, i32 %c) {
88entry:
89  br label %loop1
90
91loop1:
92  %n1 = phi i32 [ 0, %entry ], [ %add1, %loop2 ]
93  %val1 = phi i32* [ @X, %entry ], [ %val2, %loop2 ]
94  %add1 = add i32 %n1, 1
95  %cmp1 = icmp ne i32 %n1, 32
96  br i1 %cmp1, label %loop2, label %end
97
98loop2:
99  %n2 = phi i32 [ 0, %loop1 ], [ %add2, %loop3 ]
100  %val2 = phi i32* [ %val1, %loop1 ], [ %val3, %loop3 ]
101  %add2 = add i32 %n2, 1
102  %cmp2 = icmp ne i32 %n2, 32
103  br i1 %cmp2, label %loop3, label %loop1
104
105loop3:
106  %n3 = phi i32 [ 0, %loop2 ], [ %add3, %loop3 ]
107  %val3 = phi i32* [ %val2, %loop2 ], [ %val3, %loop3 ]
108  store i32 0, i32* %val3, align 4
109  store i32 0, i32* @Y, align 4
110  %add3 = add i32 %n3, 1
111  %cmp3 = icmp ne i32 %n3, 32
112  br i1 %cmp3, label %loop3, label %loop2
113
114end:
115  ret void
116}
117
118; CHECK-LABEL: phi_and_select
119; CHECK: MustAlias: i32* %p, i32* %s
120define void @phi_and_select(i1 %c, i1 %c2, i32* %x, i32* %y) {
121entry:
122  br i1 %c, label %true, label %false
123
124true:
125  br label %exit
126
127false:
128  br label %exit
129
130exit:
131  %p = phi i32* [ %x, %true ], [ %y, %false ]
132  %s = select i1 %c2, i32* %p, i32* %p
133  store i32 0, i32* %p
134  store i32 0, i32* %s
135  ret void
136}
137
138; CHECK-LABEL: phi_and_phi_cycle
139; CHECK: NoAlias: i32* %p1, i32* %p2
140define void @phi_and_phi_cycle(i32* noalias %x, i32* noalias %y) {
141entry:
142  br label %loop
143
144loop:
145  %p1 = phi i32* [ %x, %entry ], [ %p1.next, %loop ]
146  %p2 = phi i32* [ %y, %entry ], [ %p2.next, %loop ]
147  %p1.next = getelementptr i32, i32* %p1, i64 1
148  %p2.next = getelementptr i32, i32* %p1, i64 2
149  store i32 0, i32* %p1
150  store i32 0, i32* %p2
151  br label %loop
152}
153
154; CHECK-LABEL: phi_and_gep_unknown_size
155; CHECK: Just Mod:   call void @llvm.memset.p0i8.i32(i8* %g, i8 0, i32 %size, i1 false) <->   call void @llvm.memset.p0i8.i32(i8* %z, i8 0, i32 %size, i1 false)
156; TODO: This should be NoModRef.
157define void @phi_and_gep_unknown_size(i1 %c, i8* %x, i8* %y, i8* noalias %z, i32 %size) {
158entry:
159  br i1 %c, label %true, label %false
160
161true:
162  br label %exit
163
164false:
165  br label %exit
166
167exit:
168  %p = phi i8* [ %x, %true ], [ %y, %false ]
169  %g = getelementptr inbounds i8, i8* %p, i64 1
170  call void @llvm.memset.p0i8.i32(i8* %g, i8 0, i32 %size, i1 false)
171  call void @llvm.memset.p0i8.i32(i8* %z, i8 0, i32 %size, i1 false)
172  ret void
173}
174
175declare void @llvm.memset.p0i8.i32(i8*, i8, i32, i1)
176
177; CHECK-LABEL: unsound_inequality
178; CHECK: MayAlias:  i32* %arrayidx13, i32* %phi
179; CHECK: MayAlias:  i32* %arrayidx5, i32* %phi
180; CHECK: NoAlias:   i32* %arrayidx13, i32* %arrayidx5
181
182; When recursively reasoning about phis, we can't use predicates between
183; two values as we might be comparing the two from different iterations.
184define i32 @unsound_inequality(i32* %jj7, i32* %j) {
185entry:
186  %oa5 = alloca [100 x i32], align 16
187  br label %for.body
188
189for.body:                                         ; preds = %for.body, %entry
190  %phi = phi i32* [ %arrayidx13, %for.body ], [ %j, %entry ]
191  %idx = load i32, i32* %jj7, align 4
192  %arrayidx5 = getelementptr inbounds [100 x i32], [100 x i32]* %oa5, i64 0, i32 %idx
193  store i32 0, i32* %arrayidx5, align 4
194  store i32 0, i32* %phi, align 4
195  %notequal = add i32 %idx, 1
196  %arrayidx13 = getelementptr inbounds [100 x i32], [100 x i32]* %oa5, i64 0, i32 %notequal
197  store i32 0, i32* %arrayidx13, align 4
198  br label %for.body
199}
200