1; RUN: opt < %s -aa-pipeline=basic-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
2
3; getelementptr
4
5; CHECK-LABEL: gep_alloca_const_offset_1
6; CHECK-DAG:  MustAlias:    <vscale x 4 x i32>* %alloc, <vscale x 4 x i32>* %gep1
7; CHECK-DAG:  MayAlias:     <vscale x 4 x i32>* %alloc, <vscale x 4 x i32>* %gep2
8; CHECK-DAG:  MayAlias:     <vscale x 4 x i32>* %gep1, <vscale x 4 x i32>* %gep2
9define void @gep_alloca_const_offset_1() {
10  %alloc = alloca <vscale x 4 x i32>
11  %gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 0
12  %gep2 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 1
13  load <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc
14  load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep1
15  load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep2
16  ret void
17}
18
19; CHECK-LABEL: gep_alloca_const_offset_2
20; CHECK-DAG:  MayAlias:     <vscale x 4 x i32>* %alloc, <vscale x 4 x i32>* %gep1
21; CHECK-DAG:  MayAlias:     <vscale x 4 x i32>* %alloc, <vscale x 4 x i32>* %gep2
22; TODO: AliasResult for gep1,gep2 can be improved as MustAlias
23; CHECK-DAG:  MayAlias:     <vscale x 4 x i32>* %gep1, <vscale x 4 x i32>* %gep2
24define void @gep_alloca_const_offset_2() {
25  %alloc = alloca <vscale x 4 x i32>
26  %gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 1
27  %gep2 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 1
28  load <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc
29  load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep1
30  load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep2
31  ret void
32}
33
34; CHECK-LABEL: gep_alloca_const_offset_3
35; CHECK-DAG:  MustAlias:    <vscale x 4 x i32>* %alloc, <vscale x 4 x i32>* %gep1
36; CHECK-DAG:  MayAlias:     <vscale x 4 x i32>* %alloc, i32* %gep2
37; CHECK-DAG:  MayAlias:     <vscale x 4 x i32>* %gep1, i32* %gep2
38define void @gep_alloca_const_offset_3() {
39  %alloc = alloca <vscale x 4 x i32>
40  %gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 0
41  %gep2 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 0, i64 1
42  load <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc
43  load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep1
44  load i32, i32* %gep2
45  ret void
46}
47
48; CHECK-LABEL: gep_alloca_const_offset_4
49; CHECK-DAG:  MustAlias:    <vscale x 4 x i32>* %alloc, <vscale x 4 x i32>* %gep1
50; CHECK-DAG:  MustAlias:    <vscale x 4 x i32>* %alloc, i32* %gep2
51; CHECK-DAG:  MustAlias:    <vscale x 4 x i32>* %gep1, i32* %gep2
52define void @gep_alloca_const_offset_4() {
53  %alloc = alloca <vscale x 4 x i32>
54  %gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 0
55  %gep2 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 0, i64 0
56  load <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc
57  load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep1
58  load i32, i32* %gep2
59  ret void
60}
61
62; CHECK-LABEL: gep_alloca_symbolic_offset
63; CHECK-DAG:  MayAlias:     <vscale x 4 x i32>* %alloc, <vscale x 4 x i32>* %gep1
64; CHECK-DAG:  MayAlias:     <vscale x 4 x i32>* %alloc, <vscale x 4 x i32>* %gep2
65; CHECK-DAG:  MayAlias:     <vscale x 4 x i32>* %gep1, <vscale x 4 x i32>* %gep2
66define void @gep_alloca_symbolic_offset(i64 %idx1, i64 %idx2) {
67  %alloc = alloca <vscale x 4 x i32>
68  %gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 %idx1
69  %gep2 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 %idx2
70  load <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc
71  load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep1
72  load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep2
73  ret void
74}
75
76; CHECK-LABEL: gep_same_base_const_offset
77; CHECK-DAG:  MayAlias:     i32* %gep1, <vscale x 4 x i32>* %p
78; CHECK-DAG:  MayAlias:     i32* %gep2, <vscale x 4 x i32>* %p
79; TODO: AliasResult for gep1,gep2 can be improved as NoAlias
80; CHECK-DAG:  MayAlias:     i32* %gep1, i32* %gep2
81define void @gep_same_base_const_offset(<vscale x 4 x i32>* %p) {
82  %gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 1, i64 0
83  %gep2 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 1, i64 1
84  load <vscale x 4 x i32>, <vscale x 4 x i32>* %p
85  load i32, i32* %gep1
86  load i32, i32* %gep2
87  ret void
88}
89
90; CHECK-LABEL: gep_same_base_symbolic_offset
91; CHECK-DAG:  MayAlias:     <vscale x 4 x i32>* %gep1, <vscale x 4 x i32>* %p
92; CHECK-DAG:  MayAlias:     <vscale x 4 x i32>* %gep2, <vscale x 4 x i32>* %p
93; CHECK-DAG:  MayAlias:     <vscale x 4 x i32>* %gep1, <vscale x 4 x i32>* %gep2
94define void @gep_same_base_symbolic_offset(<vscale x 4 x i32>* %p, i64 %idx1, i64 %idx2) {
95  %gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 %idx1
96  %gep2 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 %idx2
97  load <vscale x 4 x i32>, <vscale x 4 x i32>* %p
98  load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep1
99  load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep2
100  ret void
101}
102
103; CHECK-LABEL: gep_different_base_const_offset
104; CHECK-DAG:  MayAlias:     <vscale x 4 x i32>* %gep1, <vscale x 4 x i32>* %p1
105; CHECK-DAG:  MayAlias:     <vscale x 4 x i32>* %gep2, <vscale x 4 x i32>* %p2
106; CHECK-DAG:  NoAlias:      <vscale x 4 x i32>* %p1, <vscale x 4 x i32>* %p2
107; CHECK-DAG:  NoAlias:      <vscale x 4 x i32>* %gep1, <vscale x 4 x i32>* %p2
108; CHECK-DAG:  NoAlias:      <vscale x 4 x i32>* %gep2, <vscale x 4 x i32>* %p1
109; CHECK-DAG:  NoAlias:      <vscale x 4 x i32>* %gep1, <vscale x 4 x i32>* %gep2
110define void @gep_different_base_const_offset(<vscale x 4 x i32>* noalias %p1, <vscale x 4 x i32>* noalias %p2) {
111  %gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p1, i64 1
112  %gep2 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p2, i64 1
113  load <vscale x 4 x i32>, <vscale x 4 x i32>* %p1
114  load <vscale x 4 x i32>, <vscale x 4 x i32>* %p2
115  load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep1
116  load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep2
117  ret void
118}
119
120; getelementptr + bitcast
121
122; CHECK-LABEL: gep_bitcast_1
123; CHECK-DAG:   MustAlias:    <vscale x 4 x i32>* %p, i32* %p2
124; CHECK-DAG:   MayAlias:     i32* %gep1, <vscale x 4 x i32>* %p
125; CHECK-DAG:   MayAlias:     i32* %gep1, i32* %p2
126; CHECK-DAG:   MayAlias:     i32* %gep2, <vscale x 4 x i32>* %p
127; CHECK-DAG:   MayAlias:     i32* %gep1, i32* %gep2
128; CHECK-DAG:   NoAlias:      i32* %gep2, i32* %p2
129define void @gep_bitcast_1(<vscale x 4 x i32>* %p) {
130  %gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 1, i64 0
131  %p2 = bitcast <vscale x 4 x i32>* %p to i32*
132  %gep2 = getelementptr i32, i32* %p2, i64 4
133  load <vscale x 4 x i32>, <vscale x 4 x i32>* %p
134  load i32, i32* %gep1
135  load i32, i32* %gep2
136  load i32, i32* %p2
137  ret void
138}
139
140; CHECK-LABEL: gep_bitcast_2
141; CHECK-DAG:  MustAlias:    <vscale x 4 x i32>* %p, <vscale x 4 x float>* %p2
142; CHECK-DAG:  MayAlias:     i32* %gep1, <vscale x 4 x i32>* %p
143; CHECK-DAG:  MayAlias:     i32* %gep1, <vscale x 4 x float>* %p2
144; CHECK-DAG:  MayAlias:     float* %gep2, <vscale x 4 x i32>* %p
145; CHECK-DAG:  MayAlias:     i32* %gep1, float* %gep2
146; CHECK-DAG:  MayAlias:     float* %gep2, <vscale x 4 x float>* %p2
147define void @gep_bitcast_2(<vscale x 4 x i32>* %p) {
148  %gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 1, i64 0
149  %p2 = bitcast <vscale x 4 x i32>* %p to <vscale x 4 x float>*
150  %gep2 = getelementptr <vscale x 4 x float>, <vscale x 4 x float>* %p2, i64 1, i64 0
151  load i32, i32* %gep1
152  load float, float* %gep2
153  load <vscale x 4 x i32>, <vscale x 4 x i32>* %p
154  load <vscale x 4 x float>, <vscale x 4 x float>* %p2
155  ret void
156}
157
158; getelementptr recursion
159
160; CHECK-LABEL: gep_recursion_level_1
161; CHECK-DAG:  MayAlias:     i32* %a, <vscale x 4 x i32>* %p
162; CHECK-DAG:  MayAlias:     i32* %a, i32* %gep
163; CHECK-DAG:  MayAlias:     i32* %a, i32* %gep_rec_1
164; CHECK-DAG:  MayAlias:     i32* %gep, <vscale x 4 x i32>* %p
165; CHECK-DAG:  MayAlias:     i32* %gep_rec_1, <vscale x 4 x i32>* %p
166; CHECK-DAG:  NoAlias:      i32* %gep, i32* %gep_rec_1
167define void @gep_recursion_level_1(i32* %a, <vscale x 4 x i32>* %p) {
168  %gep = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 1, i64 2
169  %gep_rec_1 = getelementptr i32, i32* %gep, i64 1
170  load <vscale x 4 x i32>, <vscale x 4 x i32>* %p
171  load i32, i32* %a
172  load i32, i32* %gep
173  load i32, i32* %gep_rec_1
174  ret void
175}
176
177; CHECK-LABEL: gep_recursion_level_1_bitcast
178; CHECK-DAG:  MustAlias:    i32* %a, <vscale x 4 x i32>* %p
179; CHECK-DAG:  MayAlias:     i32* %a, i32* %gep
180; CHECK-DAG:  MayAlias:     i32* %a, i32* %gep_rec_1
181; CHECK-DAG:  MayAlias:     i32* %gep, <vscale x 4 x i32>* %p
182; CHECK-DAG:  MayAlias:     i32* %gep_rec_1, <vscale x 4 x i32>* %p
183; CHECK-DAG:  NoAlias:      i32* %gep, i32* %gep_rec_1
184define void @gep_recursion_level_1_bitcast(i32* %a) {
185  %p = bitcast i32* %a to <vscale x 4 x i32>*
186  %gep = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 1, i64 2
187  %gep_rec_1 = getelementptr i32, i32* %gep, i64 1
188  load <vscale x 4 x i32>, <vscale x 4 x i32>* %p
189  load i32, i32* %a
190  load i32, i32* %gep
191  load i32, i32* %gep_rec_1
192  ret void
193}
194
195; CHECK-LABEL: gep_recursion_level_2
196; CHECK-DAG:  MayAlias:     i32* %a, <vscale x 4 x i32>* %p
197; CHECK-DAG:  MayAlias:     i32* %a, i32* %gep
198; CHECK-DAG:  MayAlias:     i32* %a, i32* %gep_rec_1
199; CHECK-DAG:  MayAlias:     i32* %a, i32* %gep_rec_2
200; CHECK-DAG:  MayAlias:     i32* %gep, <vscale x 4 x i32>* %p
201; CHECK-DAG:  MayAlias:     i32* %gep_rec_1, <vscale x 4 x i32>* %p
202; CHECK-DAG:  MayAlias:     i32* %gep_rec_2, <vscale x 4 x i32>* %p
203; CHECK-DAG:  NoAlias:      i32* %gep, i32* %gep_rec_1
204; CHECK-DAG:  NoAlias:      i32* %gep, i32* %gep_rec_2
205; CHECK-DAG:  NoAlias:      i32* %gep_rec_1, i32* %gep_rec_2
206define void @gep_recursion_level_2(i32* %a, <vscale x 4 x i32>* %p) {
207  %gep = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 1, i64 2
208  %gep_rec_1 = getelementptr i32, i32* %gep, i64 1
209  %gep_rec_2 = getelementptr i32, i32* %gep_rec_1, i64 1
210  load <vscale x 4 x i32>, <vscale x 4 x i32>* %p
211  load i32, i32* %a
212  load i32, i32* %gep
213  load i32, i32* %gep_rec_1
214  load i32, i32* %gep_rec_2
215  ret void
216}
217
218; CHECK-LABEL: gep_recursion_max_lookup_depth_reached
219; CHECK-DAG: MayAlias:     i32* %a, <vscale x 4 x i32>* %p
220; CHECK-DAG: MayAlias:     i32* %a, i32* %gep
221; CHECK-DAG: MayAlias:     i32* %a, i32* %gep_rec_1
222; CHECK-DAG: MayAlias:     i32* %a, i32* %gep_rec_2
223; CHECK-DAG: MayAlias:     i32* %a, i32* %gep_rec_3
224; CHECK-DAG: MayAlias:     i32* %a, i32* %gep_rec_4
225; CHECK-DAG: MayAlias:     i32* %a, i32* %gep_rec_5
226; CHECK-DAG: MayAlias:     i32* %a, i32* %gep_rec_6
227; CHECK-DAG: MayAlias:     i32* %gep, <vscale x 4 x i32>* %p
228; CHECK-DAG: MayAlias:     i32* %gep_rec_1, <vscale x 4 x i32>* %p
229; CHECK-DAG: MayAlias:     i32* %gep_rec_2, <vscale x 4 x i32>* %p
230; CHECK-DAG: MayAlias:     i32* %gep_rec_3, <vscale x 4 x i32>* %p
231; CHECK-DAG: MayAlias:     i32* %gep_rec_4, <vscale x 4 x i32>* %p
232; CHECK-DAG: MayAlias:     i32* %gep_rec_5, <vscale x 4 x i32>* %p
233; CHECK-DAG: MayAlias:     i32* %gep_rec_6, <vscale x 4 x i32>* %p
234; CHECK-DAG: NoAlias:      i32* %gep, i32* %gep_rec_1
235; CHECK-DAG: NoAlias:      i32* %gep, i32* %gep_rec_2
236; CHECK-DAG: NoAlias:      i32* %gep, i32* %gep_rec_3
237; CHECK-DAG: NoAlias:      i32* %gep, i32* %gep_rec_4
238; CHECK-DAG: NoAlias:      i32* %gep, i32* %gep_rec_5
239; CHECK-DAG: NoAlias:      i32* %gep, i32* %gep_rec_6
240; CHECK-DAG: NoAlias:      i32* %gep_rec_1, i32* %gep_rec_2
241; CHECK-DAG: NoAlias:      i32* %gep_rec_1, i32* %gep_rec_3
242; CHECK-DAG: NoAlias:      i32* %gep_rec_1, i32* %gep_rec_4
243; CHECK-DAG: NoAlias:      i32* %gep_rec_1, i32* %gep_rec_5
244; CHECK-DAG: NoAlias:      i32* %gep_rec_1, i32* %gep_rec_6
245; CHECK-DAG: NoAlias:      i32* %gep_rec_2, i32* %gep_rec_3
246; CHECK-DAG: NoAlias:      i32* %gep_rec_2, i32* %gep_rec_4
247; CHECK-DAG: NoAlias:      i32* %gep_rec_2, i32* %gep_rec_5
248; CHECK-DAG: NoAlias:      i32* %gep_rec_2, i32* %gep_rec_6
249; CHECK-DAG: NoAlias:      i32* %gep_rec_3, i32* %gep_rec_4
250; CHECK-DAG: NoAlias:      i32* %gep_rec_3, i32* %gep_rec_5
251; CHECK-DAG: NoAlias:      i32* %gep_rec_3, i32* %gep_rec_6
252; CHECK-DAG: NoAlias:      i32* %gep_rec_4, i32* %gep_rec_5
253; CHECK-DAG: NoAlias:      i32* %gep_rec_4, i32* %gep_rec_6
254; CHECK-DAG: NoAlias:      i32* %gep_rec_5, i32* %gep_rec_6
255; GEP max lookup depth was set to 6.
256define void @gep_recursion_max_lookup_depth_reached(i32* %a, <vscale x 4 x i32>* %p) {
257  %gep = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 1, i64 2
258  %gep_rec_1 = getelementptr i32, i32* %gep, i64 1
259  %gep_rec_2 = getelementptr i32, i32* %gep_rec_1, i64 1
260  %gep_rec_3 = getelementptr i32, i32* %gep_rec_2, i64 1
261  %gep_rec_4 = getelementptr i32, i32* %gep_rec_3, i64 1
262  %gep_rec_5 = getelementptr i32, i32* %gep_rec_4, i64 1
263  %gep_rec_6 = getelementptr i32, i32* %gep_rec_5, i64 1
264  load <vscale x 4 x i32>, <vscale x 4 x i32>* %p
265  load i32, i32* %a
266  load i32, i32* %gep
267  load i32, i32* %gep_rec_1
268  load i32, i32* %gep_rec_2
269  load i32, i32* %gep_rec_3
270  load i32, i32* %gep_rec_4
271  load i32, i32* %gep_rec_5
272  load i32, i32* %gep_rec_6
273  ret void
274}
275