xref: /llvm-project/clang/test/CodeGen/tbaa-class.cpp (revision 39db5e1ed87363a9ffea81e53520b542201b3262)
1 // RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -no-struct-path-tbaa -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s
2 // RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefixes=PATH,OLD-PATH
3 // RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-passes %s -emit-llvm -new-struct-path-tbaa -o - | FileCheck %s -check-prefixes=PATH,NEW-PATH
4 // Test TBAA metadata generated by front-end.
5 
6 typedef unsigned char uint8_t;
7 typedef unsigned short uint16_t;
8 typedef unsigned int uint32_t;
9 typedef unsigned long long uint64_t;
10 class StructA
11 {
12 public:
13    uint16_t f16;
14    uint32_t f32;
15    uint16_t f16_2;
16    uint32_t f32_2;
17 };
18 class StructB
19 {
20 public:
21    uint16_t f16;
22    StructA a;
23    uint32_t f32;
24 };
25 class StructC
26 {
27 public:
28    uint16_t f16;
29    StructB b;
30    uint32_t f32;
31 };
32 class StructD
33 {
34 public:
35    uint16_t f16;
36    StructB b;
37    uint32_t f32;
38    uint8_t f8;
39 };
40 
41 class StructS
42 {
43 public:
44    uint16_t f16;
45    uint32_t f32;
46 };
47 class StructS2 : public StructS
48 {
49 public:
50    uint16_t f16_2;
51    uint32_t f32_2;
52 };
53 
54 class StructT {
55 public:
56   uint32_t f32_2;
57   void foo();
58 };
59 class StructM1 : public StructS, public StructT {
60 public:
61   uint16_t f16_2;
62 };
63 class StructDyn {
64 public:
65   uint32_t f32_2;
66   virtual void foo();
67 };
68 class StructM2 : public StructS, public StructDyn {
69 public:
70   uint16_t f16_2;
71 };
72 
g(uint32_t * s,StructA * A,uint64_t count)73 uint32_t g(uint32_t *s, StructA *A, uint64_t count) {
74 // CHECK-LABEL: define{{.*}} i32 @_Z1g
75 // CHECK: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i32:!.*]]
76 // CHECK: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
77 // PATH-LABEL: define{{.*}} i32 @_Z1g
78 // PATH: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i32:!.*]]
79 // PATH: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_A_f32:!.*]]
80   *s = 1;
81   A->f32 = 4;
82   return *s;
83 }
84 
g2(uint32_t * s,StructA * A,uint64_t count)85 uint32_t g2(uint32_t *s, StructA *A, uint64_t count) {
86 // CHECK-LABEL: define{{.*}} i32 @_Z2g2
87 // CHECK: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
88 // CHECK: store i16 4, ptr %{{.*}}, align 4, !tbaa [[TAG_i16:!.*]]
89 // PATH-LABEL: define{{.*}} i32 @_Z2g2
90 // PATH: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
91 // PATH: store i16 4, ptr %{{.*}}, align 4, !tbaa [[TAG_A_f16:!.*]]
92   *s = 1;
93   A->f16 = 4;
94   return *s;
95 }
96 
g3(StructA * A,StructB * B,uint64_t count)97 uint32_t g3(StructA *A, StructB *B, uint64_t count) {
98 // CHECK-LABEL: define{{.*}} i32 @_Z2g3
99 // CHECK: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
100 // CHECK: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
101 // PATH-LABEL: define{{.*}} i32 @_Z2g3
102 // PATH: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
103 // PATH: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_B_a_f32:!.*]]
104   A->f32 = 1;
105   B->a.f32 = 4;
106   return A->f32;
107 }
108 
g4(StructA * A,StructB * B,uint64_t count)109 uint32_t g4(StructA *A, StructB *B, uint64_t count) {
110 // CHECK-LABEL: define{{.*}} i32 @_Z2g4
111 // CHECK: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
112 // CHECK: store i16 4, ptr %{{.*}}, align 4, !tbaa [[TAG_i16]]
113 // PATH-LABEL: define{{.*}} i32 @_Z2g4
114 // PATH: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
115 // PATH: store i16 4, ptr %{{.*}}, align 4, !tbaa [[TAG_B_a_f16:!.*]]
116   A->f32 = 1;
117   B->a.f16 = 4;
118   return A->f32;
119 }
120 
g5(StructA * A,StructB * B,uint64_t count)121 uint32_t g5(StructA *A, StructB *B, uint64_t count) {
122 // CHECK-LABEL: define{{.*}} i32 @_Z2g5
123 // CHECK: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
124 // CHECK: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
125 // PATH-LABEL: define{{.*}} i32 @_Z2g5
126 // PATH: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
127 // PATH: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_B_f32:!.*]]
128   A->f32 = 1;
129   B->f32 = 4;
130   return A->f32;
131 }
132 
g6(StructA * A,StructB * B,uint64_t count)133 uint32_t g6(StructA *A, StructB *B, uint64_t count) {
134 // CHECK-LABEL: define{{.*}} i32 @_Z2g6
135 // CHECK: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
136 // CHECK: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
137 // PATH-LABEL: define{{.*}} i32 @_Z2g6
138 // PATH: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
139 // PATH: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_B_a_f32_2:!.*]]
140   A->f32 = 1;
141   B->a.f32_2 = 4;
142   return A->f32;
143 }
144 
g7(StructA * A,StructS * S,uint64_t count)145 uint32_t g7(StructA *A, StructS *S, uint64_t count) {
146 // CHECK-LABEL: define{{.*}} i32 @_Z2g7
147 // CHECK: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
148 // CHECK: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
149 // PATH-LABEL: define{{.*}} i32 @_Z2g7
150 // PATH: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
151 // PATH: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_S_f32:!.*]]
152   A->f32 = 1;
153   S->f32 = 4;
154   return A->f32;
155 }
156 
g8(StructA * A,StructS * S,uint64_t count)157 uint32_t g8(StructA *A, StructS *S, uint64_t count) {
158 // CHECK-LABEL: define{{.*}} i32 @_Z2g8
159 // CHECK: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
160 // CHECK: store i16 4, ptr %{{.*}}, align 4, !tbaa [[TAG_i16]]
161 // PATH-LABEL: define{{.*}} i32 @_Z2g8
162 // PATH: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
163 // PATH: store i16 4, ptr %{{.*}}, align 4, !tbaa [[TAG_S_f16:!.*]]
164   A->f32 = 1;
165   S->f16 = 4;
166   return A->f32;
167 }
168 
g9(StructS * S,StructS2 * S2,uint64_t count)169 uint32_t g9(StructS *S, StructS2 *S2, uint64_t count) {
170 // CHECK-LABEL: define{{.*}} i32 @_Z2g9
171 // CHECK: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
172 // CHECK: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
173 // PATH-LABEL: define{{.*}} i32 @_Z2g9
174 // PATH: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_S_f32]]
175 // PATH: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_S_f32:!.*]]
176   S->f32 = 1;
177   S2->f32 = 4;
178   return S->f32;
179 }
180 
g10(StructS * S,StructS2 * S2,uint64_t count)181 uint32_t g10(StructS *S, StructS2 *S2, uint64_t count) {
182 // CHECK-LABEL: define{{.*}} i32 @_Z3g10
183 // CHECK: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
184 // CHECK: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
185 // PATH-LABEL: define{{.*}} i32 @_Z3g10
186 // PATH: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_S_f32]]
187 // PATH: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_S2_f32_2:!.*]]
188   S->f32 = 1;
189   S2->f32_2 = 4;
190   return S->f32;
191 }
192 
g11(StructC * C,StructD * D,uint64_t count)193 uint32_t g11(StructC *C, StructD *D, uint64_t count) {
194 // CHECK-LABEL: define{{.*}} i32 @_Z3g11
195 // CHECK: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
196 // CHECK: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
197 // PATH-LABEL: define{{.*}} i32 @_Z3g11
198 // PATH: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_C_b_a_f32:!.*]]
199 // PATH: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_D_b_a_f32:!.*]]
200   C->b.a.f32 = 1;
201   D->b.a.f32 = 4;
202   return C->b.a.f32;
203 }
204 
g12(StructC * C,StructD * D,uint64_t count)205 uint32_t g12(StructC *C, StructD *D, uint64_t count) {
206 // CHECK-LABEL: define{{.*}} i32 @_Z3g12
207 // CHECK: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
208 // CHECK: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
209 // TODO: differentiate the two accesses.
210 // PATH-LABEL: define{{.*}} i32 @_Z3g12
211 // PATH: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_B_a_f32]]
212 // PATH: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_B_a_f32]]
213   StructB *b1 = &(C->b);
214   StructB *b2 = &(D->b);
215   // b1, b2 have different context.
216   b1->a.f32 = 1;
217   b2->a.f32 = 4;
218   return b1->a.f32;
219 }
220 
g13(StructM1 * M,StructS * S)221 uint32_t g13(StructM1 *M, StructS *S) {
222   // CHECK-LABEL: define{{.*}} i32 @_Z3g13
223   // CHECK: store i16 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i16]]
224   // CHECK: store i16 4, ptr %{{.*}}, align 4, !tbaa [[TAG_i16]]
225   // PATH-LABEL: define{{.*}} i32 @_Z3g13
226   // PATH: store i16 1, ptr %{{.*}}, align 4, !tbaa [[TAG_S_f16]]
227   // PATH: store i16 4, ptr %{{.*}}, align 4, !tbaa [[TAG_M1_f16_2:!.*]]
228   S->f16 = 1;
229   M->f16_2 = 4;
230   return S->f16;
231 }
232 
g14(StructM2 * M,StructS * S)233 uint32_t g14(StructM2 *M, StructS *S) {
234   // CHECK-LABEL: define{{.*}} i32 @_Z3g14
235   // CHECK: store i16 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i16]]
236   // CHECK: store i16 4, ptr %{{.*}}, align 4, !tbaa [[TAG_i16]]
237   // PATH-LABEL: define{{.*}} i32 @_Z3g14
238   // PATH: store i16 1, ptr %{{.*}}, align 4, !tbaa [[TAG_S_f16]]
239   // PATH: store i16 4, ptr %{{.*}}, align 4, !tbaa [[TAG_M2_f16_2:!.*]]
240   S->f16 = 1;
241   M->f16_2 = 4;
242   return S->f16;
243 }
244 
245 // CHECK: [[TYPE_char:!.*]] = !{!"omnipotent char", [[TAG_cxx_tbaa:!.*]],
246 // CHECK: [[TAG_cxx_tbaa]] = !{!"Simple C++ TBAA"}
247 // CHECK: [[TAG_i32]] = !{[[TYPE_i32:!.*]], [[TYPE_i32]], i64 0}
248 // CHECK: [[TYPE_i32]] = !{!"int", [[TYPE_char]],
249 // CHECK: [[TAG_i16]] = !{[[TYPE_i16:!.*]], [[TYPE_i16]], i64 0}
250 // CHECK: [[TYPE_i16]] = !{!"short", [[TYPE_char]],
251 
252 // OLD-PATH: [[TYPE_CHAR:!.*]] = !{!"omnipotent char", !
253 // OLD-PATH: [[TAG_i32]] = !{[[TYPE_INT:!.*]], [[TYPE_INT]], i64 0}
254 // OLD-PATH: [[TYPE_INT]] = !{!"int", [[TYPE_CHAR]]
255 // OLD-PATH: [[TAG_A_f32]] = !{[[TYPE_A:!.*]], [[TYPE_INT]], i64 4}
256 // OLD-PATH: [[TYPE_A]] = !{!"_ZTS7StructA", [[TYPE_SHORT:!.*]], i64 0, [[TYPE_INT]], i64 4, [[TYPE_SHORT]], i64 8, [[TYPE_INT]], i64 12}
257 // OLD-PATH: [[TYPE_SHORT:!.*]] = !{!"short", [[TYPE_CHAR]]
258 // OLD-PATH: [[TAG_A_f16]] = !{[[TYPE_A]], [[TYPE_SHORT]], i64 0}
259 // OLD-PATH: [[TAG_B_a_f32]] = !{[[TYPE_B:!.*]], [[TYPE_INT]], i64 8}
260 // OLD-PATH: [[TYPE_B]] = !{!"_ZTS7StructB", [[TYPE_SHORT]], i64 0, [[TYPE_A]], i64 4, [[TYPE_INT]], i64 20}
261 // OLD-PATH: [[TAG_B_a_f16]] = !{[[TYPE_B]], [[TYPE_SHORT]], i64 4}
262 // OLD-PATH: [[TAG_B_f32]] = !{[[TYPE_B]], [[TYPE_INT]], i64 20}
263 // OLD-PATH: [[TAG_B_a_f32_2]] = !{[[TYPE_B]], [[TYPE_INT]], i64 16}
264 // OLD-PATH: [[TAG_S_f32]] = !{[[TYPE_S:!.*]], [[TYPE_INT]], i64 4}
265 // OLD-PATH: [[TYPE_S]] = !{!"_ZTS7StructS", [[TYPE_SHORT]], i64 0, [[TYPE_INT]], i64 4}
266 // OLD-PATH: [[TAG_S_f16]] = !{[[TYPE_S]], [[TYPE_SHORT]], i64 0}
267 // OLD-PATH: [[TAG_S2_f32_2]] = !{[[TYPE_S2:!.*]], [[TYPE_INT]], i64 12}
268 // OLD-PATH: [[TYPE_S2]] = !{!"_ZTS8StructS2", [[TYPE_S]], i64 0, [[TYPE_SHORT]], i64 8, [[TYPE_INT]], i64 12}
269 // OLD-PATH: [[TAG_C_b_a_f32]] = !{[[TYPE_C:!.*]], [[TYPE_INT]], i64 12}
270 // OLD-PATH: [[TYPE_C]] = !{!"_ZTS7StructC", [[TYPE_SHORT]], i64 0, [[TYPE_B]], i64 4, [[TYPE_INT]], i64 28}
271 // OLD-PATH: [[TAG_D_b_a_f32]] = !{[[TYPE_D:!.*]], [[TYPE_INT]], i64 12}
272 // OLD-PATH: [[TYPE_D]] = !{!"_ZTS7StructD", [[TYPE_SHORT]], i64 0, [[TYPE_B]], i64 4, [[TYPE_INT]], i64 28, [[TYPE_CHAR]], i64 32}
273 // OLD-PATH: [[TAG_M1_f16_2]] = !{[[TYPE_M1:!.*]], [[TYPE_SHORT]], i64 12}
274 // OLD-PATH: [[TYPE_M1]] = !{!"_ZTS8StructM1", [[TYPE_S]], i64 0, [[TYPE_T:!.*]], i64 8, [[TYPE_SHORT]], i64 12}
275 // OLD_PATH: [[TYPE_T]] = !{!"_ZTS7StructT", [[TYPE_INT]], i64 0}
276 // OLD-PATH: [[TAG_M2_f16_2]] = !{[[TYPE_M2:!.*]], [[TYPE_SHORT]], i64 20}
277 // OLD-PATH: [[TYPE_M2]] = !{!"_ZTS8StructM2", [[TYPE_DYN:!.*]], i64 0, [[TYPE_S]], i64 12, [[TYPE_SHORT]], i64 20}
278 // OLD_PATH: [[TYPE_DYN]] = !{!"_ZTS9StructDyn", [[TYPE_INT]], i64 8}
279 
280 // NEW-PATH: [[TYPE_CHAR:!.*]] = !{!{{.*}}, i64 1, !"omnipotent char"}
281 // NEW-PATH: [[TAG_i32]] = !{[[TYPE_INT:!.*]], [[TYPE_INT]], i64 0, i64 4}
282 // NEW-PATH: [[TYPE_INT]] = !{[[TYPE_CHAR]], i64 4, !"int"}
283 // NEW-PATH: [[TAG_A_f32]] = !{[[TYPE_A:!.*]], [[TYPE_INT]], i64 4, i64 4}
284 // NEW-PATH: [[TYPE_A]] = !{[[TYPE_CHAR]], i64 16, !"_ZTS7StructA", [[TYPE_SHORT:!.*]], i64 0, i64 2, [[TYPE_INT]], i64 4, i64 4, [[TYPE_SHORT]], i64 8, i64 2, [[TYPE_INT]], i64 12, i64 4}
285 // NEW-PATH: [[TYPE_SHORT:!.*]] = !{[[TYPE_CHAR]], i64 2, !"short"}
286 // NEW-PATH: [[TAG_A_f16]] = !{[[TYPE_A]], [[TYPE_SHORT]], i64 0, i64 2}
287 // NEW-PATH: [[TAG_B_a_f32]] = !{[[TYPE_B:!.*]], [[TYPE_INT]], i64 8, i64 4}
288 // NEW-PATH: [[TYPE_B]] = !{[[TYPE_CHAR]], i64 24, !"_ZTS7StructB", [[TYPE_SHORT]], i64 0, i64 2, [[TYPE_A]], i64 4, i64 16, [[TYPE_INT]], i64 20, i64 4}
289 // NEW-PATH: [[TAG_B_a_f16]] = !{[[TYPE_B]], [[TYPE_SHORT]], i64 4, i64 2}
290 // NEW-PATH: [[TAG_B_f32]] = !{[[TYPE_B]], [[TYPE_INT]], i64 20, i64 4}
291 // NEW-PATH: [[TAG_B_a_f32_2]] = !{[[TYPE_B]], [[TYPE_INT]], i64 16, i64 4}
292 // NEW-PATH: [[TAG_S_f32]] = !{[[TYPE_S:!.*]], [[TYPE_INT]], i64 4, i64 4}
293 // NEW-PATH: [[TYPE_S]] = !{[[TYPE_CHAR]], i64 8, !"_ZTS7StructS", [[TYPE_SHORT]], i64 0, i64 2, [[TYPE_INT]], i64 4, i64 4}
294 // NEW-PATH: [[TAG_S_f16]] = !{[[TYPE_S]], [[TYPE_SHORT]], i64 0, i64 2}
295 // NEW-PATH: [[TAG_S2_f32_2]] = !{[[TYPE_S2:!.*]], [[TYPE_INT]], i64 12, i64 4}
296 // NEW-PATH: [[TYPE_S2]] = !{[[TYPE_CHAR]], i64 16, !"_ZTS8StructS2", [[TYPE_S]], i64 0, i64 8, [[TYPE_SHORT]], i64 8, i64 2, [[TYPE_INT]], i64 12, i64 4}
297 // NEW-PATH: [[TAG_C_b_a_f32]] = !{[[TYPE_C:!.*]], [[TYPE_INT]], i64 12, i64 4}
298 // NEW-PATH: [[TYPE_C]] = !{[[TYPE_CHAR]], i64 32, !"_ZTS7StructC", [[TYPE_SHORT]], i64 0, i64 2, [[TYPE_B]], i64 4, i64 24, [[TYPE_INT]], i64 28, i64 4}
299 // NEW-PATH: [[TAG_D_b_a_f32]] = !{[[TYPE_D:!.*]], [[TYPE_INT]], i64 12, i64 4}
300 // NEW-PATH: [[TYPE_D]] = !{[[TYPE_CHAR]], i64 36, !"_ZTS7StructD", [[TYPE_SHORT]], i64 0, i64 2, [[TYPE_B]], i64 4, i64 24, [[TYPE_INT]], i64 28, i64 4, [[TYPE_CHAR]], i64 32, i64 1}
301 // NEW-PATH: [[TAG_M1_f16_2]] = !{[[TYPE_M1:!.*]], [[TYPE_SHORT]], i64 12, i64 2}
302 // NEW-PATH: [[TYPE_M1]] = !{[[TYPE_CHAR]], i64 16, !"_ZTS8StructM1", [[TYPE_S]], i64 0, i64 8, [[TYPE_T:!.*]], i64 8, i64 4, [[TYPE_SHORT]], i64 12, i64 2}
303 // NEW_PATH: [[TYPE_T]] = !{[[TYPE_CHAR]], i64 4, !"_ZTS7StructT", [[TYPE_INT]], i64 0, i64 4}
304 // NEW-PATH: [[TAG_M2_f16_2]] = !{[[TYPE_M2:!.*]], [[TYPE_SHORT]], i64 20, i64 2}
305 // NEW-PATH: [[TYPE_M2]] = !{[[TYPE_CHAR]], i64 24, !"_ZTS8StructM2", [[TYPE_DYN:!.*]], i64 0, i64 12, [[TYPE_S]], i64 12, i64 8, [[TYPE_SHORT]], i64 20, i64 2}
306 // NEW_PATH: [[TYPE_DYN]] = !{[[TYPE_CHAR]], i64 12, !"_ZTS9StructDyn", [[TYPE_INT]], i64 8, i64 4}
307