blob: 78764202f62730ad6699ea6ef74970e6f0819651 [file] [log] [blame]
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +00001; RUN: llc -verify-machineinstrs < %s -mtriple=armv7-apple-ios | FileCheck --check-prefix=CHECK-APPLE --check-prefix=CHECK-ARMV7 %s
Manman Ren57518142016-04-11 21:08:06 +00002; RUN: llc -verify-machineinstrs -O0 < %s -mtriple=armv7-apple-ios | FileCheck --check-prefix=CHECK-O0 %s
3
4declare i8* @malloc(i64)
5declare void @free(i8*)
6%swift_error = type { i64, i8 }
7%struct.S = type { i32, i32, i32, i32, i32, i32 }
8
9; This tests the basic usage of a swifterror parameter. "foo" is the function
10; that takes a swifterror parameter and "caller" is the caller of "foo".
11define float @foo(%swift_error** swifterror %error_ptr_ref) {
12; CHECK-APPLE-LABEL: foo:
13; CHECK-APPLE: mov r0, #16
14; CHECK-APPLE: malloc
15; CHECK-APPLE-DAG: mov [[ID:r[0-9]+]], #1
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +000016; CHECK-APPLE-DAG: mov r8, r{{.*}}
Manman Ren57518142016-04-11 21:08:06 +000017; CHECK-APPLE-DAG: strb [[ID]], [r{{.*}}, #8]
18
19; CHECK-O0-LABEL: foo:
20; CHECK-O0: mov r{{.*}}, #16
21; CHECK-O0: malloc
22; CHECK-O0: mov [[ID2:r[0-9]+]], r0
23; CHECK-O0: mov [[ID:r[0-9]+]], #1
24; CHECK-O0: strb [[ID]], [r0, #8]
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +000025; CHECK-O0: mov r8, [[ID2]]
Manman Ren57518142016-04-11 21:08:06 +000026entry:
27 %call = call i8* @malloc(i64 16)
28 %call.0 = bitcast i8* %call to %swift_error*
29 store %swift_error* %call.0, %swift_error** %error_ptr_ref
30 %tmp = getelementptr inbounds i8, i8* %call, i64 8
31 store i8 1, i8* %tmp
32 ret float 1.0
33}
34
35; "caller" calls "foo" that takes a swifterror parameter.
36define float @caller(i8* %error_ref) {
37; CHECK-APPLE-LABEL: caller:
38; CHECK-APPLE-DAG: mov [[ID:r[0-9]+]], r0
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +000039; CHECK-APPLE-DAG: mov r8, #0
Manman Ren57518142016-04-11 21:08:06 +000040; CHECK-APPLE: bl {{.*}}foo
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +000041; CHECK-APPLE: cmp r8, #0
Manman Ren57518142016-04-11 21:08:06 +000042; Access part of the error object and save it to error_ref
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +000043; CHECK-APPLE: ldrbeq [[CODE:r[0-9]+]], [r8, #8]
Manman Ren57518142016-04-11 21:08:06 +000044; CHECK-APPLE: strbeq [[CODE]], [{{.*}}[[ID]]]
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +000045; CHECK-APPLE: mov r0, r8
Arnold Schwaighofer3f256582016-10-07 22:06:55 +000046; CHECK-APPLE: bl {{.*}}free
Manman Ren57518142016-04-11 21:08:06 +000047
48; CHECK-O0-LABEL: caller:
49; spill r0
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +000050; CHECK-O0-DAG: mov r8, #0
Arnold Schwaighofer3f256582016-10-07 22:06:55 +000051; CHECK-O0-DAG: str r0, [sp, [[SLOT:#[0-9]+]]
Manman Ren57518142016-04-11 21:08:06 +000052; CHECK-O0: bl {{.*}}foo
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +000053; CHECK-O0: mov [[TMP:r[0-9]+]], r8
Arnold Schwaighofer3f256582016-10-07 22:06:55 +000054; CHECK-O0: str [[TMP]], [sp]
Manman Ren57518142016-04-11 21:08:06 +000055; CHECK-O0: bne
56; CHECK-O0: ldrb [[CODE:r[0-9]+]], [r0, #8]
Arnold Schwaighofer3f256582016-10-07 22:06:55 +000057; CHECK-O0: ldr [[ID:r[0-9]+]], [sp, [[SLOT]]]
Manman Ren57518142016-04-11 21:08:06 +000058; CHECK-O0: strb [[CODE]], [{{.*}}[[ID]]]
Arnold Schwaighofer3f256582016-10-07 22:06:55 +000059; reload r0
60; CHECK-O0: ldr r0, [sp]
Manman Ren57518142016-04-11 21:08:06 +000061; CHECK-O0: free
62entry:
63 %error_ptr_ref = alloca swifterror %swift_error*
64 store %swift_error* null, %swift_error** %error_ptr_ref
65 %call = call float @foo(%swift_error** swifterror %error_ptr_ref)
66 %error_from_foo = load %swift_error*, %swift_error** %error_ptr_ref
67 %had_error_from_foo = icmp ne %swift_error* %error_from_foo, null
68 %tmp = bitcast %swift_error* %error_from_foo to i8*
69 br i1 %had_error_from_foo, label %handler, label %cont
70cont:
71 %v1 = getelementptr inbounds %swift_error, %swift_error* %error_from_foo, i64 0, i32 1
72 %t = load i8, i8* %v1
73 store i8 %t, i8* %error_ref
74 br label %handler
75handler:
76 call void @free(i8* %tmp)
77 ret float 1.0
78}
79
80; "caller2" is the caller of "foo", it calls "foo" inside a loop.
81define float @caller2(i8* %error_ref) {
82; CHECK-APPLE-LABEL: caller2:
83; CHECK-APPLE-DAG: mov [[ID:r[0-9]+]], r0
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +000084; CHECK-APPLE-DAG: mov r8, #0
Manman Ren57518142016-04-11 21:08:06 +000085; CHECK-APPLE: bl {{.*}}foo
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +000086; CHECK-APPLE: cmp r8, #0
Manman Ren57518142016-04-11 21:08:06 +000087; CHECK-APPLE: bne
88; Access part of the error object and save it to error_ref
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +000089; CHECK-APPLE: ldrb [[CODE:r[0-9]+]], [r8, #8]
Manman Ren57518142016-04-11 21:08:06 +000090; CHECK-APPLE: strb [[CODE]], [{{.*}}[[ID]]]
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +000091; CHECK-APPLE: mov r0, r8
Arnold Schwaighofer3f256582016-10-07 22:06:55 +000092; CHECK-APPLE: bl {{.*}}free
Manman Ren57518142016-04-11 21:08:06 +000093
94; CHECK-O0-LABEL: caller2:
95; spill r0
96; CHECK-O0-DAG: str r0,
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +000097; CHECK-O0-DAG: mov r8, #0
Manman Ren57518142016-04-11 21:08:06 +000098; CHECK-O0: bl {{.*}}foo
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +000099; CHECK-O0: mov r{{.*}}, r8
Arnold Schwaighofer3f256582016-10-07 22:06:55 +0000100; CHECK-O0: str r0, [sp]
Manman Ren57518142016-04-11 21:08:06 +0000101; CHECK-O0: bne
102; CHECK-O0: ble
103; CHECK-O0: ldrb [[CODE:r[0-9]+]], [r0, #8]
104; reload r0
105; CHECK-O0: ldr [[ID:r[0-9]+]],
106; CHECK-O0: strb [[CODE]], [{{.*}}[[ID]]]
Arnold Schwaighofer3f256582016-10-07 22:06:55 +0000107; CHECK-O0: ldr r0, [sp]
Manman Ren57518142016-04-11 21:08:06 +0000108; CHECK-O0: free
109entry:
110 %error_ptr_ref = alloca swifterror %swift_error*
111 br label %bb_loop
112bb_loop:
113 store %swift_error* null, %swift_error** %error_ptr_ref
114 %call = call float @foo(%swift_error** swifterror %error_ptr_ref)
115 %error_from_foo = load %swift_error*, %swift_error** %error_ptr_ref
116 %had_error_from_foo = icmp ne %swift_error* %error_from_foo, null
117 %tmp = bitcast %swift_error* %error_from_foo to i8*
118 br i1 %had_error_from_foo, label %handler, label %cont
119cont:
120 %cmp = fcmp ogt float %call, 1.000000e+00
121 br i1 %cmp, label %bb_end, label %bb_loop
122bb_end:
123 %v1 = getelementptr inbounds %swift_error, %swift_error* %error_from_foo, i64 0, i32 1
124 %t = load i8, i8* %v1
125 store i8 %t, i8* %error_ref
126 br label %handler
127handler:
128 call void @free(i8* %tmp)
129 ret float 1.0
130}
131
132; "foo_if" is a function that takes a swifterror parameter, it sets swifterror
133; under a certain condition.
134define float @foo_if(%swift_error** swifterror %error_ptr_ref, i32 %cc) {
135; CHECK-APPLE-LABEL: foo_if:
136; CHECK-APPLE: cmp r0, #0
137; CHECK-APPLE: eq
138; CHECK-APPLE: mov r0, #16
139; CHECK-APPLE: malloc
140; CHECK-APPLE: mov [[ID:r[0-9]+]], #1
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000141; CHECK-APPLE-DAG: mov r8, r{{.*}}
Manman Ren57518142016-04-11 21:08:06 +0000142; CHECK-APPLE-DAG: strb [[ID]], [r{{.*}}, #8]
143
144; CHECK-O0-LABEL: foo_if:
145; CHECK-O0: cmp r0, #0
146; spill to stack
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000147; CHECK-O0: str r8
Manman Ren57518142016-04-11 21:08:06 +0000148; CHECK-O0: beq
149; CHECK-O0: mov r0, #16
150; CHECK-O0: malloc
151; CHECK-O0: mov [[ID:r[0-9]+]], r0
152; CHECK-O0: mov [[ID2:[a-z0-9]+]], #1
153; CHECK-O0: strb [[ID2]], [r0, #8]
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000154; CHECK-O0: mov r8, [[ID]]
Manman Ren57518142016-04-11 21:08:06 +0000155; reload from stack
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000156; CHECK-O0: ldr r8
Manman Ren57518142016-04-11 21:08:06 +0000157entry:
158 %cond = icmp ne i32 %cc, 0
159 br i1 %cond, label %gen_error, label %normal
160
161gen_error:
162 %call = call i8* @malloc(i64 16)
163 %call.0 = bitcast i8* %call to %swift_error*
164 store %swift_error* %call.0, %swift_error** %error_ptr_ref
165 %tmp = getelementptr inbounds i8, i8* %call, i64 8
166 store i8 1, i8* %tmp
167 ret float 1.0
168
169normal:
170 ret float 0.0
171}
172
173; "foo_loop" is a function that takes a swifterror parameter, it sets swifterror
174; under a certain condition inside a loop.
175define float @foo_loop(%swift_error** swifterror %error_ptr_ref, i32 %cc, float %cc2) {
176; CHECK-APPLE-LABEL: foo_loop:
177; CHECK-APPLE: mov [[CODE:r[0-9]+]], r0
178; swifterror is kept in a register
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000179; CHECK-APPLE: mov [[ID:r[0-9]+]], r8
Manman Ren57518142016-04-11 21:08:06 +0000180; CHECK-APPLE: cmp [[CODE]], #0
181; CHECK-APPLE: beq
182; CHECK-APPLE: mov r0, #16
183; CHECK-APPLE: malloc
184; CHECK-APPLE: strb r{{.*}}, [{{.*}}[[ID]], #8]
185; CHECK-APPLE: ble
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000186; CHECK-APPLE: mov r8, [[ID]]
Manman Ren57518142016-04-11 21:08:06 +0000187
188; CHECK-O0-LABEL: foo_loop:
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000189; CHECK-O0: mov r{{.*}}, r8
Manman Ren57518142016-04-11 21:08:06 +0000190; CHECK-O0: cmp r{{.*}}, #0
191; CHECK-O0: beq
192; CHECK-O0-DAG: movw r{{.*}}, #1
193; CHECK-O0-DAG: mov r{{.*}}, #16
194; CHECK-O0: malloc
195; CHECK-O0-DAG: mov [[ID:r[0-9]+]], r0
196; CHECK-O0-DAG: ldr [[ID2:r[0-9]+]], [sp{{.*}}]
197; CHECK-O0: strb [[ID2]], [{{.*}}[[ID]], #8]
198; spill r0
199; CHECK-O0: str r0, [sp{{.*}}]
200; CHECK-O0: vcmpe
201; CHECK-O0: ble
202; reload from stack
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000203; CHECK-O0: ldr r8
Manman Ren57518142016-04-11 21:08:06 +0000204entry:
205 br label %bb_loop
206
207bb_loop:
208 %cond = icmp ne i32 %cc, 0
209 br i1 %cond, label %gen_error, label %bb_cont
210
211gen_error:
212 %call = call i8* @malloc(i64 16)
213 %call.0 = bitcast i8* %call to %swift_error*
214 store %swift_error* %call.0, %swift_error** %error_ptr_ref
215 %tmp = getelementptr inbounds i8, i8* %call, i64 8
216 store i8 1, i8* %tmp
217 br label %bb_cont
218
219bb_cont:
220 %cmp = fcmp ogt float %cc2, 1.000000e+00
221 br i1 %cmp, label %bb_end, label %bb_loop
222bb_end:
223 ret float 0.0
224}
225
226; "foo_sret" is a function that takes a swifterror parameter, it also has a sret
227; parameter.
228define void @foo_sret(%struct.S* sret %agg.result, i32 %val1, %swift_error** swifterror %error_ptr_ref) {
229; CHECK-APPLE-LABEL: foo_sret:
230; CHECK-APPLE: mov [[SRET:r[0-9]+]], r0
231; CHECK-APPLE: mov r0, #16
232; CHECK-APPLE: malloc
233; CHECK-APPLE: mov [[REG:r[0-9]+]], #1
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000234; CHECK-APPLE-DAG: mov r8, r0
Manman Ren57518142016-04-11 21:08:06 +0000235; CHECK-APPLE-DAG: strb [[REG]], [r0, #8]
236; CHECK-APPLE-DAG: str r{{.*}}, [{{.*}}[[SRET]], #4]
237
238; CHECK-O0-LABEL: foo_sret:
239; CHECK-O0: mov r{{.*}}, #16
240; spill to stack: sret and val1
241; CHECK-O0-DAG: str r0
242; CHECK-O0-DAG: str r1
243; CHECK-O0: malloc
244; CHECK-O0: mov [[ID:r[0-9]+]], #1
245; CHECK-O0: strb [[ID]], [r0, #8]
246; reload from stack: sret and val1
247; CHECK-O0: ldr
248; CHECK-O0: ldr
249; CHECK-O0: str r{{.*}}, [{{.*}}, #4]
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000250; CHECK-O0: mov r8
Manman Ren57518142016-04-11 21:08:06 +0000251entry:
252 %call = call i8* @malloc(i64 16)
253 %call.0 = bitcast i8* %call to %swift_error*
254 store %swift_error* %call.0, %swift_error** %error_ptr_ref
255 %tmp = getelementptr inbounds i8, i8* %call, i64 8
256 store i8 1, i8* %tmp
257 %v2 = getelementptr inbounds %struct.S, %struct.S* %agg.result, i32 0, i32 1
258 store i32 %val1, i32* %v2
259 ret void
260}
261
262; "caller3" calls "foo_sret" that takes a swifterror parameter.
263define float @caller3(i8* %error_ref) {
264; CHECK-APPLE-LABEL: caller3:
265; CHECK-APPLE: mov [[ID:r[0-9]+]], r0
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000266; CHECK-APPLE: mov r8, #0
Manman Ren57518142016-04-11 21:08:06 +0000267; CHECK-APPLE: bl {{.*}}foo_sret
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000268; CHECK-APPLE: cmp r8, #0
Manman Ren57518142016-04-11 21:08:06 +0000269; Access part of the error object and save it to error_ref
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000270; CHECK-APPLE: ldrbeq [[CODE:r[0-9]+]], [r8, #8]
Manman Ren57518142016-04-11 21:08:06 +0000271; CHECK-APPLE: strbeq [[CODE]], [{{.*}}[[ID]]]
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000272; CHECK-APPLE: mov r0, r8
Arnold Schwaighofer3f256582016-10-07 22:06:55 +0000273; CHECK-APPLE: bl {{.*}}free
Manman Ren57518142016-04-11 21:08:06 +0000274
275; CHECK-O0-LABEL: caller3:
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000276; CHECK-O0-DAG: mov r8, #0
Manman Ren57518142016-04-11 21:08:06 +0000277; CHECK-O0-DAG: mov r0
278; CHECK-O0-DAG: mov r1
279; CHECK-O0: bl {{.*}}foo_sret
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000280; CHECK-O0: mov [[ID2:r[0-9]+]], r8
281; CHECK-O0: cmp r8
Arnold Schwaighofer3f256582016-10-07 22:06:55 +0000282; CHECK-O0: str [[ID2]], [sp[[SLOT:.*]]]
Manman Ren57518142016-04-11 21:08:06 +0000283; CHECK-O0: bne
284; Access part of the error object and save it to error_ref
285; CHECK-O0: ldrb [[CODE:r[0-9]+]]
286; CHECK-O0: ldr [[ID:r[0-9]+]]
287; CHECK-O0: strb [[CODE]], [{{.*}}[[ID]]]
Arnold Schwaighofer3f256582016-10-07 22:06:55 +0000288; CHECK-O0: ldr r0, [sp[[SLOT]]
289; CHECK-O0: bl {{.*}}free
Manman Ren57518142016-04-11 21:08:06 +0000290entry:
291 %s = alloca %struct.S, align 8
292 %error_ptr_ref = alloca swifterror %swift_error*
293 store %swift_error* null, %swift_error** %error_ptr_ref
294 call void @foo_sret(%struct.S* sret %s, i32 1, %swift_error** swifterror %error_ptr_ref)
295 %error_from_foo = load %swift_error*, %swift_error** %error_ptr_ref
296 %had_error_from_foo = icmp ne %swift_error* %error_from_foo, null
297 %tmp = bitcast %swift_error* %error_from_foo to i8*
298 br i1 %had_error_from_foo, label %handler, label %cont
299cont:
300 %v1 = getelementptr inbounds %swift_error, %swift_error* %error_from_foo, i64 0, i32 1
301 %t = load i8, i8* %v1
302 store i8 %t, i8* %error_ref
303 br label %handler
304handler:
305 call void @free(i8* %tmp)
306 ret float 1.0
307}
308
309; "foo_vararg" is a function that takes a swifterror parameter, it also has
310; variable number of arguments.
311declare void @llvm.va_start(i8*) nounwind
312define float @foo_vararg(%swift_error** swifterror %error_ptr_ref, ...) {
313; CHECK-APPLE-LABEL: foo_vararg:
314; CHECK-APPLE: mov r0, #16
315; CHECK-APPLE: malloc
316; CHECK-APPLE: mov [[REG:r[0-9]+]], r0
317; CHECK-APPLE: mov [[ID:r[0-9]+]], #1
318; CHECK-APPLE-DAG: strb [[ID]], [{{.*}}[[REG]], #8]
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000319; CHECK-APPLE-DAG: mov r8, [[REG]]
Manman Ren57518142016-04-11 21:08:06 +0000320
321entry:
322 %call = call i8* @malloc(i64 16)
323 %call.0 = bitcast i8* %call to %swift_error*
324 store %swift_error* %call.0, %swift_error** %error_ptr_ref
325 %tmp = getelementptr inbounds i8, i8* %call, i64 8
326 store i8 1, i8* %tmp
327
328 %args = alloca i8*, align 8
329 %a10 = alloca i32, align 4
330 %a11 = alloca i32, align 4
331 %a12 = alloca i32, align 4
332 %v10 = bitcast i8** %args to i8*
333 call void @llvm.va_start(i8* %v10)
334 %v11 = va_arg i8** %args, i32
335 store i32 %v11, i32* %a10, align 4
336 %v12 = va_arg i8** %args, i32
337 store i32 %v12, i32* %a11, align 4
338 %v13 = va_arg i8** %args, i32
339 store i32 %v13, i32* %a12, align 4
340
341 ret float 1.0
342}
343
344; "caller4" calls "foo_vararg" that takes a swifterror parameter.
345define float @caller4(i8* %error_ref) {
346; CHECK-APPLE-LABEL: caller4:
347; CHECK-APPLE: mov [[ID:r[0-9]+]], r0
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000348; CHECK-APPLE: mov r8, #0
Manman Ren57518142016-04-11 21:08:06 +0000349; CHECK-APPLE: bl {{.*}}foo_vararg
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000350; CHECK-APPLE: cmp r8, #0
Manman Ren57518142016-04-11 21:08:06 +0000351; Access part of the error object and save it to error_ref
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000352; CHECK-APPLE: ldrbeq [[CODE:r[0-9]+]], [r8, #8]
Manman Ren57518142016-04-11 21:08:06 +0000353; CHECK-APPLE: strbeq [[CODE]], [{{.*}}[[ID]]]
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000354; CHECK-APPLE: mov r0, r8
Arnold Schwaighofer3f256582016-10-07 22:06:55 +0000355; CHECK-APPLE: bl {{.*}}free
Manman Ren57518142016-04-11 21:08:06 +0000356entry:
357 %error_ptr_ref = alloca swifterror %swift_error*
358 store %swift_error* null, %swift_error** %error_ptr_ref
359
360 %a10 = alloca i32, align 4
361 %a11 = alloca i32, align 4
362 %a12 = alloca i32, align 4
363 store i32 10, i32* %a10, align 4
364 store i32 11, i32* %a11, align 4
365 store i32 12, i32* %a12, align 4
366 %v10 = load i32, i32* %a10, align 4
367 %v11 = load i32, i32* %a11, align 4
368 %v12 = load i32, i32* %a12, align 4
369
370 %call = call float (%swift_error**, ...) @foo_vararg(%swift_error** swifterror %error_ptr_ref, i32 %v10, i32 %v11, i32 %v12)
371 %error_from_foo = load %swift_error*, %swift_error** %error_ptr_ref
372 %had_error_from_foo = icmp ne %swift_error* %error_from_foo, null
373 %tmp = bitcast %swift_error* %error_from_foo to i8*
374 br i1 %had_error_from_foo, label %handler, label %cont
375
376cont:
377 %v1 = getelementptr inbounds %swift_error, %swift_error* %error_from_foo, i64 0, i32 1
378 %t = load i8, i8* %v1
379 store i8 %t, i8* %error_ref
380 br label %handler
381handler:
382 call void @free(i8* %tmp)
383 ret float 1.0
384}
Arnold Schwaighoferde2490d2016-09-21 16:53:36 +0000385
386; Check that we don't blow up on tail calling swifterror argument functions.
387define float @tailcallswifterror(%swift_error** swifterror %error_ptr_ref) {
388entry:
389 %0 = tail call float @tailcallswifterror(%swift_error** swifterror %error_ptr_ref)
390 ret float %0
391}
392define swiftcc float @tailcallswifterror_swiftcc(%swift_error** swifterror %error_ptr_ref) {
393entry:
394 %0 = tail call swiftcc float @tailcallswifterror_swiftcc(%swift_error** swifterror %error_ptr_ref)
395 ret float %0
396}
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000397
398; CHECK-APPLE-LABEL: swifterror_clobber
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000399; CHECK-APPLE: mov [[REG:r[0-9]+]], r8
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000400; CHECK-APPLE: nop
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000401; CHECK-APPLE: mov r8, [[REG]]
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000402define swiftcc void @swifterror_clobber(%swift_error** nocapture swifterror %err) {
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000403 call void asm sideeffect "nop", "~{r8}"()
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000404 ret void
405}
406
407; CHECK-APPLE-LABEL: swifterror_reg_clobber
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000408; CHECK-APPLE: push {{.*}}r8
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000409; CHECK-APPLE: nop
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000410; CHECK-APPLE: pop {{.*}}r8
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000411define swiftcc void @swifterror_reg_clobber(%swift_error** nocapture %err) {
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000412 call void asm sideeffect "nop", "~{r8}"()
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000413 ret void
414}
415
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +0000416; CHECK-ARMV7-LABEL: _params_in_reg
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000417; Store callee saved registers excluding swifterror.
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000418; CHECK-ARMV7: push {r4, r5, r6, r7, r10, r11, lr}
419; Store swiftself (r10) and swifterror (r8).
420; CHECK-ARMV7-DAG: str r8, [s[[STK1:.*]]]
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +0000421; CHECK-ARMV7-DAG: str r10, [s[[STK2:.*]]]
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000422; Store arguments.
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000423; CHECK-ARMV7: mov r6, r3
424; CHECK-ARMV7: mov r4, r2
425; CHECK-ARMV7: mov r11, r1
426; CHECK-ARMV7: mov r5, r0
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000427; Setup call.
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +0000428; CHECK-ARMV7: mov r0, #1
429; CHECK-ARMV7: mov r1, #2
430; CHECK-ARMV7: mov r2, #3
431; CHECK-ARMV7: mov r3, #4
432; CHECK-ARMV7: mov r10, #0
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000433; CHECK-ARMV7: mov r8, #0
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +0000434; CHECK-ARMV7: bl _params_in_reg2
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000435; Restore original arguments.
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +0000436; CHECK-ARMV7-DAG: ldr r10, [s[[STK2]]]
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000437; CHECK-ARMV7-DAG: ldr r8, [s[[STK1]]]
438; CHECK-ARMV7: mov r0, r5
439; CHECK-ARMV7: mov r1, r11
440; CHECK-ARMV7: mov r2, r4
441; CHECK-ARMV7: mov r3, r6
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +0000442; CHECK-ARMV7: bl _params_in_reg2
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000443; CHECK-ARMV7: pop {r4, r5, r6, r7, r10, r11, pc}
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000444define swiftcc void @params_in_reg(i32, i32, i32, i32, i8* swiftself, %swift_error** nocapture swifterror %err) {
445 %error_ptr_ref = alloca swifterror %swift_error*, align 8
446 store %swift_error* null, %swift_error** %error_ptr_ref
447 call swiftcc void @params_in_reg2(i32 1, i32 2, i32 3, i32 4, i8* swiftself null, %swift_error** nocapture swifterror %error_ptr_ref)
448 call swiftcc void @params_in_reg2(i32 %0, i32 %1, i32 %2, i32 %3, i8* swiftself %4, %swift_error** nocapture swifterror %err)
449 ret void
450}
451declare swiftcc void @params_in_reg2(i32, i32, i32, i32, i8* swiftself, %swift_error** nocapture swifterror %err)
452
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +0000453; CHECK-ARMV7-LABEL: params_and_return_in_reg
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000454; CHECK-ARMV7: push {r4, r5, r6, r7, r10, r11, lr}
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000455; Store swifterror and swiftself
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000456; CHECK-ARMV7: mov r6, r8
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +0000457; CHECK-ARMV7: str r10, [s[[STK1:.*]]]
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000458; Store arguments.
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +0000459; CHECK-ARMV7: str r3, [s[[STK2:.*]]]
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000460; CHECK-ARMV7: mov r4, r2
461; CHECK-ARMV7: mov r11, r1
462; CHECK-ARMV7: mov r5, r0
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000463; Setup call.
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +0000464; CHECK-ARMV7: mov r0, #1
465; CHECK-ARMV7: mov r1, #2
466; CHECK-ARMV7: mov r2, #3
467; CHECK-ARMV7: mov r3, #4
468; CHECK-ARMV7: mov r10, #0
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000469; CHECK-ARMV7: mov r8, #0
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +0000470; CHECK-ARMV7: bl _params_in_reg2
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000471; Restore original arguments.
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +0000472; CHECK-ARMV7: ldr r3, [s[[STK2]]]
473; CHECK-ARMV7: ldr r10, [s[[STK1]]]
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000474; Store %error_ptr_ref;
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000475; CHECK-ARMV7: str r8, [s[[STK3:.*]]]
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000476; Restore original arguments.
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000477; CHECK-ARMV7: mov r0, r5
478; CHECK-ARMV7: mov r1, r11
479; CHECK-ARMV7: mov r2, r4
480; CHECK-ARMV7: mov r8, r6
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +0000481; CHECK-ARMV7: bl _params_and_return_in_reg2
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000482; Store swifterror return %err;
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000483; CHECK-ARMV7: str r8, [s[[STK1]]]
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000484; Load swifterror value %error_ptr_ref.
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000485; CHECK-ARMV7: ldr r8, [s[[STK3]]]
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000486; Save return values.
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000487; CHECK-ARMV7: mov r4, r0
488; CHECK-ARMV7: mov r5, r1
489; CHECK-ARMV7: mov r6, r2
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +0000490; CHECK-ARMV7: mov r11, r3
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000491; Setup call.
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +0000492; CHECK-ARMV7: mov r0, #1
493; CHECK-ARMV7: mov r1, #2
494; CHECK-ARMV7: mov r2, #3
495; CHECK-ARMV7: mov r3, #4
496; CHECK-ARMV7: mov r10, #0
497; CHECK-ARMV7: bl _params_in_reg2
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000498; Load swifterror %err;
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000499; CHECK-ARMV7: ldr r8, [s[[STK1]]]
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000500; Restore return values for returning.
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000501; CHECK-ARMV7: mov r0, r4
502; CHECK-ARMV7: mov r1, r5
503; CHECK-ARMV7: mov r2, r6
Arnold Schwaighofer6200b2b2016-10-28 19:18:09 +0000504; CHECK-ARMV7: mov r3, r11
Arnold Schwaighofer26f016f2017-02-09 01:52:17 +0000505; CHECK-ARMV7: pop {r4, r5, r6, r7, r10, r11, pc}
Arnold Schwaighofer7f4b31c2016-10-28 17:21:05 +0000506define swiftcc { i32, i32, i32, i32} @params_and_return_in_reg(i32, i32, i32, i32, i8* swiftself, %swift_error** nocapture swifterror %err) {
507 %error_ptr_ref = alloca swifterror %swift_error*, align 8
508 store %swift_error* null, %swift_error** %error_ptr_ref
509 call swiftcc void @params_in_reg2(i32 1, i32 2, i32 3, i32 4, i8* swiftself null, %swift_error** nocapture swifterror %error_ptr_ref)
510 %val = call swiftcc { i32, i32, i32, i32 } @params_and_return_in_reg2(i32 %0, i32 %1, i32 %2, i32 %3, i8* swiftself %4, %swift_error** nocapture swifterror %err)
511 call swiftcc void @params_in_reg2(i32 1, i32 2, i32 3, i32 4, i8* swiftself null, %swift_error** nocapture swifterror %error_ptr_ref)
512 ret { i32, i32, i32, i32 }%val
513}
514
515declare swiftcc { i32, i32, i32, i32 } @params_and_return_in_reg2(i32, i32, i32, i32, i8* swiftself, %swift_error** nocapture swifterror %err)
Arnold Schwaighofer8f3df732017-02-13 19:58:28 +0000516
517
518declare void @acallee(i8*)
519
520; Make sure we don't tail call if the caller returns a swifterror value. We
521; would have to move into the swifterror register before the tail call.
522; CHECK-APPLE: tailcall_from_swifterror:
523; CHECK-APPLE-NOT: b _acallee
524; CHECK-APPLE: bl _acallee
525
526define swiftcc void @tailcall_from_swifterror(%swift_error** swifterror %error_ptr_ref) {
527entry:
528 tail call void @acallee(i8* null)
529 ret void
530}