Clang Project

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