xref: /llvm-project/llvm/test/Analysis/TypeBasedAliasAnalysis/tbaa-path.ll (revision 6402fc22e1bccd0984beadfe931511175bac688c)
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".
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(ptr %s, ptr %A, i64 %count) #0 {
13entry:
14; Access to ptr and &(A->f32).
15; CHECK: Function
16; CHECK: MayAlias:   store i32 4, ptr %f32, align 4, !tbaa !8 <->   store i32 1, ptr %0, align 4, !tbaa !6
17; OPT: define
18; OPT: store i32 1
19; OPT: store i32 4
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
35  ret i32 %3
36}
37
38define i32 @_Z2g2PjP7StructAy(ptr %s, ptr %A, i64 %count) #0 {
39entry:
40; Access to ptr and &(A->f16).
41; CHECK: Function
42; CHECK: NoAlias:   store i16 4, ptr %1, align 2, !tbaa !8 <->   store i32 1, ptr %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 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
60  ret i32 %3
61}
62
63define i32 @_Z2g3P7StructAP7StructBy(ptr %A, ptr %B, i64 %count) #0 {
64entry:
65; Access to &(A->f32) and &(B->a.f32).
66; CHECK: Function
67; CHECK: MayAlias:   store i32 4, ptr %f321, align 4, !tbaa !10 <->   store i32 1, ptr %f32, align 4, !tbaa !6
68; OPT: define
69; OPT: store i32 1
70; OPT: store i32 4
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
89  ret i32 %3
90}
91
92define i32 @_Z2g4P7StructAP7StructBy(ptr %A, ptr %B, i64 %count) #0 {
93entry:
94; Access to &(A->f32) and &(B->a.f16).
95; CHECK: Function
96; CHECK: NoAlias:   store i16 4, ptr %a, align 2, !tbaa !10 <->   store i32 1, ptr %f32, align 4, !tbaa !6
97; OPT: define
98; OPT: store i32 1
99; OPT: store i16 4
100; Remove a load and propagate the value from store.
101; OPT: ret i32 1
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
117  ret i32 %3
118}
119
120define i32 @_Z2g5P7StructAP7StructBy(ptr %A, ptr %B, i64 %count) #0 {
121entry:
122; Access to &(A->f32) and &(B->f32).
123; CHECK: Function
124; CHECK: NoAlias:   store i32 4, ptr %f321, align 4, !tbaa !10 <->   store i32 1, ptr %f32, align 4, !tbaa !6
125; OPT: define
126; OPT: store i32 1
127; OPT: store i32 4
128; Remove a load and propagate the value from store.
129; OPT: ret i32 1
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
145  ret i32 %3
146}
147
148define i32 @_Z2g6P7StructAP7StructBy(ptr %A, ptr %B, i64 %count) #0 {
149entry:
150; Access to &(A->f32) and &(B->a.f32_2).
151; CHECK: Function
152; CHECK: NoAlias:   store i32 4, ptr %f32_2, align 4, !tbaa !10 <->   store i32 1, ptr %f32, align 4, !tbaa !6
153; OPT: define
154; OPT: store i32 1
155; OPT: store i32 4
156; Remove a load and propagate the value from store.
157; OPT: ret i32 1
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
174  ret i32 %3
175}
176
177define i32 @_Z2g7P7StructAP7StructSy(ptr %A, ptr %S, i64 %count) #0 {
178entry:
179; Access to &(A->f32) and &(S->f32).
180; CHECK: Function
181; CHECK: NoAlias:   store i32 4, ptr %f321, align 4, !tbaa !10 <->   store i32 1, ptr %f32, align 4, !tbaa !6
182; OPT: define
183; OPT: store i32 1
184; OPT: store i32 4
185; Remove a load and propagate the value from store.
186; OPT: ret i32 1
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
202  ret i32 %3
203}
204
205define i32 @_Z2g8P7StructAP7StructSy(ptr %A, ptr %S, i64 %count) #0 {
206entry:
207; Access to &(A->f32) and &(S->f16).
208; CHECK: Function
209; CHECK: NoAlias:   store i16 4, ptr %1, align 2, !tbaa !10 <->   store i32 1, ptr %f32, align 4, !tbaa !6
210; OPT: define
211; OPT: store i32 1
212; OPT: store i16 4
213; Remove a load and propagate the value from store.
214; OPT: ret i32 1
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
229  ret i32 %3
230}
231
232define i32 @_Z2g9P7StructSP8StructS2y(ptr %S, ptr %S2, i64 %count) #0 {
233entry:
234; Access to &(S->f32) and &(S2->f32).
235; CHECK: Function
236; CHECK: NoAlias:   store i32 4, ptr %f321, align 4, !tbaa !10 <->   store i32 1, ptr %f32, align 4, !tbaa !6
237; OPT: define
238; OPT: store i32 1
239; OPT: store i32 4
240; Remove a load and propagate the value from store.
241; OPT: ret i32 1
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
257  ret i32 %3
258}
259
260define i32 @_Z3g10P7StructSP8StructS2y(ptr %S, ptr %S2, i64 %count) #0 {
261entry:
262; Access to &(S->f32) and &(S2->f16).
263; CHECK: Function
264; CHECK: NoAlias:   store i16 4, ptr %1, align 2, !tbaa !10 <->   store i32 1, ptr %f32, align 4, !tbaa !6
265; OPT: define
266; OPT: store i32 1
267; OPT: store i16 4
268; Remove a load and propagate the value from store.
269; OPT: ret i32 1
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
284  ret i32 %3
285}
286
287define i32 @_Z3g11P7StructCP7StructDy(ptr %C, ptr %D, i64 %count) #0 {
288entry:
289; Access to &(C->b.a.f32) and &(D->b.a.f32).
290; CHECK: Function
291; CHECK: NoAlias:   store i32 4, ptr %f323, align 4, !tbaa !12 <->   store i32 1, ptr %f32, align 4, !tbaa !6
292; OPT: define
293; OPT: store i32 1
294; OPT: store i32 4
295; Remove a load and propagate the value from store.
296; OPT: ret i32 1
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
318  ret i32 %3
319}
320
321define i32 @_Z3g12P7StructCP7StructDy(ptr %C, ptr %D, i64 %count) #0 {
322entry:
323; Access to &(b1->a.f32) and &(b2->a.f32).
324; CHECK: Function
325; CHECK: MayAlias:   store i32 4, ptr %f325, align 4, !tbaa !6 <->   store i32 1, ptr %f32, align 4, !tbaa !6
326; OPT: define
327; OPT: store i32 1
328; OPT: store i32 4
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
357  ret i32 %5
358}
359
360attributes #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" }
361
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}
369!7 = !{!"int", !2}
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}
389