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