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