1; RUN: opt < %s -tbaa -basicaa -aa-eval -evaluate-aa-metadata -print-no-aliases -print-may-aliases -disable-output 2>&1 | FileCheck %s
2; RUN: opt < %s -tbaa -basicaa -gvn -S | FileCheck %s --check-prefix=OPT
3; Generated from clang/test/CodeGen/tbaa.cpp with "-O1 -struct-path-tbaa -disable-llvm-optzns".
4
5%struct.StructA = type { i16, i32, i16, i32 }
6%struct.StructB = type { i16, %struct.StructA, i32 }
7%struct.StructS = type { i16, i32 }
8%struct.StructS2 = type { i16, i32 }
9%struct.StructC = type { i16, %struct.StructB, i32 }
10%struct.StructD = type { i16, %struct.StructB, i32, i8 }
11
12define i32 @_Z1gPjP7StructAy(i32* %s, %struct.StructA* %A, i64 %count) #0 {
13entry:
14; Access to i32* and &(A->f32).
15; CHECK: Function
16; CHECK: MayAlias:   store i32 4, i32* %f32, align 4, !tbaa !8 <->   store i32 1, i32* %0, align 4, !tbaa !6
17; OPT: define
18; OPT: store i32 1
19; OPT: store i32 4
20; OPT: %[[RET:.*]] = load i32*
21; OPT: ret i32 %[[RET]]
22  %s.addr = alloca i32*, align 8
23  %A.addr = alloca %struct.StructA*, align 8
24  %count.addr = alloca i64, align 8
25  store i32* %s, i32** %s.addr, align 8, !tbaa !0
26  store %struct.StructA* %A, %struct.StructA** %A.addr, align 8, !tbaa !0
27  store i64 %count, i64* %count.addr, align 8, !tbaa !4
28  %0 = load i32** %s.addr, align 8, !tbaa !0
29  store i32 1, i32* %0, align 4, !tbaa !6
30  %1 = load %struct.StructA** %A.addr, align 8, !tbaa !0
31  %f32 = getelementptr inbounds %struct.StructA* %1, i32 0, i32 1
32  store i32 4, i32* %f32, align 4, !tbaa !8
33  %2 = load i32** %s.addr, align 8, !tbaa !0
34  %3 = load i32* %2, align 4, !tbaa !6
35  ret i32 %3
36}
37
38define i32 @_Z2g2PjP7StructAy(i32* %s, %struct.StructA* %A, i64 %count) #0 {
39entry:
40; Access to i32* and &(A->f16).
41; CHECK: Function
42; CHECK: NoAlias:   store i16 4, i16* %f16, align 2, !tbaa !8 <->   store i32 1, i32* %0, align 4, !tbaa !6
43; OPT: define
44; OPT: store i32 1
45; OPT: store i16 4
46; Remove a load and propagate the value from store.
47; OPT: ret i32 1
48  %s.addr = alloca i32*, align 8
49  %A.addr = alloca %struct.StructA*, align 8
50  %count.addr = alloca i64, align 8
51  store i32* %s, i32** %s.addr, align 8, !tbaa !0
52  store %struct.StructA* %A, %struct.StructA** %A.addr, align 8, !tbaa !0
53  store i64 %count, i64* %count.addr, align 8, !tbaa !4
54  %0 = load i32** %s.addr, align 8, !tbaa !0
55  store i32 1, i32* %0, align 4, !tbaa !6
56  %1 = load %struct.StructA** %A.addr, align 8, !tbaa !0
57  %f16 = getelementptr inbounds %struct.StructA* %1, i32 0, i32 0
58  store i16 4, i16* %f16, align 2, !tbaa !11
59  %2 = load i32** %s.addr, align 8, !tbaa !0
60  %3 = load i32* %2, align 4, !tbaa !6
61  ret i32 %3
62}
63
64define i32 @_Z2g3P7StructAP7StructBy(%struct.StructA* %A, %struct.StructB* %B, i64 %count) #0 {
65entry:
66; Access to &(A->f32) and &(B->a.f32).
67; CHECK: Function
68; CHECK: MayAlias:   store i32 4, i32* %f321, align 4, !tbaa !10 <->   store i32 1, i32* %f32, align 4, !tbaa !6
69; OPT: define
70; OPT: store i32 1
71; OPT: store i32 4
72; OPT: %[[RET:.*]] = load i32*
73; OPT: ret i32 %[[RET]]
74  %A.addr = alloca %struct.StructA*, align 8
75  %B.addr = alloca %struct.StructB*, align 8
76  %count.addr = alloca i64, align 8
77  store %struct.StructA* %A, %struct.StructA** %A.addr, align 8, !tbaa !0
78  store %struct.StructB* %B, %struct.StructB** %B.addr, align 8, !tbaa !0
79  store i64 %count, i64* %count.addr, align 8, !tbaa !4
80  %0 = load %struct.StructA** %A.addr, align 8, !tbaa !0
81  %f32 = getelementptr inbounds %struct.StructA* %0, i32 0, i32 1
82  store i32 1, i32* %f32, align 4, !tbaa !8
83  %1 = load %struct.StructB** %B.addr, align 8, !tbaa !0
84  %a = getelementptr inbounds %struct.StructB* %1, i32 0, i32 1
85  %f321 = getelementptr inbounds %struct.StructA* %a, i32 0, i32 1
86  store i32 4, i32* %f321, align 4, !tbaa !12
87  %2 = load %struct.StructA** %A.addr, align 8, !tbaa !0
88  %f322 = getelementptr inbounds %struct.StructA* %2, i32 0, i32 1
89  %3 = load i32* %f322, align 4, !tbaa !8
90  ret i32 %3
91}
92
93define i32 @_Z2g4P7StructAP7StructBy(%struct.StructA* %A, %struct.StructB* %B, i64 %count) #0 {
94entry:
95; Access to &(A->f32) and &(B->a.f16).
96; CHECK: Function
97; CHECK: NoAlias:   store i16 4, i16* %f16, align 2, !tbaa !10 <->   store i32 1, i32* %f32, align 4, !tbaa !6
98; OPT: define
99; OPT: store i32 1
100; OPT: store i16 4
101; Remove a load and propagate the value from store.
102; OPT: ret i32 1
103  %A.addr = alloca %struct.StructA*, align 8
104  %B.addr = alloca %struct.StructB*, align 8
105  %count.addr = alloca i64, align 8
106  store %struct.StructA* %A, %struct.StructA** %A.addr, align 8, !tbaa !0
107  store %struct.StructB* %B, %struct.StructB** %B.addr, align 8, !tbaa !0
108  store i64 %count, i64* %count.addr, align 8, !tbaa !4
109  %0 = load %struct.StructA** %A.addr, align 8, !tbaa !0
110  %f32 = getelementptr inbounds %struct.StructA* %0, i32 0, i32 1
111  store i32 1, i32* %f32, align 4, !tbaa !8
112  %1 = load %struct.StructB** %B.addr, align 8, !tbaa !0
113  %a = getelementptr inbounds %struct.StructB* %1, i32 0, i32 1
114  %f16 = getelementptr inbounds %struct.StructA* %a, i32 0, i32 0
115  store i16 4, i16* %f16, align 2, !tbaa !14
116  %2 = load %struct.StructA** %A.addr, align 8, !tbaa !0
117  %f321 = getelementptr inbounds %struct.StructA* %2, i32 0, i32 1
118  %3 = load i32* %f321, align 4, !tbaa !8
119  ret i32 %3
120}
121
122define i32 @_Z2g5P7StructAP7StructBy(%struct.StructA* %A, %struct.StructB* %B, i64 %count) #0 {
123entry:
124; Access to &(A->f32) and &(B->f32).
125; CHECK: Function
126; CHECK: NoAlias:   store i32 4, i32* %f321, align 4, !tbaa !10 <->   store i32 1, i32* %f32, align 4, !tbaa !6
127; OPT: define
128; OPT: store i32 1
129; OPT: store i32 4
130; Remove a load and propagate the value from store.
131; OPT: ret i32 1
132  %A.addr = alloca %struct.StructA*, align 8
133  %B.addr = alloca %struct.StructB*, align 8
134  %count.addr = alloca i64, align 8
135  store %struct.StructA* %A, %struct.StructA** %A.addr, align 8, !tbaa !0
136  store %struct.StructB* %B, %struct.StructB** %B.addr, align 8, !tbaa !0
137  store i64 %count, i64* %count.addr, align 8, !tbaa !4
138  %0 = load %struct.StructA** %A.addr, align 8, !tbaa !0
139  %f32 = getelementptr inbounds %struct.StructA* %0, i32 0, i32 1
140  store i32 1, i32* %f32, align 4, !tbaa !8
141  %1 = load %struct.StructB** %B.addr, align 8, !tbaa !0
142  %f321 = getelementptr inbounds %struct.StructB* %1, i32 0, i32 2
143  store i32 4, i32* %f321, align 4, !tbaa !15
144  %2 = load %struct.StructA** %A.addr, align 8, !tbaa !0
145  %f322 = getelementptr inbounds %struct.StructA* %2, i32 0, i32 1
146  %3 = load i32* %f322, align 4, !tbaa !8
147  ret i32 %3
148}
149
150define i32 @_Z2g6P7StructAP7StructBy(%struct.StructA* %A, %struct.StructB* %B, i64 %count) #0 {
151entry:
152; Access to &(A->f32) and &(B->a.f32_2).
153; CHECK: Function
154; CHECK: NoAlias:   store i32 4, i32* %f32_2, align 4, !tbaa !10 <->   store i32 1, i32* %f32, align 4, !tbaa !6
155; OPT: define
156; OPT: store i32 1
157; OPT: store i32 4
158; Remove a load and propagate the value from store.
159; OPT: ret i32 1
160  %A.addr = alloca %struct.StructA*, align 8
161  %B.addr = alloca %struct.StructB*, align 8
162  %count.addr = alloca i64, align 8
163  store %struct.StructA* %A, %struct.StructA** %A.addr, align 8, !tbaa !0
164  store %struct.StructB* %B, %struct.StructB** %B.addr, align 8, !tbaa !0
165  store i64 %count, i64* %count.addr, align 8, !tbaa !4
166  %0 = load %struct.StructA** %A.addr, align 8, !tbaa !0
167  %f32 = getelementptr inbounds %struct.StructA* %0, i32 0, i32 1
168  store i32 1, i32* %f32, align 4, !tbaa !8
169  %1 = load %struct.StructB** %B.addr, align 8, !tbaa !0
170  %a = getelementptr inbounds %struct.StructB* %1, i32 0, i32 1
171  %f32_2 = getelementptr inbounds %struct.StructA* %a, i32 0, i32 3
172  store i32 4, i32* %f32_2, align 4, !tbaa !16
173  %2 = load %struct.StructA** %A.addr, align 8, !tbaa !0
174  %f321 = getelementptr inbounds %struct.StructA* %2, i32 0, i32 1
175  %3 = load i32* %f321, align 4, !tbaa !8
176  ret i32 %3
177}
178
179define i32 @_Z2g7P7StructAP7StructSy(%struct.StructA* %A, %struct.StructS* %S, i64 %count) #0 {
180entry:
181; Access to &(A->f32) and &(S->f32).
182; CHECK: Function
183; CHECK: NoAlias:   store i32 4, i32* %f321, align 4, !tbaa !10 <->   store i32 1, i32* %f32, align 4, !tbaa !6
184; OPT: define
185; OPT: store i32 1
186; OPT: store i32 4
187; Remove a load and propagate the value from store.
188; OPT: ret i32 1
189  %A.addr = alloca %struct.StructA*, align 8
190  %S.addr = alloca %struct.StructS*, align 8
191  %count.addr = alloca i64, align 8
192  store %struct.StructA* %A, %struct.StructA** %A.addr, align 8, !tbaa !0
193  store %struct.StructS* %S, %struct.StructS** %S.addr, align 8, !tbaa !0
194  store i64 %count, i64* %count.addr, align 8, !tbaa !4
195  %0 = load %struct.StructA** %A.addr, align 8, !tbaa !0
196  %f32 = getelementptr inbounds %struct.StructA* %0, i32 0, i32 1
197  store i32 1, i32* %f32, align 4, !tbaa !8
198  %1 = load %struct.StructS** %S.addr, align 8, !tbaa !0
199  %f321 = getelementptr inbounds %struct.StructS* %1, i32 0, i32 1
200  store i32 4, i32* %f321, align 4, !tbaa !17
201  %2 = load %struct.StructA** %A.addr, align 8, !tbaa !0
202  %f322 = getelementptr inbounds %struct.StructA* %2, i32 0, i32 1
203  %3 = load i32* %f322, align 4, !tbaa !8
204  ret i32 %3
205}
206
207define i32 @_Z2g8P7StructAP7StructSy(%struct.StructA* %A, %struct.StructS* %S, i64 %count) #0 {
208entry:
209; Access to &(A->f32) and &(S->f16).
210; CHECK: Function
211; CHECK: NoAlias:   store i16 4, i16* %f16, align 2, !tbaa !10 <->   store i32 1, i32* %f32, align 4, !tbaa !6
212; OPT: define
213; OPT: store i32 1
214; OPT: store i16 4
215; Remove a load and propagate the value from store.
216; OPT: ret i32 1
217  %A.addr = alloca %struct.StructA*, align 8
218  %S.addr = alloca %struct.StructS*, align 8
219  %count.addr = alloca i64, align 8
220  store %struct.StructA* %A, %struct.StructA** %A.addr, align 8, !tbaa !0
221  store %struct.StructS* %S, %struct.StructS** %S.addr, align 8, !tbaa !0
222  store i64 %count, i64* %count.addr, align 8, !tbaa !4
223  %0 = load %struct.StructA** %A.addr, align 8, !tbaa !0
224  %f32 = getelementptr inbounds %struct.StructA* %0, i32 0, i32 1
225  store i32 1, i32* %f32, align 4, !tbaa !8
226  %1 = load %struct.StructS** %S.addr, align 8, !tbaa !0
227  %f16 = getelementptr inbounds %struct.StructS* %1, i32 0, i32 0
228  store i16 4, i16* %f16, align 2, !tbaa !19
229  %2 = load %struct.StructA** %A.addr, align 8, !tbaa !0
230  %f321 = getelementptr inbounds %struct.StructA* %2, i32 0, i32 1
231  %3 = load i32* %f321, align 4, !tbaa !8
232  ret i32 %3
233}
234
235define i32 @_Z2g9P7StructSP8StructS2y(%struct.StructS* %S, %struct.StructS2* %S2, i64 %count) #0 {
236entry:
237; Access to &(S->f32) and &(S2->f32).
238; CHECK: Function
239; CHECK: NoAlias:   store i32 4, i32* %f321, align 4, !tbaa !10 <->   store i32 1, i32* %f32, align 4, !tbaa !6
240; OPT: define
241; OPT: store i32 1
242; OPT: store i32 4
243; Remove a load and propagate the value from store.
244; OPT: ret i32 1
245  %S.addr = alloca %struct.StructS*, align 8
246  %S2.addr = alloca %struct.StructS2*, align 8
247  %count.addr = alloca i64, align 8
248  store %struct.StructS* %S, %struct.StructS** %S.addr, align 8, !tbaa !0
249  store %struct.StructS2* %S2, %struct.StructS2** %S2.addr, align 8, !tbaa !0
250  store i64 %count, i64* %count.addr, align 8, !tbaa !4
251  %0 = load %struct.StructS** %S.addr, align 8, !tbaa !0
252  %f32 = getelementptr inbounds %struct.StructS* %0, i32 0, i32 1
253  store i32 1, i32* %f32, align 4, !tbaa !17
254  %1 = load %struct.StructS2** %S2.addr, align 8, !tbaa !0
255  %f321 = getelementptr inbounds %struct.StructS2* %1, i32 0, i32 1
256  store i32 4, i32* %f321, align 4, !tbaa !20
257  %2 = load %struct.StructS** %S.addr, align 8, !tbaa !0
258  %f322 = getelementptr inbounds %struct.StructS* %2, i32 0, i32 1
259  %3 = load i32* %f322, align 4, !tbaa !17
260  ret i32 %3
261}
262
263define i32 @_Z3g10P7StructSP8StructS2y(%struct.StructS* %S, %struct.StructS2* %S2, i64 %count) #0 {
264entry:
265; Access to &(S->f32) and &(S2->f16).
266; CHECK: Function
267; CHECK: NoAlias:   store i16 4, i16* %f16, align 2, !tbaa !10 <->   store i32 1, i32* %f32, align 4, !tbaa !6
268; OPT: define
269; OPT: store i32 1
270; OPT: store i16 4
271; Remove a load and propagate the value from store.
272; OPT: ret i32 1
273  %S.addr = alloca %struct.StructS*, align 8
274  %S2.addr = alloca %struct.StructS2*, align 8
275  %count.addr = alloca i64, align 8
276  store %struct.StructS* %S, %struct.StructS** %S.addr, align 8, !tbaa !0
277  store %struct.StructS2* %S2, %struct.StructS2** %S2.addr, align 8, !tbaa !0
278  store i64 %count, i64* %count.addr, align 8, !tbaa !4
279  %0 = load %struct.StructS** %S.addr, align 8, !tbaa !0
280  %f32 = getelementptr inbounds %struct.StructS* %0, i32 0, i32 1
281  store i32 1, i32* %f32, align 4, !tbaa !17
282  %1 = load %struct.StructS2** %S2.addr, align 8, !tbaa !0
283  %f16 = getelementptr inbounds %struct.StructS2* %1, i32 0, i32 0
284  store i16 4, i16* %f16, align 2, !tbaa !22
285  %2 = load %struct.StructS** %S.addr, align 8, !tbaa !0
286  %f321 = getelementptr inbounds %struct.StructS* %2, i32 0, i32 1
287  %3 = load i32* %f321, align 4, !tbaa !17
288  ret i32 %3
289}
290
291define i32 @_Z3g11P7StructCP7StructDy(%struct.StructC* %C, %struct.StructD* %D, i64 %count) #0 {
292entry:
293; Access to &(C->b.a.f32) and &(D->b.a.f32).
294; CHECK: Function
295; CHECK: NoAlias:   store i32 4, i32* %f323, align 4, !tbaa !12 <->   store i32 1, i32* %f32, align 4, !tbaa !6
296; OPT: define
297; OPT: store i32 1
298; OPT: store i32 4
299; Remove a load and propagate the value from store.
300; OPT: ret i32 1
301  %C.addr = alloca %struct.StructC*, align 8
302  %D.addr = alloca %struct.StructD*, align 8
303  %count.addr = alloca i64, align 8
304  store %struct.StructC* %C, %struct.StructC** %C.addr, align 8, !tbaa !0
305  store %struct.StructD* %D, %struct.StructD** %D.addr, align 8, !tbaa !0
306  store i64 %count, i64* %count.addr, align 8, !tbaa !4
307  %0 = load %struct.StructC** %C.addr, align 8, !tbaa !0
308  %b = getelementptr inbounds %struct.StructC* %0, i32 0, i32 1
309  %a = getelementptr inbounds %struct.StructB* %b, i32 0, i32 1
310  %f32 = getelementptr inbounds %struct.StructA* %a, i32 0, i32 1
311  store i32 1, i32* %f32, align 4, !tbaa !23
312  %1 = load %struct.StructD** %D.addr, align 8, !tbaa !0
313  %b1 = getelementptr inbounds %struct.StructD* %1, i32 0, i32 1
314  %a2 = getelementptr inbounds %struct.StructB* %b1, i32 0, i32 1
315  %f323 = getelementptr inbounds %struct.StructA* %a2, i32 0, i32 1
316  store i32 4, i32* %f323, align 4, !tbaa !25
317  %2 = load %struct.StructC** %C.addr, align 8, !tbaa !0
318  %b4 = getelementptr inbounds %struct.StructC* %2, i32 0, i32 1
319  %a5 = getelementptr inbounds %struct.StructB* %b4, i32 0, i32 1
320  %f326 = getelementptr inbounds %struct.StructA* %a5, i32 0, i32 1
321  %3 = load i32* %f326, align 4, !tbaa !23
322  ret i32 %3
323}
324
325define i32 @_Z3g12P7StructCP7StructDy(%struct.StructC* %C, %struct.StructD* %D, i64 %count) #0 {
326entry:
327; Access to &(b1->a.f32) and &(b2->a.f32).
328; CHECK: Function
329; CHECK: MayAlias:   store i32 4, i32* %f325, align 4, !tbaa !6 <->   store i32 1, i32* %f32, align 4, !tbaa !6
330; OPT: define
331; OPT: store i32 1
332; OPT: store i32 4
333; OPT: %[[RET:.*]] = load i32*
334; OPT: ret i32 %[[RET]]
335  %C.addr = alloca %struct.StructC*, align 8
336  %D.addr = alloca %struct.StructD*, align 8
337  %count.addr = alloca i64, align 8
338  %b1 = alloca %struct.StructB*, align 8
339  %b2 = alloca %struct.StructB*, align 8
340  store %struct.StructC* %C, %struct.StructC** %C.addr, align 8, !tbaa !0
341  store %struct.StructD* %D, %struct.StructD** %D.addr, align 8, !tbaa !0
342  store i64 %count, i64* %count.addr, align 8, !tbaa !4
343  %0 = load %struct.StructC** %C.addr, align 8, !tbaa !0
344  %b = getelementptr inbounds %struct.StructC* %0, i32 0, i32 1
345  store %struct.StructB* %b, %struct.StructB** %b1, align 8, !tbaa !0
346  %1 = load %struct.StructD** %D.addr, align 8, !tbaa !0
347  %b3 = getelementptr inbounds %struct.StructD* %1, i32 0, i32 1
348  store %struct.StructB* %b3, %struct.StructB** %b2, align 8, !tbaa !0
349  %2 = load %struct.StructB** %b1, align 8, !tbaa !0
350  %a = getelementptr inbounds %struct.StructB* %2, i32 0, i32 1
351  %f32 = getelementptr inbounds %struct.StructA* %a, i32 0, i32 1
352  store i32 1, i32* %f32, align 4, !tbaa !12
353  %3 = load %struct.StructB** %b2, align 8, !tbaa !0
354  %a4 = getelementptr inbounds %struct.StructB* %3, i32 0, i32 1
355  %f325 = getelementptr inbounds %struct.StructA* %a4, i32 0, i32 1
356  store i32 4, i32* %f325, align 4, !tbaa !12
357  %4 = load %struct.StructB** %b1, align 8, !tbaa !0
358  %a6 = getelementptr inbounds %struct.StructB* %4, i32 0, i32 1
359  %f327 = getelementptr inbounds %struct.StructA* %a6, i32 0, i32 1
360  %5 = load i32* %f327, align 4, !tbaa !12
361  ret i32 %5
362}
363
364attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
365
366!0 = !{!1, !1, i64 0}
367!1 = !{!"any pointer", !2}
368!2 = !{!"omnipotent char", !3}
369!3 = !{!"Simple C/C++ TBAA"}
370!4 = !{!5, !5, i64 0}
371!5 = !{!"long long", !2}
372!6 = !{!7, !7, i64 0}
373!7 = !{!"int", !2}
374!8 = !{!9, !7, i64 4}
375!9 = !{!"_ZTS7StructA", !10, i64 0, !7, i64 4, !10, i64 8, !7, i64 12}
376!10 = !{!"short", !2}
377!11 = !{!9, !10, i64 0}
378!12 = !{!13, !7, i64 8}
379!13 = !{!"_ZTS7StructB", !10, i64 0, !9, i64 4, !7, i64 20}
380!14 = !{!13, !10, i64 4}
381!15 = !{!13, !7, i64 20}
382!16 = !{!13, !7, i64 16}
383!17 = !{!18, !7, i64 4}
384!18 = !{!"_ZTS7StructS", !10, i64 0, !7, i64 4}
385!19 = !{!18, !10, i64 0}
386!20 = !{!21, !7, i64 4}
387!21 = !{!"_ZTS8StructS2", !10, i64 0, !7, i64 4}
388!22 = !{!21, !10, i64 0}
389!23 = !{!24, !7, i64 12}
390!24 = !{!"_ZTS7StructC", !10, i64 0, !13, i64 4, !7, i64 28}
391!25 = !{!26, !7, i64 12}
392!26 = !{!"_ZTS7StructD", !10, i64 0, !13, i64 4, !7, i64 28, !2, i64 32}
393