Mercurial > hg > CbC > CbC_llvm
comparison clang/test/CodeGenObjC/strong-in-c-struct.m @ 150:1d019706d866
LLVM10
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 15:10:13 +0900 |
parents | |
children | 0572611fdcc8 |
comparison
equal
deleted
inserted
replaced
147:c2174574ed3a | 150:1d019706d866 |
---|---|
1 // RUN: %clang_cc1 -triple arm64-apple-ios11 -fobjc-arc -fblocks -fobjc-runtime=ios-11.0 -emit-llvm -o - -DUSESTRUCT %s | FileCheck %s | |
2 | |
3 // RUN: %clang_cc1 -triple arm64-apple-ios11 -fobjc-arc -fblocks -fobjc-runtime=ios-11.0 -emit-pch -o %t %s | |
4 // RUN: %clang_cc1 -triple arm64-apple-ios11 -fobjc-arc -fblocks -fobjc-runtime=ios-11.0 -include-pch %t -emit-llvm -o - -DUSESTRUCT %s | FileCheck %s | |
5 | |
6 #ifndef HEADER | |
7 #define HEADER | |
8 | |
9 typedef void (^BlockTy)(void); | |
10 | |
11 typedef struct { | |
12 int a[4]; | |
13 } Trivial; | |
14 | |
15 typedef struct { | |
16 Trivial f0; | |
17 id f1; | |
18 } Strong; | |
19 | |
20 typedef struct { | |
21 int i; | |
22 id f1; | |
23 } StrongSmall; | |
24 | |
25 typedef struct { | |
26 Strong f0; | |
27 id f1; | |
28 double d; | |
29 } StrongOuter; | |
30 | |
31 typedef struct { | |
32 id f0; | |
33 Strong f1; | |
34 } StrongOuter2; | |
35 | |
36 typedef struct { | |
37 int f0; | |
38 volatile id f1; | |
39 } StrongVolatile; | |
40 | |
41 typedef struct { | |
42 BlockTy f0; | |
43 } StrongBlock; | |
44 | |
45 typedef struct { | |
46 int i; | |
47 id f0[2][2]; | |
48 } IDArray; | |
49 | |
50 typedef struct { | |
51 double d; | |
52 Strong f0[2][2]; | |
53 } StructArray; | |
54 | |
55 typedef struct { | |
56 id f0; | |
57 int i : 9; | |
58 } Bitfield0; | |
59 | |
60 typedef struct { | |
61 char c; | |
62 int i0 : 2; | |
63 int i1 : 4; | |
64 id f0; | |
65 int i2 : 31; | |
66 int i3 : 1; | |
67 id f1; | |
68 int : 0; | |
69 int a[3]; | |
70 id f2; | |
71 double d; | |
72 int i4 : 1; | |
73 volatile int i5 : 2; | |
74 volatile char i6; | |
75 } Bitfield1; | |
76 | |
77 typedef struct { | |
78 id x; | |
79 volatile int a[16]; | |
80 } VolatileArray ; | |
81 | |
82 #endif | |
83 | |
84 #ifdef USESTRUCT | |
85 | |
86 StrongSmall getStrongSmall(void); | |
87 StrongOuter getStrongOuter(void); | |
88 StrongOuter2 getStrongOuter2(void); | |
89 void calleeStrongSmall(StrongSmall); | |
90 void func(Strong *); | |
91 | |
92 // CHECK: %[[STRUCT_STRONGOUTER:.*]] = type { %[[STRUCT_STRONG:.*]], i8*, double } | |
93 // CHECK: %[[STRUCT_STRONG]] = type { %[[STRUCT_TRIVIAL:.*]], i8* } | |
94 // CHECK: %[[STRUCT_TRIVIAL]] = type { [4 x i32] } | |
95 // CHECK: %[[STRUCT_BLOCK_BYREF_T:.*]] = type { i8*, %[[STRUCT_BLOCK_BYREF_T]]*, i32, i32, i8*, i8*, i8*, %[[STRUCT_STRONGOUTER]] } | |
96 // CHECK: %[[STRUCT_STRONGSMALL:.*]] = type { i32, i8* } | |
97 // CHECK: %[[STRUCT_STRONGBLOCK:.*]] = type { void ()* } | |
98 // CHECK: %[[STRUCT_BITFIELD1:.*]] = type { i8, i8, i8*, i32, i8*, [3 x i32], i8*, double, i8, i8 } | |
99 | |
100 // CHECK: define void @test_constructor_destructor_StrongOuter() | |
101 // CHECK: %[[T:.*]] = alloca %[[STRUCT_STRONGOUTER]], align 8 | |
102 // CHECK: %[[V0:.*]] = bitcast %[[STRUCT_STRONGOUTER]]* %[[T]] to i8** | |
103 // CHECK: call void @__default_constructor_8_S_s16_s24(i8** %[[V0]]) | |
104 // CHECK: %[[V1:.*]] = bitcast %[[STRUCT_STRONGOUTER]]* %[[T]] to i8** | |
105 // CHECK: call void @__destructor_8_S_s16_s24(i8** %[[V1]]) | |
106 // CHECK: ret void | |
107 | |
108 // CHECK: define linkonce_odr hidden void @__default_constructor_8_S_s16_s24(i8** %[[DST:.*]]) | |
109 // CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8 | |
110 // CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 | |
111 // CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 | |
112 // CHECK: call void @__default_constructor_8_s16(i8** %[[V0]]) | |
113 // CHECK: %[[V1:.*]] = bitcast i8** %[[V0]] to i8* | |
114 // CHECK: %[[V2:.*]] = getelementptr inbounds i8, i8* %[[V1]], i64 24 | |
115 // CHECK: %[[V3:.*]] = bitcast i8* %[[V2]] to i8** | |
116 // CHECK: %[[V4:.*]] = bitcast i8** %[[V3]] to i8* | |
117 // CHECK: call void @llvm.memset.p0i8.i64(i8* align 8 %[[V4]], i8 0, i64 8, i1 false) | |
118 // CHECK: ret void | |
119 | |
120 // CHECK: define linkonce_odr hidden void @__default_constructor_8_s16(i8** %[[DST:.*]]) | |
121 // CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8 | |
122 // CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 | |
123 // CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 | |
124 // CHECK: %[[V1:.*]] = bitcast i8** %[[V0]] to i8* | |
125 // CHECK: %[[V2:.*]] = getelementptr inbounds i8, i8* %[[V1]], i64 16 | |
126 // CHECK: %[[V3:.*]] = bitcast i8* %[[V2]] to i8** | |
127 // CHECK: %[[V4:.*]] = bitcast i8** %[[V3]] to i8* | |
128 // CHECK: call void @llvm.memset.p0i8.i64(i8* align 8 %[[V4]], i8 0, i64 8, i1 false) | |
129 // CHECK: ret void | |
130 | |
131 // CHECK: define linkonce_odr hidden void @__destructor_8_S_s16_s24(i8** %[[DST:.*]]) | |
132 // CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8 | |
133 // CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 | |
134 // CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 | |
135 // CHECK: call void @__destructor_8_s16(i8** %[[V0]]) | |
136 // CHECK: %[[V1:.*]] = bitcast i8** %[[V0]] to i8* | |
137 // CHECK: %[[V2:.*]] = getelementptr inbounds i8, i8* %[[V1]], i64 24 | |
138 // CHECK: %[[V3:.*]] = bitcast i8* %[[V2]] to i8** | |
139 // CHECK: call void @llvm.objc.storeStrong(i8** %[[V3]], i8* null) | |
140 // CHECK: ret void | |
141 | |
142 // CHECK: define linkonce_odr hidden void @__destructor_8_s16(i8** %[[DST:.*]]) | |
143 // CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8 | |
144 // CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 | |
145 // CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 | |
146 // CHECK: %[[V1:.*]] = bitcast i8** %[[V0]] to i8* | |
147 // CHECK: %[[V2:.*]] = getelementptr inbounds i8, i8* %[[V1]], i64 16 | |
148 // CHECK: %[[V3:.*]] = bitcast i8* %[[V2]] to i8** | |
149 // CHECK: call void @llvm.objc.storeStrong(i8** %[[V3]], i8* null) | |
150 // CHECK: ret void | |
151 | |
152 void test_constructor_destructor_StrongOuter(void) { | |
153 StrongOuter t; | |
154 } | |
155 | |
156 // CHECK: define void @test_copy_constructor_StrongOuter(%[[STRUCT_STRONGOUTER]]* %[[S:.*]]) | |
157 // CHECK: %[[S_ADDR:.*]] = alloca %[[STRUCT_STRONGOUTER]]*, align 8 | |
158 // CHECK: %[[T:.*]] = alloca %[[STRUCT_STRONGOUTER]], align 8 | |
159 // CHECK: store %[[STRUCT_STRONGOUTER]]* %[[S]], %[[STRUCT_STRONGOUTER]]** %[[S_ADDR]], align 8 | |
160 // CHECK: %[[V0:.*]] = load %[[STRUCT_STRONGOUTER]]*, %[[STRUCT_STRONGOUTER]]** %[[S_ADDR]], align 8 | |
161 // CHECK: %[[V1:.*]] = bitcast %[[STRUCT_STRONGOUTER]]* %[[T]] to i8** | |
162 // CHECK: %[[V2:.*]] = bitcast %[[STRUCT_STRONGOUTER]]* %[[V0]] to i8** | |
163 // CHECK: call void @__copy_constructor_8_8_S_t0w16_s16_s24_t32w8(i8** %[[V1]], i8** %[[V2]]) | |
164 // CHECK: %[[V3:.*]] = bitcast %[[STRUCT_STRONGOUTER]]* %[[T]] to i8** | |
165 // CHECK: call void @__destructor_8_S_s16_s24(i8** %[[V3]]) | |
166 // CHECK: ret void | |
167 | |
168 // CHECK: define linkonce_odr hidden void @__copy_constructor_8_8_S_t0w16_s16_s24_t32w8(i8** %[[DST:.*]], i8** %[[SRC:.*]]) | |
169 // CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8 | |
170 // CHECK: %[[SRC_ADDR:.*]] = alloca i8**, align 8 | |
171 // CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 | |
172 // CHECK: store i8** %[[SRC]], i8*** %[[SRC_ADDR]], align 8 | |
173 // CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 | |
174 // CHECK: %[[V1:.*]] = load i8**, i8*** %[[SRC_ADDR]], align 8 | |
175 // CHECK: call void @__copy_constructor_8_8_t0w16_s16(i8** %[[V0]], i8** %[[V1]]) | |
176 // CHECK: %[[V2:.*]] = bitcast i8** %[[V0]] to i8* | |
177 // CHECK: %[[V3:.*]] = getelementptr inbounds i8, i8* %[[V2]], i64 24 | |
178 // CHECK: %[[V4:.*]] = bitcast i8* %[[V3]] to i8** | |
179 // CHECK: %[[V5:.*]] = bitcast i8** %[[V1]] to i8* | |
180 // CHECK: %[[V6:.*]] = getelementptr inbounds i8, i8* %[[V5]], i64 24 | |
181 // CHECK: %[[V7:.*]] = bitcast i8* %[[V6]] to i8** | |
182 // CHECK: %[[V8:.*]] = load i8*, i8** %[[V7]], align 8 | |
183 // CHECK: %[[V9:.*]] = call i8* @llvm.objc.retain(i8* %[[V8]]) | |
184 // CHECK: store i8* %[[V9]], i8** %[[V4]], align 8 | |
185 // CHECK: %[[V10:.*]] = bitcast i8** %[[V0]] to i8* | |
186 // CHECK: %[[V11:.*]] = getelementptr inbounds i8, i8* %[[V10]], i64 32 | |
187 // CHECK: %[[V12:.*]] = bitcast i8* %[[V11]] to i8** | |
188 // CHECK: %[[V13:.*]] = bitcast i8** %[[V1]] to i8* | |
189 // CHECK: %[[V14:.*]] = getelementptr inbounds i8, i8* %[[V13]], i64 32 | |
190 // CHECK: %[[V15:.*]] = bitcast i8* %[[V14]] to i8** | |
191 // CHECK: %[[V16:.*]] = bitcast i8** %[[V12]] to i64* | |
192 // CHECK: %[[V17:.*]] = bitcast i8** %[[V15]] to i64* | |
193 // CHECK: %[[V18:.*]] = load i64, i64* %[[V17]], align 8 | |
194 // CHECK: store i64 %[[V18]], i64* %[[V16]], align 8 | |
195 // CHECK: ret void | |
196 | |
197 // CHECK: define linkonce_odr hidden void @__copy_constructor_8_8_t0w16_s16(i8** %[[DST:.*]], i8** %[[SRC:.*]]) | |
198 // CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8 | |
199 // CHECK: %[[SRC_ADDR:.*]] = alloca i8**, align 8 | |
200 // CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 | |
201 // CHECK: store i8** %[[SRC]], i8*** %[[SRC_ADDR]], align 8 | |
202 // CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 | |
203 // CHECK: %[[V1:.*]] = load i8**, i8*** %[[SRC_ADDR]], align 8 | |
204 // CHECK: %[[V2:.*]] = bitcast i8** %[[V0]] to i8* | |
205 // CHECK: %[[V3:.*]] = bitcast i8** %[[V1]] to i8* | |
206 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %[[V2]], i8* align 8 %[[V3]], i64 16, i1 false) | |
207 // CHECK: %[[V4:.*]] = bitcast i8** %[[V0]] to i8* | |
208 // CHECK: %[[V5:.*]] = getelementptr inbounds i8, i8* %[[V4]], i64 16 | |
209 // CHECK: %[[V6:.*]] = bitcast i8* %[[V5]] to i8** | |
210 // CHECK: %[[V7:.*]] = bitcast i8** %[[V1]] to i8* | |
211 // CHECK: %[[V8:.*]] = getelementptr inbounds i8, i8* %[[V7]], i64 16 | |
212 // CHECK: %[[V9:.*]] = bitcast i8* %[[V8]] to i8** | |
213 // CHECK: %[[V10:.*]] = load i8*, i8** %[[V9]], align 8 | |
214 // CHECK: %[[V11:.*]] = call i8* @llvm.objc.retain(i8* %[[V10]]) | |
215 // CHECK: store i8* %[[V11]], i8** %[[V6]], align 8 | |
216 // CHECK: ret void | |
217 | |
218 void test_copy_constructor_StrongOuter(StrongOuter *s) { | |
219 StrongOuter t = *s; | |
220 } | |
221 | |
222 /// CHECK: define linkonce_odr hidden void @__copy_assignment_8_8_S_t0w16_s16_s24_t32w8(i8** %[[DST:.*]], i8** %[[SRC:.*]]) | |
223 // CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8 | |
224 // CHECK: %[[SRC_ADDR:.*]] = alloca i8**, align 8 | |
225 // CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 | |
226 // CHECK: store i8** %[[SRC]], i8*** %[[SRC_ADDR]], align 8 | |
227 // CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 | |
228 // CHECK: %[[V1:.*]] = load i8**, i8*** %[[SRC_ADDR]], align 8 | |
229 // CHECK: %[[V2:.*]] = bitcast i8** %[[V0]] to i8* | |
230 // CHECK: %[[V3:.*]] = getelementptr inbounds i8, i8* %[[V2]], i64 24 | |
231 // CHECK: %[[V4:.*]] = bitcast i8* %[[V3]] to i8** | |
232 // CHECK: %[[V5:.*]] = bitcast i8** %[[V1]] to i8* | |
233 // CHECK: %[[V6:.*]] = getelementptr inbounds i8, i8* %[[V5]], i64 24 | |
234 // CHECK: %[[V7:.*]] = bitcast i8* %[[V6]] to i8** | |
235 // CHECK: %[[V8:.*]] = load i8*, i8** %[[V7]], align 8 | |
236 // CHECK: call void @llvm.objc.storeStrong(i8** %[[V4]], i8* %[[V8]]) | |
237 | |
238 void test_copy_assignment_StrongOuter(StrongOuter *d, StrongOuter *s) { | |
239 *d = *s; | |
240 } | |
241 | |
242 // CHECK: define void @test_move_constructor_StrongOuter() | |
243 // CHECK: %[[T1:.*]] = getelementptr inbounds %[[STRUCT_BLOCK_BYREF_T]], %[[STRUCT_BLOCK_BYREF_T]]* %{{.*}}, i32 0, i32 7 | |
244 // CHECK: %[[V1:.*]] = bitcast %[[STRUCT_STRONGOUTER]]* %[[T1]] to i8** | |
245 // CHECK: call void @__default_constructor_8_S_s16_s24(i8** %[[V1]]) | |
246 // CHECK: %[[T2:.*]] = getelementptr inbounds %[[STRUCT_BLOCK_BYREF_T]], %[[STRUCT_BLOCK_BYREF_T]]* %{{.*}}, i32 0, i32 7 | |
247 // CHECK: %[[V9:.*]] = bitcast %[[STRUCT_STRONGOUTER]]* %[[T2]] to i8** | |
248 // CHECK: call void @__destructor_8_S_s16_s24(i8** %[[V9]]) | |
249 | |
250 // CHECK: define internal void @__Block_byref_object_copy_(i8* %0, i8* %1) | |
251 // CHECK: call void @__move_constructor_8_8_S_t0w16_s16_s24_t32w8( | |
252 | |
253 // CHECK: define linkonce_odr hidden void @__move_constructor_8_8_S_t0w16_s16_s24_t32w8(i8** %[[DST:.*]], i8** %[[SRC:.*]]) | |
254 // CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8 | |
255 // CHECK: %[[SRC_ADDR:.*]] = alloca i8**, align 8 | |
256 // CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 | |
257 // CHECK: store i8** %[[SRC]], i8*** %[[SRC_ADDR]], align 8 | |
258 // CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 | |
259 // CHECK: %[[V1:.*]] = load i8**, i8*** %[[SRC_ADDR]], align 8 | |
260 // CHECK: call void @__move_constructor_8_8_t0w16_s16(i8** %[[V0]], i8** %[[V1]]) | |
261 // CHECK: %[[V2:.*]] = bitcast i8** %[[V0]] to i8* | |
262 // CHECK: %[[V3:.*]] = getelementptr inbounds i8, i8* %[[V2]], i64 24 | |
263 // CHECK: %[[V4:.*]] = bitcast i8* %[[V3]] to i8** | |
264 // CHECK: %[[V5:.*]] = bitcast i8** %[[V1]] to i8* | |
265 // CHECK: %[[V6:.*]] = getelementptr inbounds i8, i8* %[[V5]], i64 24 | |
266 // CHECK: %[[V7:.*]] = bitcast i8* %[[V6]] to i8** | |
267 // CHECK: %[[V8:.*]] = load i8*, i8** %[[V7]], align 8 | |
268 // CHECK: store i8* null, i8** %[[V7]], align 8 | |
269 // CHECK: store i8* %[[V8]], i8** %[[V4]], align 8 | |
270 | |
271 // CHECK: define internal void @__Block_byref_object_dispose_(i8* %0) | |
272 // CHECK: call void @__destructor_8_S_s16_s24( | |
273 | |
274 void test_move_constructor_StrongOuter(void) { | |
275 __block StrongOuter t; | |
276 BlockTy b = ^{ (void)t; }; | |
277 } | |
278 | |
279 // CHECK: define linkonce_odr hidden void @__move_assignment_8_8_S_t0w16_s16_s24_t32w8(i8** %[[DST:.*]], i8** %[[SRC:.*]]) | |
280 // CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8 | |
281 // CHECK: %[[SRC_ADDR:.*]] = alloca i8**, align 8 | |
282 // CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 | |
283 // CHECK: store i8** %[[SRC]], i8*** %[[SRC_ADDR]], align 8 | |
284 // CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 | |
285 // CHECK: %[[V1:.*]] = load i8**, i8*** %[[SRC_ADDR]], align 8 | |
286 // CHECK: call void @__move_assignment_8_8_t0w16_s16(i8** %[[V0]], i8** %[[V1]]) | |
287 // CHECK: %[[V2:.*]] = bitcast i8** %[[V0]] to i8* | |
288 // CHECK: %[[V3:.*]] = getelementptr inbounds i8, i8* %[[V2]], i64 24 | |
289 // CHECK: %[[V4:.*]] = bitcast i8* %[[V3]] to i8** | |
290 // CHECK: %[[V5:.*]] = bitcast i8** %[[V1]] to i8* | |
291 // CHECK: %[[V6:.*]] = getelementptr inbounds i8, i8* %[[V5]], i64 24 | |
292 // CHECK: %[[V7:.*]] = bitcast i8* %[[V6]] to i8** | |
293 // CHECK: %[[V8:.*]] = load i8*, i8** %[[V7]], align 8 | |
294 // CHECK: store i8* null, i8** %[[V7]], align 8 | |
295 // CHECK: %[[V9:.*]] = load i8*, i8** %[[V4]], align 8 | |
296 // CHECK: store i8* %[[V8]], i8** %[[V4]], align 8 | |
297 // CHECK: call void @llvm.objc.release(i8* %[[V9]]) | |
298 | |
299 void test_move_assignment_StrongOuter(StrongOuter *p) { | |
300 *p = getStrongOuter(); | |
301 } | |
302 | |
303 // CHECK: define linkonce_odr hidden void @__default_constructor_8_s0_S_s24(i8** %[[DST:.*]]) | |
304 // CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8 | |
305 // CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 | |
306 // CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 | |
307 // CHECK: %[[V1:.*]] = bitcast i8** %[[V0]] to i8* | |
308 // CHECK: call void @llvm.memset.p0i8.i64(i8* align 8 %[[V1]], i8 0, i64 8, i1 false) | |
309 // CHECK: %[[V2:.*]] = bitcast i8** %[[V0]] to i8* | |
310 // CHECK: %[[V3:.*]] = getelementptr inbounds i8, i8* %[[V2]], i64 8 | |
311 // CHECK: %[[V4:.*]] = bitcast i8* %[[V3]] to i8** | |
312 // CHECK: call void @__default_constructor_8_s16(i8** %[[V4]]) | |
313 | |
314 // CHECK: define linkonce_odr hidden void @__destructor_8_s0_S_s24(i8** %[[DST:.*]]) | |
315 // CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8 | |
316 // CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 | |
317 // CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 | |
318 // CHECK: call void @llvm.objc.storeStrong(i8** %[[V0]], i8* null) | |
319 // CHECK: %[[V1:.*]] = bitcast i8** %[[V0]] to i8* | |
320 // CHECK: %[[V2:.*]] = getelementptr inbounds i8, i8* %[[V1]], i64 8 | |
321 // CHECK: %[[V3:.*]] = bitcast i8* %[[V2]] to i8** | |
322 // CHECK: call void @__destructor_8_s16(i8** %[[V3]]) | |
323 | |
324 void test_constructor_destructor_StrongOuter2(void) { | |
325 StrongOuter2 t; | |
326 } | |
327 | |
328 // CHECK: define linkonce_odr hidden void @__copy_constructor_8_8_s0_S_t8w16_s24(i8** %[[DST:.*]], i8** %[[SRC:.*]]) | |
329 // CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8 | |
330 // CHECK: %[[SRC_ADDR:.*]] = alloca i8**, align 8 | |
331 // CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 | |
332 // CHECK: store i8** %[[SRC]], i8*** %[[SRC_ADDR]], align 8 | |
333 // CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 | |
334 // CHECK: %[[V1:.*]] = load i8**, i8*** %[[SRC_ADDR]], align 8 | |
335 // CHECK: %[[V2:.*]] = load i8*, i8** %[[V1]], align 8 | |
336 // CHECK: %[[V3:.*]] = call i8* @llvm.objc.retain(i8* %[[V2]]) | |
337 // CHECK: store i8* %[[V3]], i8** %[[V0]], align 8 | |
338 // CHECK: %[[V4:.*]] = bitcast i8** %[[V0]] to i8* | |
339 // CHECK: %[[V5:.*]] = getelementptr inbounds i8, i8* %[[V4]], i64 8 | |
340 // CHECK: %[[V6:.*]] = bitcast i8* %[[V5]] to i8** | |
341 // CHECK: %[[V7:.*]] = bitcast i8** %[[V1]] to i8* | |
342 // CHECK: %[[V8:.*]] = getelementptr inbounds i8, i8* %[[V7]], i64 8 | |
343 // CHECK: %[[V9:.*]] = bitcast i8* %[[V8]] to i8** | |
344 // CHECK: call void @__copy_constructor_8_8_t0w16_s16(i8** %[[V6]], i8** %[[V9]]) | |
345 | |
346 void test_copy_constructor_StrongOuter2(StrongOuter2 *s) { | |
347 StrongOuter2 t = *s; | |
348 } | |
349 | |
350 // CHECK: define linkonce_odr hidden void @__copy_assignment_8_8_s0_S_t8w16_s24(i8** %[[DST:.*]], i8** %[[SRC:.*]]) | |
351 // CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8 | |
352 // CHECK: %[[SRC_ADDR:.*]] = alloca i8**, align 8 | |
353 // CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 | |
354 // CHECK: store i8** %[[SRC]], i8*** %[[SRC_ADDR]], align 8 | |
355 // CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 | |
356 // CHECK: %[[V1:.*]] = load i8**, i8*** %[[SRC_ADDR]], align 8 | |
357 // CHECK: %[[V2:.*]] = load i8*, i8** %[[V1]], align 8 | |
358 // CHECK: call void @llvm.objc.storeStrong(i8** %[[V0]], i8* %[[V2]]) | |
359 // CHECK: %[[V3:.*]] = bitcast i8** %[[V0]] to i8* | |
360 // CHECK: %[[V4:.*]] = getelementptr inbounds i8, i8* %[[V3]], i64 8 | |
361 // CHECK: %[[V5:.*]] = bitcast i8* %[[V4]] to i8** | |
362 // CHECK: %[[V6:.*]] = bitcast i8** %[[V1]] to i8* | |
363 // CHECK: %[[V7:.*]] = getelementptr inbounds i8, i8* %[[V6]], i64 8 | |
364 // CHECK: %[[V8:.*]] = bitcast i8* %[[V7]] to i8** | |
365 // CHECK: call void @__copy_assignment_8_8_t0w16_s16(i8** %[[V5]], i8** %[[V8]]) | |
366 | |
367 void test_copy_assignment_StrongOuter2(StrongOuter2 *d, StrongOuter2 *s) { | |
368 *d = *s; | |
369 } | |
370 | |
371 // CHECK: define linkonce_odr hidden void @__move_constructor_8_8_s0_S_t8w16_s24(i8** %[[DST:.*]], i8** %[[SRC:.*]]) | |
372 // CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8 | |
373 // CHECK: %[[SRC_ADDR:.*]] = alloca i8**, align 8 | |
374 // CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 | |
375 // CHECK: store i8** %[[SRC]], i8*** %[[SRC_ADDR]], align 8 | |
376 // CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 | |
377 // CHECK: %[[V1:.*]] = load i8**, i8*** %[[SRC_ADDR]], align 8 | |
378 // CHECK: %[[V2:.*]] = load i8*, i8** %[[V1]], align 8 | |
379 // CHECK: store i8* null, i8** %[[V1]], align 8 | |
380 // CHECK: store i8* %[[V2]], i8** %[[V0]], align 8 | |
381 // CHECK: %[[V3:.*]] = bitcast i8** %[[V0]] to i8* | |
382 // CHECK: %[[V4:.*]] = getelementptr inbounds i8, i8* %[[V3]], i64 8 | |
383 // CHECK: %[[V5:.*]] = bitcast i8* %[[V4]] to i8** | |
384 // CHECK: %[[V6:.*]] = bitcast i8** %[[V1]] to i8* | |
385 // CHECK: %[[V7:.*]] = getelementptr inbounds i8, i8* %[[V6]], i64 8 | |
386 // CHECK: %[[V8:.*]] = bitcast i8* %[[V7]] to i8** | |
387 // CHECK: call void @__move_constructor_8_8_t0w16_s16(i8** %[[V5]], i8** %[[V8]]) | |
388 | |
389 void test_move_constructor_StrongOuter2(void) { | |
390 __block StrongOuter2 t; | |
391 BlockTy b = ^{ (void)t; }; | |
392 } | |
393 | |
394 // CHECK: define linkonce_odr hidden void @__move_assignment_8_8_s0_S_t8w16_s24(i8** %[[DST:.*]], i8** %[[SRC:.*]]) | |
395 // CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8 | |
396 // CHECK: %[[SRC_ADDR:.*]] = alloca i8**, align 8 | |
397 // CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 | |
398 // CHECK: store i8** %[[SRC]], i8*** %[[SRC_ADDR]], align 8 | |
399 // CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 | |
400 // CHECK: %[[V1:.*]] = load i8**, i8*** %[[SRC_ADDR]], align 8 | |
401 // CHECK: %[[V2:.*]] = load i8*, i8** %[[V1]], align 8 | |
402 // CHECK: store i8* null, i8** %[[V1]], align 8 | |
403 // CHECK: %[[V3:.*]] = load i8*, i8** %[[V0]], align 8 | |
404 // CHECK: store i8* %[[V2]], i8** %[[V0]], align 8 | |
405 // CHECK: call void @llvm.objc.release(i8* %[[V3]]) | |
406 // CHECK: %[[V4:.*]] = bitcast i8** %[[V0]] to i8* | |
407 // CHECK: %[[V5:.*]] = getelementptr inbounds i8, i8* %[[V4]], i64 8 | |
408 // CHECK: %[[V6:.*]] = bitcast i8* %[[V5]] to i8** | |
409 // CHECK: %[[V7:.*]] = bitcast i8** %[[V1]] to i8* | |
410 // CHECK: %[[V8:.*]] = getelementptr inbounds i8, i8* %[[V7]], i64 8 | |
411 // CHECK: %[[V9:.*]] = bitcast i8* %[[V8]] to i8** | |
412 // CHECK: call void @__move_assignment_8_8_t0w16_s16(i8** %[[V6]], i8** %[[V9]]) | |
413 | |
414 void test_move_assignment_StrongOuter2(StrongOuter2 *p) { | |
415 *p = getStrongOuter2(); | |
416 } | |
417 | |
418 // CHECK: define void @test_parameter_StrongSmall([2 x i64] %[[A_COERCE:.*]]) | |
419 // CHECK: %[[A:.*]] = alloca %[[STRUCT_STRONGSMALL]], align 8 | |
420 // CHECK: %[[V0:.*]] = bitcast %[[STRUCT_STRONGSMALL]]* %[[A]] to [2 x i64]* | |
421 // CHECK: store [2 x i64] %[[A_COERCE]], [2 x i64]* %[[V0]], align 8 | |
422 // CHECK: %[[V1:.*]] = bitcast %[[STRUCT_STRONGSMALL]]* %[[A]] to i8** | |
423 // CHECK: call void @__destructor_8_s8(i8** %[[V1]]) | |
424 // CHECK: ret void | |
425 | |
426 void test_parameter_StrongSmall(StrongSmall a) { | |
427 } | |
428 | |
429 // CHECK: define void @test_argument_StrongSmall([2 x i64] %[[A_COERCE:.*]]) | |
430 // CHECK: %[[A:.*]] = alloca %[[STRUCT_STRONGSMALL]], align 8 | |
431 // CHECK: %[[TEMP_LVALUE:.*]] = alloca %[[STRUCT_STRONGSMALL]], align 8 | |
432 // CHECK: %[[V0:.*]] = bitcast %[[STRUCT_STRONGSMALL]]* %[[A]] to [2 x i64]* | |
433 // CHECK: store [2 x i64] %[[A_COERCE]], [2 x i64]* %[[V0]], align 8 | |
434 // CHECK: %[[V1:.*]] = bitcast %[[STRUCT_STRONGSMALL]]* %[[TEMP_LVALUE]] to i8** | |
435 // CHECK: %[[V2:.*]] = bitcast %[[STRUCT_STRONGSMALL]]* %[[A]] to i8** | |
436 // CHECK: call void @__copy_constructor_8_8_t0w4_s8(i8** %[[V1]], i8** %[[V2]]) | |
437 // CHECK: %[[V3:.*]] = bitcast %[[STRUCT_STRONGSMALL]]* %[[TEMP_LVALUE]] to [2 x i64]* | |
438 // CHECK: %[[V4:.*]] = load [2 x i64], [2 x i64]* %[[V3]], align 8 | |
439 // CHECK: call void @calleeStrongSmall([2 x i64] %[[V4]]) | |
440 // CHECK: %[[V5:.*]] = bitcast %[[STRUCT_STRONGSMALL]]* %[[A]] to i8** | |
441 // CHECK: call void @__destructor_8_s8(i8** %[[V5]]) | |
442 // CHECK: ret void | |
443 | |
444 void test_argument_StrongSmall(StrongSmall a) { | |
445 calleeStrongSmall(a); | |
446 } | |
447 | |
448 // CHECK: define [2 x i64] @test_return_StrongSmall([2 x i64] %[[A_COERCE:.*]]) | |
449 // CHECK: %[[RETVAL:.*]] = alloca %[[STRUCT_STRONGSMALL]], align 8 | |
450 // CHECK: %[[A:.*]] = alloca %[[STRUCT_STRONGSMALL]], align 8 | |
451 // CHECK: %[[V0:.*]] = bitcast %[[STRUCT_STRONGSMALL]]* %[[A]] to [2 x i64]* | |
452 // CHECK: store [2 x i64] %[[A_COERCE]], [2 x i64]* %[[V0]], align 8 | |
453 // CHECK: %[[V1:.*]] = bitcast %[[STRUCT_STRONGSMALL]]* %[[RETVAL]] to i8** | |
454 // CHECK: %[[V2:.*]] = bitcast %[[STRUCT_STRONGSMALL]]* %[[A]] to i8** | |
455 // CHECK: call void @__copy_constructor_8_8_t0w4_s8(i8** %[[V1]], i8** %[[V2]]) | |
456 // CHECK: %[[V3:.*]] = bitcast %[[STRUCT_STRONGSMALL]]* %[[A]] to i8** | |
457 // CHECK: call void @__destructor_8_s8(i8** %[[V3]]) | |
458 // CHECK: %[[V4:.*]] = bitcast %[[STRUCT_STRONGSMALL]]* %[[RETVAL]] to [2 x i64]* | |
459 // CHECK: %[[V5:.*]] = load [2 x i64], [2 x i64]* %[[V4]], align 8 | |
460 // CHECK: ret [2 x i64] %[[V5]] | |
461 | |
462 StrongSmall test_return_StrongSmall(StrongSmall a) { | |
463 return a; | |
464 } | |
465 | |
466 // CHECK: define void @test_destructor_ignored_result() | |
467 // CHECK: %[[COERCE:.*]] = alloca %[[STRUCT_STRONGSMALL]], align 8 | |
468 // CHECK: %[[CALL:.*]] = call [2 x i64] @getStrongSmall() | |
469 // CHECK: %[[V0:.*]] = bitcast %[[STRUCT_STRONGSMALL]]* %[[COERCE]] to [2 x i64]* | |
470 // CHECK: store [2 x i64] %[[CALL]], [2 x i64]* %[[V0]], align 8 | |
471 // CHECK: %[[V1:.*]] = bitcast %[[STRUCT_STRONGSMALL]]* %[[COERCE]] to i8** | |
472 // CHECK: call void @__destructor_8_s8(i8** %[[V1]]) | |
473 // CHECK: ret void | |
474 | |
475 void test_destructor_ignored_result(void) { | |
476 getStrongSmall(); | |
477 } | |
478 | |
479 // CHECK: define void @test_copy_constructor_StrongBlock( | |
480 // CHECK: call void @__copy_constructor_8_8_sb0( | |
481 // CHECK: call void @__destructor_8_sb0( | |
482 // CHECK: ret void | |
483 | |
484 // CHECK: define linkonce_odr hidden void @__copy_constructor_8_8_sb0(i8** %[[DST:.*]], i8** %[[SRC:.*]]) | |
485 // CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8 | |
486 // CHECK: %[[SRC_ADDR:.*]] = alloca i8**, align 8 | |
487 // CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 | |
488 // CHECK: store i8** %[[SRC]], i8*** %[[SRC_ADDR]], align 8 | |
489 // CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 | |
490 // CHECK: %[[V1:.*]] = load i8**, i8*** %[[SRC_ADDR]], align 8 | |
491 // CHECK: %[[V2:.*]] = load i8*, i8** %[[V1]], align 8 | |
492 // CHECK: %[[V3:.*]] = call i8* @llvm.objc.retainBlock(i8* %[[V2]]) | |
493 // CHECK: store i8* %[[V3]], i8** %[[V0]], align 8 | |
494 // CHECK: ret void | |
495 | |
496 void test_copy_constructor_StrongBlock(StrongBlock *s) { | |
497 StrongBlock t = *s; | |
498 } | |
499 | |
500 // CHECK: define void @test_copy_assignment_StrongBlock(%[[STRUCT_STRONGBLOCK]]* %[[D:.*]], %[[STRUCT_STRONGBLOCK]]* %[[S:.*]]) | |
501 // CHECK: call void @__copy_assignment_8_8_sb0( | |
502 | |
503 // CHECK: define linkonce_odr hidden void @__copy_assignment_8_8_sb0(i8** %[[DST:.*]], i8** %[[SRC:.*]]) | |
504 // CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8 | |
505 // CHECK: %[[SRC_ADDR:.*]] = alloca i8**, align 8 | |
506 // CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 | |
507 // CHECK: store i8** %[[SRC]], i8*** %[[SRC_ADDR]], align 8 | |
508 // CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 | |
509 // CHECK: %[[V1:.*]] = load i8**, i8*** %[[SRC_ADDR]], align 8 | |
510 // CHECK: %[[V2:.*]] = load i8*, i8** %[[V1]], align 8 | |
511 // CHECK: %[[V3:.*]] = call i8* @llvm.objc.retainBlock(i8* %[[V2]]) | |
512 // CHECK: %[[V4:.*]] = load i8*, i8** %[[V0]], align 8 | |
513 // CHECK: store i8* %[[V3]], i8** %[[V0]], align 8 | |
514 // CHECK: call void @llvm.objc.release(i8* %[[V4]]) | |
515 // CHECK: ret void | |
516 | |
517 void test_copy_assignment_StrongBlock(StrongBlock *d, StrongBlock *s) { | |
518 *d = *s; | |
519 } | |
520 | |
521 // CHECK: define void @test_copy_constructor_StrongVolatile0( | |
522 // CHECK: call void @__copy_constructor_8_8_t0w4_sv8( | |
523 // CHECK: call void @__destructor_8_sv8( | |
524 | |
525 // CHECK: define linkonce_odr hidden void @__copy_constructor_8_8_t0w4_sv8( | |
526 // CHECK: %[[V8:.*]] = load volatile i8*, i8** %{{.*}}, align 8 | |
527 // CHECK: %[[V9:.*]] = call i8* @llvm.objc.retain(i8* %[[V8]]) | |
528 // CHECK: store volatile i8* %[[V9]], i8** %{{.*}}, align 8 | |
529 | |
530 void test_copy_constructor_StrongVolatile0(StrongVolatile *s) { | |
531 StrongVolatile t = *s; | |
532 } | |
533 | |
534 // CHECK: define void @test_copy_constructor_StrongVolatile1( | |
535 // CHECK: call void @__copy_constructor_8_8_tv0w128_sv16( | |
536 | |
537 void test_copy_constructor_StrongVolatile1(Strong *s) { | |
538 volatile Strong t = *s; | |
539 } | |
540 | |
541 // CHECK: define void @test_block_capture_Strong() | |
542 // CHECK: call void @__default_constructor_8_s16( | |
543 // CHECK: call void @__copy_constructor_8_8_t0w16_s16( | |
544 // CHECK: call void @__destructor_8_s16( | |
545 // CHECK: call void @__destructor_8_s16( | |
546 // CHECK: ret void | |
547 | |
548 // CHECK: define linkonce_odr hidden void @__copy_helper_block_8_32n13_8_8_t0w16_s16(i8* %0, i8* %1) | |
549 // CHECK: call void @__copy_constructor_8_8_t0w16_s16( | |
550 // CHECK: ret void | |
551 | |
552 // CHECK: define linkonce_odr hidden void @__destroy_helper_block_8_32n5_8_s16( | |
553 // CHECK: call void @__destructor_8_s16( | |
554 // CHECK: ret void | |
555 | |
556 void test_block_capture_Strong(void) { | |
557 Strong t; | |
558 BlockTy b = ^(){ (void)t; }; | |
559 } | |
560 | |
561 // CHECK: define void @test_variable_length_array(i32 %[[N:.*]]) | |
562 // CHECK: %[[N_ADDR:.*]] = alloca i32, align 4 | |
563 // CHECK: store i32 %[[N]], i32* %[[N_ADDR]], align 4 | |
564 // CHECK: %[[V0:.*]] = load i32, i32* %[[N_ADDR]], align 4 | |
565 // CHECK: %[[V1:.*]] = zext i32 %[[V0]] to i64 | |
566 // CHECK: %[[VLA:.*]] = alloca %[[STRUCT_STRONG]], i64 %[[V1]], align 8 | |
567 // CHECK: %[[V3:.*]] = bitcast %[[STRUCT_STRONG]]* %[[VLA]] to i8** | |
568 // CHECK: %[[V4:.*]] = mul nuw i64 24, %[[V1]] | |
569 // CHECK: %[[V5:.*]] = bitcast i8** %[[V3]] to i8* | |
570 // CHECK: %[[V6:.*]] = getelementptr inbounds i8, i8* %[[V5]], i64 %[[V4]] | |
571 // CHECK: %[[DSTARRAY_END:.*]] = bitcast i8* %[[V6]] to i8** | |
572 // CHECK: br label | |
573 | |
574 // CHECK: %[[DSTADDR_CUR:.*]] = phi i8** [ %[[V3]], {{.*}} ], [ %[[V7:.*]], {{.*}} ] | |
575 // CHECK: %[[DONE:.*]] = icmp eq i8** %[[DSTADDR_CUR]], %[[DSTARRAY_END]] | |
576 // CHECK: br i1 %[[DONE]], label | |
577 | |
578 // CHECK: call void @__default_constructor_8_s16(i8** %[[DSTADDR_CUR]]) | |
579 // CHECK: %[[V8:.*]] = bitcast i8** %[[DSTADDR_CUR]] to i8* | |
580 // CHECK: %[[V9:.*]] = getelementptr inbounds i8, i8* %[[V8]], i64 24 | |
581 // CHECK: %[[V7]] = bitcast i8* %[[V9]] to i8** | |
582 // CHECK: br label | |
583 | |
584 // CHECK: call void @func(%[[STRUCT_STRONG]]* %[[VLA]]) | |
585 // CHECK: %[[V10:.*]] = getelementptr inbounds %[[STRUCT_STRONG]], %[[STRUCT_STRONG]]* %[[VLA]], i64 %[[V1]] | |
586 // CHECK: %[[ARRAYDESTROY_ISEMPTY:.*]] = icmp eq %[[STRUCT_STRONG]]* %[[VLA]], %[[V10]] | |
587 // CHECK: br i1 %[[ARRAYDESTROY_ISEMPTY]], label | |
588 | |
589 // CHECK: %[[ARRAYDESTROY_ELEMENTPAST:.*]] = phi %[[STRUCT_STRONG]]* [ %[[V10]], {{.*}} ], [ %[[ARRAYDESTROY_ELEMENT:.*]], {{.*}} ] | |
590 // CHECK: %[[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds %[[STRUCT_STRONG]], %[[STRUCT_STRONG]]* %[[ARRAYDESTROY_ELEMENTPAST]], i64 -1 | |
591 // CHECK: %[[V11:.*]] = bitcast %[[STRUCT_STRONG]]* %[[ARRAYDESTROY_ELEMENT]] to i8** | |
592 // CHECK: call void @__destructor_8_s16(i8** %[[V11]]) | |
593 // CHECK: %[[ARRAYDESTROY_DONE:.*]] = icmp eq %[[STRUCT_STRONG]]* %[[ARRAYDESTROY_ELEMENT]], %[[VLA]] | |
594 // CHECK: br i1 %[[ARRAYDESTROY_DONE]], label | |
595 | |
596 // CHECK: ret void | |
597 | |
598 void test_variable_length_array(int n) { | |
599 Strong a[n]; | |
600 func(a); | |
601 } | |
602 | |
603 // CHECK: define linkonce_odr hidden void @__default_constructor_8_AB8s8n4_s8_AE( | |
604 // CHECK: call void @llvm.memset.p0i8.i64(i8* align 8 %{{.*}}, i8 0, i64 32, i1 false) | |
605 void test_constructor_destructor_IDArray(void) { | |
606 IDArray t; | |
607 } | |
608 | |
609 // CHECK: define linkonce_odr hidden void @__default_constructor_8_AB8s24n4_S_s24_AE( | |
610 void test_constructor_destructor_StructArray(void) { | |
611 StructArray t; | |
612 } | |
613 | |
614 // Test that StructArray's field 'd' is copied before entering the loop. | |
615 | |
616 // CHECK: define linkonce_odr hidden void @__copy_constructor_8_8_t0w8_AB8s24n4_S_t8w16_s24_AE(i8** %[[DST:.*]], i8** %[[SRC:.*]]) | |
617 // CHECK: entry: | |
618 // CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8 | |
619 // CHECK: %[[SRC_ADDR:.*]] = alloca i8**, align 8 | |
620 // CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8 | |
621 // CHECK: store i8** %[[SRC]], i8*** %[[SRC_ADDR]], align 8 | |
622 // CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8 | |
623 // CHECK: %[[V1:.*]] = load i8**, i8*** %[[SRC_ADDR]], align 8 | |
624 // CHECK: %[[V2:.*]] = bitcast i8** %[[V0]] to i64* | |
625 // CHECK: %[[V3:.*]] = bitcast i8** %[[V1]] to i64* | |
626 // CHECK: %[[V4:.*]] = load i64, i64* %[[V3]], align 8 | |
627 // CHECK: store i64 %[[V4]], i64* %[[V2]], align 8 | |
628 | |
629 // CHECK: phi i8** | |
630 // CHECK: phi i8** | |
631 | |
632 // CHECK: phi i8** | |
633 // CHECK: phi i8** | |
634 | |
635 // CHECK-NOT: load i64, i64* % | |
636 // CHECK-NOT: store i64 % | |
637 // CHECK: call void @__copy_constructor_8_8_t0w16_s16( | |
638 | |
639 void test_copy_constructor_StructArray(StructArray a) { | |
640 StructArray t = a; | |
641 } | |
642 | |
643 // Check that IRGen copies the 9-bit bitfield emitting i16 load and store. | |
644 | |
645 // CHECK: define void @test_copy_constructor_Bitfield0( | |
646 | |
647 // CHECK: define linkonce_odr hidden void @__copy_constructor_8_8_s0_t8w2( | |
648 // CHECK: %[[V4:.*]] = bitcast i8** %{{.*}} to i8* | |
649 // CHECK: %[[V5:.*]] = getelementptr inbounds i8, i8* %[[V4]], i64 8 | |
650 // CHECK: %[[V6:.*]] = bitcast i8* %[[V5]] to i8** | |
651 // CHECK: %[[V7:.*]] = bitcast i8** %{{.*}} to i8* | |
652 // CHECK: %[[V8:.*]] = getelementptr inbounds i8, i8* %[[V7]], i64 8 | |
653 // CHECK: %[[V9:.*]] = bitcast i8* %[[V8]] to i8** | |
654 // CHECK: %[[V10:.*]] = bitcast i8** %[[V6]] to i16* | |
655 // CHECK: %[[V11:.*]] = bitcast i8** %[[V9]] to i16* | |
656 // CHECK: %[[V12:.*]] = load i16, i16* %[[V11]], align 8 | |
657 // CHECK: store i16 %[[V12]], i16* %[[V10]], align 8 | |
658 // CHECK: ret void | |
659 | |
660 void test_copy_constructor_Bitfield0(Bitfield0 *a) { | |
661 Bitfield0 t = *a; | |
662 } | |
663 | |
664 // CHECK: define linkonce_odr hidden void @__copy_constructor_8_8_t0w2_s8_t16w4_s24_t32w12_s48_t56w9_tv513w2_tv520w8 | |
665 // CHECK: %[[V4:.*]] = load i16, i16* %{{.*}}, align 8 | |
666 // CHECK: store i16 %[[V4]], i16* %{{.*}}, align 8 | |
667 // CHECK: %[[V21:.*]] = load i32, i32* %{{.*}}, align 8 | |
668 // CHECK: store i32 %[[V21]], i32* %{{.*}}, align 8 | |
669 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %{{.*}}, i8* align 8 %{{.*}}, i64 12, i1 false) | |
670 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %{{.*}}, i8* align 8 %{{.*}}, i64 9, i1 false) | |
671 // CHECK: %[[V54:.*]] = bitcast i8** %[[V0:.*]] to %[[STRUCT_BITFIELD1]]* | |
672 // CHECK: %[[I5:.*]] = getelementptr inbounds %[[STRUCT_BITFIELD1]], %[[STRUCT_BITFIELD1]]* %[[V54]], i32 0, i32 8 | |
673 // CHECK: %[[V55:.*]] = bitcast i8** %[[V1:.*]] to %[[STRUCT_BITFIELD1]]* | |
674 // CHECK: %[[I51:.*]] = getelementptr inbounds %[[STRUCT_BITFIELD1]], %[[STRUCT_BITFIELD1]]* %[[V55]], i32 0, i32 8 | |
675 // CHECK: %[[BF_LOAD:.*]] = load volatile i8, i8* %[[I51]], align 8 | |
676 // CHECK: %[[BF_SHL:.*]] = shl i8 %[[BF_LOAD]], 5 | |
677 // CHECK: %[[BF_ASHR:.*]] = ashr i8 %[[BF_SHL]], 6 | |
678 // CHECK: %[[BF_CAST:.*]] = sext i8 %[[BF_ASHR]] to i32 | |
679 // CHECK: %[[V56:.*]] = trunc i32 %[[BF_CAST]] to i8 | |
680 // CHECK: %[[BF_LOAD2:.*]] = load volatile i8, i8* %[[I5]], align 8 | |
681 // CHECK: %[[BF_VALUE:.*]] = and i8 %[[V56]], 3 | |
682 // CHECK: %[[BF_SHL3:.*]] = shl i8 %[[BF_VALUE]], 1 | |
683 // CHECK: %[[BF_CLEAR:.*]] = and i8 %[[BF_LOAD2]], -7 | |
684 // CHECK: %[[BF_SET:.*]] = or i8 %[[BF_CLEAR]], %[[BF_SHL3]] | |
685 // CHECK: store volatile i8 %[[BF_SET]], i8* %[[I5]], align 8 | |
686 // CHECK: %[[V57:.*]] = bitcast i8** %[[V0]] to %[[STRUCT_BITFIELD1]]* | |
687 // CHECK: %[[I6:.*]] = getelementptr inbounds %[[STRUCT_BITFIELD1]], %[[STRUCT_BITFIELD1]]* %[[V57]], i32 0, i32 9 | |
688 // CHECK: %[[V58:.*]] = bitcast i8** %[[V1]] to %[[STRUCT_BITFIELD1]]* | |
689 // CHECK: %[[I64:.*]] = getelementptr inbounds %[[STRUCT_BITFIELD1]], %[[STRUCT_BITFIELD1]]* %[[V58]], i32 0, i32 9 | |
690 // CHECK: %[[V59:.*]] = load volatile i8, i8* %[[I64]], align 1 | |
691 // CHECK: store volatile i8 %[[V59]], i8* %[[I6]], align 1 | |
692 | |
693 void test_copy_constructor_Bitfield1(Bitfield1 *a) { | |
694 Bitfield1 t = *a; | |
695 } | |
696 | |
697 // CHECK: define void @test_copy_constructor_VolatileArray( | |
698 // CHECK: call void @__copy_constructor_8_8_s0_AB8s4n16_tv64w32_AE( | |
699 | |
700 // CHECK: define linkonce_odr hidden void @__copy_constructor_8_8_s0_AB8s4n16_tv64w32_AE( | |
701 // CHECK: %[[ADDR_CUR:.*]] = phi i8** | |
702 // CHECK: %[[ADDR_CUR1:.*]] = phi i8** | |
703 // CHECK: %[[V12:.*]] = bitcast i8** %[[ADDR_CUR]] to i32* | |
704 // CHECK: %[[V13:.*]] = bitcast i8** %[[ADDR_CUR1]] to i32* | |
705 // CHECK: %[[V14:.*]] = load volatile i32, i32* %[[V13]], align 4 | |
706 // CHECK: store volatile i32 %[[V14]], i32* %[[V12]], align 4 | |
707 | |
708 void test_copy_constructor_VolatileArray(VolatileArray *a) { | |
709 VolatileArray t = *a; | |
710 } | |
711 | |
712 #endif /* USESTRUCT */ |