xref: /llvm-project/llvm/test/Analysis/TypeBasedAliasAnalysis/tbaa-path-new.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 -new-struct-path-tbaa".
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
12; uint32_t g(uint32_t *s, StructA *A, uint64_t count) {
13;   *s = 1;
14;   A->f32 = 4;
15;   return *s;
16; }
17;
18define i32 @_Z1gPjP7StructAy(ptr nocapture %s, ptr nocapture %A, i64 %count) {
19entry:
20; CHECK-LABEL: Z1gPjP7StructAy
21; CHECK: MayAlias: store i32 4, {{.*}} <-> store i32 1,
22; OPT-LABEL: _Z1gPjP7StructAy
23; OPT: store i32 1,
24; OPT: store i32 4,
25; OPT: %[[RET:.*]] = load i32,
26; OPT: ret i32 %[[RET]]
27  store i32 1, ptr %s, align 4, !tbaa !2
28  %f32 = getelementptr inbounds %struct.StructA, ptr %A, i64 0, i32 1
29  store i32 4, ptr %f32, align 4, !tbaa !6
30  %0 = load i32, ptr %s, align 4, !tbaa !2
31  ret i32 %0
32}
33
34; uint32_t g2(uint32_t *s, StructA *A, uint64_t count) {
35;   *s = 1;
36;   A->f16 = 4;
37;   return *s;
38; }
39;
40define i32 @_Z2g2PjP7StructAy(ptr nocapture %s, ptr nocapture %A, i64 %count) {
41entry:
42; CHECK-LABEL: _Z2g2PjP7StructAy
43; CHECK: NoAlias: store i16 4, {{.*}} <-> store i32 1,
44; OPT-LABEL: _Z2g2PjP7StructAy
45; OPT: store i32 1,
46; OPT: store i16 4,
47; Remove a load and propagate the value from store.
48; OPT: ret i32 1
49  store i32 1, ptr %s, align 4, !tbaa !2
50  store i16 4, ptr %A, align 4, !tbaa !9
51  ret i32 1
52}
53
54; uint32_t g3(StructA *A, StructB *B, uint64_t count) {
55;   A->f32 = 1;
56;   B->a.f32 = 4;
57;   return A->f32;
58; }
59;
60define i32 @_Z2g3P7StructAP7StructBy(ptr nocapture %A, ptr nocapture %B, i64 %count) {
61entry:
62; CHECK-LABEL: _Z2g3P7StructAP7StructBy
63; CHECK: MayAlias: store i32 4, {{.*}} <-> store i32 1,
64; OPT-LABEL: _Z2g3P7StructAP7StructBy
65; OPT: store i32 1
66; OPT: store i32 4
67; OPT: %[[RET:.*]] = load i32,
68; OPT: ret i32 %[[RET]]
69  %f32 = getelementptr inbounds %struct.StructA, ptr %A, i64 0, i32 1
70  store i32 1, ptr %f32, align 4, !tbaa !6
71  %f321 = getelementptr inbounds %struct.StructB, ptr %B, i64 0, i32 1, i32 1
72  store i32 4, ptr %f321, align 4, !tbaa !10
73  %0 = load i32, ptr %f32, align 4, !tbaa !6
74  ret i32 %0
75}
76
77; uint32_t g4(StructA *A, StructB *B, uint64_t count) {
78;   A->f32 = 1;
79;   B->a.f16 = 4;
80;   return A->f32;
81; }
82;
83define i32 @_Z2g4P7StructAP7StructBy(ptr nocapture %A, ptr nocapture %B, i64 %count) {
84entry:
85; CHECK-LABEL: _Z2g4P7StructAP7StructBy
86; CHECK: NoAlias: store i16 4, {{.*}} <-> store i32 1,
87; OPT-LABEL: _Z2g4P7StructAP7StructBy
88; OPT: store i32 1,
89; OPT: store i16 4,
90; Remove a load and propagate the value from store.
91; OPT: ret i32 1
92  %f32 = getelementptr inbounds %struct.StructA, ptr %A, i64 0, i32 1
93  store i32 1, ptr %f32, align 4, !tbaa !6
94  %f16 = getelementptr inbounds %struct.StructB, ptr %B, i64 0, i32 1, i32 0
95  store i16 4, ptr %f16, align 4, !tbaa !12
96  ret i32 1
97}
98
99; uint32_t g5(StructA *A, StructB *B, uint64_t count) {
100;   A->f32 = 1;
101;   B->f32 = 4;
102;   return A->f32;
103; }
104;
105define i32 @_Z2g5P7StructAP7StructBy(ptr nocapture %A, ptr nocapture %B, i64 %count) {
106entry:
107; CHECK-LABEL: _Z2g5P7StructAP7StructBy
108; CHECK: NoAlias: store i32 4, {{.*}} <-> store i32 1,
109; OPT-LABEL: _Z2g5P7StructAP7StructBy
110; OPT: store i32 1,
111; OPT: store i32 4,
112; Remove a load and propagate the value from store.
113; OPT: ret i32 1
114  %f32 = getelementptr inbounds %struct.StructA, ptr %A, i64 0, i32 1
115  store i32 1, ptr %f32, align 4, !tbaa !6
116  %f321 = getelementptr inbounds %struct.StructB, ptr %B, i64 0, i32 2
117  store i32 4, ptr %f321, align 4, !tbaa !13
118  ret i32 1
119}
120
121; uint32_t g6(StructA *A, StructB *B, uint64_t count) {
122;   A->f32 = 1;
123;   B->a.f32_2 = 4;
124;   return A->f32;
125; }
126;
127define i32 @_Z2g6P7StructAP7StructBy(ptr nocapture %A, ptr nocapture %B, i64 %count) {
128entry:
129; CHECK-LABEL: _Z2g6P7StructAP7StructBy
130; CHECK: NoAlias: store i32 4, {{.*}} <-> store i32 1,
131; OPT-LABEL: _Z2g6P7StructAP7StructBy
132; OPT: store i32 1,
133; OPT: store i32 4,
134; Remove a load and propagate the value from store.
135; OPT: ret i32 1
136  %f32 = getelementptr inbounds %struct.StructA, ptr %A, i64 0, i32 1
137  store i32 1, ptr %f32, align 4, !tbaa !6
138  %f32_2 = getelementptr inbounds %struct.StructB, ptr %B, i64 0, i32 1, i32 3
139  store i32 4, ptr %f32_2, align 4, !tbaa !14
140  ret i32 1
141}
142
143; uint32_t g7(StructA *A, StructS *S, uint64_t count) {
144;   A->f32 = 1;
145;   S->f32 = 4;
146;   return A->f32;
147; }
148;
149define i32 @_Z2g7P7StructAP7StructSy(ptr nocapture %A, ptr nocapture %S, i64 %count) {
150entry:
151; CHECK-LABEL: _Z2g7P7StructAP7StructSy
152; CHECK: NoAlias: store i32 4, {{.*}} <-> store i32 1,
153; OPT-LABEL: _Z2g7P7StructAP7StructSy
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  %f32 = getelementptr inbounds %struct.StructA, ptr %A, i64 0, i32 1
159  store i32 1, ptr %f32, align 4, !tbaa !6
160  %f321 = getelementptr inbounds %struct.StructS, ptr %S, i64 0, i32 1
161  store i32 4, ptr %f321, align 4, !tbaa !15
162  ret i32 1
163}
164
165; uint32_t g8(StructA *A, StructS *S, uint64_t count) {
166;   A->f32 = 1;
167;   S->f16 = 4;
168;   return A->f32;
169; }
170;
171define i32 @_Z2g8P7StructAP7StructSy(ptr nocapture %A, ptr nocapture %S, i64 %count) {
172entry:
173; CHECK-LABEL: _Z2g8P7StructAP7StructSy
174; CHECK: NoAlias: store i16 4, {{.*}} <-> store i32 1,
175; OPT-LABEL: _Z2g8P7StructAP7StructSy
176; OPT: store i32 1,
177; OPT: store i16 4,
178; Remove a load and propagate the value from store.
179; OPT: ret i32 1
180  %f32 = getelementptr inbounds %struct.StructA, ptr %A, i64 0, i32 1
181  store i32 1, ptr %f32, align 4, !tbaa !6
182  store i16 4, ptr %S, align 4, !tbaa !17
183  ret i32 1
184}
185
186; uint32_t g9(StructS *S, StructS2 *S2, uint64_t count) {
187;   S->f32 = 1;
188;   S2->f32 = 4;
189;   return S->f32;
190; }
191;
192define i32 @_Z2g9P7StructSP8StructS2y(ptr nocapture %S, ptr nocapture %S2, i64 %count) {
193entry:
194; CHECK-LABEL: _Z2g9P7StructSP8StructS2y
195; CHECK: NoAlias: store i32 4, {{.*}} <-> store i32 1,
196; OPT-LABEL: _Z2g9P7StructSP8StructS2y
197; OPT: store i32 1,
198; OPT: store i32 4,
199; Remove a load and propagate the value from store.
200; OPT: ret i32 1
201  %f32 = getelementptr inbounds %struct.StructS, ptr %S, i64 0, i32 1
202  store i32 1, ptr %f32, align 4, !tbaa !15
203  %f321 = getelementptr inbounds %struct.StructS2, ptr %S2, i64 0, i32 1
204  store i32 4, ptr %f321, align 4, !tbaa !18
205  ret i32 1
206}
207
208; uint32_t g10(StructS *S, StructS2 *S2, uint64_t count) {
209;   S->f32 = 1;
210;   S2->f16 = 4;
211;   return S->f32;
212; }
213;
214define i32 @_Z3g10P7StructSP8StructS2y(ptr nocapture %S, ptr nocapture %S2, i64 %count) {
215entry:
216; CHECK-LABEL: _Z3g10P7StructSP8StructS2y
217; CHECK: NoAlias: store i16 4, {{.*}} <-> store i32 1,
218; OPT-LABEL: _Z3g10P7StructSP8StructS2y
219; OPT: store i32 1,
220; OPT: store i16 4,
221; Remove a load and propagate the value from store.
222; OPT: ret i32 1
223  %f32 = getelementptr inbounds %struct.StructS, ptr %S, i64 0, i32 1
224  store i32 1, ptr %f32, align 4, !tbaa !15
225  store i16 4, ptr %S2, align 4, !tbaa !20
226  ret i32 1
227}
228
229; uint32_t g11(StructC *C, StructD *D, uint64_t count) {
230;   C->b.a.f32 = 1;
231;   D->b.a.f32 = 4;
232;   return C->b.a.f32;
233; }
234;
235define i32 @_Z3g11P7StructCP7StructDy(ptr nocapture %C, ptr nocapture %D, i64 %count) {
236entry:
237; CHECK-LABEL: _Z3g11P7StructCP7StructDy
238; CHECK: NoAlias: store i32 4, {{.*}} <-> store i32 1,
239; OPT-LABEL: _Z3g11P7StructCP7StructDy
240; OPT: store i32 1,
241; OPT: store i32 4,
242; Remove a load and propagate the value from store.
243; OPT: ret i32 1
244  %f32 = getelementptr inbounds %struct.StructC, ptr %C, i64 0, i32 1, i32 1, i32 1
245  store i32 1, ptr %f32, align 4, !tbaa !21
246  %f323 = getelementptr inbounds %struct.StructD, ptr %D, i64 0, i32 1, i32 1, i32 1
247  store i32 4, ptr %f323, align 4, !tbaa !23
248  ret i32 1
249}
250
251; uint32_t g12(StructC *C, StructD *D, uint64_t count) {
252;   StructB *b1 = &(C->b);
253;   StructB *b2 = &(D->b);
254;   // b1, b2 have different context.
255;   b1->a.f32 = 1;
256;   b2->a.f32 = 4;
257;   return b1->a.f32;
258; }
259;
260define i32 @_Z3g12P7StructCP7StructDy(ptr nocapture %C, ptr nocapture %D, i64 %count) {
261entry:
262; CHECK-LABEL: _Z3g12P7StructCP7StructDy
263; CHECK: MayAlias: store i32 4, {{.*}} <-> store i32 1,
264; OPT-LABEL: _Z3g12P7StructCP7StructDy
265; OPT: store i32 1,
266; OPT: store i32 4,
267; OPT: %[[RET:.*]] = load i32,
268; OPT: ret i32 %[[RET]]
269  %f32 = getelementptr inbounds %struct.StructC, ptr %C, i64 0, i32 1, i32 1, i32 1
270  store i32 1, ptr %f32, align 4, !tbaa !10
271  %f325 = getelementptr inbounds %struct.StructD, ptr %D, i64 0, i32 1, i32 1, i32 1
272  store i32 4, ptr %f325, align 4, !tbaa !10
273  %0 = load i32, ptr %f32, align 4, !tbaa !10
274  ret i32 %0
275}
276
277!2 = !{!3, !3, i64 0, i64 4}
278!3 = !{!4, i64 4, !"int"}
279!4 = !{!5, i64 1, !"omnipotent char"}
280!5 = !{!"Simple C++ TBAA"}
281!6 = !{!7, !3, i64 4, i64 4}
282!7 = !{!4, i64 16, !"_ZTS7StructA", !8, i64 0, i64 2, !3, i64 4, i64 4, !8, i64 8, i64 2, !3, i64 12, i64 4}
283!8 = !{!4, i64 2, !"short"}
284!9 = !{!7, !8, i64 0, i64 2}
285!10 = !{!11, !3, i64 8, i64 4}
286!11 = !{!4, i64 24, !"_ZTS7StructB", !8, i64 0, i64 2, !7, i64 4, i64 16, !3, i64 20, i64 4}
287!12 = !{!11, !8, i64 4, i64 2}
288!13 = !{!11, !3, i64 20, i64 4}
289!14 = !{!11, !3, i64 16, i64 4}
290!15 = !{!16, !3, i64 4, i64 4}
291!16 = !{!4, i64 8, !"_ZTS7StructS", !8, i64 0, i64 2, !3, i64 4, i64 4}
292!17 = !{!16, !8, i64 0, i64 2}
293!18 = !{!19, !3, i64 4, i64 4}
294!19 = !{!4, i64 8, !"_ZTS8StructS2", !8, i64 0, i64 2, !3, i64 4, i64 4}
295!20 = !{!19, !8, i64 0, i64 2}
296!21 = !{!22, !3, i64 12, i64 4}
297!22 = !{!4, i64 32, !"_ZTS7StructC", !8, i64 0, i64 2, !11, i64 4, i64 24, !3, i64 28, i64 4}
298!23 = !{!24, !3, i64 12, i64 4}
299!24 = !{!4, i64 36, !"_ZTS7StructD", !8, i64 0, i64 2, !11, i64 4, i64 24, !3, i64 28, i64 4, !4, i64 32, i64 1}
300!25 = !{!26, !4, i64 1, i64 1}
301!26 = !{!4, i64 3, !"_ZTS4five", !4, i64 0, i64 1, !3, i64 1, i64 4, !4, i64 1, i64 1, !4, i64 2, i64 1}
302!27 = !{!28, !4, i64 4, i64 1}
303!28 = !{!4, i64 6, !"_ZTS3six", !4, i64 0, i64 1, !3, i64 4, i64 4, !4, i64 4, i64 1, !4, i64 5, i64 1}
304