xref: /minix3/external/bsd/llvm/dist/clang/test/CodeGen/tbaa-class.cpp (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -no-struct-path-tbaa -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s
2*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s -check-prefix=PATH
3*f4a2713aSLionel Sambuc // Test TBAA metadata generated by front-end.
4*f4a2713aSLionel Sambuc 
5*f4a2713aSLionel Sambuc typedef unsigned char uint8_t;
6*f4a2713aSLionel Sambuc typedef unsigned short uint16_t;
7*f4a2713aSLionel Sambuc typedef unsigned int uint32_t;
8*f4a2713aSLionel Sambuc typedef unsigned long long uint64_t;
9*f4a2713aSLionel Sambuc class StructA
10*f4a2713aSLionel Sambuc {
11*f4a2713aSLionel Sambuc public:
12*f4a2713aSLionel Sambuc    uint16_t f16;
13*f4a2713aSLionel Sambuc    uint32_t f32;
14*f4a2713aSLionel Sambuc    uint16_t f16_2;
15*f4a2713aSLionel Sambuc    uint32_t f32_2;
16*f4a2713aSLionel Sambuc };
17*f4a2713aSLionel Sambuc class StructB
18*f4a2713aSLionel Sambuc {
19*f4a2713aSLionel Sambuc public:
20*f4a2713aSLionel Sambuc    uint16_t f16;
21*f4a2713aSLionel Sambuc    StructA a;
22*f4a2713aSLionel Sambuc    uint32_t f32;
23*f4a2713aSLionel Sambuc };
24*f4a2713aSLionel Sambuc class StructC
25*f4a2713aSLionel Sambuc {
26*f4a2713aSLionel Sambuc public:
27*f4a2713aSLionel Sambuc    uint16_t f16;
28*f4a2713aSLionel Sambuc    StructB b;
29*f4a2713aSLionel Sambuc    uint32_t f32;
30*f4a2713aSLionel Sambuc };
31*f4a2713aSLionel Sambuc class StructD
32*f4a2713aSLionel Sambuc {
33*f4a2713aSLionel Sambuc public:
34*f4a2713aSLionel Sambuc    uint16_t f16;
35*f4a2713aSLionel Sambuc    StructB b;
36*f4a2713aSLionel Sambuc    uint32_t f32;
37*f4a2713aSLionel Sambuc    uint8_t f8;
38*f4a2713aSLionel Sambuc };
39*f4a2713aSLionel Sambuc 
40*f4a2713aSLionel Sambuc class StructS
41*f4a2713aSLionel Sambuc {
42*f4a2713aSLionel Sambuc public:
43*f4a2713aSLionel Sambuc    uint16_t f16;
44*f4a2713aSLionel Sambuc    uint32_t f32;
45*f4a2713aSLionel Sambuc };
46*f4a2713aSLionel Sambuc class StructS2 : public StructS
47*f4a2713aSLionel Sambuc {
48*f4a2713aSLionel Sambuc public:
49*f4a2713aSLionel Sambuc    uint16_t f16_2;
50*f4a2713aSLionel Sambuc    uint32_t f32_2;
51*f4a2713aSLionel Sambuc };
52*f4a2713aSLionel Sambuc 
53*f4a2713aSLionel Sambuc uint32_t g(uint32_t *s, StructA *A, uint64_t count) {
54*f4a2713aSLionel Sambuc // CHECK: define i32 @{{.*}}(
55*f4a2713aSLionel Sambuc // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32:!.*]]
56*f4a2713aSLionel Sambuc // CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
57*f4a2713aSLionel Sambuc // PATH: define i32 @{{.*}}(
58*f4a2713aSLionel Sambuc // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32:!.*]]
59*f4a2713aSLionel Sambuc // PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32:!.*]]
60*f4a2713aSLionel Sambuc   *s = 1;
61*f4a2713aSLionel Sambuc   A->f32 = 4;
62*f4a2713aSLionel Sambuc   return *s;
63*f4a2713aSLionel Sambuc }
64*f4a2713aSLionel Sambuc 
65*f4a2713aSLionel Sambuc uint32_t g2(uint32_t *s, StructA *A, uint64_t count) {
66*f4a2713aSLionel Sambuc // CHECK: define i32 @{{.*}}(
67*f4a2713aSLionel Sambuc // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
68*f4a2713aSLionel Sambuc // CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_i16:!.*]]
69*f4a2713aSLionel Sambuc // PATH: define i32 @{{.*}}(
70*f4a2713aSLionel Sambuc // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
71*f4a2713aSLionel Sambuc // PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_A_f16:!.*]]
72*f4a2713aSLionel Sambuc   *s = 1;
73*f4a2713aSLionel Sambuc   A->f16 = 4;
74*f4a2713aSLionel Sambuc   return *s;
75*f4a2713aSLionel Sambuc }
76*f4a2713aSLionel Sambuc 
77*f4a2713aSLionel Sambuc uint32_t g3(StructA *A, StructB *B, uint64_t count) {
78*f4a2713aSLionel Sambuc // CHECK: define i32 @{{.*}}(
79*f4a2713aSLionel Sambuc // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
80*f4a2713aSLionel Sambuc // CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
81*f4a2713aSLionel Sambuc // PATH: define i32 @{{.*}}(
82*f4a2713aSLionel Sambuc // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
83*f4a2713aSLionel Sambuc // PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32:!.*]]
84*f4a2713aSLionel Sambuc   A->f32 = 1;
85*f4a2713aSLionel Sambuc   B->a.f32 = 4;
86*f4a2713aSLionel Sambuc   return A->f32;
87*f4a2713aSLionel Sambuc }
88*f4a2713aSLionel Sambuc 
89*f4a2713aSLionel Sambuc uint32_t g4(StructA *A, StructB *B, uint64_t count) {
90*f4a2713aSLionel Sambuc // CHECK: define i32 @{{.*}}(
91*f4a2713aSLionel Sambuc // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
92*f4a2713aSLionel Sambuc // CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_i16]]
93*f4a2713aSLionel Sambuc // PATH: define i32 @{{.*}}(
94*f4a2713aSLionel Sambuc // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
95*f4a2713aSLionel Sambuc // PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_B_a_f16:!.*]]
96*f4a2713aSLionel Sambuc   A->f32 = 1;
97*f4a2713aSLionel Sambuc   B->a.f16 = 4;
98*f4a2713aSLionel Sambuc   return A->f32;
99*f4a2713aSLionel Sambuc }
100*f4a2713aSLionel Sambuc 
101*f4a2713aSLionel Sambuc uint32_t g5(StructA *A, StructB *B, uint64_t count) {
102*f4a2713aSLionel Sambuc // CHECK: define i32 @{{.*}}(
103*f4a2713aSLionel Sambuc // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
104*f4a2713aSLionel Sambuc // CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
105*f4a2713aSLionel Sambuc // PATH: define i32 @{{.*}}(
106*f4a2713aSLionel Sambuc // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
107*f4a2713aSLionel Sambuc // PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_f32:!.*]]
108*f4a2713aSLionel Sambuc   A->f32 = 1;
109*f4a2713aSLionel Sambuc   B->f32 = 4;
110*f4a2713aSLionel Sambuc   return A->f32;
111*f4a2713aSLionel Sambuc }
112*f4a2713aSLionel Sambuc 
113*f4a2713aSLionel Sambuc uint32_t g6(StructA *A, StructB *B, uint64_t count) {
114*f4a2713aSLionel Sambuc // CHECK: define i32 @{{.*}}(
115*f4a2713aSLionel Sambuc // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
116*f4a2713aSLionel Sambuc // CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
117*f4a2713aSLionel Sambuc // PATH: define i32 @{{.*}}(
118*f4a2713aSLionel Sambuc // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
119*f4a2713aSLionel Sambuc // PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32_2:!.*]]
120*f4a2713aSLionel Sambuc   A->f32 = 1;
121*f4a2713aSLionel Sambuc   B->a.f32_2 = 4;
122*f4a2713aSLionel Sambuc   return A->f32;
123*f4a2713aSLionel Sambuc }
124*f4a2713aSLionel Sambuc 
125*f4a2713aSLionel Sambuc uint32_t g7(StructA *A, StructS *S, uint64_t count) {
126*f4a2713aSLionel Sambuc // CHECK: define i32 @{{.*}}(
127*f4a2713aSLionel Sambuc // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
128*f4a2713aSLionel Sambuc // CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
129*f4a2713aSLionel Sambuc // PATH: define i32 @{{.*}}(
130*f4a2713aSLionel Sambuc // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
131*f4a2713aSLionel Sambuc // PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32:!.*]]
132*f4a2713aSLionel Sambuc   A->f32 = 1;
133*f4a2713aSLionel Sambuc   S->f32 = 4;
134*f4a2713aSLionel Sambuc   return A->f32;
135*f4a2713aSLionel Sambuc }
136*f4a2713aSLionel Sambuc 
137*f4a2713aSLionel Sambuc uint32_t g8(StructA *A, StructS *S, uint64_t count) {
138*f4a2713aSLionel Sambuc // CHECK: define i32 @{{.*}}(
139*f4a2713aSLionel Sambuc // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
140*f4a2713aSLionel Sambuc // CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_i16]]
141*f4a2713aSLionel Sambuc // PATH: define i32 @{{.*}}(
142*f4a2713aSLionel Sambuc // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
143*f4a2713aSLionel Sambuc // PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_S_f16:!.*]]
144*f4a2713aSLionel Sambuc   A->f32 = 1;
145*f4a2713aSLionel Sambuc   S->f16 = 4;
146*f4a2713aSLionel Sambuc   return A->f32;
147*f4a2713aSLionel Sambuc }
148*f4a2713aSLionel Sambuc 
149*f4a2713aSLionel Sambuc uint32_t g9(StructS *S, StructS2 *S2, uint64_t count) {
150*f4a2713aSLionel Sambuc // CHECK: define i32 @{{.*}}(
151*f4a2713aSLionel Sambuc // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
152*f4a2713aSLionel Sambuc // CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
153*f4a2713aSLionel Sambuc // PATH: define i32 @{{.*}}(
154*f4a2713aSLionel Sambuc // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32]]
155*f4a2713aSLionel Sambuc // PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32:!.*]]
156*f4a2713aSLionel Sambuc   S->f32 = 1;
157*f4a2713aSLionel Sambuc   S2->f32 = 4;
158*f4a2713aSLionel Sambuc   return S->f32;
159*f4a2713aSLionel Sambuc }
160*f4a2713aSLionel Sambuc 
161*f4a2713aSLionel Sambuc uint32_t g10(StructS *S, StructS2 *S2, uint64_t count) {
162*f4a2713aSLionel Sambuc // CHECK: define i32 @{{.*}}(
163*f4a2713aSLionel Sambuc // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
164*f4a2713aSLionel Sambuc // CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
165*f4a2713aSLionel Sambuc // PATH: define i32 @{{.*}}(
166*f4a2713aSLionel Sambuc // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32]]
167*f4a2713aSLionel Sambuc // PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_S2_f32_2:!.*]]
168*f4a2713aSLionel Sambuc   S->f32 = 1;
169*f4a2713aSLionel Sambuc   S2->f32_2 = 4;
170*f4a2713aSLionel Sambuc   return S->f32;
171*f4a2713aSLionel Sambuc }
172*f4a2713aSLionel Sambuc 
173*f4a2713aSLionel Sambuc uint32_t g11(StructC *C, StructD *D, uint64_t count) {
174*f4a2713aSLionel Sambuc // CHECK: define i32 @{{.*}}(
175*f4a2713aSLionel Sambuc // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
176*f4a2713aSLionel Sambuc // CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
177*f4a2713aSLionel Sambuc // PATH: define i32 @{{.*}}(
178*f4a2713aSLionel Sambuc // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_C_b_a_f32:!.*]]
179*f4a2713aSLionel Sambuc // PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_D_b_a_f32:!.*]]
180*f4a2713aSLionel Sambuc   C->b.a.f32 = 1;
181*f4a2713aSLionel Sambuc   D->b.a.f32 = 4;
182*f4a2713aSLionel Sambuc   return C->b.a.f32;
183*f4a2713aSLionel Sambuc }
184*f4a2713aSLionel Sambuc 
185*f4a2713aSLionel Sambuc uint32_t g12(StructC *C, StructD *D, uint64_t count) {
186*f4a2713aSLionel Sambuc // CHECK: define i32 @{{.*}}(
187*f4a2713aSLionel Sambuc // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
188*f4a2713aSLionel Sambuc // CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
189*f4a2713aSLionel Sambuc // TODO: differentiate the two accesses.
190*f4a2713aSLionel Sambuc // PATH: define i32 @{{.*}}(
191*f4a2713aSLionel Sambuc // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32]]
192*f4a2713aSLionel Sambuc // PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32]]
193*f4a2713aSLionel Sambuc   StructB *b1 = &(C->b);
194*f4a2713aSLionel Sambuc   StructB *b2 = &(D->b);
195*f4a2713aSLionel Sambuc   // b1, b2 have different context.
196*f4a2713aSLionel Sambuc   b1->a.f32 = 1;
197*f4a2713aSLionel Sambuc   b2->a.f32 = 4;
198*f4a2713aSLionel Sambuc   return b1->a.f32;
199*f4a2713aSLionel Sambuc }
200*f4a2713aSLionel Sambuc 
201*f4a2713aSLionel Sambuc // CHECK: [[TYPE_char:!.*]] = metadata !{metadata !"omnipotent char", metadata [[TAG_cxx_tbaa:!.*]],
202*f4a2713aSLionel Sambuc // CHECK: [[TAG_cxx_tbaa]] = metadata !{metadata !"Simple C/C++ TBAA"}
203*f4a2713aSLionel Sambuc // CHECK: [[TAG_i32]] = metadata !{metadata [[TYPE_i32:!.*]], metadata [[TYPE_i32]], i64 0}
204*f4a2713aSLionel Sambuc // CHECK: [[TYPE_i32]] = metadata !{metadata !"int", metadata [[TYPE_char]],
205*f4a2713aSLionel Sambuc // CHECK: [[TAG_i16]] = metadata !{metadata [[TYPE_i16:!.*]], metadata [[TYPE_i16]], i64 0}
206*f4a2713aSLionel Sambuc // CHECK: [[TYPE_i16]] = metadata !{metadata !"short", metadata [[TYPE_char]],
207*f4a2713aSLionel Sambuc 
208*f4a2713aSLionel Sambuc // PATH: [[TYPE_CHAR:!.*]] = metadata !{metadata !"omnipotent char", metadata
209*f4a2713aSLionel Sambuc // PATH: [[TAG_i32]] = metadata !{metadata [[TYPE_INT:!.*]], metadata [[TYPE_INT]], i64 0}
210*f4a2713aSLionel Sambuc // PATH: [[TYPE_INT]] = metadata !{metadata !"int", metadata [[TYPE_CHAR]]
211*f4a2713aSLionel Sambuc // PATH: [[TAG_A_f32]] = metadata !{metadata [[TYPE_A:!.*]], metadata [[TYPE_INT]], i64 4}
212*f4a2713aSLionel Sambuc // PATH: [[TYPE_A]] = metadata !{metadata !"_ZTS7StructA", metadata [[TYPE_SHORT:!.*]], i64 0, metadata [[TYPE_INT]], i64 4, metadata [[TYPE_SHORT]], i64 8, metadata [[TYPE_INT]], i64 12}
213*f4a2713aSLionel Sambuc // PATH: [[TYPE_SHORT:!.*]] = metadata !{metadata !"short", metadata [[TYPE_CHAR]]
214*f4a2713aSLionel Sambuc // PATH: [[TAG_A_f16]] = metadata !{metadata [[TYPE_A]], metadata [[TYPE_SHORT]], i64 0}
215*f4a2713aSLionel Sambuc // PATH: [[TAG_B_a_f32]] = metadata !{metadata [[TYPE_B:!.*]], metadata [[TYPE_INT]], i64 8}
216*f4a2713aSLionel Sambuc // PATH: [[TYPE_B]] = metadata !{metadata !"_ZTS7StructB", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_A]], i64 4, metadata [[TYPE_INT]], i64 20}
217*f4a2713aSLionel Sambuc // PATH: [[TAG_B_a_f16]] = metadata !{metadata [[TYPE_B]], metadata [[TYPE_SHORT]], i64 4}
218*f4a2713aSLionel Sambuc // PATH: [[TAG_B_f32]] = metadata !{metadata [[TYPE_B]], metadata [[TYPE_INT]], i64 20}
219*f4a2713aSLionel Sambuc // PATH: [[TAG_B_a_f32_2]] = metadata !{metadata [[TYPE_B]], metadata [[TYPE_INT]], i64 16}
220*f4a2713aSLionel Sambuc // PATH: [[TAG_S_f32]] = metadata !{metadata [[TYPE_S:!.*]], metadata [[TYPE_INT]], i64 4}
221*f4a2713aSLionel Sambuc // PATH: [[TYPE_S]] = metadata !{metadata !"_ZTS7StructS", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_INT]], i64 4}
222*f4a2713aSLionel Sambuc // PATH: [[TAG_S_f16]] = metadata !{metadata [[TYPE_S]], metadata [[TYPE_SHORT]], i64 0}
223*f4a2713aSLionel Sambuc // PATH: [[TAG_S2_f32_2]] = metadata !{metadata [[TYPE_S2:!.*]], metadata [[TYPE_INT]], i64 12}
224*f4a2713aSLionel Sambuc // PATH: [[TYPE_S2]] = metadata !{metadata !"_ZTS8StructS2", metadata [[TYPE_SHORT]], i64 8, metadata [[TYPE_INT]], i64 12}
225*f4a2713aSLionel Sambuc // PATH: [[TAG_C_b_a_f32]] = metadata !{metadata [[TYPE_C:!.*]], metadata [[TYPE_INT]], i64 12}
226*f4a2713aSLionel Sambuc // PATH: [[TYPE_C]] = metadata !{metadata !"_ZTS7StructC", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_B]], i64 4, metadata [[TYPE_INT]], i64 28}
227*f4a2713aSLionel Sambuc // PATH: [[TAG_D_b_a_f32]] = metadata !{metadata [[TYPE_D:!.*]], metadata [[TYPE_INT]], i64 12}
228*f4a2713aSLionel Sambuc // PATH: [[TYPE_D]] = metadata !{metadata !"_ZTS7StructD", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_B]], i64 4, metadata [[TYPE_INT]], i64 28, metadata [[TYPE_CHAR]], i64 32}
229