Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / CodeGen / ARM / swifterror.ll
blob4f950ba68760802996e8ef10ca42fedb77f0034f
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -verify-machineinstrs < %s -mtriple=armv7-apple-ios | FileCheck --check-prefix=CHECK-APPLE %s
3 ; RUN: llc -verify-machineinstrs -O0 < %s -mtriple=armv7-apple-ios | FileCheck --check-prefix=CHECK-O0 %s
4 ; RUN: llc -verify-machineinstrs < %s -mtriple=armv7-linux-androideabi | FileCheck --check-prefix=CHECK-ANDROID %s
6 declare ptr @malloc(i64)
7 declare void @free(ptr)
8 %swift_error = type { i64, i8 }
9 %struct.S = type { i32, i32, i32, i32, i32, i32 }
11 ; This tests the basic usage of a swifterror parameter. "foo" is the function
12 ; that takes a swifterror parameter and "caller" is the caller of "foo".
13 define float @foo(ptr swifterror %error_ptr_ref) {
14 ; CHECK-APPLE-LABEL: foo:
15 ; CHECK-APPLE:       @ %bb.0: @ %entry
16 ; CHECK-APPLE-NEXT:    push {lr}
17 ; CHECK-APPLE-NEXT:    mov r0, #16
18 ; CHECK-APPLE-NEXT:    mov r1, #0
19 ; CHECK-APPLE-NEXT:    bl _malloc
20 ; CHECK-APPLE-NEXT:    mov r8, r0
21 ; CHECK-APPLE-NEXT:    mov r0, #1
22 ; CHECK-APPLE-NEXT:    strb r0, [r8, #8]
23 ; CHECK-APPLE-NEXT:    mov r0, #1065353216
24 ; CHECK-APPLE-NEXT:    pop {lr}
25 ; CHECK-APPLE-NEXT:    bx lr
27 ; CHECK-O0-LABEL: foo:
28 ; CHECK-O0:       @ %bb.0: @ %entry
29 ; CHECK-O0-NEXT:    push {r7, lr}
30 ; CHECK-O0-NEXT:    mov r7, sp
31 ; CHECK-O0-NEXT:    mov r0, #16
32 ; CHECK-O0-NEXT:    mov r1, #0
33 ; CHECK-O0-NEXT:    bl _malloc
34 ; CHECK-O0-NEXT:    mov r1, r0
35 ; CHECK-O0-NEXT:    mov r8, r1
36 ; CHECK-O0-NEXT:    mov r0, #1
37 ; CHECK-O0-NEXT:    strb r0, [r1, #8]
38 ; CHECK-O0-NEXT:    mov r0, #1065353216
39 ; CHECK-O0-NEXT:    pop {r7, pc}
41 ; CHECK-ANDROID-LABEL: foo:
42 ; CHECK-ANDROID:       @ %bb.0: @ %entry
43 ; CHECK-ANDROID-NEXT:    .save {r11, lr}
44 ; CHECK-ANDROID-NEXT:    push {r11, lr}
45 ; CHECK-ANDROID-NEXT:    mov r0, #16
46 ; CHECK-ANDROID-NEXT:    mov r1, #0
47 ; CHECK-ANDROID-NEXT:    bl malloc
48 ; CHECK-ANDROID-NEXT:    mov r8, r0
49 ; CHECK-ANDROID-NEXT:    mov r0, #1
50 ; CHECK-ANDROID-NEXT:    strb r0, [r8, #8]
51 ; CHECK-ANDROID-NEXT:    mov r0, #1065353216
52 ; CHECK-ANDROID-NEXT:    pop {r11, pc}
54 entry:
55   %call = call ptr @malloc(i64 16)
56   store ptr %call, ptr %error_ptr_ref
57   %tmp = getelementptr inbounds i8, ptr %call, i64 8
58   store i8 1, ptr %tmp
59   ret float 1.0
62 ; "caller" calls "foo" that takes a swifterror parameter.
63 define float @caller(ptr %error_ref) {
64 ; CHECK-APPLE-LABEL: caller:
65 ; CHECK-APPLE:       @ %bb.0: @ %entry
66 ; CHECK-APPLE-NEXT:    push {r4, r8, lr}
67 ; CHECK-APPLE-NEXT:    sub sp, sp, #4
68 ; CHECK-APPLE-NEXT:    mov r8, #0
69 ; CHECK-APPLE-NEXT:    mov r4, r0
70 ; CHECK-APPLE-NEXT:    bl _foo
71 ; CHECK-APPLE-NEXT:    mov r0, r8
72 ; CHECK-APPLE-NEXT:    cmp r8, #0
73 ; CHECK-APPLE-NEXT:    ldrbeq r1, [r0, #8]
74 ; CHECK-APPLE-NEXT:    strbeq r1, [r4]
75 ; CHECK-APPLE-NEXT:    bl _free
76 ; CHECK-APPLE-NEXT:    mov r0, #1065353216
77 ; CHECK-APPLE-NEXT:    add sp, sp, #4
78 ; CHECK-APPLE-NEXT:    pop {r4, r8, pc}
80 ; CHECK-O0-LABEL: caller:
81 ; CHECK-O0:       @ %bb.0: @ %entry
82 ; CHECK-O0-NEXT:    push {r7, lr}
83 ; CHECK-O0-NEXT:    mov r7, sp
84 ; CHECK-O0-NEXT:    push {r8}
85 ; CHECK-O0-NEXT:    sub sp, sp, #12
86 ; CHECK-O0-NEXT:    @ implicit-def: $r1
87 ; CHECK-O0-NEXT:    str r0, [sp] @ 4-byte Spill
88 ; CHECK-O0-NEXT:    mov r8, #0
89 ; CHECK-O0-NEXT:    bl _foo
90 ; CHECK-O0-NEXT:    str r8, [sp, #4] @ 4-byte Spill
91 ; CHECK-O0-NEXT:    movw r0, #0
92 ; CHECK-O0-NEXT:    cmp r8, r0
93 ; CHECK-O0-NEXT:    bne LBB1_2
94 ; CHECK-O0-NEXT:  @ %bb.1: @ %cont
95 ; CHECK-O0-NEXT:    ldr r1, [sp] @ 4-byte Reload
96 ; CHECK-O0-NEXT:    ldr r0, [sp, #4] @ 4-byte Reload
97 ; CHECK-O0-NEXT:    ldrb r0, [r0, #8]
98 ; CHECK-O0-NEXT:    strb r0, [r1]
99 ; CHECK-O0-NEXT:  LBB1_2: @ %handler
100 ; CHECK-O0-NEXT:    ldr r0, [sp, #4] @ 4-byte Reload
101 ; CHECK-O0-NEXT:    bl _free
102 ; CHECK-O0-NEXT:    mov r0, #1065353216
103 ; CHECK-O0-NEXT:    sub sp, r7, #4
104 ; CHECK-O0-NEXT:    pop {r8}
105 ; CHECK-O0-NEXT:    pop {r7, pc}
107 ; CHECK-ANDROID-LABEL: caller:
108 ; CHECK-ANDROID:       @ %bb.0: @ %entry
109 ; CHECK-ANDROID-NEXT:    .save {r4, r8, r11, lr}
110 ; CHECK-ANDROID-NEXT:    push {r4, r8, r11, lr}
111 ; CHECK-ANDROID-NEXT:    .pad #8
112 ; CHECK-ANDROID-NEXT:    sub sp, sp, #8
113 ; CHECK-ANDROID-NEXT:    mov r8, #0
114 ; CHECK-ANDROID-NEXT:    mov r4, r0
115 ; CHECK-ANDROID-NEXT:    bl foo
116 ; CHECK-ANDROID-NEXT:    mov r0, r8
117 ; CHECK-ANDROID-NEXT:    cmp r8, #0
118 ; CHECK-ANDROID-NEXT:    ldrbeq r1, [r0, #8]
119 ; CHECK-ANDROID-NEXT:    strbeq r1, [r4]
120 ; CHECK-ANDROID-NEXT:    bl free
121 ; CHECK-ANDROID-NEXT:    mov r0, #1065353216
122 ; CHECK-ANDROID-NEXT:    add sp, sp, #8
123 ; CHECK-ANDROID-NEXT:    pop {r4, r8, r11, pc}
124 ; Access part of the error object and save it to error_ref
126 ; spill r0
127 ; reload r0
128 entry:
129   %error_ptr_ref = alloca swifterror ptr
130   store ptr null, ptr %error_ptr_ref
131   %call = call float @foo(ptr swifterror %error_ptr_ref)
132   %error_from_foo = load ptr, ptr %error_ptr_ref
133   %had_error_from_foo = icmp ne ptr %error_from_foo, null
134   br i1 %had_error_from_foo, label %handler, label %cont
135 cont:
136   %v1 = getelementptr inbounds %swift_error, ptr %error_from_foo, i64 0, i32 1
137   %t = load i8, ptr %v1
138   store i8 %t, ptr %error_ref
139   br label %handler
140 handler:
141   call void @free(ptr %error_from_foo)
142   ret float 1.0
145 ; "caller2" is the caller of "foo", it calls "foo" inside a loop.
146 define float @caller2(ptr %error_ref) {
147 ; CHECK-APPLE-LABEL: caller2:
148 ; CHECK-APPLE:       @ %bb.0: @ %entry
149 ; CHECK-APPLE-NEXT:    push {r4, r8, lr}
150 ; CHECK-APPLE-NEXT:    vpush {d8}
151 ; CHECK-APPLE-NEXT:    sub sp, sp, #4
152 ; CHECK-APPLE-NEXT:    vmov.f32 s16, #1.000000e+00
153 ; CHECK-APPLE-NEXT:    mov r4, r0
154 ; CHECK-APPLE-NEXT:  LBB2_1: @ %bb_loop
155 ; CHECK-APPLE-NEXT:    @ =>This Inner Loop Header: Depth=1
156 ; CHECK-APPLE-NEXT:    mov r8, #0
157 ; CHECK-APPLE-NEXT:    bl _foo
158 ; CHECK-APPLE-NEXT:    cmp r8, #0
159 ; CHECK-APPLE-NEXT:    bne LBB2_4
160 ; CHECK-APPLE-NEXT:  @ %bb.2: @ %cont
161 ; CHECK-APPLE-NEXT:    @ in Loop: Header=BB2_1 Depth=1
162 ; CHECK-APPLE-NEXT:    vmov s0, r0
163 ; CHECK-APPLE-NEXT:    vcmp.f32 s0, s16
164 ; CHECK-APPLE-NEXT:    vmrs APSR_nzcv, fpscr
165 ; CHECK-APPLE-NEXT:    ble LBB2_1
166 ; CHECK-APPLE-NEXT:  @ %bb.3: @ %bb_end
167 ; CHECK-APPLE-NEXT:    ldrb r0, [r8, #8]
168 ; CHECK-APPLE-NEXT:    strb r0, [r4]
169 ; CHECK-APPLE-NEXT:  LBB2_4: @ %handler
170 ; CHECK-APPLE-NEXT:    mov r0, r8
171 ; CHECK-APPLE-NEXT:    bl _free
172 ; CHECK-APPLE-NEXT:    mov r0, #1065353216
173 ; CHECK-APPLE-NEXT:    add sp, sp, #4
174 ; CHECK-APPLE-NEXT:    vpop {d8}
175 ; CHECK-APPLE-NEXT:    pop {r4, r8, pc}
177 ; CHECK-O0-LABEL: caller2:
178 ; CHECK-O0:       @ %bb.0: @ %entry
179 ; CHECK-O0-NEXT:    push {r7, lr}
180 ; CHECK-O0-NEXT:    mov r7, sp
181 ; CHECK-O0-NEXT:    push {r8}
182 ; CHECK-O0-NEXT:    sub sp, sp, #16
183 ; CHECK-O0-NEXT:    @ implicit-def: $r1
184 ; CHECK-O0-NEXT:    str r0, [sp, #8] @ 4-byte Spill
185 ; CHECK-O0-NEXT:  LBB2_1: @ %bb_loop
186 ; CHECK-O0-NEXT:    @ =>This Inner Loop Header: Depth=1
187 ; CHECK-O0-NEXT:    mov r8, #0
188 ; CHECK-O0-NEXT:    bl _foo
189 ; CHECK-O0-NEXT:    vmov s0, r0
190 ; CHECK-O0-NEXT:    vstr s0, [sp] @ 4-byte Spill
191 ; CHECK-O0-NEXT:    str r8, [sp, #4] @ 4-byte Spill
192 ; CHECK-O0-NEXT:    movw r0, #0
193 ; CHECK-O0-NEXT:    cmp r8, r0
194 ; CHECK-O0-NEXT:    bne LBB2_4
195 ; CHECK-O0-NEXT:  @ %bb.2: @ %cont
196 ; CHECK-O0-NEXT:    @ in Loop: Header=BB2_1 Depth=1
197 ; CHECK-O0-NEXT:    vldr s0, [sp] @ 4-byte Reload
198 ; CHECK-O0-NEXT:    vmov.f32 s2, #1.000000e+00
199 ; CHECK-O0-NEXT:    vcmp.f32 s0, s2
200 ; CHECK-O0-NEXT:    vmrs APSR_nzcv, fpscr
201 ; CHECK-O0-NEXT:    ble LBB2_1
202 ; CHECK-O0-NEXT:  @ %bb.3: @ %bb_end
203 ; CHECK-O0-NEXT:    ldr r1, [sp, #8] @ 4-byte Reload
204 ; CHECK-O0-NEXT:    ldr r0, [sp, #4] @ 4-byte Reload
205 ; CHECK-O0-NEXT:    ldrb r0, [r0, #8]
206 ; CHECK-O0-NEXT:    strb r0, [r1]
207 ; CHECK-O0-NEXT:  LBB2_4: @ %handler
208 ; CHECK-O0-NEXT:    ldr r0, [sp, #4] @ 4-byte Reload
209 ; CHECK-O0-NEXT:    bl _free
210 ; CHECK-O0-NEXT:    mov r0, #1065353216
211 ; CHECK-O0-NEXT:    sub sp, r7, #4
212 ; CHECK-O0-NEXT:    pop {r8}
213 ; CHECK-O0-NEXT:    pop {r7, pc}
215 ; CHECK-ANDROID-LABEL: caller2:
216 ; CHECK-ANDROID:       @ %bb.0: @ %entry
217 ; CHECK-ANDROID-NEXT:    .save {r4, r8, r11, lr}
218 ; CHECK-ANDROID-NEXT:    push {r4, r8, r11, lr}
219 ; CHECK-ANDROID-NEXT:    .vsave {d8}
220 ; CHECK-ANDROID-NEXT:    vpush {d8}
221 ; CHECK-ANDROID-NEXT:    .pad #8
222 ; CHECK-ANDROID-NEXT:    sub sp, sp, #8
223 ; CHECK-ANDROID-NEXT:    vmov.f32 s16, #1.000000e+00
224 ; CHECK-ANDROID-NEXT:    mov r4, r0
225 ; CHECK-ANDROID-NEXT:  .LBB2_1: @ %bb_loop
226 ; CHECK-ANDROID-NEXT:    @ =>This Inner Loop Header: Depth=1
227 ; CHECK-ANDROID-NEXT:    mov r8, #0
228 ; CHECK-ANDROID-NEXT:    bl foo
229 ; CHECK-ANDROID-NEXT:    cmp r8, #0
230 ; CHECK-ANDROID-NEXT:    bne .LBB2_4
231 ; CHECK-ANDROID-NEXT:  @ %bb.2: @ %cont
232 ; CHECK-ANDROID-NEXT:    @ in Loop: Header=BB2_1 Depth=1
233 ; CHECK-ANDROID-NEXT:    vmov s0, r0
234 ; CHECK-ANDROID-NEXT:    vcmp.f32 s0, s16
235 ; CHECK-ANDROID-NEXT:    vmrs APSR_nzcv, fpscr
236 ; CHECK-ANDROID-NEXT:    ble .LBB2_1
237 ; CHECK-ANDROID-NEXT:  @ %bb.3: @ %bb_end
238 ; CHECK-ANDROID-NEXT:    ldrb r0, [r8, #8]
239 ; CHECK-ANDROID-NEXT:    strb r0, [r4]
240 ; CHECK-ANDROID-NEXT:  .LBB2_4: @ %handler
241 ; CHECK-ANDROID-NEXT:    mov r0, r8
242 ; CHECK-ANDROID-NEXT:    bl free
243 ; CHECK-ANDROID-NEXT:    mov r0, #1065353216
244 ; CHECK-ANDROID-NEXT:    add sp, sp, #8
245 ; CHECK-ANDROID-NEXT:    vpop {d8}
246 ; CHECK-ANDROID-NEXT:    pop {r4, r8, r11, pc}
247 ; Access part of the error object and save it to error_ref
249 ; spill r0
250 ; reload r0
251 entry:
252   %error_ptr_ref = alloca swifterror ptr
253   br label %bb_loop
254 bb_loop:
255   store ptr null, ptr %error_ptr_ref
256   %call = call float @foo(ptr swifterror %error_ptr_ref)
257   %error_from_foo = load ptr, ptr %error_ptr_ref
258   %had_error_from_foo = icmp ne ptr %error_from_foo, null
259   br i1 %had_error_from_foo, label %handler, label %cont
260 cont:
261   %cmp = fcmp ogt float %call, 1.000000e+00
262   br i1 %cmp, label %bb_end, label %bb_loop
263 bb_end:
264   %v1 = getelementptr inbounds %swift_error, ptr %error_from_foo, i64 0, i32 1
265   %t = load i8, ptr %v1
266   store i8 %t, ptr %error_ref
267   br label %handler
268 handler:
269   call void @free(ptr %error_from_foo)
270   ret float 1.0
273 ; "foo_if" is a function that takes a swifterror parameter, it sets swifterror
274 ; under a certain condition.
275 define float @foo_if(ptr swifterror %error_ptr_ref, i32 %cc) {
276 ; CHECK-APPLE-LABEL: foo_if:
277 ; CHECK-APPLE:       @ %bb.0: @ %entry
278 ; CHECK-APPLE-NEXT:    cmp r0, #0
279 ; CHECK-APPLE-NEXT:    vldreq s0, LCPI3_0
280 ; CHECK-APPLE-NEXT:    vmoveq r0, s0
281 ; CHECK-APPLE-NEXT:    bxeq lr
282 ; CHECK-APPLE-NEXT:  LBB3_1: @ %gen_error
283 ; CHECK-APPLE-NEXT:    push {lr}
284 ; CHECK-APPLE-NEXT:    mov r0, #16
285 ; CHECK-APPLE-NEXT:    mov r1, #0
286 ; CHECK-APPLE-NEXT:    bl _malloc
287 ; CHECK-APPLE-NEXT:    mov r8, r0
288 ; CHECK-APPLE-NEXT:    mov r0, #1
289 ; CHECK-APPLE-NEXT:    vmov.f32 s0, #1.000000e+00
290 ; CHECK-APPLE-NEXT:    strb r0, [r8, #8]
291 ; CHECK-APPLE-NEXT:    pop {lr}
292 ; CHECK-APPLE-NEXT:    vmov r0, s0
293 ; CHECK-APPLE-NEXT:    bx lr
294 ; CHECK-APPLE-NEXT:    .p2align 2
295 ; CHECK-APPLE-NEXT:  @ %bb.2:
296 ; CHECK-APPLE-NEXT:    .data_region
297 ; CHECK-APPLE-NEXT:  LCPI3_0:
298 ; CHECK-APPLE-NEXT:    .long 0x00000000 @ float 0
299 ; CHECK-APPLE-NEXT:    .end_data_region
301 ; CHECK-O0-LABEL: foo_if:
302 ; CHECK-O0:       @ %bb.0: @ %entry
303 ; CHECK-O0-NEXT:    push {r7, lr}
304 ; CHECK-O0-NEXT:    mov r7, sp
305 ; CHECK-O0-NEXT:    sub sp, sp, #4
306 ; CHECK-O0-NEXT:    str r8, [sp] @ 4-byte Spill
307 ; CHECK-O0-NEXT:    cmp r0, #0
308 ; CHECK-O0-NEXT:    beq LBB3_2
309 ; CHECK-O0-NEXT:  @ %bb.1: @ %gen_error
310 ; CHECK-O0-NEXT:    mov r0, #16
311 ; CHECK-O0-NEXT:    mov r1, #0
312 ; CHECK-O0-NEXT:    bl _malloc
313 ; CHECK-O0-NEXT:    mov r1, r0
314 ; CHECK-O0-NEXT:    mov r8, r1
315 ; CHECK-O0-NEXT:    mov r0, #1
316 ; CHECK-O0-NEXT:    strb r0, [r1, #8]
317 ; CHECK-O0-NEXT:    mov r0, #1065353216
318 ; CHECK-O0-NEXT:    mov sp, r7
319 ; CHECK-O0-NEXT:    pop {r7, pc}
320 ; CHECK-O0-NEXT:  LBB3_2: @ %normal
321 ; CHECK-O0-NEXT:    ldr r8, [sp] @ 4-byte Reload
322 ; CHECK-O0-NEXT:    mov r0, #0
323 ; CHECK-O0-NEXT:    mov sp, r7
324 ; CHECK-O0-NEXT:    pop {r7, pc}
326 ; CHECK-ANDROID-LABEL: foo_if:
327 ; CHECK-ANDROID:       @ %bb.0: @ %entry
328 ; CHECK-ANDROID-NEXT:    cmp r0, #0
329 ; CHECK-ANDROID-NEXT:    vldreq s0, .LCPI3_0
330 ; CHECK-ANDROID-NEXT:    vmoveq r0, s0
331 ; CHECK-ANDROID-NEXT:    bxeq lr
332 ; CHECK-ANDROID-NEXT:  .LBB3_1: @ %gen_error
333 ; CHECK-ANDROID-NEXT:    .save {r11, lr}
334 ; CHECK-ANDROID-NEXT:    push {r11, lr}
335 ; CHECK-ANDROID-NEXT:    mov r0, #16
336 ; CHECK-ANDROID-NEXT:    mov r1, #0
337 ; CHECK-ANDROID-NEXT:    bl malloc
338 ; CHECK-ANDROID-NEXT:    mov r8, r0
339 ; CHECK-ANDROID-NEXT:    mov r0, #1
340 ; CHECK-ANDROID-NEXT:    vmov.f32 s0, #1.000000e+00
341 ; CHECK-ANDROID-NEXT:    strb r0, [r8, #8]
342 ; CHECK-ANDROID-NEXT:    pop {r11, lr}
343 ; CHECK-ANDROID-NEXT:    vmov r0, s0
344 ; CHECK-ANDROID-NEXT:    bx lr
345 ; CHECK-ANDROID-NEXT:    .p2align 2
346 ; CHECK-ANDROID-NEXT:  @ %bb.2:
347 ; CHECK-ANDROID-NEXT:  .LCPI3_0:
348 ; CHECK-ANDROID-NEXT:    .long 0x00000000 @ float 0
350 ; spill to stack
351 ; reload from stack
352 entry:
353   %cond = icmp ne i32 %cc, 0
354   br i1 %cond, label %gen_error, label %normal
356 gen_error:
357   %call = call ptr @malloc(i64 16)
358   store ptr %call, ptr %error_ptr_ref
359   %tmp = getelementptr inbounds i8, ptr %call, i64 8
360   store i8 1, ptr %tmp
361   ret float 1.0
363 normal:
364   ret float 0.0
367 ; "foo_loop" is a function that takes a swifterror parameter, it sets swifterror
368 ; under a certain condition inside a loop.
369 define float @foo_loop(ptr swifterror %error_ptr_ref, i32 %cc, float %cc2) {
370 ; CHECK-APPLE-LABEL: foo_loop:
371 ; CHECK-APPLE:       @ %bb.0: @ %entry
372 ; CHECK-APPLE-NEXT:    push {r4, r5, lr}
373 ; CHECK-APPLE-NEXT:    vpush {d8, d9}
374 ; CHECK-APPLE-NEXT:    vmov.f32 s18, #1.000000e+00
375 ; CHECK-APPLE-NEXT:    mov r4, r0
376 ; CHECK-APPLE-NEXT:    vmov s16, r1
377 ; CHECK-APPLE-NEXT:    mov r5, #1
378 ; CHECK-APPLE-NEXT:    b LBB4_2
379 ; CHECK-APPLE-NEXT:  LBB4_1: @ %bb_cont
380 ; CHECK-APPLE-NEXT:    @ in Loop: Header=BB4_2 Depth=1
381 ; CHECK-APPLE-NEXT:    vcmp.f32 s16, s18
382 ; CHECK-APPLE-NEXT:    vmrs APSR_nzcv, fpscr
383 ; CHECK-APPLE-NEXT:    bgt LBB4_4
384 ; CHECK-APPLE-NEXT:  LBB4_2: @ %bb_loop
385 ; CHECK-APPLE-NEXT:    @ =>This Inner Loop Header: Depth=1
386 ; CHECK-APPLE-NEXT:    cmp r4, #0
387 ; CHECK-APPLE-NEXT:    beq LBB4_1
388 ; CHECK-APPLE-NEXT:  @ %bb.3: @ %gen_error
389 ; CHECK-APPLE-NEXT:    @ in Loop: Header=BB4_2 Depth=1
390 ; CHECK-APPLE-NEXT:    mov r0, #16
391 ; CHECK-APPLE-NEXT:    mov r1, #0
392 ; CHECK-APPLE-NEXT:    bl _malloc
393 ; CHECK-APPLE-NEXT:    mov r8, r0
394 ; CHECK-APPLE-NEXT:    strb r5, [r0, #8]
395 ; CHECK-APPLE-NEXT:    b LBB4_1
396 ; CHECK-APPLE-NEXT:  LBB4_4: @ %bb_end
397 ; CHECK-APPLE-NEXT:    mov r0, #0
398 ; CHECK-APPLE-NEXT:    vpop {d8, d9}
399 ; CHECK-APPLE-NEXT:    pop {r4, r5, pc}
401 ; CHECK-O0-LABEL: foo_loop:
402 ; CHECK-O0:       @ %bb.0: @ %entry
403 ; CHECK-O0-NEXT:    push {r7, lr}
404 ; CHECK-O0-NEXT:    mov r7, sp
405 ; CHECK-O0-NEXT:    sub sp, sp, #20
406 ; CHECK-O0-NEXT:    str r0, [sp, #8] @ 4-byte Spill
407 ; CHECK-O0-NEXT:    vmov s0, r1
408 ; CHECK-O0-NEXT:    vstr s0, [r7, #-8] @ 4-byte Spill
409 ; CHECK-O0-NEXT:    str r8, [r7, #-4] @ 4-byte Spill
410 ; CHECK-O0-NEXT:    b LBB4_1
411 ; CHECK-O0-NEXT:  LBB4_1: @ %bb_loop
412 ; CHECK-O0-NEXT:    @ =>This Inner Loop Header: Depth=1
413 ; CHECK-O0-NEXT:    ldr r1, [sp, #8] @ 4-byte Reload
414 ; CHECK-O0-NEXT:    ldr r0, [r7, #-4] @ 4-byte Reload
415 ; CHECK-O0-NEXT:    cmp r1, #0
416 ; CHECK-O0-NEXT:    str r0, [sp, #4] @ 4-byte Spill
417 ; CHECK-O0-NEXT:    beq LBB4_3
418 ; CHECK-O0-NEXT:  @ %bb.2: @ %gen_error
419 ; CHECK-O0-NEXT:    @ in Loop: Header=BB4_1 Depth=1
420 ; CHECK-O0-NEXT:    mov r0, #16
421 ; CHECK-O0-NEXT:    mov r1, #0
422 ; CHECK-O0-NEXT:    bl _malloc
423 ; CHECK-O0-NEXT:    mov r2, r0
424 ; CHECK-O0-NEXT:    movw r1, #1
425 ; CHECK-O0-NEXT:    strb r1, [r2, #8]
426 ; CHECK-O0-NEXT:    str r0, [sp, #4] @ 4-byte Spill
427 ; CHECK-O0-NEXT:  LBB4_3: @ %bb_cont
428 ; CHECK-O0-NEXT:    @ in Loop: Header=BB4_1 Depth=1
429 ; CHECK-O0-NEXT:    vldr s0, [r7, #-8] @ 4-byte Reload
430 ; CHECK-O0-NEXT:    ldr r0, [sp, #4] @ 4-byte Reload
431 ; CHECK-O0-NEXT:    str r0, [sp] @ 4-byte Spill
432 ; CHECK-O0-NEXT:    vmov.f32 s2, #1.000000e+00
433 ; CHECK-O0-NEXT:    vcmp.f32 s0, s2
434 ; CHECK-O0-NEXT:    vmrs APSR_nzcv, fpscr
435 ; CHECK-O0-NEXT:    str r0, [r7, #-4] @ 4-byte Spill
436 ; CHECK-O0-NEXT:    ble LBB4_1
437 ; CHECK-O0-NEXT:  @ %bb.4: @ %bb_end
438 ; CHECK-O0-NEXT:    ldr r8, [sp] @ 4-byte Reload
439 ; CHECK-O0-NEXT:    mov r0, #0
440 ; CHECK-O0-NEXT:    mov sp, r7
441 ; CHECK-O0-NEXT:    pop {r7, pc}
443 ; CHECK-ANDROID-LABEL: foo_loop:
444 ; CHECK-ANDROID:       @ %bb.0: @ %entry
445 ; CHECK-ANDROID-NEXT:    .save {r4, r5, r11, lr}
446 ; CHECK-ANDROID-NEXT:    push {r4, r5, r11, lr}
447 ; CHECK-ANDROID-NEXT:    .vsave {d8, d9}
448 ; CHECK-ANDROID-NEXT:    vpush {d8, d9}
449 ; CHECK-ANDROID-NEXT:    vmov.f32 s18, #1.000000e+00
450 ; CHECK-ANDROID-NEXT:    mov r4, r0
451 ; CHECK-ANDROID-NEXT:    vmov s16, r1
452 ; CHECK-ANDROID-NEXT:    mov r5, #1
453 ; CHECK-ANDROID-NEXT:    b .LBB4_2
454 ; CHECK-ANDROID-NEXT:  .LBB4_1: @ %bb_cont
455 ; CHECK-ANDROID-NEXT:    @ in Loop: Header=BB4_2 Depth=1
456 ; CHECK-ANDROID-NEXT:    vcmp.f32 s16, s18
457 ; CHECK-ANDROID-NEXT:    vmrs APSR_nzcv, fpscr
458 ; CHECK-ANDROID-NEXT:    bgt .LBB4_4
459 ; CHECK-ANDROID-NEXT:  .LBB4_2: @ %bb_loop
460 ; CHECK-ANDROID-NEXT:    @ =>This Inner Loop Header: Depth=1
461 ; CHECK-ANDROID-NEXT:    cmp r4, #0
462 ; CHECK-ANDROID-NEXT:    beq .LBB4_1
463 ; CHECK-ANDROID-NEXT:  @ %bb.3: @ %gen_error
464 ; CHECK-ANDROID-NEXT:    @ in Loop: Header=BB4_2 Depth=1
465 ; CHECK-ANDROID-NEXT:    mov r0, #16
466 ; CHECK-ANDROID-NEXT:    mov r1, #0
467 ; CHECK-ANDROID-NEXT:    bl malloc
468 ; CHECK-ANDROID-NEXT:    mov r8, r0
469 ; CHECK-ANDROID-NEXT:    strb r5, [r0, #8]
470 ; CHECK-ANDROID-NEXT:    b .LBB4_1
471 ; CHECK-ANDROID-NEXT:  .LBB4_4: @ %bb_end
472 ; CHECK-ANDROID-NEXT:    mov r0, #0
473 ; CHECK-ANDROID-NEXT:    vpop {d8, d9}
474 ; CHECK-ANDROID-NEXT:    pop {r4, r5, r11, pc}
475 ; swifterror is kept in a register
477 ; spill r0
478 ; reload from stack
479 entry:
480   br label %bb_loop
482 bb_loop:
483   %cond = icmp ne i32 %cc, 0
484   br i1 %cond, label %gen_error, label %bb_cont
486 gen_error:
487   %call = call ptr @malloc(i64 16)
488   store ptr %call, ptr %error_ptr_ref
489   %tmp = getelementptr inbounds i8, ptr %call, i64 8
490   store i8 1, ptr %tmp
491   br label %bb_cont
493 bb_cont:
494   %cmp = fcmp ogt float %cc2, 1.000000e+00
495   br i1 %cmp, label %bb_end, label %bb_loop
496 bb_end:
497   ret float 0.0
500 ; "foo_sret" is a function that takes a swifterror parameter, it also has a sret
501 ; parameter.
502 define void @foo_sret(ptr sret(%struct.S) %agg.result, i32 %val1, ptr swifterror %error_ptr_ref) {
503 ; CHECK-APPLE-LABEL: foo_sret:
504 ; CHECK-APPLE:       @ %bb.0: @ %entry
505 ; CHECK-APPLE-NEXT:    push {r4, r5, lr}
506 ; CHECK-APPLE-NEXT:    mov r4, r1
507 ; CHECK-APPLE-NEXT:    mov r5, r0
508 ; CHECK-APPLE-NEXT:    mov r0, #16
509 ; CHECK-APPLE-NEXT:    mov r1, #0
510 ; CHECK-APPLE-NEXT:    bl _malloc
511 ; CHECK-APPLE-NEXT:    mov r1, #1
512 ; CHECK-APPLE-NEXT:    mov r8, r0
513 ; CHECK-APPLE-NEXT:    strb r1, [r0, #8]
514 ; CHECK-APPLE-NEXT:    str r4, [r5, #4]
515 ; CHECK-APPLE-NEXT:    pop {r4, r5, pc}
517 ; CHECK-O0-LABEL: foo_sret:
518 ; CHECK-O0:       @ %bb.0: @ %entry
519 ; CHECK-O0-NEXT:    push {r7, lr}
520 ; CHECK-O0-NEXT:    mov r7, sp
521 ; CHECK-O0-NEXT:    sub sp, sp, #8
522 ; CHECK-O0-NEXT:    str r1, [sp] @ 4-byte Spill
523 ; CHECK-O0-NEXT:    str r0, [sp, #4] @ 4-byte Spill
524 ; CHECK-O0-NEXT:    mov r0, #16
525 ; CHECK-O0-NEXT:    mov r1, #0
526 ; CHECK-O0-NEXT:    bl _malloc
527 ; CHECK-O0-NEXT:    ldr r1, [sp] @ 4-byte Reload
528 ; CHECK-O0-NEXT:    mov r3, r0
529 ; CHECK-O0-NEXT:    ldr r0, [sp, #4] @ 4-byte Reload
530 ; CHECK-O0-NEXT:    mov r8, r3
531 ; CHECK-O0-NEXT:    mov r2, #1
532 ; CHECK-O0-NEXT:    strb r2, [r3, #8]
533 ; CHECK-O0-NEXT:    str r1, [r0, #4]
534 ; CHECK-O0-NEXT:    mov sp, r7
535 ; CHECK-O0-NEXT:    pop {r7, pc}
537 ; CHECK-ANDROID-LABEL: foo_sret:
538 ; CHECK-ANDROID:       @ %bb.0: @ %entry
539 ; CHECK-ANDROID-NEXT:    .save {r4, r5, r11, lr}
540 ; CHECK-ANDROID-NEXT:    push {r4, r5, r11, lr}
541 ; CHECK-ANDROID-NEXT:    mov r4, r1
542 ; CHECK-ANDROID-NEXT:    mov r5, r0
543 ; CHECK-ANDROID-NEXT:    mov r0, #16
544 ; CHECK-ANDROID-NEXT:    mov r1, #0
545 ; CHECK-ANDROID-NEXT:    bl malloc
546 ; CHECK-ANDROID-NEXT:    mov r1, #1
547 ; CHECK-ANDROID-NEXT:    mov r8, r0
548 ; CHECK-ANDROID-NEXT:    strb r1, [r0, #8]
549 ; CHECK-ANDROID-NEXT:    str r4, [r5, #4]
550 ; CHECK-ANDROID-NEXT:    pop {r4, r5, r11, pc}
552 ; spill to stack: sret and val1
553 ; reload from stack: sret and val1
554 entry:
555   %call = call ptr @malloc(i64 16)
556   store ptr %call, ptr %error_ptr_ref
557   %tmp = getelementptr inbounds i8, ptr %call, i64 8
558   store i8 1, ptr %tmp
559   %v2 = getelementptr inbounds %struct.S, ptr %agg.result, i32 0, i32 1
560   store i32 %val1, ptr %v2
561   ret void
564 ; "caller3" calls "foo_sret" that takes a swifterror parameter.
565 define float @caller3(ptr %error_ref) {
566 ; CHECK-APPLE-LABEL: caller3:
567 ; CHECK-APPLE:       @ %bb.0: @ %entry
568 ; CHECK-APPLE-NEXT:    push {r4, r7, r8, lr}
569 ; CHECK-APPLE-NEXT:    add r7, sp, #8
570 ; CHECK-APPLE-NEXT:    sub sp, sp, #32
571 ; CHECK-APPLE-NEXT:    bfc sp, #0, #3
572 ; CHECK-APPLE-NEXT:    mov r4, r0
573 ; CHECK-APPLE-NEXT:    add r0, sp, #8
574 ; CHECK-APPLE-NEXT:    mov r1, #1
575 ; CHECK-APPLE-NEXT:    mov r8, #0
576 ; CHECK-APPLE-NEXT:    bl _foo_sret
577 ; CHECK-APPLE-NEXT:    mov r0, r8
578 ; CHECK-APPLE-NEXT:    cmp r8, #0
579 ; CHECK-APPLE-NEXT:    ldrbeq r1, [r0, #8]
580 ; CHECK-APPLE-NEXT:    strbeq r1, [r4]
581 ; CHECK-APPLE-NEXT:    bl _free
582 ; CHECK-APPLE-NEXT:    mov r0, #1065353216
583 ; CHECK-APPLE-NEXT:    sub sp, r7, #8
584 ; CHECK-APPLE-NEXT:    pop {r4, r7, r8, pc}
586 ; CHECK-O0-LABEL: caller3:
587 ; CHECK-O0:       @ %bb.0: @ %entry
588 ; CHECK-O0-NEXT:    push {r7, lr}
589 ; CHECK-O0-NEXT:    mov r7, sp
590 ; CHECK-O0-NEXT:    push {r8}
591 ; CHECK-O0-NEXT:    sub sp, sp, #44
592 ; CHECK-O0-NEXT:    bfc sp, #0, #3
593 ; CHECK-O0-NEXT:    @ implicit-def: $r1
594 ; CHECK-O0-NEXT:    str r0, [sp, #4] @ 4-byte Spill
595 ; CHECK-O0-NEXT:    mov r8, #0
596 ; CHECK-O0-NEXT:    add r0, sp, #16
597 ; CHECK-O0-NEXT:    mov r1, #1
598 ; CHECK-O0-NEXT:    bl _foo_sret
599 ; CHECK-O0-NEXT:    str r8, [sp, #8] @ 4-byte Spill
600 ; CHECK-O0-NEXT:    movw r0, #0
601 ; CHECK-O0-NEXT:    cmp r8, r0
602 ; CHECK-O0-NEXT:    bne LBB6_2
603 ; CHECK-O0-NEXT:  @ %bb.1: @ %cont
604 ; CHECK-O0-NEXT:    ldr r1, [sp, #4] @ 4-byte Reload
605 ; CHECK-O0-NEXT:    ldr r0, [sp, #8] @ 4-byte Reload
606 ; CHECK-O0-NEXT:    ldrb r0, [r0, #8]
607 ; CHECK-O0-NEXT:    strb r0, [r1]
608 ; CHECK-O0-NEXT:  LBB6_2: @ %handler
609 ; CHECK-O0-NEXT:    ldr r0, [sp, #8] @ 4-byte Reload
610 ; CHECK-O0-NEXT:    bl _free
611 ; CHECK-O0-NEXT:    mov r0, #1065353216
612 ; CHECK-O0-NEXT:    sub sp, r7, #4
613 ; CHECK-O0-NEXT:    pop {r8}
614 ; CHECK-O0-NEXT:    pop {r7, pc}
616 ; CHECK-ANDROID-LABEL: caller3:
617 ; CHECK-ANDROID:       @ %bb.0: @ %entry
618 ; CHECK-ANDROID-NEXT:    .save {r4, r8, r11, lr}
619 ; CHECK-ANDROID-NEXT:    push {r4, r8, r11, lr}
620 ; CHECK-ANDROID-NEXT:    .pad #32
621 ; CHECK-ANDROID-NEXT:    sub sp, sp, #32
622 ; CHECK-ANDROID-NEXT:    mov r4, r0
623 ; CHECK-ANDROID-NEXT:    add r0, sp, #8
624 ; CHECK-ANDROID-NEXT:    mov r1, #1
625 ; CHECK-ANDROID-NEXT:    mov r8, #0
626 ; CHECK-ANDROID-NEXT:    bl foo_sret
627 ; CHECK-ANDROID-NEXT:    mov r0, r8
628 ; CHECK-ANDROID-NEXT:    cmp r8, #0
629 ; CHECK-ANDROID-NEXT:    ldrbeq r1, [r0, #8]
630 ; CHECK-ANDROID-NEXT:    strbeq r1, [r4]
631 ; CHECK-ANDROID-NEXT:    bl free
632 ; CHECK-ANDROID-NEXT:    mov r0, #1065353216
633 ; CHECK-ANDROID-NEXT:    add sp, sp, #32
634 ; CHECK-ANDROID-NEXT:    pop {r4, r8, r11, pc}
635 ; Access part of the error object and save it to error_ref
637 ; Access part of the error object and save it to error_ref
638 entry:
639   %s = alloca %struct.S, align 8
640   %error_ptr_ref = alloca swifterror ptr
641   store ptr null, ptr %error_ptr_ref
642   call void @foo_sret(ptr sret(%struct.S) %s, i32 1, ptr swifterror %error_ptr_ref)
643   %error_from_foo = load ptr, ptr %error_ptr_ref
644   %had_error_from_foo = icmp ne ptr %error_from_foo, null
645   br i1 %had_error_from_foo, label %handler, label %cont
646 cont:
647   %v1 = getelementptr inbounds %swift_error, ptr %error_from_foo, i64 0, i32 1
648   %t = load i8, ptr %v1
649   store i8 %t, ptr %error_ref
650   br label %handler
651 handler:
652   call void @free(ptr %error_from_foo)
653   ret float 1.0
656 ; "foo_vararg" is a function that takes a swifterror parameter, it also has
657 ; variable number of arguments.
658 declare void @llvm.va_start(ptr) nounwind
659 define float @foo_vararg(ptr swifterror %error_ptr_ref, ...) {
660 ; CHECK-APPLE-LABEL: foo_vararg:
661 ; CHECK-APPLE:       @ %bb.0: @ %entry
662 ; CHECK-APPLE-NEXT:    sub sp, sp, #16
663 ; CHECK-APPLE-NEXT:    push {r7, lr}
664 ; CHECK-APPLE-NEXT:    mov r7, sp
665 ; CHECK-APPLE-NEXT:    sub sp, sp, #24
666 ; CHECK-APPLE-NEXT:    bfc sp, #0, #3
667 ; CHECK-APPLE-NEXT:    add r8, r7, #8
668 ; CHECK-APPLE-NEXT:    stm r8, {r0, r1, r2, r3}
669 ; CHECK-APPLE-NEXT:    mov r0, #16
670 ; CHECK-APPLE-NEXT:    mov r1, #0
671 ; CHECK-APPLE-NEXT:    bl _malloc
672 ; CHECK-APPLE-NEXT:    mov r8, r0
673 ; CHECK-APPLE-NEXT:    mov r0, #1
674 ; CHECK-APPLE-NEXT:    strb r0, [r8, #8]
675 ; CHECK-APPLE-NEXT:    add r0, r7, #8
676 ; CHECK-APPLE-NEXT:    add r0, r0, #4
677 ; CHECK-APPLE-NEXT:    ldr r2, [r7, #8]
678 ; CHECK-APPLE-NEXT:    ldr r1, [r0], #4
679 ; CHECK-APPLE-NEXT:    ldr r3, [r0], #4
680 ; CHECK-APPLE-NEXT:    str r0, [sp, #16]
681 ; CHECK-APPLE-NEXT:    mov r0, #1065353216
682 ; CHECK-APPLE-NEXT:    str r2, [sp, #12]
683 ; CHECK-APPLE-NEXT:    str r1, [sp, #8]
684 ; CHECK-APPLE-NEXT:    str r3, [sp, #4]
685 ; CHECK-APPLE-NEXT:    mov sp, r7
686 ; CHECK-APPLE-NEXT:    pop {r7, lr}
687 ; CHECK-APPLE-NEXT:    add sp, sp, #16
688 ; CHECK-APPLE-NEXT:    bx lr
690 ; CHECK-O0-LABEL: foo_vararg:
691 ; CHECK-O0:       @ %bb.0: @ %entry
692 ; CHECK-O0-NEXT:    sub sp, sp, #16
693 ; CHECK-O0-NEXT:    push {r7, lr}
694 ; CHECK-O0-NEXT:    mov r7, sp
695 ; CHECK-O0-NEXT:    sub sp, sp, #24
696 ; CHECK-O0-NEXT:    bfc sp, #0, #3
697 ; CHECK-O0-NEXT:    str r3, [r7, #20]
698 ; CHECK-O0-NEXT:    str r2, [r7, #16]
699 ; CHECK-O0-NEXT:    str r1, [r7, #12]
700 ; CHECK-O0-NEXT:    str r0, [r7, #8]
701 ; CHECK-O0-NEXT:    mov r0, #16
702 ; CHECK-O0-NEXT:    mov r1, #0
703 ; CHECK-O0-NEXT:    bl _malloc
704 ; CHECK-O0-NEXT:    mov r1, r0
705 ; CHECK-O0-NEXT:    mov r8, r1
706 ; CHECK-O0-NEXT:    mov r0, #1
707 ; CHECK-O0-NEXT:    strb r0, [r1, #8]
708 ; CHECK-O0-NEXT:    add r0, r7, #8
709 ; CHECK-O0-NEXT:    str r0, [sp, #16]
710 ; CHECK-O0-NEXT:    ldr r0, [sp, #16]
711 ; CHECK-O0-NEXT:    add r1, r0, #4
712 ; CHECK-O0-NEXT:    str r1, [sp, #16]
713 ; CHECK-O0-NEXT:    ldr r0, [r0]
714 ; CHECK-O0-NEXT:    str r0, [sp, #12]
715 ; CHECK-O0-NEXT:    ldr r0, [sp, #16]
716 ; CHECK-O0-NEXT:    add r1, r0, #4
717 ; CHECK-O0-NEXT:    str r1, [sp, #16]
718 ; CHECK-O0-NEXT:    ldr r0, [r0]
719 ; CHECK-O0-NEXT:    str r0, [sp, #8]
720 ; CHECK-O0-NEXT:    ldr r0, [sp, #16]
721 ; CHECK-O0-NEXT:    add r1, r0, #4
722 ; CHECK-O0-NEXT:    str r1, [sp, #16]
723 ; CHECK-O0-NEXT:    ldr r0, [r0]
724 ; CHECK-O0-NEXT:    str r0, [sp, #4]
725 ; CHECK-O0-NEXT:    mov r0, #1065353216
726 ; CHECK-O0-NEXT:    mov sp, r7
727 ; CHECK-O0-NEXT:    pop {r7, lr}
728 ; CHECK-O0-NEXT:    add sp, sp, #16
729 ; CHECK-O0-NEXT:    bx lr
731 ; CHECK-ANDROID-LABEL: foo_vararg:
732 ; CHECK-ANDROID:       @ %bb.0: @ %entry
733 ; CHECK-ANDROID-NEXT:    .pad #16
734 ; CHECK-ANDROID-NEXT:    sub sp, sp, #16
735 ; CHECK-ANDROID-NEXT:    .save {r11, lr}
736 ; CHECK-ANDROID-NEXT:    push {r11, lr}
737 ; CHECK-ANDROID-NEXT:    .pad #24
738 ; CHECK-ANDROID-NEXT:    sub sp, sp, #24
739 ; CHECK-ANDROID-NEXT:    add r8, sp, #32
740 ; CHECK-ANDROID-NEXT:    stm r8, {r0, r1, r2, r3}
741 ; CHECK-ANDROID-NEXT:    mov r0, #16
742 ; CHECK-ANDROID-NEXT:    mov r1, #0
743 ; CHECK-ANDROID-NEXT:    bl malloc
744 ; CHECK-ANDROID-NEXT:    mov r8, r0
745 ; CHECK-ANDROID-NEXT:    mov r0, #1
746 ; CHECK-ANDROID-NEXT:    strb r0, [r8, #8]
747 ; CHECK-ANDROID-NEXT:    add r0, sp, #32
748 ; CHECK-ANDROID-NEXT:    orr r0, r0, #4
749 ; CHECK-ANDROID-NEXT:    ldr r2, [sp, #32]
750 ; CHECK-ANDROID-NEXT:    ldr r1, [r0], #4
751 ; CHECK-ANDROID-NEXT:    ldr r3, [r0], #4
752 ; CHECK-ANDROID-NEXT:    str r0, [sp, #16]
753 ; CHECK-ANDROID-NEXT:    mov r0, #1065353216
754 ; CHECK-ANDROID-NEXT:    str r2, [sp, #12]
755 ; CHECK-ANDROID-NEXT:    str r1, [sp, #8]
756 ; CHECK-ANDROID-NEXT:    str r3, [sp, #4]
757 ; CHECK-ANDROID-NEXT:    add sp, sp, #24
758 ; CHECK-ANDROID-NEXT:    pop {r11, lr}
759 ; CHECK-ANDROID-NEXT:    add sp, sp, #16
760 ; CHECK-ANDROID-NEXT:    bx lr
762 entry:
763   %call = call ptr @malloc(i64 16)
764   store ptr %call, ptr %error_ptr_ref
765   %tmp = getelementptr inbounds i8, ptr %call, i64 8
766   store i8 1, ptr %tmp
768   %args = alloca ptr, align 8
769   %a10 = alloca i32, align 4
770   %a11 = alloca i32, align 4
771   %a12 = alloca i32, align 4
772   call void @llvm.va_start(ptr %args)
773   %v11 = va_arg ptr %args, i32
774   store i32 %v11, ptr %a10, align 4
775   %v12 = va_arg ptr %args, i32
776   store i32 %v12, ptr %a11, align 4
777   %v13 = va_arg ptr %args, i32
778   store i32 %v13, ptr %a12, align 4
780   ret float 1.0
783 ; "caller4" calls "foo_vararg" that takes a swifterror parameter.
784 define float @caller4(ptr %error_ref) {
785 ; CHECK-APPLE-LABEL: caller4:
786 ; CHECK-APPLE:       @ %bb.0: @ %entry
787 ; CHECK-APPLE-NEXT:    push {r4, r8, lr}
788 ; CHECK-APPLE-NEXT:    sub sp, sp, #16
789 ; CHECK-APPLE-NEXT:    mov r4, r0
790 ; CHECK-APPLE-NEXT:    mov r0, #11
791 ; CHECK-APPLE-NEXT:    str r0, [sp, #4]
792 ; CHECK-APPLE-NEXT:    mov r0, #10
793 ; CHECK-APPLE-NEXT:    str r0, [sp, #8]
794 ; CHECK-APPLE-NEXT:    mov r0, #12
795 ; CHECK-APPLE-NEXT:    str r0, [sp]
796 ; CHECK-APPLE-NEXT:    mov r8, #0
797 ; CHECK-APPLE-NEXT:    mov r0, #10
798 ; CHECK-APPLE-NEXT:    mov r1, #11
799 ; CHECK-APPLE-NEXT:    mov r2, #12
800 ; CHECK-APPLE-NEXT:    bl _foo_vararg
801 ; CHECK-APPLE-NEXT:    mov r0, r8
802 ; CHECK-APPLE-NEXT:    cmp r8, #0
803 ; CHECK-APPLE-NEXT:    ldrbeq r1, [r0, #8]
804 ; CHECK-APPLE-NEXT:    strbeq r1, [r4]
805 ; CHECK-APPLE-NEXT:    bl _free
806 ; CHECK-APPLE-NEXT:    mov r0, #1065353216
807 ; CHECK-APPLE-NEXT:    add sp, sp, #16
808 ; CHECK-APPLE-NEXT:    pop {r4, r8, pc}
810 ; CHECK-O0-LABEL: caller4:
811 ; CHECK-O0:       @ %bb.0: @ %entry
812 ; CHECK-O0-NEXT:    push {r7, lr}
813 ; CHECK-O0-NEXT:    mov r7, sp
814 ; CHECK-O0-NEXT:    push {r8}
815 ; CHECK-O0-NEXT:    sub sp, sp, #24
816 ; CHECK-O0-NEXT:    @ implicit-def: $r1
817 ; CHECK-O0-NEXT:    str r0, [sp] @ 4-byte Spill
818 ; CHECK-O0-NEXT:    mov r8, #0
819 ; CHECK-O0-NEXT:    mov r0, #10
820 ; CHECK-O0-NEXT:    str r0, [r7, #-12]
821 ; CHECK-O0-NEXT:    mov r0, #11
822 ; CHECK-O0-NEXT:    str r0, [sp, #12]
823 ; CHECK-O0-NEXT:    mov r0, #12
824 ; CHECK-O0-NEXT:    str r0, [sp, #8]
825 ; CHECK-O0-NEXT:    ldr r0, [r7, #-12]
826 ; CHECK-O0-NEXT:    ldr r1, [sp, #12]
827 ; CHECK-O0-NEXT:    ldr r2, [sp, #8]
828 ; CHECK-O0-NEXT:    bl _foo_vararg
829 ; CHECK-O0-NEXT:    str r8, [sp, #4] @ 4-byte Spill
830 ; CHECK-O0-NEXT:    movw r0, #0
831 ; CHECK-O0-NEXT:    cmp r8, r0
832 ; CHECK-O0-NEXT:    bne LBB8_2
833 ; CHECK-O0-NEXT:  @ %bb.1: @ %cont
834 ; CHECK-O0-NEXT:    ldr r1, [sp] @ 4-byte Reload
835 ; CHECK-O0-NEXT:    ldr r0, [sp, #4] @ 4-byte Reload
836 ; CHECK-O0-NEXT:    ldrb r0, [r0, #8]
837 ; CHECK-O0-NEXT:    strb r0, [r1]
838 ; CHECK-O0-NEXT:  LBB8_2: @ %handler
839 ; CHECK-O0-NEXT:    ldr r0, [sp, #4] @ 4-byte Reload
840 ; CHECK-O0-NEXT:    bl _free
841 ; CHECK-O0-NEXT:    mov r0, #1065353216
842 ; CHECK-O0-NEXT:    sub sp, r7, #4
843 ; CHECK-O0-NEXT:    pop {r8}
844 ; CHECK-O0-NEXT:    pop {r7, pc}
846 ; CHECK-ANDROID-LABEL: caller4:
847 ; CHECK-ANDROID:       @ %bb.0: @ %entry
848 ; CHECK-ANDROID-NEXT:    .save {r4, r8, r11, lr}
849 ; CHECK-ANDROID-NEXT:    push {r4, r8, r11, lr}
850 ; CHECK-ANDROID-NEXT:    .pad #16
851 ; CHECK-ANDROID-NEXT:    sub sp, sp, #16
852 ; CHECK-ANDROID-NEXT:    mov r4, r0
853 ; CHECK-ANDROID-NEXT:    mov r0, #11
854 ; CHECK-ANDROID-NEXT:    str r0, [sp, #4]
855 ; CHECK-ANDROID-NEXT:    mov r0, #10
856 ; CHECK-ANDROID-NEXT:    str r0, [sp, #8]
857 ; CHECK-ANDROID-NEXT:    mov r0, #12
858 ; CHECK-ANDROID-NEXT:    str r0, [sp]
859 ; CHECK-ANDROID-NEXT:    mov r8, #0
860 ; CHECK-ANDROID-NEXT:    mov r0, #10
861 ; CHECK-ANDROID-NEXT:    mov r1, #11
862 ; CHECK-ANDROID-NEXT:    mov r2, #12
863 ; CHECK-ANDROID-NEXT:    bl foo_vararg
864 ; CHECK-ANDROID-NEXT:    mov r0, r8
865 ; CHECK-ANDROID-NEXT:    cmp r8, #0
866 ; CHECK-ANDROID-NEXT:    ldrbeq r1, [r0, #8]
867 ; CHECK-ANDROID-NEXT:    strbeq r1, [r4]
868 ; CHECK-ANDROID-NEXT:    bl free
869 ; CHECK-ANDROID-NEXT:    mov r0, #1065353216
870 ; CHECK-ANDROID-NEXT:    add sp, sp, #16
871 ; CHECK-ANDROID-NEXT:    pop {r4, r8, r11, pc}
872 ; Access part of the error object and save it to error_ref
873 entry:
874   %error_ptr_ref = alloca swifterror ptr
875   store ptr null, ptr %error_ptr_ref
877   %a10 = alloca i32, align 4
878   %a11 = alloca i32, align 4
879   %a12 = alloca i32, align 4
880   store i32 10, ptr %a10, align 4
881   store i32 11, ptr %a11, align 4
882   store i32 12, ptr %a12, align 4
883   %v10 = load i32, ptr %a10, align 4
884   %v11 = load i32, ptr %a11, align 4
885   %v12 = load i32, ptr %a12, align 4
887   %call = call float (ptr, ...) @foo_vararg(ptr swifterror %error_ptr_ref, i32 %v10, i32 %v11, i32 %v12)
888   %error_from_foo = load ptr, ptr %error_ptr_ref
889   %had_error_from_foo = icmp ne ptr %error_from_foo, null
890   br i1 %had_error_from_foo, label %handler, label %cont
892 cont:
893   %v1 = getelementptr inbounds %swift_error, ptr %error_from_foo, i64 0, i32 1
894   %t = load i8, ptr %v1
895   store i8 %t, ptr %error_ref
896   br label %handler
897 handler:
898   call void @free(ptr %error_from_foo)
899   ret float 1.0
902 ; Check that we don't blow up on tail calling swifterror argument functions.
903 define float @tailcallswifterror(ptr swifterror %error_ptr_ref) {
904 ; CHECK-APPLE-LABEL: tailcallswifterror:
905 ; CHECK-APPLE:       @ %bb.0: @ %entry
906 ; CHECK-APPLE-NEXT:    push {lr}
907 ; CHECK-APPLE-NEXT:    bl _tailcallswifterror
908 ; CHECK-APPLE-NEXT:    pop {lr}
909 ; CHECK-APPLE-NEXT:    bx lr
911 ; CHECK-O0-LABEL: tailcallswifterror:
912 ; CHECK-O0:       @ %bb.0: @ %entry
913 ; CHECK-O0-NEXT:    push {r7, lr}
914 ; CHECK-O0-NEXT:    mov r7, sp
915 ; CHECK-O0-NEXT:    bl _tailcallswifterror
916 ; CHECK-O0-NEXT:    pop {r7, pc}
918 ; CHECK-ANDROID-LABEL: tailcallswifterror:
919 ; CHECK-ANDROID:       @ %bb.0: @ %entry
920 ; CHECK-ANDROID-NEXT:    .save {r11, lr}
921 ; CHECK-ANDROID-NEXT:    push {r11, lr}
922 ; CHECK-ANDROID-NEXT:    bl tailcallswifterror
923 ; CHECK-ANDROID-NEXT:    pop {r11, pc}
924 entry:
925   %0 = tail call float @tailcallswifterror(ptr swifterror %error_ptr_ref)
926   ret float %0
928 define swiftcc float @tailcallswifterror_swiftcc(ptr swifterror %error_ptr_ref) {
929 ; CHECK-APPLE-LABEL: tailcallswifterror_swiftcc:
930 ; CHECK-APPLE:       @ %bb.0: @ %entry
931 ; CHECK-APPLE-NEXT:    push {lr}
932 ; CHECK-APPLE-NEXT:    bl _tailcallswifterror_swiftcc
933 ; CHECK-APPLE-NEXT:    pop {lr}
934 ; CHECK-APPLE-NEXT:    bx lr
936 ; CHECK-O0-LABEL: tailcallswifterror_swiftcc:
937 ; CHECK-O0:       @ %bb.0: @ %entry
938 ; CHECK-O0-NEXT:    push {r7, lr}
939 ; CHECK-O0-NEXT:    mov r7, sp
940 ; CHECK-O0-NEXT:    bl _tailcallswifterror_swiftcc
941 ; CHECK-O0-NEXT:    pop {r7, pc}
943 ; CHECK-ANDROID-LABEL: tailcallswifterror_swiftcc:
944 ; CHECK-ANDROID:       @ %bb.0: @ %entry
945 ; CHECK-ANDROID-NEXT:    .save {r11, lr}
946 ; CHECK-ANDROID-NEXT:    push {r11, lr}
947 ; CHECK-ANDROID-NEXT:    bl tailcallswifterror_swiftcc
948 ; CHECK-ANDROID-NEXT:    pop {r11, pc}
949 entry:
950   %0 = tail call swiftcc float @tailcallswifterror_swiftcc(ptr swifterror %error_ptr_ref)
951   ret float %0
954 define swiftcc void @swifterror_clobber(ptr nocapture swifterror %err) {
955 ; CHECK-APPLE-LABEL: swifterror_clobber:
956 ; CHECK-APPLE:       @ %bb.0:
957 ; CHECK-APPLE-NEXT:    mov r0, r8
958 ; CHECK-APPLE-NEXT:    @ InlineAsm Start
959 ; CHECK-APPLE-NEXT:    nop
960 ; CHECK-APPLE-NEXT:    @ InlineAsm End
961 ; CHECK-APPLE-NEXT:    mov r8, r0
962 ; CHECK-APPLE-NEXT:    bx lr
964 ; CHECK-O0-LABEL: swifterror_clobber:
965 ; CHECK-O0:       @ %bb.0:
966 ; CHECK-O0-NEXT:    sub sp, sp, #4
967 ; CHECK-O0-NEXT:    str r8, [sp] @ 4-byte Spill
968 ; CHECK-O0-NEXT:    @ InlineAsm Start
969 ; CHECK-O0-NEXT:    nop
970 ; CHECK-O0-NEXT:    @ InlineAsm End
971 ; CHECK-O0-NEXT:    ldr r8, [sp] @ 4-byte Reload
972 ; CHECK-O0-NEXT:    add sp, sp, #4
973 ; CHECK-O0-NEXT:    bx lr
975 ; CHECK-ANDROID-LABEL: swifterror_clobber:
976 ; CHECK-ANDROID:       @ %bb.0:
977 ; CHECK-ANDROID-NEXT:    mov r0, r8
978 ; CHECK-ANDROID-NEXT:    @APP
979 ; CHECK-ANDROID-NEXT:    nop
980 ; CHECK-ANDROID-NEXT:    @NO_APP
981 ; CHECK-ANDROID-NEXT:    mov r8, r0
982 ; CHECK-ANDROID-NEXT:    bx lr
983   call void asm sideeffect "nop", "~{r8}"()
984   ret void
987 define swiftcc void @swifterror_reg_clobber(ptr nocapture %err) {
988 ; CHECK-APPLE-LABEL: swifterror_reg_clobber:
989 ; CHECK-APPLE:       @ %bb.0:
990 ; CHECK-APPLE-NEXT:    push {r8, lr}
991 ; CHECK-APPLE-NEXT:    @ InlineAsm Start
992 ; CHECK-APPLE-NEXT:    nop
993 ; CHECK-APPLE-NEXT:    @ InlineAsm End
994 ; CHECK-APPLE-NEXT:    pop {r8, pc}
996 ; CHECK-O0-LABEL: swifterror_reg_clobber:
997 ; CHECK-O0:       @ %bb.0:
998 ; CHECK-O0-NEXT:    push {r7, lr}
999 ; CHECK-O0-NEXT:    mov r7, sp
1000 ; CHECK-O0-NEXT:    push {r8}
1001 ; CHECK-O0-NEXT:    @ InlineAsm Start
1002 ; CHECK-O0-NEXT:    nop
1003 ; CHECK-O0-NEXT:    @ InlineAsm End
1004 ; CHECK-O0-NEXT:    pop {r8}
1005 ; CHECK-O0-NEXT:    pop {r7, pc}
1007 ; CHECK-ANDROID-LABEL: swifterror_reg_clobber:
1008 ; CHECK-ANDROID:       @ %bb.0:
1009 ; CHECK-ANDROID-NEXT:    .save {r8, lr}
1010 ; CHECK-ANDROID-NEXT:    push {r8, lr}
1011 ; CHECK-ANDROID-NEXT:    @APP
1012 ; CHECK-ANDROID-NEXT:    nop
1013 ; CHECK-ANDROID-NEXT:    @NO_APP
1014 ; CHECK-ANDROID-NEXT:    pop {r8, pc}
1015   call void asm sideeffect "nop", "~{r8}"()
1016   ret void
1019 define swiftcc void @params_in_reg(i32, i32, i32, i32, ptr swiftself, ptr nocapture swifterror %err) {
1020 ; CHECK-APPLE-LABEL: params_in_reg:
1021 ; CHECK-APPLE:       @ %bb.0:
1022 ; CHECK-APPLE-NEXT:    push {r4, r5, r6, r7, r10, r11, lr}
1023 ; CHECK-APPLE-NEXT:    add r7, sp, #20
1024 ; CHECK-APPLE-NEXT:    sub sp, sp, #12
1025 ; CHECK-APPLE-NEXT:    bfc sp, #0, #3
1026 ; CHECK-APPLE-NEXT:    str r8, [sp, #4] @ 4-byte Spill
1027 ; CHECK-APPLE-NEXT:    mov r6, r3
1028 ; CHECK-APPLE-NEXT:    str r10, [sp] @ 4-byte Spill
1029 ; CHECK-APPLE-NEXT:    mov r4, r2
1030 ; CHECK-APPLE-NEXT:    mov r11, r1
1031 ; CHECK-APPLE-NEXT:    mov r5, r0
1032 ; CHECK-APPLE-NEXT:    mov r0, #1
1033 ; CHECK-APPLE-NEXT:    mov r1, #2
1034 ; CHECK-APPLE-NEXT:    mov r2, #3
1035 ; CHECK-APPLE-NEXT:    mov r3, #4
1036 ; CHECK-APPLE-NEXT:    mov r10, #0
1037 ; CHECK-APPLE-NEXT:    mov r8, #0
1038 ; CHECK-APPLE-NEXT:    bl _params_in_reg2
1039 ; CHECK-APPLE-NEXT:    ldr r10, [sp] @ 4-byte Reload
1040 ; CHECK-APPLE-NEXT:    mov r0, r5
1041 ; CHECK-APPLE-NEXT:    ldr r8, [sp, #4] @ 4-byte Reload
1042 ; CHECK-APPLE-NEXT:    mov r1, r11
1043 ; CHECK-APPLE-NEXT:    mov r2, r4
1044 ; CHECK-APPLE-NEXT:    mov r3, r6
1045 ; CHECK-APPLE-NEXT:    bl _params_in_reg2
1046 ; CHECK-APPLE-NEXT:    sub sp, r7, #20
1047 ; CHECK-APPLE-NEXT:    pop {r4, r5, r6, r7, r10, r11, pc}
1049 ; CHECK-O0-LABEL: params_in_reg:
1050 ; CHECK-O0:       @ %bb.0:
1051 ; CHECK-O0-NEXT:    push {r7, lr}
1052 ; CHECK-O0-NEXT:    mov r7, sp
1053 ; CHECK-O0-NEXT:    push {r10}
1054 ; CHECK-O0-NEXT:    sub sp, sp, #28
1055 ; CHECK-O0-NEXT:    bfc sp, #0, #3
1056 ; CHECK-O0-NEXT:    str r8, [sp, #20] @ 4-byte Spill
1057 ; CHECK-O0-NEXT:    str r10, [sp] @ 4-byte Spill
1058 ; CHECK-O0-NEXT:    str r3, [sp, #16] @ 4-byte Spill
1059 ; CHECK-O0-NEXT:    str r2, [sp, #12] @ 4-byte Spill
1060 ; CHECK-O0-NEXT:    str r1, [sp, #8] @ 4-byte Spill
1061 ; CHECK-O0-NEXT:    str r0, [sp, #4] @ 4-byte Spill
1062 ; CHECK-O0-NEXT:    @ implicit-def: $r0
1063 ; CHECK-O0-NEXT:    mov r8, #0
1064 ; CHECK-O0-NEXT:    mov r0, #1
1065 ; CHECK-O0-NEXT:    mov r1, #2
1066 ; CHECK-O0-NEXT:    mov r2, #3
1067 ; CHECK-O0-NEXT:    mov r3, #4
1068 ; CHECK-O0-NEXT:    mov r10, r8
1069 ; CHECK-O0-NEXT:    bl _params_in_reg2
1070 ; CHECK-O0-NEXT:    ldr r10, [sp] @ 4-byte Reload
1071 ; CHECK-O0-NEXT:    ldr r0, [sp, #4] @ 4-byte Reload
1072 ; CHECK-O0-NEXT:    ldr r1, [sp, #8] @ 4-byte Reload
1073 ; CHECK-O0-NEXT:    ldr r2, [sp, #12] @ 4-byte Reload
1074 ; CHECK-O0-NEXT:    ldr r3, [sp, #16] @ 4-byte Reload
1075 ; CHECK-O0-NEXT:    mov r9, r8
1076 ; CHECK-O0-NEXT:    ldr r8, [sp, #20] @ 4-byte Reload
1077 ; CHECK-O0-NEXT:    bl _params_in_reg2
1078 ; CHECK-O0-NEXT:    sub sp, r7, #4
1079 ; CHECK-O0-NEXT:    pop {r10}
1080 ; CHECK-O0-NEXT:    pop {r7, pc}
1082 ; CHECK-ANDROID-LABEL: params_in_reg:
1083 ; CHECK-ANDROID:       @ %bb.0:
1084 ; CHECK-ANDROID-NEXT:    .save {r4, r5, r6, r7, r9, r10, r11, lr}
1085 ; CHECK-ANDROID-NEXT:    push {r4, r5, r6, r7, r9, r10, r11, lr}
1086 ; CHECK-ANDROID-NEXT:    .pad #8
1087 ; CHECK-ANDROID-NEXT:    sub sp, sp, #8
1088 ; CHECK-ANDROID-NEXT:    mov r9, r8
1089 ; CHECK-ANDROID-NEXT:    mov r11, r10
1090 ; CHECK-ANDROID-NEXT:    mov r6, r3
1091 ; CHECK-ANDROID-NEXT:    mov r7, r2
1092 ; CHECK-ANDROID-NEXT:    mov r4, r1
1093 ; CHECK-ANDROID-NEXT:    mov r5, r0
1094 ; CHECK-ANDROID-NEXT:    mov r0, #1
1095 ; CHECK-ANDROID-NEXT:    mov r1, #2
1096 ; CHECK-ANDROID-NEXT:    mov r2, #3
1097 ; CHECK-ANDROID-NEXT:    mov r3, #4
1098 ; CHECK-ANDROID-NEXT:    mov r10, #0
1099 ; CHECK-ANDROID-NEXT:    mov r8, #0
1100 ; CHECK-ANDROID-NEXT:    bl params_in_reg2
1101 ; CHECK-ANDROID-NEXT:    mov r0, r5
1102 ; CHECK-ANDROID-NEXT:    mov r1, r4
1103 ; CHECK-ANDROID-NEXT:    mov r2, r7
1104 ; CHECK-ANDROID-NEXT:    mov r3, r6
1105 ; CHECK-ANDROID-NEXT:    mov r10, r11
1106 ; CHECK-ANDROID-NEXT:    mov r8, r9
1107 ; CHECK-ANDROID-NEXT:    bl params_in_reg2
1108 ; CHECK-ANDROID-NEXT:    add sp, sp, #8
1109 ; CHECK-ANDROID-NEXT:    pop {r4, r5, r6, r7, r9, r10, r11, pc}
1110   %error_ptr_ref = alloca swifterror ptr, align 8
1111   store ptr null, ptr %error_ptr_ref
1112   call swiftcc void @params_in_reg2(i32 1, i32 2, i32 3, i32 4, ptr swiftself null, ptr nocapture swifterror %error_ptr_ref)
1113   call swiftcc void @params_in_reg2(i32 %0, i32 %1, i32 %2, i32 %3, ptr swiftself %4, ptr nocapture swifterror %err)
1114   ret void
1116 declare swiftcc void @params_in_reg2(i32, i32, i32, i32, ptr swiftself, ptr nocapture swifterror %err)
1118 define swiftcc { i32, i32, i32, i32} @params_and_return_in_reg(i32, i32, i32, i32, ptr swiftself, ptr nocapture swifterror %err) {
1119 ; CHECK-APPLE-LABEL: params_and_return_in_reg:
1120 ; CHECK-APPLE:       @ %bb.0:
1121 ; CHECK-APPLE-NEXT:    push {r4, r5, r6, r7, r10, r11, lr}
1122 ; CHECK-APPLE-NEXT:    add r7, sp, #20
1123 ; CHECK-APPLE-NEXT:    sub sp, sp, #20
1124 ; CHECK-APPLE-NEXT:    bfc sp, #0, #3
1125 ; CHECK-APPLE-NEXT:    mov r6, r8
1126 ; CHECK-APPLE-NEXT:    str r10, [sp, #12] @ 4-byte Spill
1127 ; CHECK-APPLE-NEXT:    str r3, [sp, #8] @ 4-byte Spill
1128 ; CHECK-APPLE-NEXT:    mov r4, r2
1129 ; CHECK-APPLE-NEXT:    mov r11, r1
1130 ; CHECK-APPLE-NEXT:    mov r5, r0
1131 ; CHECK-APPLE-NEXT:    mov r0, #1
1132 ; CHECK-APPLE-NEXT:    mov r1, #2
1133 ; CHECK-APPLE-NEXT:    mov r2, #3
1134 ; CHECK-APPLE-NEXT:    mov r3, #4
1135 ; CHECK-APPLE-NEXT:    mov r10, #0
1136 ; CHECK-APPLE-NEXT:    mov r8, #0
1137 ; CHECK-APPLE-NEXT:    bl _params_in_reg2
1138 ; CHECK-APPLE-NEXT:    ldr r3, [sp, #8] @ 4-byte Reload
1139 ; CHECK-APPLE-NEXT:    mov r0, r5
1140 ; CHECK-APPLE-NEXT:    ldr r10, [sp, #12] @ 4-byte Reload
1141 ; CHECK-APPLE-NEXT:    mov r1, r11
1142 ; CHECK-APPLE-NEXT:    str r8, [sp, #4] @ 4-byte Spill
1143 ; CHECK-APPLE-NEXT:    mov r2, r4
1144 ; CHECK-APPLE-NEXT:    mov r8, r6
1145 ; CHECK-APPLE-NEXT:    bl _params_and_return_in_reg2
1146 ; CHECK-APPLE-NEXT:    str r8, [sp, #12] @ 4-byte Spill
1147 ; CHECK-APPLE-NEXT:    mov r4, r0
1148 ; CHECK-APPLE-NEXT:    ldr r8, [sp, #4] @ 4-byte Reload
1149 ; CHECK-APPLE-NEXT:    mov r5, r1
1150 ; CHECK-APPLE-NEXT:    mov r6, r2
1151 ; CHECK-APPLE-NEXT:    mov r11, r3
1152 ; CHECK-APPLE-NEXT:    mov r0, #1
1153 ; CHECK-APPLE-NEXT:    mov r1, #2
1154 ; CHECK-APPLE-NEXT:    mov r2, #3
1155 ; CHECK-APPLE-NEXT:    mov r3, #4
1156 ; CHECK-APPLE-NEXT:    mov r10, #0
1157 ; CHECK-APPLE-NEXT:    bl _params_in_reg2
1158 ; CHECK-APPLE-NEXT:    mov r0, r4
1159 ; CHECK-APPLE-NEXT:    mov r1, r5
1160 ; CHECK-APPLE-NEXT:    mov r2, r6
1161 ; CHECK-APPLE-NEXT:    mov r3, r11
1162 ; CHECK-APPLE-NEXT:    ldr r8, [sp, #12] @ 4-byte Reload
1163 ; CHECK-APPLE-NEXT:    sub sp, r7, #20
1164 ; CHECK-APPLE-NEXT:    pop {r4, r5, r6, r7, r10, r11, pc}
1166 ; CHECK-O0-LABEL: params_and_return_in_reg:
1167 ; CHECK-O0:       @ %bb.0:
1168 ; CHECK-O0-NEXT:    push {r7, lr}
1169 ; CHECK-O0-NEXT:    mov r7, sp
1170 ; CHECK-O0-NEXT:    push {r10}
1171 ; CHECK-O0-NEXT:    sub sp, sp, #76
1172 ; CHECK-O0-NEXT:    bfc sp, #0, #3
1173 ; CHECK-O0-NEXT:    str r8, [sp, #24] @ 4-byte Spill
1174 ; CHECK-O0-NEXT:    str r10, [sp, #4] @ 4-byte Spill
1175 ; CHECK-O0-NEXT:    str r3, [sp, #20] @ 4-byte Spill
1176 ; CHECK-O0-NEXT:    str r2, [sp, #16] @ 4-byte Spill
1177 ; CHECK-O0-NEXT:    str r1, [sp, #12] @ 4-byte Spill
1178 ; CHECK-O0-NEXT:    str r0, [sp, #8] @ 4-byte Spill
1179 ; CHECK-O0-NEXT:    @ implicit-def: $r0
1180 ; CHECK-O0-NEXT:    mov r8, #0
1181 ; CHECK-O0-NEXT:    str r8, [sp, #28] @ 4-byte Spill
1182 ; CHECK-O0-NEXT:    mov r0, #1
1183 ; CHECK-O0-NEXT:    str r0, [sp, #32] @ 4-byte Spill
1184 ; CHECK-O0-NEXT:    mov r1, #2
1185 ; CHECK-O0-NEXT:    str r1, [sp, #36] @ 4-byte Spill
1186 ; CHECK-O0-NEXT:    mov r2, #3
1187 ; CHECK-O0-NEXT:    str r2, [sp, #40] @ 4-byte Spill
1188 ; CHECK-O0-NEXT:    mov r3, #4
1189 ; CHECK-O0-NEXT:    str r3, [sp, #44] @ 4-byte Spill
1190 ; CHECK-O0-NEXT:    mov r10, r8
1191 ; CHECK-O0-NEXT:    bl _params_in_reg2
1192 ; CHECK-O0-NEXT:    ldr r10, [sp, #4] @ 4-byte Reload
1193 ; CHECK-O0-NEXT:    ldr r0, [sp, #8] @ 4-byte Reload
1194 ; CHECK-O0-NEXT:    ldr r1, [sp, #12] @ 4-byte Reload
1195 ; CHECK-O0-NEXT:    ldr r2, [sp, #16] @ 4-byte Reload
1196 ; CHECK-O0-NEXT:    ldr r3, [sp, #20] @ 4-byte Reload
1197 ; CHECK-O0-NEXT:    mov r9, r8
1198 ; CHECK-O0-NEXT:    ldr r8, [sp, #24] @ 4-byte Reload
1199 ; CHECK-O0-NEXT:    str r9, [sp, #48] @ 4-byte Spill
1200 ; CHECK-O0-NEXT:    bl _params_and_return_in_reg2
1201 ; CHECK-O0-NEXT:    ldr r10, [sp, #28] @ 4-byte Reload
1202 ; CHECK-O0-NEXT:    mov r9, r0
1203 ; CHECK-O0-NEXT:    ldr r0, [sp, #32] @ 4-byte Reload
1204 ; CHECK-O0-NEXT:    str r9, [sp, #52] @ 4-byte Spill
1205 ; CHECK-O0-NEXT:    mov r9, r1
1206 ; CHECK-O0-NEXT:    ldr r1, [sp, #36] @ 4-byte Reload
1207 ; CHECK-O0-NEXT:    str r9, [sp, #56] @ 4-byte Spill
1208 ; CHECK-O0-NEXT:    mov r9, r2
1209 ; CHECK-O0-NEXT:    ldr r2, [sp, #40] @ 4-byte Reload
1210 ; CHECK-O0-NEXT:    str r9, [sp, #60] @ 4-byte Spill
1211 ; CHECK-O0-NEXT:    mov r9, r3
1212 ; CHECK-O0-NEXT:    ldr r3, [sp, #44] @ 4-byte Reload
1213 ; CHECK-O0-NEXT:    str r9, [sp, #64] @ 4-byte Spill
1214 ; CHECK-O0-NEXT:    mov r9, r8
1215 ; CHECK-O0-NEXT:    ldr r8, [sp, #48] @ 4-byte Reload
1216 ; CHECK-O0-NEXT:    str r9, [sp, #68] @ 4-byte Spill
1217 ; CHECK-O0-NEXT:    bl _params_in_reg2
1218 ; CHECK-O0-NEXT:    ldr r0, [sp, #52] @ 4-byte Reload
1219 ; CHECK-O0-NEXT:    ldr r1, [sp, #56] @ 4-byte Reload
1220 ; CHECK-O0-NEXT:    ldr r2, [sp, #60] @ 4-byte Reload
1221 ; CHECK-O0-NEXT:    ldr r3, [sp, #64] @ 4-byte Reload
1222 ; CHECK-O0-NEXT:    mov r9, r8
1223 ; CHECK-O0-NEXT:    ldr r8, [sp, #68] @ 4-byte Reload
1224 ; CHECK-O0-NEXT:    sub sp, r7, #4
1225 ; CHECK-O0-NEXT:    pop {r10}
1226 ; CHECK-O0-NEXT:    pop {r7, pc}
1228 ; CHECK-ANDROID-LABEL: params_and_return_in_reg:
1229 ; CHECK-ANDROID:       @ %bb.0:
1230 ; CHECK-ANDROID-NEXT:    .save {r4, r5, r6, r7, r9, r10, r11, lr}
1231 ; CHECK-ANDROID-NEXT:    push {r4, r5, r6, r7, r9, r10, r11, lr}
1232 ; CHECK-ANDROID-NEXT:    .pad #16
1233 ; CHECK-ANDROID-NEXT:    sub sp, sp, #16
1234 ; CHECK-ANDROID-NEXT:    str r8, [sp, #4] @ 4-byte Spill
1235 ; CHECK-ANDROID-NEXT:    mov r11, r10
1236 ; CHECK-ANDROID-NEXT:    mov r6, r3
1237 ; CHECK-ANDROID-NEXT:    mov r7, r2
1238 ; CHECK-ANDROID-NEXT:    mov r4, r1
1239 ; CHECK-ANDROID-NEXT:    mov r5, r0
1240 ; CHECK-ANDROID-NEXT:    mov r0, #1
1241 ; CHECK-ANDROID-NEXT:    mov r1, #2
1242 ; CHECK-ANDROID-NEXT:    mov r2, #3
1243 ; CHECK-ANDROID-NEXT:    mov r3, #4
1244 ; CHECK-ANDROID-NEXT:    mov r10, #0
1245 ; CHECK-ANDROID-NEXT:    mov r8, #0
1246 ; CHECK-ANDROID-NEXT:    bl params_in_reg2
1247 ; CHECK-ANDROID-NEXT:    mov r9, r8
1248 ; CHECK-ANDROID-NEXT:    ldr r8, [sp, #4] @ 4-byte Reload
1249 ; CHECK-ANDROID-NEXT:    mov r0, r5
1250 ; CHECK-ANDROID-NEXT:    mov r1, r4
1251 ; CHECK-ANDROID-NEXT:    mov r2, r7
1252 ; CHECK-ANDROID-NEXT:    mov r3, r6
1253 ; CHECK-ANDROID-NEXT:    mov r10, r11
1254 ; CHECK-ANDROID-NEXT:    bl params_and_return_in_reg2
1255 ; CHECK-ANDROID-NEXT:    mov r4, r0
1256 ; CHECK-ANDROID-NEXT:    mov r5, r1
1257 ; CHECK-ANDROID-NEXT:    mov r6, r2
1258 ; CHECK-ANDROID-NEXT:    mov r7, r3
1259 ; CHECK-ANDROID-NEXT:    mov r11, r8
1260 ; CHECK-ANDROID-NEXT:    mov r0, #1
1261 ; CHECK-ANDROID-NEXT:    mov r1, #2
1262 ; CHECK-ANDROID-NEXT:    mov r2, #3
1263 ; CHECK-ANDROID-NEXT:    mov r3, #4
1264 ; CHECK-ANDROID-NEXT:    mov r10, #0
1265 ; CHECK-ANDROID-NEXT:    mov r8, r9
1266 ; CHECK-ANDROID-NEXT:    bl params_in_reg2
1267 ; CHECK-ANDROID-NEXT:    mov r0, r4
1268 ; CHECK-ANDROID-NEXT:    mov r1, r5
1269 ; CHECK-ANDROID-NEXT:    mov r2, r6
1270 ; CHECK-ANDROID-NEXT:    mov r3, r7
1271 ; CHECK-ANDROID-NEXT:    mov r8, r11
1272 ; CHECK-ANDROID-NEXT:    add sp, sp, #16
1273 ; CHECK-ANDROID-NEXT:    pop {r4, r5, r6, r7, r9, r10, r11, pc}
1274   %error_ptr_ref = alloca swifterror ptr, align 8
1275   store ptr null, ptr %error_ptr_ref
1276   call swiftcc void @params_in_reg2(i32 1, i32 2, i32 3, i32 4, ptr swiftself null, ptr nocapture swifterror %error_ptr_ref)
1277   %val = call swiftcc  { i32, i32, i32, i32 } @params_and_return_in_reg2(i32 %0, i32 %1, i32 %2, i32 %3, ptr swiftself %4, ptr nocapture swifterror %err)
1278   call swiftcc void @params_in_reg2(i32 1, i32 2, i32 3, i32 4, ptr swiftself null, ptr nocapture swifterror %error_ptr_ref)
1279   ret { i32, i32, i32, i32 }%val
1282 declare swiftcc { i32, i32, i32, i32 } @params_and_return_in_reg2(i32, i32, i32, i32, ptr swiftself, ptr nocapture swifterror %err)
1285 declare void @acallee(ptr)
1287 ; Make sure we don't tail call if the caller returns a swifterror value. We
1288 ; would have to move into the swifterror register before the tail call.
1289 define swiftcc void @tailcall_from_swifterror(ptr swifterror %error_ptr_ref) {
1290 ; CHECK-APPLE-LABEL: tailcall_from_swifterror:
1291 ; CHECK-APPLE:       @ %bb.0: @ %entry
1292 ; CHECK-APPLE-NEXT:    push {r4, lr}
1293 ; CHECK-APPLE-NEXT:    mov r0, #0
1294 ; CHECK-APPLE-NEXT:    mov r4, r8
1295 ; CHECK-APPLE-NEXT:    bl _acallee
1296 ; CHECK-APPLE-NEXT:    mov r8, r4
1297 ; CHECK-APPLE-NEXT:    pop {r4, pc}
1299 ; CHECK-O0-LABEL: tailcall_from_swifterror:
1300 ; CHECK-O0:       @ %bb.0: @ %entry
1301 ; CHECK-O0-NEXT:    push {r7, lr}
1302 ; CHECK-O0-NEXT:    mov r7, sp
1303 ; CHECK-O0-NEXT:    sub sp, sp, #4
1304 ; CHECK-O0-NEXT:    str r8, [sp] @ 4-byte Spill
1305 ; CHECK-O0-NEXT:    mov r0, #0
1306 ; CHECK-O0-NEXT:    bl _acallee
1307 ; CHECK-O0-NEXT:    ldr r8, [sp] @ 4-byte Reload
1308 ; CHECK-O0-NEXT:    mov sp, r7
1309 ; CHECK-O0-NEXT:    pop {r7, pc}
1311 ; CHECK-ANDROID-LABEL: tailcall_from_swifterror:
1312 ; CHECK-ANDROID:       @ %bb.0: @ %entry
1313 ; CHECK-ANDROID-NEXT:    .save {r4, lr}
1314 ; CHECK-ANDROID-NEXT:    push {r4, lr}
1315 ; CHECK-ANDROID-NEXT:    mov r0, #0
1316 ; CHECK-ANDROID-NEXT:    mov r4, r8
1317 ; CHECK-ANDROID-NEXT:    bl acallee
1318 ; CHECK-ANDROID-NEXT:    mov r8, r4
1319 ; CHECK-ANDROID-NEXT:    pop {r4, pc}
1320 entry:
1321   tail call void @acallee(ptr null)
1322   ret void
1326 declare swiftcc void @foo2(ptr swifterror)
1328 ; Make sure we properly assign registers during fast-isel.
1329 define swiftcc ptr @testAssign(ptr %error_ref) {
1330 ; CHECK-APPLE-LABEL: testAssign:
1331 ; CHECK-APPLE:       @ %bb.0: @ %entry
1332 ; CHECK-APPLE-NEXT:    push {r8, lr}
1333 ; CHECK-APPLE-NEXT:    sub sp, sp, #4
1334 ; CHECK-APPLE-NEXT:    mov r8, #0
1335 ; CHECK-APPLE-NEXT:    bl _foo2
1336 ; CHECK-APPLE-NEXT:    mov r0, r8
1337 ; CHECK-APPLE-NEXT:    add sp, sp, #4
1338 ; CHECK-APPLE-NEXT:    pop {r8, pc}
1340 ; CHECK-O0-LABEL: testAssign:
1341 ; CHECK-O0:       @ %bb.0: @ %entry
1342 ; CHECK-O0-NEXT:    push {r7, lr}
1343 ; CHECK-O0-NEXT:    mov r7, sp
1344 ; CHECK-O0-NEXT:    push {r8}
1345 ; CHECK-O0-NEXT:    sub sp, sp, #8
1346 ; CHECK-O0-NEXT:    @ implicit-def: $r1
1347 ; CHECK-O0-NEXT:    mov r8, #0
1348 ; CHECK-O0-NEXT:    bl _foo2
1349 ; CHECK-O0-NEXT:    str r8, [sp] @ 4-byte Spill
1350 ; CHECK-O0-NEXT:  @ %bb.1: @ %a
1351 ; CHECK-O0-NEXT:    ldr r0, [sp] @ 4-byte Reload
1352 ; CHECK-O0-NEXT:    sub sp, r7, #4
1353 ; CHECK-O0-NEXT:    pop {r8}
1354 ; CHECK-O0-NEXT:    pop {r7, pc}
1356 ; CHECK-ANDROID-LABEL: testAssign:
1357 ; CHECK-ANDROID:       @ %bb.0: @ %entry
1358 ; CHECK-ANDROID-NEXT:    .save {r8, lr}
1359 ; CHECK-ANDROID-NEXT:    push {r8, lr}
1360 ; CHECK-ANDROID-NEXT:    .pad #8
1361 ; CHECK-ANDROID-NEXT:    sub sp, sp, #8
1362 ; CHECK-ANDROID-NEXT:    mov r8, #0
1363 ; CHECK-ANDROID-NEXT:    bl foo2
1364 ; CHECK-ANDROID-NEXT:    mov r0, r8
1365 ; CHECK-ANDROID-NEXT:    add sp, sp, #8
1366 ; CHECK-ANDROID-NEXT:    pop {r8, pc}
1367 entry:
1368   %error_ptr = alloca swifterror ptr
1369   store ptr null, ptr %error_ptr
1370   call swiftcc void @foo2(ptr swifterror %error_ptr)
1371   br label %a
1374   %error = load ptr, ptr %error_ptr
1375   ret ptr %error