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".
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 }
12 define i32 @_Z1gPjP7StructAy(i32* %s, %struct.StructA* %A, i64 %count) #0 {
14 ; Access to i32* and &(A->f32).
16 ; CHECK: MayAlias: store i32 4, i32* %f32, align 4, !tbaa !8 <-> store i32 1, i32* %0, align 4, !tbaa !6
20 ; OPT: %[[RET:.*]] = load i32, 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*, i32** %s.addr, align 8, !tbaa !0
29 store i32 1, i32* %0, align 4, !tbaa !6
30 %1 = load %struct.StructA*, %struct.StructA** %A.addr, align 8, !tbaa !0
31 %f32 = getelementptr inbounds %struct.StructA, %struct.StructA* %1, i32 0, i32 1
32 store i32 4, i32* %f32, align 4, !tbaa !8
33 %2 = load i32*, i32** %s.addr, align 8, !tbaa !0
34 %3 = load i32, i32* %2, align 4, !tbaa !6
38 define i32 @_Z2g2PjP7StructAy(i32* %s, %struct.StructA* %A, i64 %count) #0 {
40 ; Access to i32* and &(A->f16).
42 ; CHECK: NoAlias: store i16 4, i16* %f16, align 2, !tbaa !8 <-> store i32 1, i32* %0, align 4, !tbaa !6
46 ; Remove a load and propagate the value from store.
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*, i32** %s.addr, align 8, !tbaa !0
55 store i32 1, i32* %0, align 4, !tbaa !6
56 %1 = load %struct.StructA*, %struct.StructA** %A.addr, align 8, !tbaa !0
57 %f16 = getelementptr inbounds %struct.StructA, %struct.StructA* %1, i32 0, i32 0
58 store i16 4, i16* %f16, align 2, !tbaa !11
59 %2 = load i32*, i32** %s.addr, align 8, !tbaa !0
60 %3 = load i32, i32* %2, align 4, !tbaa !6
64 define i32 @_Z2g3P7StructAP7StructBy(%struct.StructA* %A, %struct.StructB* %B, i64 %count) #0 {
66 ; Access to &(A->f32) and &(B->a.f32).
68 ; CHECK: MayAlias: store i32 4, i32* %f321, align 4, !tbaa !10 <-> store i32 1, i32* %f32, align 4, !tbaa !6
72 ; OPT: %[[RET:.*]] = load i32, 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*, %struct.StructA** %A.addr, align 8, !tbaa !0
81 %f32 = getelementptr inbounds %struct.StructA, %struct.StructA* %0, i32 0, i32 1
82 store i32 1, i32* %f32, align 4, !tbaa !8
83 %1 = load %struct.StructB*, %struct.StructB** %B.addr, align 8, !tbaa !0
84 %a = getelementptr inbounds %struct.StructB, %struct.StructB* %1, i32 0, i32 1
85 %f321 = getelementptr inbounds %struct.StructA, %struct.StructA* %a, i32 0, i32 1
86 store i32 4, i32* %f321, align 4, !tbaa !12
87 %2 = load %struct.StructA*, %struct.StructA** %A.addr, align 8, !tbaa !0
88 %f322 = getelementptr inbounds %struct.StructA, %struct.StructA* %2, i32 0, i32 1
89 %3 = load i32, i32* %f322, align 4, !tbaa !8
93 define i32 @_Z2g4P7StructAP7StructBy(%struct.StructA* %A, %struct.StructB* %B, i64 %count) #0 {
95 ; Access to &(A->f32) and &(B->a.f16).
97 ; CHECK: NoAlias: store i16 4, i16* %f16, align 2, !tbaa !10 <-> store i32 1, i32* %f32, align 4, !tbaa !6
101 ; Remove a load and propagate the value from store.
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*, %struct.StructA** %A.addr, align 8, !tbaa !0
110 %f32 = getelementptr inbounds %struct.StructA, %struct.StructA* %0, i32 0, i32 1
111 store i32 1, i32* %f32, align 4, !tbaa !8
112 %1 = load %struct.StructB*, %struct.StructB** %B.addr, align 8, !tbaa !0
113 %a = getelementptr inbounds %struct.StructB, %struct.StructB* %1, i32 0, i32 1
114 %f16 = getelementptr inbounds %struct.StructA, %struct.StructA* %a, i32 0, i32 0
115 store i16 4, i16* %f16, align 2, !tbaa !14
116 %2 = load %struct.StructA*, %struct.StructA** %A.addr, align 8, !tbaa !0
117 %f321 = getelementptr inbounds %struct.StructA, %struct.StructA* %2, i32 0, i32 1
118 %3 = load i32, i32* %f321, align 4, !tbaa !8
122 define i32 @_Z2g5P7StructAP7StructBy(%struct.StructA* %A, %struct.StructB* %B, i64 %count) #0 {
124 ; Access to &(A->f32) and &(B->f32).
126 ; CHECK: NoAlias: store i32 4, i32* %f321, align 4, !tbaa !10 <-> store i32 1, i32* %f32, align 4, !tbaa !6
130 ; Remove a load and propagate the value from store.
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*, %struct.StructA** %A.addr, align 8, !tbaa !0
139 %f32 = getelementptr inbounds %struct.StructA, %struct.StructA* %0, i32 0, i32 1
140 store i32 1, i32* %f32, align 4, !tbaa !8
141 %1 = load %struct.StructB*, %struct.StructB** %B.addr, align 8, !tbaa !0
142 %f321 = getelementptr inbounds %struct.StructB, %struct.StructB* %1, i32 0, i32 2
143 store i32 4, i32* %f321, align 4, !tbaa !15
144 %2 = load %struct.StructA*, %struct.StructA** %A.addr, align 8, !tbaa !0
145 %f322 = getelementptr inbounds %struct.StructA, %struct.StructA* %2, i32 0, i32 1
146 %3 = load i32, i32* %f322, align 4, !tbaa !8
150 define i32 @_Z2g6P7StructAP7StructBy(%struct.StructA* %A, %struct.StructB* %B, i64 %count) #0 {
152 ; Access to &(A->f32) and &(B->a.f32_2).
154 ; CHECK: NoAlias: store i32 4, i32* %f32_2, align 4, !tbaa !10 <-> store i32 1, i32* %f32, align 4, !tbaa !6
158 ; Remove a load and propagate the value from store.
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*, %struct.StructA** %A.addr, align 8, !tbaa !0
167 %f32 = getelementptr inbounds %struct.StructA, %struct.StructA* %0, i32 0, i32 1
168 store i32 1, i32* %f32, align 4, !tbaa !8
169 %1 = load %struct.StructB*, %struct.StructB** %B.addr, align 8, !tbaa !0
170 %a = getelementptr inbounds %struct.StructB, %struct.StructB* %1, i32 0, i32 1
171 %f32_2 = getelementptr inbounds %struct.StructA, %struct.StructA* %a, i32 0, i32 3
172 store i32 4, i32* %f32_2, align 4, !tbaa !16
173 %2 = load %struct.StructA*, %struct.StructA** %A.addr, align 8, !tbaa !0
174 %f321 = getelementptr inbounds %struct.StructA, %struct.StructA* %2, i32 0, i32 1
175 %3 = load i32, i32* %f321, align 4, !tbaa !8
179 define i32 @_Z2g7P7StructAP7StructSy(%struct.StructA* %A, %struct.StructS* %S, i64 %count) #0 {
181 ; Access to &(A->f32) and &(S->f32).
183 ; CHECK: NoAlias: store i32 4, i32* %f321, align 4, !tbaa !10 <-> store i32 1, i32* %f32, align 4, !tbaa !6
187 ; Remove a load and propagate the value from store.
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*, %struct.StructA** %A.addr, align 8, !tbaa !0
196 %f32 = getelementptr inbounds %struct.StructA, %struct.StructA* %0, i32 0, i32 1
197 store i32 1, i32* %f32, align 4, !tbaa !8
198 %1 = load %struct.StructS*, %struct.StructS** %S.addr, align 8, !tbaa !0
199 %f321 = getelementptr inbounds %struct.StructS, %struct.StructS* %1, i32 0, i32 1
200 store i32 4, i32* %f321, align 4, !tbaa !17
201 %2 = load %struct.StructA*, %struct.StructA** %A.addr, align 8, !tbaa !0
202 %f322 = getelementptr inbounds %struct.StructA, %struct.StructA* %2, i32 0, i32 1
203 %3 = load i32, i32* %f322, align 4, !tbaa !8
207 define i32 @_Z2g8P7StructAP7StructSy(%struct.StructA* %A, %struct.StructS* %S, i64 %count) #0 {
209 ; Access to &(A->f32) and &(S->f16).
211 ; CHECK: NoAlias: store i16 4, i16* %f16, align 2, !tbaa !10 <-> store i32 1, i32* %f32, align 4, !tbaa !6
215 ; Remove a load and propagate the value from store.
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*, %struct.StructA** %A.addr, align 8, !tbaa !0
224 %f32 = getelementptr inbounds %struct.StructA, %struct.StructA* %0, i32 0, i32 1
225 store i32 1, i32* %f32, align 4, !tbaa !8
226 %1 = load %struct.StructS*, %struct.StructS** %S.addr, align 8, !tbaa !0
227 %f16 = getelementptr inbounds %struct.StructS, %struct.StructS* %1, i32 0, i32 0
228 store i16 4, i16* %f16, align 2, !tbaa !19
229 %2 = load %struct.StructA*, %struct.StructA** %A.addr, align 8, !tbaa !0
230 %f321 = getelementptr inbounds %struct.StructA, %struct.StructA* %2, i32 0, i32 1
231 %3 = load i32, i32* %f321, align 4, !tbaa !8
235 define i32 @_Z2g9P7StructSP8StructS2y(%struct.StructS* %S, %struct.StructS2* %S2, i64 %count) #0 {
237 ; Access to &(S->f32) and &(S2->f32).
239 ; CHECK: NoAlias: store i32 4, i32* %f321, align 4, !tbaa !10 <-> store i32 1, i32* %f32, align 4, !tbaa !6
243 ; Remove a load and propagate the value from store.
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*, %struct.StructS** %S.addr, align 8, !tbaa !0
252 %f32 = getelementptr inbounds %struct.StructS, %struct.StructS* %0, i32 0, i32 1
253 store i32 1, i32* %f32, align 4, !tbaa !17
254 %1 = load %struct.StructS2*, %struct.StructS2** %S2.addr, align 8, !tbaa !0
255 %f321 = getelementptr inbounds %struct.StructS2, %struct.StructS2* %1, i32 0, i32 1
256 store i32 4, i32* %f321, align 4, !tbaa !20
257 %2 = load %struct.StructS*, %struct.StructS** %S.addr, align 8, !tbaa !0
258 %f322 = getelementptr inbounds %struct.StructS, %struct.StructS* %2, i32 0, i32 1
259 %3 = load i32, i32* %f322, align 4, !tbaa !17
263 define i32 @_Z3g10P7StructSP8StructS2y(%struct.StructS* %S, %struct.StructS2* %S2, i64 %count) #0 {
265 ; Access to &(S->f32) and &(S2->f16).
267 ; CHECK: NoAlias: store i16 4, i16* %f16, align 2, !tbaa !10 <-> store i32 1, i32* %f32, align 4, !tbaa !6
271 ; Remove a load and propagate the value from store.
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*, %struct.StructS** %S.addr, align 8, !tbaa !0
280 %f32 = getelementptr inbounds %struct.StructS, %struct.StructS* %0, i32 0, i32 1
281 store i32 1, i32* %f32, align 4, !tbaa !17
282 %1 = load %struct.StructS2*, %struct.StructS2** %S2.addr, align 8, !tbaa !0
283 %f16 = getelementptr inbounds %struct.StructS2, %struct.StructS2* %1, i32 0, i32 0
284 store i16 4, i16* %f16, align 2, !tbaa !22
285 %2 = load %struct.StructS*, %struct.StructS** %S.addr, align 8, !tbaa !0
286 %f321 = getelementptr inbounds %struct.StructS, %struct.StructS* %2, i32 0, i32 1
287 %3 = load i32, i32* %f321, align 4, !tbaa !17
291 define i32 @_Z3g11P7StructCP7StructDy(%struct.StructC* %C, %struct.StructD* %D, i64 %count) #0 {
293 ; Access to &(C->b.a.f32) and &(D->b.a.f32).
295 ; CHECK: NoAlias: store i32 4, i32* %f323, align 4, !tbaa !12 <-> store i32 1, i32* %f32, align 4, !tbaa !6
299 ; Remove a load and propagate the value from store.
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*, %struct.StructC** %C.addr, align 8, !tbaa !0
308 %b = getelementptr inbounds %struct.StructC, %struct.StructC* %0, i32 0, i32 1
309 %a = getelementptr inbounds %struct.StructB, %struct.StructB* %b, i32 0, i32 1
310 %f32 = getelementptr inbounds %struct.StructA, %struct.StructA* %a, i32 0, i32 1
311 store i32 1, i32* %f32, align 4, !tbaa !23
312 %1 = load %struct.StructD*, %struct.StructD** %D.addr, align 8, !tbaa !0
313 %b1 = getelementptr inbounds %struct.StructD, %struct.StructD* %1, i32 0, i32 1
314 %a2 = getelementptr inbounds %struct.StructB, %struct.StructB* %b1, i32 0, i32 1
315 %f323 = getelementptr inbounds %struct.StructA, %struct.StructA* %a2, i32 0, i32 1
316 store i32 4, i32* %f323, align 4, !tbaa !25
317 %2 = load %struct.StructC*, %struct.StructC** %C.addr, align 8, !tbaa !0
318 %b4 = getelementptr inbounds %struct.StructC, %struct.StructC* %2, i32 0, i32 1
319 %a5 = getelementptr inbounds %struct.StructB, %struct.StructB* %b4, i32 0, i32 1
320 %f326 = getelementptr inbounds %struct.StructA, %struct.StructA* %a5, i32 0, i32 1
321 %3 = load i32, i32* %f326, align 4, !tbaa !23
325 define i32 @_Z3g12P7StructCP7StructDy(%struct.StructC* %C, %struct.StructD* %D, i64 %count) #0 {
327 ; Access to &(b1->a.f32) and &(b2->a.f32).
329 ; CHECK: MayAlias: store i32 4, i32* %f325, align 4, !tbaa !6 <-> store i32 1, i32* %f32, align 4, !tbaa !6
333 ; OPT: %[[RET:.*]] = load i32, 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*, %struct.StructC** %C.addr, align 8, !tbaa !0
344 %b = getelementptr inbounds %struct.StructC, %struct.StructC* %0, i32 0, i32 1
345 store %struct.StructB* %b, %struct.StructB** %b1, align 8, !tbaa !0
346 %1 = load %struct.StructD*, %struct.StructD** %D.addr, align 8, !tbaa !0
347 %b3 = getelementptr inbounds %struct.StructD, %struct.StructD* %1, i32 0, i32 1
348 store %struct.StructB* %b3, %struct.StructB** %b2, align 8, !tbaa !0
349 %2 = load %struct.StructB*, %struct.StructB** %b1, align 8, !tbaa !0
350 %a = getelementptr inbounds %struct.StructB, %struct.StructB* %2, i32 0, i32 1
351 %f32 = getelementptr inbounds %struct.StructA, %struct.StructA* %a, i32 0, i32 1
352 store i32 1, i32* %f32, align 4, !tbaa !12
353 %3 = load %struct.StructB*, %struct.StructB** %b2, align 8, !tbaa !0
354 %a4 = getelementptr inbounds %struct.StructB, %struct.StructB* %3, i32 0, i32 1
355 %f325 = getelementptr inbounds %struct.StructA, %struct.StructA* %a4, i32 0, i32 1
356 store i32 4, i32* %f325, align 4, !tbaa !12
357 %4 = load %struct.StructB*, %struct.StructB** %b1, align 8, !tbaa !0
358 %a6 = getelementptr inbounds %struct.StructB, %struct.StructB* %4, i32 0, i32 1
359 %f327 = getelementptr inbounds %struct.StructA, %struct.StructA* %a6, i32 0, i32 1
360 %5 = load i32, i32* %f327, align 4, !tbaa !12
364 attributes #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" }
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}
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}