1; RUN: opt < %s -aa-pipeline=basic-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
2target 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"
3target triple = "x86_64-unknown-linux-gnu"
4
5; CHECK-LABEL: test_with_zext
6; CHECK:  NoAlias: i8* %a, i8* %b
7
8define void @test_with_zext() {
9  %1 = tail call i8* @malloc(i64 120)
10  %a = getelementptr inbounds i8, i8* %1, i64 8
11  %2 = getelementptr inbounds i8, i8* %1, i64 16
12  %3 = zext i32 3 to i64
13  %b = getelementptr inbounds i8, i8* %2, i64 %3
14  load i8, i8* %a
15  load i8, i8* %b
16  ret void
17}
18
19; CHECK-LABEL: test_with_lshr
20; CHECK:  NoAlias: i8* %a, i8* %b
21
22define void @test_with_lshr(i64 %i) {
23  %1 = tail call i8* @malloc(i64 120)
24  %a = getelementptr inbounds i8, i8* %1, i64 8
25  %2 = getelementptr inbounds i8, i8* %1, i64 16
26  %3 = lshr i64 %i, 2
27  %b = getelementptr inbounds i8, i8* %2, i64 %3
28  load i8, i8* %a
29  load i8, i8* %b
30  ret void
31}
32
33; CHECK-LABEL: test_with_lshr_different_sizes
34; CHECK:  NoAlias: i8* %m1, i16* %m2.idx
35
36define void @test_with_lshr_different_sizes(i64 %i) {
37  %m0 = tail call i8* @malloc(i64 120)
38  %m1 = getelementptr inbounds i8, i8* %m0, i64 1
39  load i8, i8* %m1
40  %m2 = getelementptr inbounds i8, i8* %m0, i64 2
41  %idx = lshr i64 %i, 2
42  %m2.i16 = bitcast i8* %m2 to i16*
43  %m2.idx = getelementptr inbounds i16, i16* %m2.i16, i64 %idx
44  load i16, i16* %m2.idx
45  ret void
46}
47
48; CHECK-LABEL: test_with_a_loop
49; CHECK:  NoAlias: i8* %a, i8* %b
50
51define void @test_with_a_loop(i8* %mem) {
52  br label %for.loop
53
54for.loop:
55  %i = phi i32 [ 0, %0 ], [ %i.plus1, %for.loop ]
56  %a = getelementptr inbounds i8, i8* %mem, i64 8
57  load i8, i8* %a
58  %a.plus1 = getelementptr inbounds i8, i8* %mem, i64 16
59  %i.64 = zext i32 %i to i64
60  %b = getelementptr inbounds i8, i8* %a.plus1, i64 %i.64
61  load i8, i8* %b
62  %i.plus1 = add nuw nsw i32 %i, 1
63  %cmp = icmp eq i32 %i.plus1, 10
64  br i1 %cmp, label %for.loop.exit, label %for.loop
65
66for.loop.exit:
67  ret void
68}
69
70; CHECK-LABEL: test_with_varying_base_pointer_in_loop
71; CHECK:  NoAlias: i8* %a, i8* %b
72
73define void @test_with_varying_base_pointer_in_loop(i8* %mem.orig) {
74  br label %for.loop
75
76for.loop:
77  %mem = phi i8* [ %mem.orig, %0 ], [ %mem.plus1, %for.loop ]
78  %i = phi i32 [ 0, %0 ], [ %i.plus1, %for.loop ]
79  %a = getelementptr inbounds i8, i8* %mem, i64 8
80  load i8, i8* %a
81  %a.plus1 = getelementptr inbounds i8, i8* %mem, i64 16
82  %i.64 = zext i32 %i to i64
83  %b = getelementptr inbounds i8, i8* %a.plus1, i64 %i.64
84  load i8, i8* %b
85  %i.plus1 = add nuw nsw i32 %i, 1
86  %mem.plus1 = getelementptr inbounds i8, i8* %mem, i64 8
87  %cmp = icmp eq i32 %i.plus1, 10
88  br i1 %cmp, label %for.loop.exit, label %for.loop
89
90for.loop.exit:
91  ret void
92}
93
94; CHECK-LABEL: test_sign_extension
95; CHECK:  MayAlias: i8* %a, i64* %b.i64
96
97define void @test_sign_extension(i32 %p) {
98  %1 = tail call i8* @malloc(i64 120)
99  %p.64 = zext i32 %p to i64
100  %a = getelementptr inbounds i8, i8* %1, i64 %p.64
101  load i8, i8* %a
102  %p.minus1 = add i32 %p, -1
103  %p.minus1.64 = zext i32 %p.minus1 to i64
104  %b.i8 = getelementptr inbounds i8, i8* %1, i64 %p.minus1.64
105  %b.i64 = bitcast i8* %b.i8 to i64*
106  load i64, i64* %b.i64
107  ret void
108}
109
110; CHECK-LABEL: test_fe_tools
111; CHECK:  MayAlias: i32* %a, i32* %b
112
113define void @test_fe_tools([8 x i32]* %values) {
114  br label %reorder
115
116for.loop:
117  %i = phi i32 [ 0, %reorder ], [ %i.next, %for.loop ]
118  %idxprom = zext i32 %i to i64
119  %b = getelementptr inbounds [8 x i32], [8 x i32]* %values, i64 0, i64 %idxprom
120  load i32, i32* %b
121  %i.next = add nuw nsw i32 %i, 1
122  %cmp = icmp eq i32 %i.next, 10
123  br i1 %cmp, label %for.loop.exit, label %for.loop
124
125reorder:
126  %a = getelementptr inbounds [8 x i32], [8 x i32]* %values, i64 0, i64 1
127  load i32, i32* %a
128  br label %for.loop
129
130for.loop.exit:
131  ret void
132}
133
134@b = global i32 0, align 4
135@d = global i32 0, align 4
136
137; CHECK-LABEL: test_spec2006
138; CHECK:  MayAlias: i32** %x, i32** %y
139
140define void @test_spec2006() {
141  %h = alloca [1 x [2 x i32*]], align 16
142  %d.val = load i32, i32* @d, align 4
143  %d.promoted = sext i32 %d.val to i64
144  %1 = icmp slt i32 %d.val, 2
145  br i1 %1, label %.lr.ph, label %bb3
146
147.lr.ph:                                           ; preds = %0
148  br label %bb2
149
150bb2:
151  %i = phi i32 [ %d.val, %.lr.ph ], [ %i.plus1, %bb2 ]
152  %i.promoted = sext i32 %i to i64
153  %x = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 %d.promoted, i64 %i.promoted
154  load i32*, i32** %x
155  %i.plus1 = add nsw i32 %i, 1
156  %cmp = icmp slt i32 %i.plus1, 2
157  br i1 %cmp, label %bb2, label %bb3
158
159bb3:
160  %y = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 0, i64 1
161  load i32*, i32** %y
162  ret void
163}
164
165; CHECK-LABEL: test_modulo_analysis_easy_case
166; CHECK:  NoAlias: i32** %x, i32** %y
167
168define void @test_modulo_analysis_easy_case(i64 %i) {
169  %h = alloca [1 x [2 x i32*]], align 16
170  %x = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 %i, i64 0
171  %y = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 0, i64 1
172  load i32*, i32** %x
173  load i32*, i32** %y
174  ret void
175}
176
177; CHECK-LABEL: test_modulo_analysis_in_loop
178; CHECK:  NoAlias: i32** %x, i32** %y
179
180define void @test_modulo_analysis_in_loop() {
181  %h = alloca [1 x [2 x i32*]], align 16
182  br label %for.loop
183
184for.loop:
185  %i = phi i32 [ 0, %0 ], [ %i.plus1, %for.loop ]
186  %i.promoted = sext i32 %i to i64
187  %x = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 %i.promoted, i64 0
188  %y = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 0, i64 1
189  load i32*, i32** %x
190  load i32*, i32** %y
191  %i.plus1 = add nsw i32 %i, 1
192  %cmp = icmp slt i32 %i.plus1, 2
193  br i1 %cmp, label %for.loop, label %for.loop.exit
194
195for.loop.exit:
196  ret void
197}
198
199; CHECK-LABEL: test_modulo_analysis_with_global
200; CHECK:  MayAlias: i32** %x, i32** %y
201
202define void @test_modulo_analysis_with_global() {
203  %h = alloca [1 x [2 x i32*]], align 16
204  %b = load i32, i32* @b, align 4
205  %b.promoted = sext i32 %b to i64
206  br label %for.loop
207
208for.loop:
209  %i = phi i32 [ 0, %0 ], [ %i.plus1, %for.loop ]
210  %i.promoted = sext i32 %i to i64
211  %x = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 %i.promoted, i64 %b.promoted
212  %y = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 0, i64 1
213  load i32*, i32** %x
214  load i32*, i32** %y
215  %i.plus1 = add nsw i32 %i, 1
216  %cmp = icmp slt i32 %i.plus1, 2
217  br i1 %cmp, label %for.loop, label %for.loop.exit
218
219for.loop.exit:
220  ret void
221}
222
223; CHECK-LABEL: test_const_eval
224; CHECK: NoAlias: i8* %a, i8* %b
225define void @test_const_eval(i8* %ptr, i64 %offset) {
226  %a = getelementptr inbounds i8, i8* %ptr, i64 %offset
227  %a.dup = getelementptr inbounds i8, i8* %ptr, i64 %offset
228  %three = zext i32 3 to i64
229  %b = getelementptr inbounds i8, i8* %a.dup, i64 %three
230  load i8, i8* %a
231  load i8, i8* %b
232  ret void
233}
234
235; CHECK-LABEL: test_const_eval_scaled
236; CHECK: MustAlias: i8* %a, i8* %b
237define void @test_const_eval_scaled(i8* %ptr) {
238  %three = zext i32 3 to i64
239  %six = mul i64 %three, 2
240  %a = getelementptr inbounds i8, i8* %ptr, i64 %six
241  %b = getelementptr inbounds i8, i8* %ptr, i64 6
242  load i8, i8* %a
243  load i8, i8* %b
244  ret void
245}
246
247; CHECK-LABEL: Function: foo
248; CHECK: MustAlias:    float* %arrayidx, float* %arrayidx4.84
249define float @foo(i32 *%A, float %rend, float** %wayar)  {
250entry:
251  %x0 = load i32, i32* %A, align 4
252  %conv = sext i32 %x0 to i64
253  %mul = shl nsw i64 %conv, 3
254  %call = tail call i8* @malloc(i64 %mul)
255  %x1 = bitcast i8* %call to float*
256
257  %sub = add nsw i32 %x0, -1
258  %idxprom = sext i32 %sub to i64
259  %arrayidx = getelementptr inbounds float, float* %x1, i64 %idxprom
260  store float %rend, float* %arrayidx, align 8
261
262  %indvars.iv76.83 = add nsw i64 %conv, -1
263  %arrayidx4.84 = getelementptr inbounds float, float* %x1, i64 %indvars.iv76.83
264  %x4 = load float, float* %arrayidx4.84, align 8
265
266  ret float %x4
267}
268
269; CHECK-LABEL: Function: test_shl_nuw_zext
270; CHECK: MustAlias: i8* %p.1, i8* %p.2
271define void @test_shl_nuw_zext(i8* %p, i32 %x) {
272  %shl = shl nuw i32 %x, 1
273  %shl.ext = zext i32 %shl to i64
274  %ext = zext i32 %x to i64
275  %ext.shl = shl nuw i64 %ext, 1
276  %p.1 = getelementptr i8, i8* %p, i64 %shl.ext
277  %p.2 = getelementptr i8, i8* %p, i64 %ext.shl
278  load i8, i8* %p.1
279  load i8, i8* %p.2
280  ret void
281}
282
283; CHECK-LABEL: Function: test_shl_nsw_sext
284; CHECK: MustAlias: i8* %p.1, i8* %p.2
285define void @test_shl_nsw_sext(i8* %p, i32 %x) {
286  %shl = shl nsw i32 %x, 1
287  %shl.ext = sext i32 %shl to i64
288  %ext = sext i32 %x to i64
289  %ext.shl = shl nsw i64 %ext, 1
290  %p.1 = getelementptr i8, i8* %p, i64 %shl.ext
291  %p.2 = getelementptr i8, i8* %p, i64 %ext.shl
292  load i8, i8* %p.1
293  load i8, i8* %p.2
294  ret void
295}
296
297; CHECK-LABEL: Function: test_implicit_sext
298; CHECK: MayAlias: i8* %p.1, i8* %p.2
299define void @test_implicit_sext(i8* %p, i32 %x) {
300  %add = add i32 %x, 1
301  %ext = sext i32 %x to i64
302  %ext.add = add i64 %ext, 1
303  %p.1 = getelementptr i8, i8* %p, i32 %add
304  %p.2 = getelementptr i8, i8* %p, i64 %ext.add
305  load i8, i8* %p.1
306  load i8, i8* %p.2
307  ret void
308}
309
310; CHECK-LABEL: Function: test_partial_decomposition
311; CHECK: MustAlias: i8* %p.1, i8* %p.2
312define void @test_partial_decomposition(i8* %p, i32 %x) {
313  %add = add i32 %x, 1
314  %add.1 = add nsw i32 %add, 1
315  %add.2 = add nsw i32 %add, 1
316  %p.1 = getelementptr i8, i8* %p, i32 %add.1
317  %p.2 = getelementptr i8, i8* %p, i32 %add.2
318  load i8, i8* %p.1
319  load i8, i8* %p.2
320  ret void
321}
322
323; Function Attrs: nounwind
324declare noalias i8* @malloc(i64)
325