blob: 35402832fd352562b7dd8cafe321128c4ec3119e [file] [log] [blame]
Manman Ren57518142016-04-11 21:08:06 +00001; RUN: llc -verify-machineinstrs < %s -mtriple=armv7-apple-ios | FileCheck --check-prefix=CHECK-APPLE %s
2; 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
16; CHECK-APPLE-DAG: mov r6, r{{.*}}
17; 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]
25; CHECK-O0: mov r6, [[ID2]]
26entry:
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
39; CHECK-APPLE-DAG: mov r6, #0
40; CHECK-APPLE: bl {{.*}}foo
41; CHECK-APPLE: cmp r6, #0
42; Access part of the error object and save it to error_ref
43; CHECK-APPLE: ldrbeq [[CODE:r[0-9]+]], [r6, #8]
44; CHECK-APPLE: strbeq [[CODE]], [{{.*}}[[ID]]]
45; CHECK-APPLE: mov r0, r6
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
Manman Ren57518142016-04-11 21:08:06 +000050; CHECK-O0-DAG: mov r6, #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 Schwaighofer3f256582016-10-07 22:06:55 +000053; CHECK-O0: mov [[TMP:r[0-9]+]], r6
54; 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
84; CHECK-APPLE-DAG: mov r6, #0
85; CHECK-APPLE: bl {{.*}}foo
86; CHECK-APPLE: cmp r6, #0
87; CHECK-APPLE: bne
88; Access part of the error object and save it to error_ref
89; CHECK-APPLE: ldrb [[CODE:r[0-9]+]], [r6, #8]
90; CHECK-APPLE: strb [[CODE]], [{{.*}}[[ID]]]
91; CHECK-APPLE: mov r0, r6
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,
97; CHECK-O0-DAG: mov r6, #0
98; CHECK-O0: bl {{.*}}foo
99; CHECK-O0: mov r{{.*}}, r6
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
141; CHECK-APPLE-DAG: mov r6, r{{.*}}
142; CHECK-APPLE-DAG: strb [[ID]], [r{{.*}}, #8]
143
144; CHECK-O0-LABEL: foo_if:
145; CHECK-O0: cmp r0, #0
146; spill to stack
147; CHECK-O0: str r6
148; 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]
154; CHECK-O0: mov r6, [[ID]]
155; reload from stack
156; CHECK-O0: ldr r6
157entry:
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
179; CHECK-APPLE: mov [[ID:r[0-9]+]], r6
180; 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
186; CHECK-APPLE: mov r6, [[ID]]
187
188; CHECK-O0-LABEL: foo_loop:
189; CHECK-O0: mov r{{.*}}, r6
190; 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
203; CHECK-O0: ldr r6
204entry:
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
234; CHECK-APPLE-DAG: mov r6, r0
235; 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]
250; CHECK-O0: mov r6
251entry:
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
266; CHECK-APPLE: mov r6, #0
267; CHECK-APPLE: bl {{.*}}foo_sret
268; CHECK-APPLE: cmp r6, #0
269; Access part of the error object and save it to error_ref
270; CHECK-APPLE: ldrbeq [[CODE:r[0-9]+]], [r6, #8]
271; CHECK-APPLE: strbeq [[CODE]], [{{.*}}[[ID]]]
272; CHECK-APPLE: mov r0, r6
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:
276; CHECK-O0-DAG: mov r6, #0
277; CHECK-O0-DAG: mov r0
278; CHECK-O0-DAG: mov r1
279; CHECK-O0: bl {{.*}}foo_sret
280; CHECK-O0: mov [[ID2:r[0-9]+]], r6
Arnold Schwaighofer3f256582016-10-07 22:06:55 +0000281; CHECK-O0: cmp r6
282; 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]
319; CHECK-APPLE-DAG: mov r6, [[REG]]
320
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
348; CHECK-APPLE: mov r6, #0
349; CHECK-APPLE: bl {{.*}}foo_vararg
350; CHECK-APPLE: cmp r6, #0
351; Access part of the error object and save it to error_ref
352; CHECK-APPLE: ldrbeq [[CODE:r[0-9]+]], [r6, #8]
353; CHECK-APPLE: strbeq [[CODE]], [{{.*}}[[ID]]]
354; CHECK-APPLE: mov r0, r6
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
399; CHECK-APPLE: mov [[REG:r[0-9]+]], r6
400; CHECK-APPLE: nop
401; CHECK-APPLE: mov r6, [[REG]]
402define swiftcc void @swifterror_clobber(%swift_error** nocapture swifterror %err) {
403 call void asm sideeffect "nop", "~{r6}"()
404 ret void
405}
406
407; CHECK-APPLE-LABEL: swifterror_reg_clobber
408; CHECK-APPLE: push {{.*}}r6
409; CHECK-APPLE: nop
410; CHECK-APPLE: pop {{.*}}r6
411define swiftcc void @swifterror_reg_clobber(%swift_error** nocapture %err) {
412 call void asm sideeffect "nop", "~{r6}"()
413 ret void
414}
415
416; CHECK-APPLE-LABEL: _params_in_reg
417; Store callee saved registers excluding swifterror.
418; CHECK-APPLE: push {r8, r10, r11, r4, r5, r7, lr}
419; Store swiftself (r10) and swifterror (r6).
420; CHECK-APPLE: str r6, [sp, #4]
421; CHECK-APPLE: str r10, [sp]
422; Store arguments.
423; CHECK-APPLE: mov r4, r3
424; CHECK-APPLE: mov r5, r2
425; CHECK-APPLE: mov r8, r1
426; CHECK-APPLE: mov r11, r0
427; Setup call.
428; CHECK-APPLE: mov r0, #1
429; CHECK-APPLE: mov r1, #2
430; CHECK-APPLE: mov r2, #3
431; CHECK-APPLE: mov r3, #4
432; CHECK-APPLE: mov r10, #0
433; CHECK-APPLE: mov r6, #0
434; CHECK-APPLE: bl _params_in_reg2
435; Restore original arguments.
436; CHECK-APPLE: ldr r10, [sp]
437; CHECK-APPLE: ldr r6, [sp, #4]
438; CHECK-APPLE: mov r0, r11
439; CHECK-APPLE: mov r1, r8
440; CHECK-APPLE: mov r2, r5
441; CHECK-APPLE: mov r3, r4
442; CHECK-APPLE: bl _params_in_reg2
443; CHECK-APPLE: sub sp, r7, #20
444; CHECK-APPLE: pop {r8, r10, r11, r4, r5, r7, pc}
445define swiftcc void @params_in_reg(i32, i32, i32, i32, i8* swiftself, %swift_error** nocapture swifterror %err) {
446 %error_ptr_ref = alloca swifterror %swift_error*, align 8
447 store %swift_error* null, %swift_error** %error_ptr_ref
448 call swiftcc void @params_in_reg2(i32 1, i32 2, i32 3, i32 4, i8* swiftself null, %swift_error** nocapture swifterror %error_ptr_ref)
449 call swiftcc void @params_in_reg2(i32 %0, i32 %1, i32 %2, i32 %3, i8* swiftself %4, %swift_error** nocapture swifterror %err)
450 ret void
451}
452declare swiftcc void @params_in_reg2(i32, i32, i32, i32, i8* swiftself, %swift_error** nocapture swifterror %err)
453
454; CHECK-LABEL: params_and_return_in_reg
455; CHECK-APPLE: push {r8, r10, r11, r4, r5, r7, lr}
456; Store swifterror and swiftself
457; CHECK-APPLE: mov r4, r6
458; CHECK-APPLE: str r10, [sp, #12]
459; Store arguments.
460; CHECK-APPLE: str r3, [sp, #8]
461; CHECK-APPLE: mov r5, r2
462; CHECK-APPLE: mov r8, r1
463; CHECK-APPLE: mov r11, r0
464; Setup call.
465; CHECK-APPLE: mov r0, #1
466; CHECK-APPLE: mov r1, #2
467; CHECK-APPLE: mov r2, #3
468; CHECK-APPLE: mov r3, #4
469; CHECK-APPLE: mov r10, #0
470; CHECK-APPLE: mov r6, #0
471; CHECK-APPLE: bl _params_in_reg2
472; Restore original arguments.
473; CHECK-APPLE: ldr r3, [sp, #8]
474; CHECK-APPLE: ldr r10, [sp, #12]
475; Store %error_ptr_ref;
476; CHECK-APPLE: str r6, [sp, #4]
477; Restore original arguments.
478; CHECK-APPLE: mov r0, r11
479; CHECK-APPLE: mov r1, r8
480; CHECK-APPLE: mov r2, r5
481; CHECK-APPLE: mov r6, r4
482; CHECK-APPLE: bl _params_and_return_in_reg2
483; Store swifterror return %err;
484; CHECK-APPLE: str r6, [sp, #12]
485; Load swifterror value %error_ptr_ref.
486; CHECK-APPLE: ldr r6, [sp, #4]
487; Save return values.
488; CHECK-APPLE: mov r5, r0
489; CHECK-APPLE: mov r4, r1
490; CHECK-APPLE: mov r8, r2
491; CHECK-APPLE: mov r11, r3
492; Setup call.
493; CHECK-APPLE: mov r0, #1
494; CHECK-APPLE: mov r1, #2
495; CHECK-APPLE: mov r2, #3
496; CHECK-APPLE: mov r3, #4
497; CHECK-APPLE: mov r10, #0
498; CHECK-APPLE: bl _params_in_reg2
499; Load swifterror %err;
500; CHECK-APPLE: ldr r6, [sp, #12]
501; Restore return values for returning.
502; CHECK-APPLE: mov r0, r5
503; CHECK-APPLE: mov r1, r4
504; CHECK-APPLE: mov r2, r8
505; CHECK-APPLE: mov r3, r11
506; CHECK-APPLE: sub sp, r7, #20
507; CHECK-APPLE: pop {r8, r10, r11, r4, r5, r7, pc}
508define swiftcc { i32, i32, i32, i32} @params_and_return_in_reg(i32, i32, i32, i32, i8* swiftself, %swift_error** nocapture swifterror %err) {
509 %error_ptr_ref = alloca swifterror %swift_error*, align 8
510 store %swift_error* null, %swift_error** %error_ptr_ref
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 %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)
513 call swiftcc void @params_in_reg2(i32 1, i32 2, i32 3, i32 4, i8* swiftself null, %swift_error** nocapture swifterror %error_ptr_ref)
514 ret { i32, i32, i32, i32 }%val
515}
516
517declare swiftcc { i32, i32, i32, i32 } @params_and_return_in_reg2(i32, i32, i32, i32, i8* swiftself, %swift_error** nocapture swifterror %err)