1 ; RUN: opt < %s -aa-pipeline=tbaa,basic-aa -passes=aa-eval -evaluate-aa-metadata -print-no-aliases -print-may-aliases -disable-output 2>&1 | FileCheck %s
2 ; RUN: opt < %s -aa-pipeline=tbaa,basic-aa -passes=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(ptr %s, ptr %A, i64 %count) #0 {
14 ; Access to ptr and &(A->f32).
16 ; CHECK: MayAlias: store i32 4, ptr %f32, align 4, !tbaa !8 <-> store i32 1, ptr %0, align 4, !tbaa !6
20 ; OPT: %[[RET:.*]] = load i32, ptr
21 ; OPT: ret i32 %[[RET]]
22 %s.addr = alloca ptr, align 8
23 %A.addr = alloca ptr, align 8
24 %count.addr = alloca i64, align 8
25 store ptr %s, ptr %s.addr, align 8, !tbaa !0
26 store ptr %A, ptr %A.addr, align 8, !tbaa !0
27 store i64 %count, ptr %count.addr, align 8, !tbaa !4
28 %0 = load ptr, ptr %s.addr, align 8, !tbaa !0
29 store i32 1, ptr %0, align 4, !tbaa !6
30 %1 = load ptr, ptr %A.addr, align 8, !tbaa !0
31 %f32 = getelementptr inbounds %struct.StructA, ptr %1, i32 0, i32 1
32 store i32 4, ptr %f32, align 4, !tbaa !8
33 %2 = load ptr, ptr %s.addr, align 8, !tbaa !0
34 %3 = load i32, ptr %2, align 4, !tbaa !6
38 define i32 @_Z2g2PjP7StructAy(ptr %s, ptr %A, i64 %count) #0 {
40 ; Access to ptr and &(A->f16).
42 ; CHECK: NoAlias: store i16 4, ptr %1, align 2, !tbaa !8 <-> store i32 1, ptr %0, align 4, !tbaa !6
46 ; Remove a load and propagate the value from store.
48 %s.addr = alloca ptr, align 8
49 %A.addr = alloca ptr, align 8
50 %count.addr = alloca i64, align 8
51 store ptr %s, ptr %s.addr, align 8, !tbaa !0
52 store ptr %A, ptr %A.addr, align 8, !tbaa !0
53 store i64 %count, ptr %count.addr, align 8, !tbaa !4
54 %0 = load ptr, ptr %s.addr, align 8, !tbaa !0
55 store i32 1, ptr %0, align 4, !tbaa !6
56 %1 = load ptr, ptr %A.addr, align 8, !tbaa !0
57 store i16 4, ptr %1, align 2, !tbaa !11
58 %2 = load ptr, ptr %s.addr, align 8, !tbaa !0
59 %3 = load i32, ptr %2, align 4, !tbaa !6
63 define i32 @_Z2g3P7StructAP7StructBy(ptr %A, ptr %B, i64 %count) #0 {
65 ; Access to &(A->f32) and &(B->a.f32).
67 ; CHECK: MayAlias: store i32 4, ptr %f321, align 4, !tbaa !10 <-> store i32 1, ptr %f32, align 4, !tbaa !6
71 ; OPT: %[[RET:.*]] = load i32, ptr
72 ; OPT: ret i32 %[[RET]]
73 %A.addr = alloca ptr, align 8
74 %B.addr = alloca ptr, align 8
75 %count.addr = alloca i64, align 8
76 store ptr %A, ptr %A.addr, align 8, !tbaa !0
77 store ptr %B, ptr %B.addr, align 8, !tbaa !0
78 store i64 %count, ptr %count.addr, align 8, !tbaa !4
79 %0 = load ptr, ptr %A.addr, align 8, !tbaa !0
80 %f32 = getelementptr inbounds %struct.StructA, ptr %0, i32 0, i32 1
81 store i32 1, ptr %f32, align 4, !tbaa !8
82 %1 = load ptr, ptr %B.addr, align 8, !tbaa !0
83 %a = getelementptr inbounds %struct.StructB, ptr %1, i32 0, i32 1
84 %f321 = getelementptr inbounds %struct.StructA, ptr %a, i32 0, i32 1
85 store i32 4, ptr %f321, align 4, !tbaa !12
86 %2 = load ptr, ptr %A.addr, align 8, !tbaa !0
87 %f322 = getelementptr inbounds %struct.StructA, ptr %2, i32 0, i32 1
88 %3 = load i32, ptr %f322, align 4, !tbaa !8
92 define i32 @_Z2g4P7StructAP7StructBy(ptr %A, ptr %B, i64 %count) #0 {
94 ; Access to &(A->f32) and &(B->a.f16).
96 ; CHECK: NoAlias: store i16 4, ptr %a, align 2, !tbaa !10 <-> store i32 1, ptr %f32, align 4, !tbaa !6
100 ; Remove a load and propagate the value from store.
102 %A.addr = alloca ptr, align 8
103 %B.addr = alloca ptr, align 8
104 %count.addr = alloca i64, align 8
105 store ptr %A, ptr %A.addr, align 8, !tbaa !0
106 store ptr %B, ptr %B.addr, align 8, !tbaa !0
107 store i64 %count, ptr %count.addr, align 8, !tbaa !4
108 %0 = load ptr, ptr %A.addr, align 8, !tbaa !0
109 %f32 = getelementptr inbounds %struct.StructA, ptr %0, i32 0, i32 1
110 store i32 1, ptr %f32, align 4, !tbaa !8
111 %1 = load ptr, ptr %B.addr, align 8, !tbaa !0
112 %a = getelementptr inbounds %struct.StructB, ptr %1, i32 0, i32 1
113 store i16 4, ptr %a, align 2, !tbaa !14
114 %2 = load ptr, ptr %A.addr, align 8, !tbaa !0
115 %f321 = getelementptr inbounds %struct.StructA, ptr %2, i32 0, i32 1
116 %3 = load i32, ptr %f321, align 4, !tbaa !8
120 define i32 @_Z2g5P7StructAP7StructBy(ptr %A, ptr %B, i64 %count) #0 {
122 ; Access to &(A->f32) and &(B->f32).
124 ; CHECK: NoAlias: store i32 4, ptr %f321, align 4, !tbaa !10 <-> store i32 1, ptr %f32, align 4, !tbaa !6
128 ; Remove a load and propagate the value from store.
130 %A.addr = alloca ptr, align 8
131 %B.addr = alloca ptr, align 8
132 %count.addr = alloca i64, align 8
133 store ptr %A, ptr %A.addr, align 8, !tbaa !0
134 store ptr %B, ptr %B.addr, align 8, !tbaa !0
135 store i64 %count, ptr %count.addr, align 8, !tbaa !4
136 %0 = load ptr, ptr %A.addr, align 8, !tbaa !0
137 %f32 = getelementptr inbounds %struct.StructA, ptr %0, i32 0, i32 1
138 store i32 1, ptr %f32, align 4, !tbaa !8
139 %1 = load ptr, ptr %B.addr, align 8, !tbaa !0
140 %f321 = getelementptr inbounds %struct.StructB, ptr %1, i32 0, i32 2
141 store i32 4, ptr %f321, align 4, !tbaa !15
142 %2 = load ptr, ptr %A.addr, align 8, !tbaa !0
143 %f322 = getelementptr inbounds %struct.StructA, ptr %2, i32 0, i32 1
144 %3 = load i32, ptr %f322, align 4, !tbaa !8
148 define i32 @_Z2g6P7StructAP7StructBy(ptr %A, ptr %B, i64 %count) #0 {
150 ; Access to &(A->f32) and &(B->a.f32_2).
152 ; CHECK: NoAlias: store i32 4, ptr %f32_2, align 4, !tbaa !10 <-> store i32 1, ptr %f32, align 4, !tbaa !6
156 ; Remove a load and propagate the value from store.
158 %A.addr = alloca ptr, align 8
159 %B.addr = alloca ptr, align 8
160 %count.addr = alloca i64, align 8
161 store ptr %A, ptr %A.addr, align 8, !tbaa !0
162 store ptr %B, ptr %B.addr, align 8, !tbaa !0
163 store i64 %count, ptr %count.addr, align 8, !tbaa !4
164 %0 = load ptr, ptr %A.addr, align 8, !tbaa !0
165 %f32 = getelementptr inbounds %struct.StructA, ptr %0, i32 0, i32 1
166 store i32 1, ptr %f32, align 4, !tbaa !8
167 %1 = load ptr, ptr %B.addr, align 8, !tbaa !0
168 %a = getelementptr inbounds %struct.StructB, ptr %1, i32 0, i32 1
169 %f32_2 = getelementptr inbounds %struct.StructA, ptr %a, i32 0, i32 3
170 store i32 4, ptr %f32_2, align 4, !tbaa !16
171 %2 = load ptr, ptr %A.addr, align 8, !tbaa !0
172 %f321 = getelementptr inbounds %struct.StructA, ptr %2, i32 0, i32 1
173 %3 = load i32, ptr %f321, align 4, !tbaa !8
177 define i32 @_Z2g7P7StructAP7StructSy(ptr %A, ptr %S, i64 %count) #0 {
179 ; Access to &(A->f32) and &(S->f32).
181 ; CHECK: NoAlias: store i32 4, ptr %f321, align 4, !tbaa !10 <-> store i32 1, ptr %f32, align 4, !tbaa !6
185 ; Remove a load and propagate the value from store.
187 %A.addr = alloca ptr, align 8
188 %S.addr = alloca ptr, align 8
189 %count.addr = alloca i64, align 8
190 store ptr %A, ptr %A.addr, align 8, !tbaa !0
191 store ptr %S, ptr %S.addr, align 8, !tbaa !0
192 store i64 %count, ptr %count.addr, align 8, !tbaa !4
193 %0 = load ptr, ptr %A.addr, align 8, !tbaa !0
194 %f32 = getelementptr inbounds %struct.StructA, ptr %0, i32 0, i32 1
195 store i32 1, ptr %f32, align 4, !tbaa !8
196 %1 = load ptr, ptr %S.addr, align 8, !tbaa !0
197 %f321 = getelementptr inbounds %struct.StructS, ptr %1, i32 0, i32 1
198 store i32 4, ptr %f321, align 4, !tbaa !17
199 %2 = load ptr, ptr %A.addr, align 8, !tbaa !0
200 %f322 = getelementptr inbounds %struct.StructA, ptr %2, i32 0, i32 1
201 %3 = load i32, ptr %f322, align 4, !tbaa !8
205 define i32 @_Z2g8P7StructAP7StructSy(ptr %A, ptr %S, i64 %count) #0 {
207 ; Access to &(A->f32) and &(S->f16).
209 ; CHECK: NoAlias: store i16 4, ptr %1, align 2, !tbaa !10 <-> store i32 1, ptr %f32, align 4, !tbaa !6
213 ; Remove a load and propagate the value from store.
215 %A.addr = alloca ptr, align 8
216 %S.addr = alloca ptr, align 8
217 %count.addr = alloca i64, align 8
218 store ptr %A, ptr %A.addr, align 8, !tbaa !0
219 store ptr %S, ptr %S.addr, align 8, !tbaa !0
220 store i64 %count, ptr %count.addr, align 8, !tbaa !4
221 %0 = load ptr, ptr %A.addr, align 8, !tbaa !0
222 %f32 = getelementptr inbounds %struct.StructA, ptr %0, i32 0, i32 1
223 store i32 1, ptr %f32, align 4, !tbaa !8
224 %1 = load ptr, ptr %S.addr, align 8, !tbaa !0
225 store i16 4, ptr %1, align 2, !tbaa !19
226 %2 = load ptr, ptr %A.addr, align 8, !tbaa !0
227 %f321 = getelementptr inbounds %struct.StructA, ptr %2, i32 0, i32 1
228 %3 = load i32, ptr %f321, align 4, !tbaa !8
232 define i32 @_Z2g9P7StructSP8StructS2y(ptr %S, ptr %S2, i64 %count) #0 {
234 ; Access to &(S->f32) and &(S2->f32).
236 ; CHECK: NoAlias: store i32 4, ptr %f321, align 4, !tbaa !10 <-> store i32 1, ptr %f32, align 4, !tbaa !6
240 ; Remove a load and propagate the value from store.
242 %S.addr = alloca ptr, align 8
243 %S2.addr = alloca ptr, align 8
244 %count.addr = alloca i64, align 8
245 store ptr %S, ptr %S.addr, align 8, !tbaa !0
246 store ptr %S2, ptr %S2.addr, align 8, !tbaa !0
247 store i64 %count, ptr %count.addr, align 8, !tbaa !4
248 %0 = load ptr, ptr %S.addr, align 8, !tbaa !0
249 %f32 = getelementptr inbounds %struct.StructS, ptr %0, i32 0, i32 1
250 store i32 1, ptr %f32, align 4, !tbaa !17
251 %1 = load ptr, ptr %S2.addr, align 8, !tbaa !0
252 %f321 = getelementptr inbounds %struct.StructS2, ptr %1, i32 0, i32 1
253 store i32 4, ptr %f321, align 4, !tbaa !20
254 %2 = load ptr, ptr %S.addr, align 8, !tbaa !0
255 %f322 = getelementptr inbounds %struct.StructS, ptr %2, i32 0, i32 1
256 %3 = load i32, ptr %f322, align 4, !tbaa !17
260 define i32 @_Z3g10P7StructSP8StructS2y(ptr %S, ptr %S2, i64 %count) #0 {
262 ; Access to &(S->f32) and &(S2->f16).
264 ; CHECK: NoAlias: store i16 4, ptr %1, align 2, !tbaa !10 <-> store i32 1, ptr %f32, align 4, !tbaa !6
268 ; Remove a load and propagate the value from store.
270 %S.addr = alloca ptr, align 8
271 %S2.addr = alloca ptr, align 8
272 %count.addr = alloca i64, align 8
273 store ptr %S, ptr %S.addr, align 8, !tbaa !0
274 store ptr %S2, ptr %S2.addr, align 8, !tbaa !0
275 store i64 %count, ptr %count.addr, align 8, !tbaa !4
276 %0 = load ptr, ptr %S.addr, align 8, !tbaa !0
277 %f32 = getelementptr inbounds %struct.StructS, ptr %0, i32 0, i32 1
278 store i32 1, ptr %f32, align 4, !tbaa !17
279 %1 = load ptr, ptr %S2.addr, align 8, !tbaa !0
280 store i16 4, ptr %1, align 2, !tbaa !22
281 %2 = load ptr, ptr %S.addr, align 8, !tbaa !0
282 %f321 = getelementptr inbounds %struct.StructS, ptr %2, i32 0, i32 1
283 %3 = load i32, ptr %f321, align 4, !tbaa !17
287 define i32 @_Z3g11P7StructCP7StructDy(ptr %C, ptr %D, i64 %count) #0 {
289 ; Access to &(C->b.a.f32) and &(D->b.a.f32).
291 ; CHECK: NoAlias: store i32 4, ptr %f323, align 4, !tbaa !12 <-> store i32 1, ptr %f32, align 4, !tbaa !6
295 ; Remove a load and propagate the value from store.
297 %C.addr = alloca ptr, align 8
298 %D.addr = alloca ptr, align 8
299 %count.addr = alloca i64, align 8
300 store ptr %C, ptr %C.addr, align 8, !tbaa !0
301 store ptr %D, ptr %D.addr, align 8, !tbaa !0
302 store i64 %count, ptr %count.addr, align 8, !tbaa !4
303 %0 = load ptr, ptr %C.addr, align 8, !tbaa !0
304 %b = getelementptr inbounds %struct.StructC, ptr %0, i32 0, i32 1
305 %a = getelementptr inbounds %struct.StructB, ptr %b, i32 0, i32 1
306 %f32 = getelementptr inbounds %struct.StructA, ptr %a, i32 0, i32 1
307 store i32 1, ptr %f32, align 4, !tbaa !23
308 %1 = load ptr, ptr %D.addr, align 8, !tbaa !0
309 %b1 = getelementptr inbounds %struct.StructD, ptr %1, i32 0, i32 1
310 %a2 = getelementptr inbounds %struct.StructB, ptr %b1, i32 0, i32 1
311 %f323 = getelementptr inbounds %struct.StructA, ptr %a2, i32 0, i32 1
312 store i32 4, ptr %f323, align 4, !tbaa !25
313 %2 = load ptr, ptr %C.addr, align 8, !tbaa !0
314 %b4 = getelementptr inbounds %struct.StructC, ptr %2, i32 0, i32 1
315 %a5 = getelementptr inbounds %struct.StructB, ptr %b4, i32 0, i32 1
316 %f326 = getelementptr inbounds %struct.StructA, ptr %a5, i32 0, i32 1
317 %3 = load i32, ptr %f326, align 4, !tbaa !23
321 define i32 @_Z3g12P7StructCP7StructDy(ptr %C, ptr %D, i64 %count) #0 {
323 ; Access to &(b1->a.f32) and &(b2->a.f32).
325 ; CHECK: MayAlias: store i32 4, ptr %f325, align 4, !tbaa !6 <-> store i32 1, ptr %f32, align 4, !tbaa !6
329 ; OPT: %[[RET:.*]] = load i32, ptr
330 ; OPT: ret i32 %[[RET]]
331 %C.addr = alloca ptr, align 8
332 %D.addr = alloca ptr, align 8
333 %count.addr = alloca i64, align 8
334 %b1 = alloca ptr, align 8
335 %b2 = alloca ptr, align 8
336 store ptr %C, ptr %C.addr, align 8, !tbaa !0
337 store ptr %D, ptr %D.addr, align 8, !tbaa !0
338 store i64 %count, ptr %count.addr, align 8, !tbaa !4
339 %0 = load ptr, ptr %C.addr, align 8, !tbaa !0
340 %b = getelementptr inbounds %struct.StructC, ptr %0, i32 0, i32 1
341 store ptr %b, ptr %b1, align 8, !tbaa !0
342 %1 = load ptr, ptr %D.addr, align 8, !tbaa !0
343 %b3 = getelementptr inbounds %struct.StructD, ptr %1, i32 0, i32 1
344 store ptr %b3, ptr %b2, align 8, !tbaa !0
345 %2 = load ptr, ptr %b1, align 8, !tbaa !0
346 %a = getelementptr inbounds %struct.StructB, ptr %2, i32 0, i32 1
347 %f32 = getelementptr inbounds %struct.StructA, ptr %a, i32 0, i32 1
348 store i32 1, ptr %f32, align 4, !tbaa !12
349 %3 = load ptr, ptr %b2, align 8, !tbaa !0
350 %a4 = getelementptr inbounds %struct.StructB, ptr %3, i32 0, i32 1
351 %f325 = getelementptr inbounds %struct.StructA, ptr %a4, i32 0, i32 1
352 store i32 4, ptr %f325, align 4, !tbaa !12
353 %4 = load ptr, ptr %b1, align 8, !tbaa !0
354 %a6 = getelementptr inbounds %struct.StructB, ptr %4, i32 0, i32 1
355 %f327 = getelementptr inbounds %struct.StructA, ptr %a6, i32 0, i32 1
356 %5 = load i32, ptr %f327, align 4, !tbaa !12
360 attributes #0 = { nounwind "less-precise-fpmad"="false" "frame-pointer"="none" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
362 !0 = !{!1, !1, i64 0}
363 !1 = !{!"any pointer", !2}
364 !2 = !{!"omnipotent char", !3}
365 !3 = !{!"Simple C/C++ TBAA"}
366 !4 = !{!5, !5, i64 0}
367 !5 = !{!"long long", !2}
368 !6 = !{!7, !7, i64 0}
370 !8 = !{!9, !7, i64 4}
371 !9 = !{!"_ZTS7StructA", !10, i64 0, !7, i64 4, !10, i64 8, !7, i64 12}
372 !10 = !{!"short", !2}
373 !11 = !{!9, !10, i64 0}
374 !12 = !{!13, !7, i64 8}
375 !13 = !{!"_ZTS7StructB", !10, i64 0, !9, i64 4, !7, i64 20}
376 !14 = !{!13, !10, i64 4}
377 !15 = !{!13, !7, i64 20}
378 !16 = !{!13, !7, i64 16}
379 !17 = !{!18, !7, i64 4}
380 !18 = !{!"_ZTS7StructS", !10, i64 0, !7, i64 4}
381 !19 = !{!18, !10, i64 0}
382 !20 = !{!21, !7, i64 4}
383 !21 = !{!"_ZTS8StructS2", !10, i64 0, !7, i64 4}
384 !22 = !{!21, !10, i64 0}
385 !23 = !{!24, !7, i64 12}
386 !24 = !{!"_ZTS7StructC", !10, i64 0, !13, i64 4, !7, i64 28}
387 !25 = !{!26, !7, i64 12}
388 !26 = !{!"_ZTS7StructD", !10, i64 0, !13, i64 4, !7, i64 28, !2, i64 32}