xref: /llvm-project/llvm/test/CodeGen/X86/swifterror.ll (revision 2b63077cfa13095b3e64f79fe825cc85ca9da7be)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --no_x86_scrub_sp
2; RUN: llc -verify-machineinstrs < %s -mtriple=x86_64-apple-darwin -disable-block-placement | FileCheck --check-prefix=CHECK-APPLE %s
3; RUN: llc -verify-machineinstrs -O0 < %s -mtriple=x86_64-apple-darwin -disable-block-placement | FileCheck --check-prefix=CHECK-O0 %s
4; RUN: llc -verify-machineinstrs < %s -mtriple=i386-apple-darwin -disable-block-placement | FileCheck --check-prefix=CHECK-i386 %s
5
6declare ptr @malloc(i64)
7declare void @free(ptr)
8%swift_error = type {i64, i8}
9
10; This tests the basic usage of a swifterror parameter. "foo" is the function
11; that takes a swifterror parameter and "caller" is the caller of "foo".
12define float @foo(ptr swifterror %error_ptr_ref) {
13; CHECK-APPLE-LABEL: foo:
14; CHECK-APPLE:       ## %bb.0: ## %entry
15; CHECK-APPLE-NEXT:    pushq %rax
16; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 16
17; CHECK-APPLE-NEXT:    movl $16, %edi
18; CHECK-APPLE-NEXT:    callq _malloc
19; CHECK-APPLE-NEXT:    movb $1, 8(%rax)
20; CHECK-APPLE-NEXT:    movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
21; CHECK-APPLE-NEXT:    movq %rax, %r12
22; CHECK-APPLE-NEXT:    popq %rax
23; CHECK-APPLE-NEXT:    retq
24;
25; CHECK-O0-LABEL: foo:
26; CHECK-O0:       ## %bb.0: ## %entry
27; CHECK-O0-NEXT:    pushq %rax
28; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
29; CHECK-O0-NEXT:    movl $16, %edi
30; CHECK-O0-NEXT:    callq _malloc
31; CHECK-O0-NEXT:    movq %rax, %r12
32; CHECK-O0-NEXT:    movb $1, 8(%rax)
33; CHECK-O0-NEXT:    movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
34; CHECK-O0-NEXT:    popq %rax
35; CHECK-O0-NEXT:    retq
36;
37; CHECK-i386-LABEL: foo:
38; CHECK-i386:       ## %bb.0: ## %entry
39; CHECK-i386-NEXT:    pushl %esi
40; CHECK-i386-NEXT:    .cfi_def_cfa_offset 8
41; CHECK-i386-NEXT:    subl $8, %esp
42; CHECK-i386-NEXT:    .cfi_def_cfa_offset 16
43; CHECK-i386-NEXT:    .cfi_offset %esi, -8
44; CHECK-i386-NEXT:    movl 16(%esp), %esi
45; CHECK-i386-NEXT:    movl $0, 4(%esp)
46; CHECK-i386-NEXT:    movl $16, (%esp)
47; CHECK-i386-NEXT:    calll _malloc
48; CHECK-i386-NEXT:    movl %eax, (%esi)
49; CHECK-i386-NEXT:    movb $1, 8(%eax)
50; CHECK-i386-NEXT:    fld1
51; CHECK-i386-NEXT:    addl $8, %esp
52; CHECK-i386-NEXT:    popl %esi
53; CHECK-i386-NEXT:    retl
54
55entry:
56  %call = call ptr @malloc(i64 16)
57  store ptr %call, ptr %error_ptr_ref
58  %tmp = getelementptr inbounds i8, ptr %call, i64 8
59  store i8 1, ptr %tmp
60  ret float 1.0
61}
62
63; "caller" calls "foo" that takes a swifterror parameter.
64define float @caller(ptr %error_ref) {
65; CHECK-APPLE-LABEL: caller:
66; CHECK-APPLE:       ## %bb.0: ## %entry
67; CHECK-APPLE-NEXT:    pushq %r12
68; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 16
69; CHECK-APPLE-NEXT:    pushq %rbx
70; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 24
71; CHECK-APPLE-NEXT:    pushq %rax
72; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 32
73; CHECK-APPLE-NEXT:    .cfi_offset %rbx, -24
74; CHECK-APPLE-NEXT:    .cfi_offset %r12, -16
75; CHECK-APPLE-NEXT:    movq %rdi, %rbx
76; CHECK-APPLE-NEXT:    xorl %r12d, %r12d
77; CHECK-APPLE-NEXT:    callq _foo
78; CHECK-APPLE-NEXT:    movq %r12, %rdi
79; CHECK-APPLE-NEXT:    testq %r12, %r12
80; CHECK-APPLE-NEXT:    jne LBB1_2
81; CHECK-APPLE-NEXT:  ## %bb.1: ## %cont
82; CHECK-APPLE-NEXT:    movzbl 8(%rdi), %eax
83; CHECK-APPLE-NEXT:    movb %al, (%rbx)
84; CHECK-APPLE-NEXT:  LBB1_2: ## %handler
85; CHECK-APPLE-NEXT:    callq _free
86; CHECK-APPLE-NEXT:    movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
87; CHECK-APPLE-NEXT:    addq $8, %rsp
88; CHECK-APPLE-NEXT:    popq %rbx
89; CHECK-APPLE-NEXT:    popq %r12
90; CHECK-APPLE-NEXT:    retq
91;
92; CHECK-O0-LABEL: caller:
93; CHECK-O0:       ## %bb.0: ## %entry
94; CHECK-O0-NEXT:    pushq %r12
95; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
96; CHECK-O0-NEXT:    subq $32, %rsp
97; CHECK-O0-NEXT:    .cfi_def_cfa_offset 48
98; CHECK-O0-NEXT:    .cfi_offset %r12, -16
99; CHECK-O0-NEXT:    ## implicit-def: $rax
100; CHECK-O0-NEXT:    movq %rdi, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
101; CHECK-O0-NEXT:    xorl %eax, %eax
102; CHECK-O0-NEXT:    movl %eax, %r12d
103; CHECK-O0-NEXT:    callq _foo
104; CHECK-O0-NEXT:    movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
105; CHECK-O0-NEXT:    cmpq $0, %r12
106; CHECK-O0-NEXT:    jne LBB1_2
107; CHECK-O0-NEXT:  ## %bb.1: ## %cont
108; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rax ## 8-byte Reload
109; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx ## 8-byte Reload
110; CHECK-O0-NEXT:    movb 8(%rcx), %cl
111; CHECK-O0-NEXT:    movb %cl, (%rax)
112; CHECK-O0-NEXT:  LBB1_2: ## %handler
113; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rdi ## 8-byte Reload
114; CHECK-O0-NEXT:    callq _free
115; CHECK-O0-NEXT:    movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
116; CHECK-O0-NEXT:    addq $32, %rsp
117; CHECK-O0-NEXT:    popq %r12
118; CHECK-O0-NEXT:    retq
119;
120; CHECK-i386-LABEL: caller:
121; CHECK-i386:       ## %bb.0: ## %entry
122; CHECK-i386-NEXT:    subl $12, %esp
123; CHECK-i386-NEXT:    .cfi_def_cfa_offset 16
124; CHECK-i386-NEXT:    movl $0, 8(%esp)
125; CHECK-i386-NEXT:    leal 8(%esp), %eax
126; CHECK-i386-NEXT:    movl %eax, (%esp)
127; CHECK-i386-NEXT:    calll _foo
128; CHECK-i386-NEXT:    fstp %st(0)
129; CHECK-i386-NEXT:    movl 8(%esp), %eax
130; CHECK-i386-NEXT:    testl %eax, %eax
131; CHECK-i386-NEXT:    jne LBB1_2
132; CHECK-i386-NEXT:  ## %bb.1: ## %cont
133; CHECK-i386-NEXT:    movl 16(%esp), %ecx
134; CHECK-i386-NEXT:    movzbl 8(%eax), %edx
135; CHECK-i386-NEXT:    movb %dl, (%ecx)
136; CHECK-i386-NEXT:  LBB1_2: ## %handler
137; CHECK-i386-NEXT:    movl %eax, (%esp)
138; CHECK-i386-NEXT:    calll _free
139; CHECK-i386-NEXT:    fld1
140; CHECK-i386-NEXT:    addl $12, %esp
141; CHECK-i386-NEXT:    retl
142; Access part of the error object and save it to error_ref
143
144entry:
145  %error_ptr_ref = alloca swifterror ptr
146  store ptr null, ptr %error_ptr_ref
147  %call = call float @foo(ptr swifterror %error_ptr_ref)
148  %error_from_foo = load ptr, ptr %error_ptr_ref
149  %had_error_from_foo = icmp ne ptr %error_from_foo, null
150  br i1 %had_error_from_foo, label %handler, label %cont
151cont:
152  %v1 = getelementptr inbounds %swift_error, ptr %error_from_foo, i64 0, i32 1
153  %t = load i8, ptr %v1
154  store i8 %t, ptr %error_ref
155  br label %handler
156handler:
157  call void @free(ptr %error_from_foo)
158  ret float 1.0
159}
160
161; "caller2" is the caller of "foo", it calls "foo" inside a loop.
162define float @caller2(ptr %error_ref) {
163; CHECK-APPLE-LABEL: caller2:
164; CHECK-APPLE:       ## %bb.0: ## %entry
165; CHECK-APPLE-NEXT:    pushq %r12
166; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 16
167; CHECK-APPLE-NEXT:    pushq %rbx
168; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 24
169; CHECK-APPLE-NEXT:    pushq %rax
170; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 32
171; CHECK-APPLE-NEXT:    .cfi_offset %rbx, -24
172; CHECK-APPLE-NEXT:    .cfi_offset %r12, -16
173; CHECK-APPLE-NEXT:    movq %rdi, %rbx
174; CHECK-APPLE-NEXT:  LBB2_1: ## %bb_loop
175; CHECK-APPLE-NEXT:    ## =>This Inner Loop Header: Depth=1
176; CHECK-APPLE-NEXT:    xorl %r12d, %r12d
177; CHECK-APPLE-NEXT:    callq _foo
178; CHECK-APPLE-NEXT:    testq %r12, %r12
179; CHECK-APPLE-NEXT:    jne LBB2_4
180; CHECK-APPLE-NEXT:  ## %bb.2: ## %cont
181; CHECK-APPLE-NEXT:    ## in Loop: Header=BB2_1 Depth=1
182; CHECK-APPLE-NEXT:    ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
183; CHECK-APPLE-NEXT:    jbe LBB2_1
184; CHECK-APPLE-NEXT:  ## %bb.3: ## %bb_end
185; CHECK-APPLE-NEXT:    movzbl 8(%r12), %eax
186; CHECK-APPLE-NEXT:    movb %al, (%rbx)
187; CHECK-APPLE-NEXT:  LBB2_4: ## %handler
188; CHECK-APPLE-NEXT:    movq %r12, %rdi
189; CHECK-APPLE-NEXT:    callq _free
190; CHECK-APPLE-NEXT:    movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
191; CHECK-APPLE-NEXT:    addq $8, %rsp
192; CHECK-APPLE-NEXT:    popq %rbx
193; CHECK-APPLE-NEXT:    popq %r12
194; CHECK-APPLE-NEXT:    retq
195;
196; CHECK-O0-LABEL: caller2:
197; CHECK-O0:       ## %bb.0: ## %entry
198; CHECK-O0-NEXT:    pushq %r12
199; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
200; CHECK-O0-NEXT:    subq $32, %rsp
201; CHECK-O0-NEXT:    .cfi_def_cfa_offset 48
202; CHECK-O0-NEXT:    .cfi_offset %r12, -16
203; CHECK-O0-NEXT:    ## implicit-def: $rax
204; CHECK-O0-NEXT:    movq %rdi, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
205; CHECK-O0-NEXT:  LBB2_1: ## %bb_loop
206; CHECK-O0-NEXT:    ## =>This Inner Loop Header: Depth=1
207; CHECK-O0-NEXT:    xorl %eax, %eax
208; CHECK-O0-NEXT:    movl %eax, %r12d
209; CHECK-O0-NEXT:    callq _foo
210; CHECK-O0-NEXT:    movss %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) ## 4-byte Spill
211; CHECK-O0-NEXT:    movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
212; CHECK-O0-NEXT:    cmpq $0, %r12
213; CHECK-O0-NEXT:    jne LBB2_4
214; CHECK-O0-NEXT:  ## %bb.2: ## %cont
215; CHECK-O0-NEXT:    ## in Loop: Header=BB2_1 Depth=1
216; CHECK-O0-NEXT:    movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 ## 4-byte Reload
217; CHECK-O0-NEXT:    ## xmm0 = mem[0],zero,zero,zero
218; CHECK-O0-NEXT:    movss {{.*#+}} xmm1 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
219; CHECK-O0-NEXT:    ucomiss %xmm1, %xmm0
220; CHECK-O0-NEXT:    jbe LBB2_1
221; CHECK-O0-NEXT:  ## %bb.3: ## %bb_end
222; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rax ## 8-byte Reload
223; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx ## 8-byte Reload
224; CHECK-O0-NEXT:    movb 8(%rcx), %cl
225; CHECK-O0-NEXT:    movb %cl, (%rax)
226; CHECK-O0-NEXT:  LBB2_4: ## %handler
227; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rdi ## 8-byte Reload
228; CHECK-O0-NEXT:    callq _free
229; CHECK-O0-NEXT:    movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
230; CHECK-O0-NEXT:    addq $32, %rsp
231; CHECK-O0-NEXT:    popq %r12
232; CHECK-O0-NEXT:    retq
233;
234; CHECK-i386-LABEL: caller2:
235; CHECK-i386:       ## %bb.0: ## %entry
236; CHECK-i386-NEXT:    pushl %edi
237; CHECK-i386-NEXT:    .cfi_def_cfa_offset 8
238; CHECK-i386-NEXT:    pushl %esi
239; CHECK-i386-NEXT:    .cfi_def_cfa_offset 12
240; CHECK-i386-NEXT:    subl $20, %esp
241; CHECK-i386-NEXT:    .cfi_def_cfa_offset 32
242; CHECK-i386-NEXT:    .cfi_offset %esi, -12
243; CHECK-i386-NEXT:    .cfi_offset %edi, -8
244; CHECK-i386-NEXT:    movl 32(%esp), %esi
245; CHECK-i386-NEXT:    leal 16(%esp), %edi
246; CHECK-i386-NEXT:  LBB2_1: ## %bb_loop
247; CHECK-i386-NEXT:    ## =>This Inner Loop Header: Depth=1
248; CHECK-i386-NEXT:    movl $0, 16(%esp)
249; CHECK-i386-NEXT:    movl %edi, (%esp)
250; CHECK-i386-NEXT:    calll _foo
251; CHECK-i386-NEXT:    movl 16(%esp), %ecx
252; CHECK-i386-NEXT:    testl %ecx, %ecx
253; CHECK-i386-NEXT:    jne LBB2_4
254; CHECK-i386-NEXT:  ## %bb.2: ## %cont
255; CHECK-i386-NEXT:    ## in Loop: Header=BB2_1 Depth=1
256; CHECK-i386-NEXT:    fld1
257; CHECK-i386-NEXT:    fxch %st(1)
258; CHECK-i386-NEXT:    fucompp
259; CHECK-i386-NEXT:    fnstsw %ax
260; CHECK-i386-NEXT:    ## kill: def $ah killed $ah killed $ax
261; CHECK-i386-NEXT:    sahf
262; CHECK-i386-NEXT:    jbe LBB2_1
263; CHECK-i386-NEXT:  ## %bb.3: ## %bb_end
264; CHECK-i386-NEXT:    movzbl 8(%ecx), %eax
265; CHECK-i386-NEXT:    movb %al, (%esi)
266; CHECK-i386-NEXT:    fldz
267; CHECK-i386-NEXT:  LBB2_4: ## %handler
268; CHECK-i386-NEXT:    fstp %st(0)
269; CHECK-i386-NEXT:    movl %ecx, (%esp)
270; CHECK-i386-NEXT:    calll _free
271; CHECK-i386-NEXT:    fld1
272; CHECK-i386-NEXT:    addl $20, %esp
273; CHECK-i386-NEXT:    popl %esi
274; CHECK-i386-NEXT:    popl %edi
275; CHECK-i386-NEXT:    retl
276; Access part of the error object and save it to error_ref
277
278entry:
279  %error_ptr_ref = alloca swifterror ptr
280  br label %bb_loop
281bb_loop:
282  store ptr null, ptr %error_ptr_ref
283  %call = call float @foo(ptr swifterror %error_ptr_ref)
284  %error_from_foo = load ptr, ptr %error_ptr_ref
285  %had_error_from_foo = icmp ne ptr %error_from_foo, null
286  br i1 %had_error_from_foo, label %handler, label %cont
287cont:
288  %cmp = fcmp ogt float %call, 1.000000e+00
289  br i1 %cmp, label %bb_end, label %bb_loop
290bb_end:
291  %v1 = getelementptr inbounds %swift_error, ptr %error_from_foo, i64 0, i32 1
292  %t = load i8, ptr %v1
293  store i8 %t, ptr %error_ref
294  br label %handler
295handler:
296  call void @free(ptr %error_from_foo)
297  ret float 1.0
298}
299
300; "foo_if" is a function that takes a swifterror parameter, it sets swifterror
301; under a certain condition.
302define float @foo_if(ptr swifterror %error_ptr_ref, i32 %cc) {
303; CHECK-APPLE-LABEL: foo_if:
304; CHECK-APPLE:       ## %bb.0: ## %entry
305; CHECK-APPLE-NEXT:    testl %edi, %edi
306; CHECK-APPLE-NEXT:    je LBB3_2
307; CHECK-APPLE-NEXT:  ## %bb.1: ## %gen_error
308; CHECK-APPLE-NEXT:    pushq %rax
309; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 16
310; CHECK-APPLE-NEXT:    movl $16, %edi
311; CHECK-APPLE-NEXT:    callq _malloc
312; CHECK-APPLE-NEXT:    movb $1, 8(%rax)
313; CHECK-APPLE-NEXT:    movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
314; CHECK-APPLE-NEXT:    movq %rax, %r12
315; CHECK-APPLE-NEXT:    popq %rax
316; CHECK-APPLE-NEXT:    retq
317; CHECK-APPLE-NEXT:  LBB3_2: ## %normal
318; CHECK-APPLE-NEXT:    xorps %xmm0, %xmm0
319; CHECK-APPLE-NEXT:    retq
320;
321; CHECK-O0-LABEL: foo_if:
322; CHECK-O0:       ## %bb.0: ## %entry
323; CHECK-O0-NEXT:    pushq %rax
324; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
325; CHECK-O0-NEXT:    movq %r12, (%rsp) ## 8-byte Spill
326; CHECK-O0-NEXT:    cmpl $0, %edi
327; CHECK-O0-NEXT:    je LBB3_2
328; CHECK-O0-NEXT:  ## %bb.1: ## %gen_error
329; CHECK-O0-NEXT:    movl $16, %edi
330; CHECK-O0-NEXT:    callq _malloc
331; CHECK-O0-NEXT:    movq %rax, %r12
332; CHECK-O0-NEXT:    movb $1, 8(%rax)
333; CHECK-O0-NEXT:    movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
334; CHECK-O0-NEXT:    popq %rax
335; CHECK-O0-NEXT:    retq
336; CHECK-O0-NEXT:  LBB3_2: ## %normal
337; CHECK-O0-NEXT:    movq (%rsp), %r12 ## 8-byte Reload
338; CHECK-O0-NEXT:    xorps %xmm0, %xmm0
339; CHECK-O0-NEXT:    popq %rax
340; CHECK-O0-NEXT:    retq
341;
342; CHECK-i386-LABEL: foo_if:
343; CHECK-i386:       ## %bb.0: ## %entry
344; CHECK-i386-NEXT:    pushl %esi
345; CHECK-i386-NEXT:    .cfi_def_cfa_offset 8
346; CHECK-i386-NEXT:    subl $8, %esp
347; CHECK-i386-NEXT:    .cfi_def_cfa_offset 16
348; CHECK-i386-NEXT:    .cfi_offset %esi, -8
349; CHECK-i386-NEXT:    cmpl $0, 20(%esp)
350; CHECK-i386-NEXT:    je LBB3_2
351; CHECK-i386-NEXT:  ## %bb.1: ## %gen_error
352; CHECK-i386-NEXT:    movl 16(%esp), %esi
353; CHECK-i386-NEXT:    movl $0, 4(%esp)
354; CHECK-i386-NEXT:    movl $16, (%esp)
355; CHECK-i386-NEXT:    calll _malloc
356; CHECK-i386-NEXT:    movl %eax, (%esi)
357; CHECK-i386-NEXT:    movb $1, 8(%eax)
358; CHECK-i386-NEXT:    fld1
359; CHECK-i386-NEXT:    jmp LBB3_3
360; CHECK-i386-NEXT:  LBB3_2: ## %normal
361; CHECK-i386-NEXT:    fldz
362; CHECK-i386-NEXT:  LBB3_3: ## %normal
363; CHECK-i386-NEXT:    addl $8, %esp
364; CHECK-i386-NEXT:    popl %esi
365; CHECK-i386-NEXT:    retl
366
367; spill to stack
368; reload from stack
369entry:
370  %cond = icmp ne i32 %cc, 0
371  br i1 %cond, label %gen_error, label %normal
372
373gen_error:
374  %call = call ptr @malloc(i64 16)
375  store ptr %call, ptr %error_ptr_ref
376  %tmp = getelementptr inbounds i8, ptr %call, i64 8
377  store i8 1, ptr %tmp
378  ret float 1.0
379
380normal:
381  ret float 0.0
382}
383
384; "foo_loop" is a function that takes a swifterror parameter, it sets swifterror
385; under a certain condition inside a loop.
386define float @foo_loop(ptr swifterror %error_ptr_ref, i32 %cc, float %cc2) {
387; CHECK-APPLE-LABEL: foo_loop:
388; CHECK-APPLE:       ## %bb.0: ## %entry
389; CHECK-APPLE-NEXT:    pushq %rbx
390; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 16
391; CHECK-APPLE-NEXT:    subq $16, %rsp
392; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 32
393; CHECK-APPLE-NEXT:    .cfi_offset %rbx, -16
394; CHECK-APPLE-NEXT:    movss %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) ## 4-byte Spill
395; CHECK-APPLE-NEXT:    movl %edi, %ebx
396; CHECK-APPLE-NEXT:    movq %r12, %rax
397; CHECK-APPLE-NEXT:  LBB4_1: ## %bb_loop
398; CHECK-APPLE-NEXT:    ## =>This Inner Loop Header: Depth=1
399; CHECK-APPLE-NEXT:    testl %ebx, %ebx
400; CHECK-APPLE-NEXT:    je LBB4_3
401; CHECK-APPLE-NEXT:  ## %bb.2: ## %gen_error
402; CHECK-APPLE-NEXT:    ## in Loop: Header=BB4_1 Depth=1
403; CHECK-APPLE-NEXT:    movl $16, %edi
404; CHECK-APPLE-NEXT:    callq _malloc
405; CHECK-APPLE-NEXT:    movb $1, 8(%rax)
406; CHECK-APPLE-NEXT:  LBB4_3: ## %bb_cont
407; CHECK-APPLE-NEXT:    ## in Loop: Header=BB4_1 Depth=1
408; CHECK-APPLE-NEXT:    movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 ## 4-byte Reload
409; CHECK-APPLE-NEXT:    ## xmm0 = mem[0],zero,zero,zero
410; CHECK-APPLE-NEXT:    ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
411; CHECK-APPLE-NEXT:    jbe LBB4_1
412; CHECK-APPLE-NEXT:  ## %bb.4: ## %bb_end
413; CHECK-APPLE-NEXT:    xorps %xmm0, %xmm0
414; CHECK-APPLE-NEXT:    movq %rax, %r12
415; CHECK-APPLE-NEXT:    addq $16, %rsp
416; CHECK-APPLE-NEXT:    popq %rbx
417; CHECK-APPLE-NEXT:    retq
418;
419; CHECK-O0-LABEL: foo_loop:
420; CHECK-O0:       ## %bb.0: ## %entry
421; CHECK-O0-NEXT:    subq $40, %rsp
422; CHECK-O0-NEXT:    .cfi_def_cfa_offset 48
423; CHECK-O0-NEXT:    movss %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) ## 4-byte Spill
424; CHECK-O0-NEXT:    movl %edi, {{[-0-9]+}}(%r{{[sb]}}p) ## 4-byte Spill
425; CHECK-O0-NEXT:    movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
426; CHECK-O0-NEXT:    jmp LBB4_1
427; CHECK-O0-NEXT:  LBB4_1: ## %bb_loop
428; CHECK-O0-NEXT:    ## =>This Inner Loop Header: Depth=1
429; CHECK-O0-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %ecx ## 4-byte Reload
430; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rax ## 8-byte Reload
431; CHECK-O0-NEXT:    cmpl $0, %ecx
432; CHECK-O0-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
433; CHECK-O0-NEXT:    je LBB4_3
434; CHECK-O0-NEXT:  ## %bb.2: ## %gen_error
435; CHECK-O0-NEXT:    ## in Loop: Header=BB4_1 Depth=1
436; CHECK-O0-NEXT:    movl $16, %edi
437; CHECK-O0-NEXT:    callq _malloc
438; CHECK-O0-NEXT:    movq %rax, %rcx
439; CHECK-O0-NEXT:    movb $1, 8(%rcx)
440; CHECK-O0-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
441; CHECK-O0-NEXT:  LBB4_3: ## %bb_cont
442; CHECK-O0-NEXT:    ## in Loop: Header=BB4_1 Depth=1
443; CHECK-O0-NEXT:    movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 ## 4-byte Reload
444; CHECK-O0-NEXT:    ## xmm0 = mem[0],zero,zero,zero
445; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rax ## 8-byte Reload
446; CHECK-O0-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
447; CHECK-O0-NEXT:    movss {{.*#+}} xmm1 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
448; CHECK-O0-NEXT:    ucomiss %xmm1, %xmm0
449; CHECK-O0-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
450; CHECK-O0-NEXT:    jbe LBB4_1
451; CHECK-O0-NEXT:  ## %bb.4: ## %bb_end
452; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r12 ## 8-byte Reload
453; CHECK-O0-NEXT:    xorps %xmm0, %xmm0
454; CHECK-O0-NEXT:    addq $40, %rsp
455; CHECK-O0-NEXT:    retq
456;
457; CHECK-i386-LABEL: foo_loop:
458; CHECK-i386:       ## %bb.0: ## %entry
459; CHECK-i386-NEXT:    pushl %edi
460; CHECK-i386-NEXT:    .cfi_def_cfa_offset 8
461; CHECK-i386-NEXT:    pushl %esi
462; CHECK-i386-NEXT:    .cfi_def_cfa_offset 12
463; CHECK-i386-NEXT:    subl $20, %esp
464; CHECK-i386-NEXT:    .cfi_def_cfa_offset 32
465; CHECK-i386-NEXT:    .cfi_offset %esi, -12
466; CHECK-i386-NEXT:    .cfi_offset %edi, -8
467; CHECK-i386-NEXT:    flds 40(%esp)
468; CHECK-i386-NEXT:    fstps {{[-0-9]+}}(%e{{[sb]}}p) ## 4-byte Folded Spill
469; CHECK-i386-NEXT:    movl 36(%esp), %esi
470; CHECK-i386-NEXT:    movl 32(%esp), %edi
471; CHECK-i386-NEXT:  LBB4_1: ## %bb_loop
472; CHECK-i386-NEXT:    ## =>This Inner Loop Header: Depth=1
473; CHECK-i386-NEXT:    testl %esi, %esi
474; CHECK-i386-NEXT:    je LBB4_3
475; CHECK-i386-NEXT:  ## %bb.2: ## %gen_error
476; CHECK-i386-NEXT:    ## in Loop: Header=BB4_1 Depth=1
477; CHECK-i386-NEXT:    movl $0, 4(%esp)
478; CHECK-i386-NEXT:    movl $16, (%esp)
479; CHECK-i386-NEXT:    calll _malloc
480; CHECK-i386-NEXT:    movl %eax, (%edi)
481; CHECK-i386-NEXT:    movb $1, 8(%eax)
482; CHECK-i386-NEXT:  LBB4_3: ## %bb_cont
483; CHECK-i386-NEXT:    ## in Loop: Header=BB4_1 Depth=1
484; CHECK-i386-NEXT:    flds {{[-0-9]+}}(%e{{[sb]}}p) ## 4-byte Folded Reload
485; CHECK-i386-NEXT:    fld1
486; CHECK-i386-NEXT:    fxch %st(1)
487; CHECK-i386-NEXT:    fucompp
488; CHECK-i386-NEXT:    fnstsw %ax
489; CHECK-i386-NEXT:    ## kill: def $ah killed $ah killed $ax
490; CHECK-i386-NEXT:    sahf
491; CHECK-i386-NEXT:    jbe LBB4_1
492; CHECK-i386-NEXT:  ## %bb.4: ## %bb_end
493; CHECK-i386-NEXT:    fldz
494; CHECK-i386-NEXT:    addl $20, %esp
495; CHECK-i386-NEXT:    popl %esi
496; CHECK-i386-NEXT:    popl %edi
497; CHECK-i386-NEXT:    retl
498
499; spill to stack
500; reload from stack
501entry:
502  br label %bb_loop
503
504bb_loop:
505  %cond = icmp ne i32 %cc, 0
506  br i1 %cond, label %gen_error, label %bb_cont
507
508gen_error:
509  %call = call ptr @malloc(i64 16)
510  store ptr %call, ptr %error_ptr_ref
511  %tmp = getelementptr inbounds i8, ptr %call, i64 8
512  store i8 1, ptr %tmp
513  br label %bb_cont
514
515bb_cont:
516  %cmp = fcmp ogt float %cc2, 1.000000e+00
517  br i1 %cmp, label %bb_end, label %bb_loop
518bb_end:
519  ret float 0.0
520}
521
522%struct.S = type { i32, i32, i32, i32, i32, i32 }
523
524; "foo_sret" is a function that takes a swifterror parameter, it also has a sret
525; parameter.
526define void @foo_sret(ptr sret(%struct.S) %agg.result, i32 %val1, ptr swifterror %error_ptr_ref) {
527; CHECK-APPLE-LABEL: foo_sret:
528; CHECK-APPLE:       ## %bb.0: ## %entry
529; CHECK-APPLE-NEXT:    pushq %r14
530; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 16
531; CHECK-APPLE-NEXT:    pushq %rbx
532; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 24
533; CHECK-APPLE-NEXT:    pushq %rax
534; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 32
535; CHECK-APPLE-NEXT:    .cfi_offset %rbx, -24
536; CHECK-APPLE-NEXT:    .cfi_offset %r14, -16
537; CHECK-APPLE-NEXT:    movl %esi, %ebx
538; CHECK-APPLE-NEXT:    movq %rdi, %r14
539; CHECK-APPLE-NEXT:    movl $16, %edi
540; CHECK-APPLE-NEXT:    callq _malloc
541; CHECK-APPLE-NEXT:    movb $1, 8(%rax)
542; CHECK-APPLE-NEXT:    movl %ebx, 4(%r14)
543; CHECK-APPLE-NEXT:    movq %rax, %r12
544; CHECK-APPLE-NEXT:    movq %r14, %rax
545; CHECK-APPLE-NEXT:    addq $8, %rsp
546; CHECK-APPLE-NEXT:    popq %rbx
547; CHECK-APPLE-NEXT:    popq %r14
548; CHECK-APPLE-NEXT:    retq
549;
550; CHECK-O0-LABEL: foo_sret:
551; CHECK-O0:       ## %bb.0: ## %entry
552; CHECK-O0-NEXT:    subq $24, %rsp
553; CHECK-O0-NEXT:    .cfi_def_cfa_offset 32
554; CHECK-O0-NEXT:    movl %esi, {{[-0-9]+}}(%r{{[sb]}}p) ## 4-byte Spill
555; CHECK-O0-NEXT:    movq %rdi, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
556; CHECK-O0-NEXT:    movq %rdi, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
557; CHECK-O0-NEXT:    movl $16, %edi
558; CHECK-O0-NEXT:    callq _malloc
559; CHECK-O0-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %esi ## 4-byte Reload
560; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rdi ## 8-byte Reload
561; CHECK-O0-NEXT:    movq %rax, %rcx
562; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rax ## 8-byte Reload
563; CHECK-O0-NEXT:    movq %rcx, %r12
564; CHECK-O0-NEXT:    movb $1, 8(%rcx)
565; CHECK-O0-NEXT:    movl %esi, 4(%rdi)
566; CHECK-O0-NEXT:    addq $24, %rsp
567; CHECK-O0-NEXT:    retq
568;
569; CHECK-i386-LABEL: foo_sret:
570; CHECK-i386:       ## %bb.0: ## %entry
571; CHECK-i386-NEXT:    pushl %ebx
572; CHECK-i386-NEXT:    .cfi_def_cfa_offset 8
573; CHECK-i386-NEXT:    pushl %edi
574; CHECK-i386-NEXT:    .cfi_def_cfa_offset 12
575; CHECK-i386-NEXT:    pushl %esi
576; CHECK-i386-NEXT:    .cfi_def_cfa_offset 16
577; CHECK-i386-NEXT:    subl $16, %esp
578; CHECK-i386-NEXT:    .cfi_def_cfa_offset 32
579; CHECK-i386-NEXT:    .cfi_offset %esi, -16
580; CHECK-i386-NEXT:    .cfi_offset %edi, -12
581; CHECK-i386-NEXT:    .cfi_offset %ebx, -8
582; CHECK-i386-NEXT:    movl 32(%esp), %esi
583; CHECK-i386-NEXT:    movl 36(%esp), %edi
584; CHECK-i386-NEXT:    movl 40(%esp), %ebx
585; CHECK-i386-NEXT:    movl $0, 4(%esp)
586; CHECK-i386-NEXT:    movl $16, (%esp)
587; CHECK-i386-NEXT:    calll _malloc
588; CHECK-i386-NEXT:    movl %eax, (%ebx)
589; CHECK-i386-NEXT:    movb $1, 8(%eax)
590; CHECK-i386-NEXT:    movl %edi, 4(%esi)
591; CHECK-i386-NEXT:    movl %esi, %eax
592; CHECK-i386-NEXT:    addl $16, %esp
593; CHECK-i386-NEXT:    popl %esi
594; CHECK-i386-NEXT:    popl %edi
595; CHECK-i386-NEXT:    popl %ebx
596; CHECK-i386-NEXT:    retl $4
597
598; spill sret to stack
599; reload sret from stack
600entry:
601  %call = call ptr @malloc(i64 16)
602  store ptr %call, ptr %error_ptr_ref
603  %tmp = getelementptr inbounds i8, ptr %call, i64 8
604  store i8 1, ptr %tmp
605  %v2 = getelementptr inbounds %struct.S, ptr %agg.result, i32 0, i32 1
606  store i32 %val1, ptr %v2
607  ret void
608}
609
610; "caller3" calls "foo_sret" that takes a swifterror parameter.
611define float @caller3(ptr %error_ref) {
612; CHECK-APPLE-LABEL: caller3:
613; CHECK-APPLE:       ## %bb.0: ## %entry
614; CHECK-APPLE-NEXT:    pushq %r12
615; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 16
616; CHECK-APPLE-NEXT:    pushq %rbx
617; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 24
618; CHECK-APPLE-NEXT:    subq $40, %rsp
619; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 64
620; CHECK-APPLE-NEXT:    .cfi_offset %rbx, -24
621; CHECK-APPLE-NEXT:    .cfi_offset %r12, -16
622; CHECK-APPLE-NEXT:    movq %rdi, %rbx
623; CHECK-APPLE-NEXT:    leaq 8(%rsp), %rdi
624; CHECK-APPLE-NEXT:    movl $1, %esi
625; CHECK-APPLE-NEXT:    xorl %r12d, %r12d
626; CHECK-APPLE-NEXT:    callq _foo_sret
627; CHECK-APPLE-NEXT:    movq %r12, %rdi
628; CHECK-APPLE-NEXT:    testq %r12, %r12
629; CHECK-APPLE-NEXT:    jne LBB6_2
630; CHECK-APPLE-NEXT:  ## %bb.1: ## %cont
631; CHECK-APPLE-NEXT:    movzbl 8(%rdi), %eax
632; CHECK-APPLE-NEXT:    movb %al, (%rbx)
633; CHECK-APPLE-NEXT:  LBB6_2: ## %handler
634; CHECK-APPLE-NEXT:    callq _free
635; CHECK-APPLE-NEXT:    movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
636; CHECK-APPLE-NEXT:    addq $40, %rsp
637; CHECK-APPLE-NEXT:    popq %rbx
638; CHECK-APPLE-NEXT:    popq %r12
639; CHECK-APPLE-NEXT:    retq
640;
641; CHECK-O0-LABEL: caller3:
642; CHECK-O0:       ## %bb.0: ## %entry
643; CHECK-O0-NEXT:    pushq %r12
644; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
645; CHECK-O0-NEXT:    subq $48, %rsp
646; CHECK-O0-NEXT:    .cfi_def_cfa_offset 64
647; CHECK-O0-NEXT:    .cfi_offset %r12, -16
648; CHECK-O0-NEXT:    ## implicit-def: $rax
649; CHECK-O0-NEXT:    movq %rdi, (%rsp) ## 8-byte Spill
650; CHECK-O0-NEXT:    xorl %eax, %eax
651; CHECK-O0-NEXT:    movl %eax, %r12d
652; CHECK-O0-NEXT:    leaq 24(%rsp), %rdi
653; CHECK-O0-NEXT:    movl $1, %esi
654; CHECK-O0-NEXT:    callq _foo_sret
655; CHECK-O0-NEXT:    movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
656; CHECK-O0-NEXT:    cmpq $0, %r12
657; CHECK-O0-NEXT:    jne LBB6_2
658; CHECK-O0-NEXT:  ## %bb.1: ## %cont
659; CHECK-O0-NEXT:    movq (%rsp), %rax ## 8-byte Reload
660; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx ## 8-byte Reload
661; CHECK-O0-NEXT:    movb 8(%rcx), %cl
662; CHECK-O0-NEXT:    movb %cl, (%rax)
663; CHECK-O0-NEXT:  LBB6_2: ## %handler
664; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rdi ## 8-byte Reload
665; CHECK-O0-NEXT:    callq _free
666; CHECK-O0-NEXT:    movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
667; CHECK-O0-NEXT:    addq $48, %rsp
668; CHECK-O0-NEXT:    popq %r12
669; CHECK-O0-NEXT:    retq
670;
671; CHECK-i386-LABEL: caller3:
672; CHECK-i386:       ## %bb.0: ## %entry
673; CHECK-i386-NEXT:    subl $44, %esp
674; CHECK-i386-NEXT:    .cfi_def_cfa_offset 48
675; CHECK-i386-NEXT:    movl $0, 12(%esp)
676; CHECK-i386-NEXT:    leal 12(%esp), %eax
677; CHECK-i386-NEXT:    movl %eax, 8(%esp)
678; CHECK-i386-NEXT:    leal 16(%esp), %eax
679; CHECK-i386-NEXT:    movl %eax, (%esp)
680; CHECK-i386-NEXT:    movl $1, 4(%esp)
681; CHECK-i386-NEXT:    calll _foo_sret
682; CHECK-i386-NEXT:    subl $4, %esp
683; CHECK-i386-NEXT:    movl 12(%esp), %eax
684; CHECK-i386-NEXT:    testl %eax, %eax
685; CHECK-i386-NEXT:    jne LBB6_2
686; CHECK-i386-NEXT:  ## %bb.1: ## %cont
687; CHECK-i386-NEXT:    movl 48(%esp), %ecx
688; CHECK-i386-NEXT:    movzbl 8(%eax), %edx
689; CHECK-i386-NEXT:    movb %dl, (%ecx)
690; CHECK-i386-NEXT:  LBB6_2: ## %handler
691; CHECK-i386-NEXT:    movl %eax, (%esp)
692; CHECK-i386-NEXT:    calll _free
693; CHECK-i386-NEXT:    fld1
694; CHECK-i386-NEXT:    addl $44, %esp
695; CHECK-i386-NEXT:    retl
696; Access part of the error object and save it to error_ref
697
698; Access part of the error object and save it to error_ref
699; reload from stack
700entry:
701  %s = alloca %struct.S, align 8
702  %error_ptr_ref = alloca swifterror ptr
703  store ptr null, ptr %error_ptr_ref
704  call void @foo_sret(ptr sret(%struct.S) %s, i32 1, ptr swifterror %error_ptr_ref)
705  %error_from_foo = load ptr, ptr %error_ptr_ref
706  %had_error_from_foo = icmp ne ptr %error_from_foo, null
707  br i1 %had_error_from_foo, label %handler, label %cont
708cont:
709  %v1 = getelementptr inbounds %swift_error, ptr %error_from_foo, i64 0, i32 1
710  %t = load i8, ptr %v1
711  store i8 %t, ptr %error_ref
712  br label %handler
713handler:
714  call void @free(ptr %error_from_foo)
715  ret float 1.0
716}
717
718; This is a caller with multiple swifterror values, it calls "foo" twice, each
719; time with a different swifterror value, from "alloca swifterror".
720define float @caller_with_multiple_swifterror_values(ptr %error_ref, ptr %error_ref2) {
721; CHECK-APPLE-LABEL: caller_with_multiple_swifterror_values:
722; CHECK-APPLE:       ## %bb.0: ## %entry
723; CHECK-APPLE-NEXT:    pushq %rbp
724; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 16
725; CHECK-APPLE-NEXT:    .cfi_offset %rbp, -16
726; CHECK-APPLE-NEXT:    movq %rsp, %rbp
727; CHECK-APPLE-NEXT:    .cfi_def_cfa_register %rbp
728; CHECK-APPLE-NEXT:    pushq %r14
729; CHECK-APPLE-NEXT:    pushq %r12
730; CHECK-APPLE-NEXT:    pushq %rbx
731; CHECK-APPLE-NEXT:    pushq %rax
732; CHECK-APPLE-NEXT:    .cfi_offset %rbx, -40
733; CHECK-APPLE-NEXT:    .cfi_offset %r12, -32
734; CHECK-APPLE-NEXT:    .cfi_offset %r14, -24
735; CHECK-APPLE-NEXT:    movq %rsi, %rbx
736; CHECK-APPLE-NEXT:    movq %rdi, %r14
737; CHECK-APPLE-NEXT:    xorl %r12d, %r12d
738; CHECK-APPLE-NEXT:    callq _foo
739; CHECK-APPLE-NEXT:    movq %r12, %rdi
740; CHECK-APPLE-NEXT:    testq %r12, %r12
741; CHECK-APPLE-NEXT:    jne LBB7_2
742; CHECK-APPLE-NEXT:  ## %bb.1: ## %cont
743; CHECK-APPLE-NEXT:    movzbl 8(%rdi), %eax
744; CHECK-APPLE-NEXT:    movb %al, (%r14)
745; CHECK-APPLE-NEXT:  LBB7_2: ## %handler
746; CHECK-APPLE-NEXT:    callq _free
747; CHECK-APPLE-NEXT:    movq %rsp, %rax
748; CHECK-APPLE-NEXT:    addq $-16, %rax
749; CHECK-APPLE-NEXT:    movq %rax, %rsp
750; CHECK-APPLE-NEXT:    xorl %r12d, %r12d
751; CHECK-APPLE-NEXT:    callq _foo
752; CHECK-APPLE-NEXT:    movq %r12, %rdi
753; CHECK-APPLE-NEXT:    testq %r12, %r12
754; CHECK-APPLE-NEXT:    jne LBB7_4
755; CHECK-APPLE-NEXT:  ## %bb.3: ## %cont2
756; CHECK-APPLE-NEXT:    movzbl 8(%rdi), %eax
757; CHECK-APPLE-NEXT:    movb %al, (%rbx)
758; CHECK-APPLE-NEXT:  LBB7_4: ## %handler2
759; CHECK-APPLE-NEXT:    callq _free
760; CHECK-APPLE-NEXT:    movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
761; CHECK-APPLE-NEXT:    leaq -24(%rbp), %rsp
762; CHECK-APPLE-NEXT:    popq %rbx
763; CHECK-APPLE-NEXT:    popq %r12
764; CHECK-APPLE-NEXT:    popq %r14
765; CHECK-APPLE-NEXT:    popq %rbp
766; CHECK-APPLE-NEXT:    retq
767;
768; CHECK-O0-LABEL: caller_with_multiple_swifterror_values:
769; CHECK-O0:       ## %bb.0: ## %entry
770; CHECK-O0-NEXT:    pushq %rbp
771; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
772; CHECK-O0-NEXT:    .cfi_offset %rbp, -16
773; CHECK-O0-NEXT:    movq %rsp, %rbp
774; CHECK-O0-NEXT:    .cfi_def_cfa_register %rbp
775; CHECK-O0-NEXT:    pushq %r12
776; CHECK-O0-NEXT:    subq $40, %rsp
777; CHECK-O0-NEXT:    .cfi_offset %r12, -24
778; CHECK-O0-NEXT:    ## implicit-def: $rax
779; CHECK-O0-NEXT:    ## implicit-def: $rax
780; CHECK-O0-NEXT:    movq %rdi, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
781; CHECK-O0-NEXT:    movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
782; CHECK-O0-NEXT:    xorl %eax, %eax
783; CHECK-O0-NEXT:    movl %eax, %r12d
784; CHECK-O0-NEXT:    callq _foo
785; CHECK-O0-NEXT:    movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
786; CHECK-O0-NEXT:    cmpq $0, %r12
787; CHECK-O0-NEXT:    jne LBB7_2
788; CHECK-O0-NEXT:  ## %bb.1: ## %cont
789; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rax ## 8-byte Reload
790; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx ## 8-byte Reload
791; CHECK-O0-NEXT:    movb 8(%rcx), %cl
792; CHECK-O0-NEXT:    movb %cl, (%rax)
793; CHECK-O0-NEXT:  LBB7_2: ## %handler
794; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rdi ## 8-byte Reload
795; CHECK-O0-NEXT:    callq _free
796; CHECK-O0-NEXT:    movq %rsp, %rax
797; CHECK-O0-NEXT:    addq $-16, %rax
798; CHECK-O0-NEXT:    movq %rax, %rsp
799; CHECK-O0-NEXT:    xorl %eax, %eax
800; CHECK-O0-NEXT:    movl %eax, %r12d
801; CHECK-O0-NEXT:    callq _foo
802; CHECK-O0-NEXT:    movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
803; CHECK-O0-NEXT:    cmpq $0, %r12
804; CHECK-O0-NEXT:    jne LBB7_4
805; CHECK-O0-NEXT:  ## %bb.3: ## %cont2
806; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rax ## 8-byte Reload
807; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx ## 8-byte Reload
808; CHECK-O0-NEXT:    movb 8(%rcx), %cl
809; CHECK-O0-NEXT:    movb %cl, (%rax)
810; CHECK-O0-NEXT:  LBB7_4: ## %handler2
811; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rdi ## 8-byte Reload
812; CHECK-O0-NEXT:    callq _free
813; CHECK-O0-NEXT:    movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
814; CHECK-O0-NEXT:    leaq -8(%rbp), %rsp
815; CHECK-O0-NEXT:    popq %r12
816; CHECK-O0-NEXT:    popq %rbp
817; CHECK-O0-NEXT:    retq
818;
819; CHECK-i386-LABEL: caller_with_multiple_swifterror_values:
820; CHECK-i386:       ## %bb.0: ## %entry
821; CHECK-i386-NEXT:    pushl %ebp
822; CHECK-i386-NEXT:    .cfi_def_cfa_offset 8
823; CHECK-i386-NEXT:    .cfi_offset %ebp, -8
824; CHECK-i386-NEXT:    movl %esp, %ebp
825; CHECK-i386-NEXT:    .cfi_def_cfa_register %ebp
826; CHECK-i386-NEXT:    pushl %esi
827; CHECK-i386-NEXT:    pushl %eax
828; CHECK-i386-NEXT:    .cfi_offset %esi, -12
829; CHECK-i386-NEXT:    movl $0, -8(%ebp)
830; CHECK-i386-NEXT:    subl $12, %esp
831; CHECK-i386-NEXT:    leal -8(%ebp), %eax
832; CHECK-i386-NEXT:    pushl %eax
833; CHECK-i386-NEXT:    calll _foo
834; CHECK-i386-NEXT:    fstp %st(0)
835; CHECK-i386-NEXT:    addl $16, %esp
836; CHECK-i386-NEXT:    movl -8(%ebp), %eax
837; CHECK-i386-NEXT:    testl %eax, %eax
838; CHECK-i386-NEXT:    jne LBB7_2
839; CHECK-i386-NEXT:  ## %bb.1: ## %cont
840; CHECK-i386-NEXT:    movl 8(%ebp), %ecx
841; CHECK-i386-NEXT:    movzbl 8(%eax), %edx
842; CHECK-i386-NEXT:    movb %dl, (%ecx)
843; CHECK-i386-NEXT:  LBB7_2: ## %handler
844; CHECK-i386-NEXT:    subl $12, %esp
845; CHECK-i386-NEXT:    pushl %eax
846; CHECK-i386-NEXT:    calll _free
847; CHECK-i386-NEXT:    addl $16, %esp
848; CHECK-i386-NEXT:    movl %esp, %esi
849; CHECK-i386-NEXT:    leal -16(%esi), %eax
850; CHECK-i386-NEXT:    movl %eax, %esp
851; CHECK-i386-NEXT:    movl $0, -16(%esi)
852; CHECK-i386-NEXT:    subl $12, %esp
853; CHECK-i386-NEXT:    pushl %eax
854; CHECK-i386-NEXT:    calll _foo
855; CHECK-i386-NEXT:    fstp %st(0)
856; CHECK-i386-NEXT:    addl $16, %esp
857; CHECK-i386-NEXT:    movl -16(%esi), %eax
858; CHECK-i386-NEXT:    testl %eax, %eax
859; CHECK-i386-NEXT:    jne LBB7_4
860; CHECK-i386-NEXT:  ## %bb.3: ## %cont2
861; CHECK-i386-NEXT:    movl 12(%ebp), %ecx
862; CHECK-i386-NEXT:    movzbl 8(%eax), %edx
863; CHECK-i386-NEXT:    movb %dl, (%ecx)
864; CHECK-i386-NEXT:  LBB7_4: ## %handler2
865; CHECK-i386-NEXT:    subl $12, %esp
866; CHECK-i386-NEXT:    pushl %eax
867; CHECK-i386-NEXT:    calll _free
868; CHECK-i386-NEXT:    addl $16, %esp
869; CHECK-i386-NEXT:    fld1
870; CHECK-i386-NEXT:    leal -4(%ebp), %esp
871; CHECK-i386-NEXT:    popl %esi
872; CHECK-i386-NEXT:    popl %ebp
873; CHECK-i386-NEXT:    retl
874
875; The first swifterror value:
876; Access part of the error object and save it to error_ref
877
878; The second swifterror value:
879; Access part of the error object and save it to error_ref
880
881
882; The first swifterror value:
883
884; The second swifterror value:
885entry:
886  %error_ptr_ref = alloca swifterror ptr
887  store ptr null, ptr %error_ptr_ref
888  %call = call float @foo(ptr swifterror %error_ptr_ref)
889  %error_from_foo = load ptr, ptr %error_ptr_ref
890  %had_error_from_foo = icmp ne ptr %error_from_foo, null
891  br i1 %had_error_from_foo, label %handler, label %cont
892cont:
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
897handler:
898  call void @free(ptr %error_from_foo)
899
900  %error_ptr_ref2 = alloca swifterror ptr
901  store ptr null, ptr %error_ptr_ref2
902  %call2 = call float @foo(ptr swifterror %error_ptr_ref2)
903  %error_from_foo2 = load ptr, ptr %error_ptr_ref2
904  %had_error_from_foo2 = icmp ne ptr %error_from_foo2, null
905  br i1 %had_error_from_foo2, label %handler2, label %cont2
906cont2:
907  %v2 = getelementptr inbounds %swift_error, ptr %error_from_foo2, i64 0, i32 1
908  %t2 = load i8, ptr %v2
909  store i8 %t2, ptr %error_ref2
910  br label %handler2
911handler2:
912  call void @free(ptr %error_from_foo2)
913
914  ret float 1.0
915}
916
917%swift.refcounted = type opaque
918
919; This test checks that we don't create bad phi nodes as part of swifterror
920; isel. We used to fail machine ir verification.
921; CHECK-APPLE: _swifterror_isel
922; CHECK-O0: _swifterror_isel
923define void @swifterror_isel(ptr) {
924; CHECK-APPLE-LABEL: swifterror_isel:
925; CHECK-APPLE:       ## %bb.0: ## %entry
926; CHECK-APPLE-NEXT:    pushq %r13
927; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 16
928; CHECK-APPLE-NEXT:    pushq %r12
929; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 24
930; CHECK-APPLE-NEXT:    pushq %rax
931; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 32
932; CHECK-APPLE-NEXT:    .cfi_offset %r12, -24
933; CHECK-APPLE-NEXT:    .cfi_offset %r13, -16
934; CHECK-APPLE-NEXT:    xorl %eax, %eax
935; CHECK-APPLE-NEXT:    testb %al, %al
936; CHECK-APPLE-NEXT:    jne LBB8_3
937; CHECK-APPLE-NEXT:  ## %bb.1: ## %.preheader
938; CHECK-APPLE-NEXT:    movq %rdi, %r13
939; CHECK-APPLE-NEXT:    ## implicit-def: $di
940; CHECK-APPLE-NEXT:    ## implicit-def: $r12
941; CHECK-APPLE-NEXT:  LBB8_2: ## =>This Inner Loop Header: Depth=1
942; CHECK-APPLE-NEXT:    callq *%rax
943; CHECK-APPLE-NEXT:    movzwl (%rax), %edi
944; CHECK-APPLE-NEXT:    jmp LBB8_2
945; CHECK-APPLE-NEXT:  LBB8_3:
946; CHECK-APPLE-NEXT:    addq $8, %rsp
947; CHECK-APPLE-NEXT:    popq %r12
948; CHECK-APPLE-NEXT:    popq %r13
949; CHECK-APPLE-NEXT:    retq
950;
951; CHECK-O0-LABEL: swifterror_isel:
952; CHECK-O0:       ## %bb.0: ## %entry
953; CHECK-O0-NEXT:    pushq %r13
954; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
955; CHECK-O0-NEXT:    pushq %r12
956; CHECK-O0-NEXT:    .cfi_def_cfa_offset 24
957; CHECK-O0-NEXT:    subq $40, %rsp
958; CHECK-O0-NEXT:    .cfi_def_cfa_offset 64
959; CHECK-O0-NEXT:    .cfi_offset %r12, -24
960; CHECK-O0-NEXT:    .cfi_offset %r13, -16
961; CHECK-O0-NEXT:    movq %rdi, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
962; CHECK-O0-NEXT:    ## implicit-def: $al
963; CHECK-O0-NEXT:    testb $1, %al
964; CHECK-O0-NEXT:    ## implicit-def: $ax
965; CHECK-O0-NEXT:    ## implicit-def: $r12
966; CHECK-O0-NEXT:    jne LBB8_2
967; CHECK-O0-NEXT:  LBB8_1: ## =>This Inner Loop Header: Depth=1
968; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r12 ## 8-byte Reload
969; CHECK-O0-NEXT:    movw {{[-0-9]+}}(%r{{[sb]}}p), %ax ## 2-byte Reload
970; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r13 ## 8-byte Reload
971; CHECK-O0-NEXT:    ## implicit-def: $edi
972; CHECK-O0-NEXT:    movw %ax, %di
973; CHECK-O0-NEXT:    ## implicit-def: $rax
974; CHECK-O0-NEXT:    callq *%rax
975; CHECK-O0-NEXT:    ## implicit-def: $rax
976; CHECK-O0-NEXT:    movw (%rax), %ax
977; CHECK-O0-NEXT:    movw %ax, {{[-0-9]+}}(%r{{[sb]}}p) ## 2-byte Spill
978; CHECK-O0-NEXT:    movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
979; CHECK-O0-NEXT:    jmp LBB8_1
980; CHECK-O0-NEXT:  LBB8_2:
981; CHECK-O0-NEXT:    addq $40, %rsp
982; CHECK-O0-NEXT:    popq %r12
983; CHECK-O0-NEXT:    popq %r13
984; CHECK-O0-NEXT:    retq
985;
986; CHECK-i386-LABEL: swifterror_isel:
987; CHECK-i386:       ## %bb.0: ## %entry
988; CHECK-i386-NEXT:    pushl %edi
989; CHECK-i386-NEXT:    .cfi_def_cfa_offset 8
990; CHECK-i386-NEXT:    pushl %esi
991; CHECK-i386-NEXT:    .cfi_def_cfa_offset 12
992; CHECK-i386-NEXT:    subl $20, %esp
993; CHECK-i386-NEXT:    .cfi_def_cfa_offset 32
994; CHECK-i386-NEXT:    .cfi_offset %esi, -12
995; CHECK-i386-NEXT:    .cfi_offset %edi, -8
996; CHECK-i386-NEXT:    xorl %eax, %eax
997; CHECK-i386-NEXT:    testb %al, %al
998; CHECK-i386-NEXT:    jne LBB8_3
999; CHECK-i386-NEXT:  ## %bb.1: ## %.preheader
1000; CHECK-i386-NEXT:    movl 32(%esp), %esi
1001; CHECK-i386-NEXT:    leal 16(%esp), %edi
1002; CHECK-i386-NEXT:    ## implicit-def: $ax
1003; CHECK-i386-NEXT:  LBB8_2: ## =>This Inner Loop Header: Depth=1
1004; CHECK-i386-NEXT:    movl %edi, 8(%esp)
1005; CHECK-i386-NEXT:    movl %esi, 4(%esp)
1006; CHECK-i386-NEXT:    movl %eax, (%esp)
1007; CHECK-i386-NEXT:    calll *%eax
1008; CHECK-i386-NEXT:    movzwl (%eax), %eax
1009; CHECK-i386-NEXT:    jmp LBB8_2
1010; CHECK-i386-NEXT:  LBB8_3:
1011; CHECK-i386-NEXT:    addl $20, %esp
1012; CHECK-i386-NEXT:    popl %esi
1013; CHECK-i386-NEXT:    popl %edi
1014; CHECK-i386-NEXT:    retl
1015entry:
1016  %swifterror = alloca swifterror ptr, align 8
1017  br i1 poison, label %5, label %1
1018
1019  %2 = phi i16 [ %4, %1 ], [ undef, %entry ]
1020  %3 = call i1 undef(i16 %2, ptr swiftself %0, ptr nocapture swifterror %swifterror)
1021  %4 = load i16, ptr undef, align 2
1022  br label %1
1023
1024  ret void
1025}
1026
1027; This tests the basic usage of a swifterror parameter with swiftcc.
1028define swiftcc float @foo_swiftcc(ptr swifterror %error_ptr_ref) {
1029; CHECK-APPLE-LABEL: foo_swiftcc:
1030; CHECK-APPLE:       ## %bb.0: ## %entry
1031; CHECK-APPLE-NEXT:    pushq %rax
1032; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 16
1033; CHECK-APPLE-NEXT:    movl $16, %edi
1034; CHECK-APPLE-NEXT:    callq _malloc
1035; CHECK-APPLE-NEXT:    movb $1, 8(%rax)
1036; CHECK-APPLE-NEXT:    movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
1037; CHECK-APPLE-NEXT:    movq %rax, %r12
1038; CHECK-APPLE-NEXT:    popq %rax
1039; CHECK-APPLE-NEXT:    retq
1040;
1041; CHECK-O0-LABEL: foo_swiftcc:
1042; CHECK-O0:       ## %bb.0: ## %entry
1043; CHECK-O0-NEXT:    pushq %rax
1044; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
1045; CHECK-O0-NEXT:    movl $16, %edi
1046; CHECK-O0-NEXT:    callq _malloc
1047; CHECK-O0-NEXT:    movq %rax, %r12
1048; CHECK-O0-NEXT:    movb $1, 8(%rax)
1049; CHECK-O0-NEXT:    movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
1050; CHECK-O0-NEXT:    popq %rax
1051; CHECK-O0-NEXT:    retq
1052;
1053; CHECK-i386-LABEL: foo_swiftcc:
1054; CHECK-i386:       ## %bb.0: ## %entry
1055; CHECK-i386-NEXT:    pushl %esi
1056; CHECK-i386-NEXT:    .cfi_def_cfa_offset 8
1057; CHECK-i386-NEXT:    subl $8, %esp
1058; CHECK-i386-NEXT:    .cfi_def_cfa_offset 16
1059; CHECK-i386-NEXT:    .cfi_offset %esi, -8
1060; CHECK-i386-NEXT:    movl 16(%esp), %esi
1061; CHECK-i386-NEXT:    movl $0, 4(%esp)
1062; CHECK-i386-NEXT:    movl $16, (%esp)
1063; CHECK-i386-NEXT:    calll _malloc
1064; CHECK-i386-NEXT:    movl %eax, (%esi)
1065; CHECK-i386-NEXT:    movb $1, 8(%eax)
1066; CHECK-i386-NEXT:    fld1
1067; CHECK-i386-NEXT:    addl $8, %esp
1068; CHECK-i386-NEXT:    popl %esi
1069; CHECK-i386-NEXT:    retl
1070
1071
1072entry:
1073  %call = call ptr @malloc(i64 16)
1074  store ptr %call, ptr %error_ptr_ref
1075  %tmp = getelementptr inbounds i8, ptr %call, i64 8
1076  store i8 1, ptr %tmp
1077  ret float 1.0
1078}
1079
1080declare swiftcc float @moo(ptr swifterror)
1081
1082; Test parameter forwarding.
1083define swiftcc float @forward_swifterror(ptr swifterror %error_ptr_ref) {
1084; CHECK-APPLE-LABEL: forward_swifterror:
1085; CHECK-APPLE:       ## %bb.0: ## %entry
1086; CHECK-APPLE-NEXT:    pushq %rax
1087; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 16
1088; CHECK-APPLE-NEXT:    callq _moo
1089; CHECK-APPLE-NEXT:    popq %rax
1090; CHECK-APPLE-NEXT:    retq
1091;
1092; CHECK-O0-LABEL: forward_swifterror:
1093; CHECK-O0:       ## %bb.0: ## %entry
1094; CHECK-O0-NEXT:    pushq %rax
1095; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
1096; CHECK-O0-NEXT:    callq _moo
1097; CHECK-O0-NEXT:    popq %rax
1098; CHECK-O0-NEXT:    retq
1099;
1100; CHECK-i386-LABEL: forward_swifterror:
1101; CHECK-i386:       ## %bb.0: ## %entry
1102; CHECK-i386-NEXT:    subl $12, %esp
1103; CHECK-i386-NEXT:    .cfi_def_cfa_offset 16
1104; CHECK-i386-NEXT:    movl 16(%esp), %eax
1105; CHECK-i386-NEXT:    movl %eax, (%esp)
1106; CHECK-i386-NEXT:    calll _moo
1107; CHECK-i386-NEXT:    addl $12, %esp
1108; CHECK-i386-NEXT:    retl
1109
1110
1111entry:
1112  %call = call swiftcc float @moo(ptr swifterror %error_ptr_ref)
1113  ret float %call
1114}
1115
1116define swiftcc float @conditionally_forward_swifterror(ptr swifterror %error_ptr_ref, i32 %cc) {
1117; CHECK-APPLE-LABEL: conditionally_forward_swifterror:
1118; CHECK-APPLE:       ## %bb.0: ## %entry
1119; CHECK-APPLE-NEXT:    testl %edi, %edi
1120; CHECK-APPLE-NEXT:    je LBB11_2
1121; CHECK-APPLE-NEXT:  ## %bb.1: ## %gen_error
1122; CHECK-APPLE-NEXT:    pushq %rax
1123; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 16
1124; CHECK-APPLE-NEXT:    callq _moo
1125; CHECK-APPLE-NEXT:    popq %rax
1126; CHECK-APPLE-NEXT:    retq
1127; CHECK-APPLE-NEXT:  LBB11_2: ## %normal
1128; CHECK-APPLE-NEXT:    xorps %xmm0, %xmm0
1129; CHECK-APPLE-NEXT:    retq
1130;
1131; CHECK-O0-LABEL: conditionally_forward_swifterror:
1132; CHECK-O0:       ## %bb.0: ## %entry
1133; CHECK-O0-NEXT:    pushq %rax
1134; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
1135; CHECK-O0-NEXT:    movq %r12, (%rsp) ## 8-byte Spill
1136; CHECK-O0-NEXT:    cmpl $0, %edi
1137; CHECK-O0-NEXT:    je LBB11_2
1138; CHECK-O0-NEXT:  ## %bb.1: ## %gen_error
1139; CHECK-O0-NEXT:    movq (%rsp), %r12 ## 8-byte Reload
1140; CHECK-O0-NEXT:    callq _moo
1141; CHECK-O0-NEXT:    popq %rax
1142; CHECK-O0-NEXT:    retq
1143; CHECK-O0-NEXT:  LBB11_2: ## %normal
1144; CHECK-O0-NEXT:    movq (%rsp), %r12 ## 8-byte Reload
1145; CHECK-O0-NEXT:    xorps %xmm0, %xmm0
1146; CHECK-O0-NEXT:    popq %rax
1147; CHECK-O0-NEXT:    retq
1148;
1149; CHECK-i386-LABEL: conditionally_forward_swifterror:
1150; CHECK-i386:       ## %bb.0: ## %entry
1151; CHECK-i386-NEXT:    subl $12, %esp
1152; CHECK-i386-NEXT:    .cfi_def_cfa_offset 16
1153; CHECK-i386-NEXT:    cmpl $0, 20(%esp)
1154; CHECK-i386-NEXT:    je LBB11_2
1155; CHECK-i386-NEXT:  ## %bb.1: ## %gen_error
1156; CHECK-i386-NEXT:    movl 16(%esp), %eax
1157; CHECK-i386-NEXT:    movl %eax, (%esp)
1158; CHECK-i386-NEXT:    calll _moo
1159; CHECK-i386-NEXT:    addl $12, %esp
1160; CHECK-i386-NEXT:    retl
1161; CHECK-i386-NEXT:  LBB11_2: ## %normal
1162; CHECK-i386-NEXT:    fldz
1163; CHECK-i386-NEXT:    addl $12, %esp
1164; CHECK-i386-NEXT:    retl
1165
1166
1167
1168
1169
1170entry:
1171  %cond = icmp ne i32 %cc, 0
1172  br i1 %cond, label %gen_error, label %normal
1173
1174gen_error:
1175  %call = call swiftcc float @moo(ptr swifterror %error_ptr_ref)
1176  ret float %call
1177
1178normal:
1179  ret float 0.0
1180}
1181
1182; Check that we don't blow up on tail calling swifterror argument functions.
1183define float @tailcallswifterror(ptr swifterror %error_ptr_ref) {
1184; CHECK-APPLE-LABEL: tailcallswifterror:
1185; CHECK-APPLE:       ## %bb.0: ## %entry
1186; CHECK-APPLE-NEXT:    pushq %rax
1187; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 16
1188; CHECK-APPLE-NEXT:    callq _tailcallswifterror
1189; CHECK-APPLE-NEXT:    popq %rax
1190; CHECK-APPLE-NEXT:    retq
1191;
1192; CHECK-O0-LABEL: tailcallswifterror:
1193; CHECK-O0:       ## %bb.0: ## %entry
1194; CHECK-O0-NEXT:    pushq %rax
1195; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
1196; CHECK-O0-NEXT:    callq _tailcallswifterror
1197; CHECK-O0-NEXT:    popq %rax
1198; CHECK-O0-NEXT:    retq
1199;
1200; CHECK-i386-LABEL: tailcallswifterror:
1201; CHECK-i386:       ## %bb.0: ## %entry
1202; CHECK-i386-NEXT:    jmp _tailcallswifterror ## TAILCALL
1203entry:
1204  %0 = tail call float @tailcallswifterror(ptr swifterror %error_ptr_ref)
1205  ret float %0
1206}
1207define swiftcc float @tailcallswifterror_swiftcc(ptr swifterror %error_ptr_ref) {
1208; CHECK-APPLE-LABEL: tailcallswifterror_swiftcc:
1209; CHECK-APPLE:       ## %bb.0: ## %entry
1210; CHECK-APPLE-NEXT:    pushq %rax
1211; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 16
1212; CHECK-APPLE-NEXT:    callq _tailcallswifterror_swiftcc
1213; CHECK-APPLE-NEXT:    popq %rax
1214; CHECK-APPLE-NEXT:    retq
1215;
1216; CHECK-O0-LABEL: tailcallswifterror_swiftcc:
1217; CHECK-O0:       ## %bb.0: ## %entry
1218; CHECK-O0-NEXT:    pushq %rax
1219; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
1220; CHECK-O0-NEXT:    callq _tailcallswifterror_swiftcc
1221; CHECK-O0-NEXT:    popq %rax
1222; CHECK-O0-NEXT:    retq
1223;
1224; CHECK-i386-LABEL: tailcallswifterror_swiftcc:
1225; CHECK-i386:       ## %bb.0: ## %entry
1226; CHECK-i386-NEXT:    jmp _tailcallswifterror_swiftcc ## TAILCALL
1227entry:
1228  %0 = tail call swiftcc float @tailcallswifterror_swiftcc(ptr swifterror %error_ptr_ref)
1229  ret float %0
1230}
1231
1232; Check that we can handle an empty function with swifterror argument.
1233define swiftcc {i32, i32, i32} @empty_swiftcc({i32, i32, i32} , ptr swifterror %error_ptr_ref) {
1234; CHECK-APPLE-LABEL: empty_swiftcc:
1235; CHECK-APPLE:       ## %bb.0: ## %entry
1236; CHECK-APPLE-NEXT:    movl %edx, %ecx
1237; CHECK-APPLE-NEXT:    movl %esi, %edx
1238; CHECK-APPLE-NEXT:    movl %edi, %eax
1239; CHECK-APPLE-NEXT:    retq
1240;
1241; CHECK-O0-LABEL: empty_swiftcc:
1242; CHECK-O0:       ## %bb.0: ## %entry
1243; CHECK-O0-NEXT:    movl %edx, %ecx
1244; CHECK-O0-NEXT:    movl %esi, %edx
1245; CHECK-O0-NEXT:    movl %edi, %eax
1246; CHECK-O0-NEXT:    retq
1247;
1248; CHECK-i386-LABEL: empty_swiftcc:
1249; CHECK-i386:       ## %bb.0: ## %entry
1250; CHECK-i386-NEXT:    movl 4(%esp), %eax
1251; CHECK-i386-NEXT:    movl 8(%esp), %edx
1252; CHECK-i386-NEXT:    movl 12(%esp), %ecx
1253; CHECK-i386-NEXT:    retl
1254entry:
1255  ret {i32, i32, i32} %0
1256}
1257
1258; Make sure we can handle the case when isel generates new machine basic blocks.
1259define swiftcc void @dont_crash_on_new_isel_blocks(ptr nocapture swifterror, i1, ptr) {
1260; CHECK-APPLE-LABEL: dont_crash_on_new_isel_blocks:
1261; CHECK-APPLE:       ## %bb.0: ## %entry
1262; CHECK-APPLE-NEXT:    testb $1, %dil
1263; CHECK-APPLE-NEXT:    pushq %rax
1264; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 16
1265; CHECK-APPLE-NEXT:    callq *%rax
1266; CHECK-APPLE-NEXT:    popq %rax
1267; CHECK-APPLE-NEXT:    retq
1268;
1269; CHECK-O0-LABEL: dont_crash_on_new_isel_blocks:
1270; CHECK-O0:       ## %bb.0: ## %entry
1271; CHECK-O0-NEXT:    pushq %rax
1272; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
1273; CHECK-O0-NEXT:    movq %r12, (%rsp) ## 8-byte Spill
1274; CHECK-O0-NEXT:    movb %dil, %al
1275; CHECK-O0-NEXT:    orb $0, %al
1276; CHECK-O0-NEXT:    testb $1, %al
1277; CHECK-O0-NEXT:    jne LBB15_2
1278; CHECK-O0-NEXT:  ## %bb.1: ## %falsebb
1279; CHECK-O0-NEXT:  LBB15_2: ## %cont
1280; CHECK-O0-NEXT:    movq (%rsp), %r12 ## 8-byte Reload
1281; CHECK-O0-NEXT:    ## implicit-def: $rax
1282; CHECK-O0-NEXT:    callq *%rax
1283; CHECK-O0-NEXT:    popq %rax
1284; CHECK-O0-NEXT:    retq
1285;
1286; CHECK-i386-LABEL: dont_crash_on_new_isel_blocks:
1287; CHECK-i386:       ## %bb.0: ## %entry
1288; CHECK-i386-NEXT:    testb $1, 8(%esp)
1289; CHECK-i386-NEXT:    jmpl *%eax ## TAILCALL
1290entry:
1291  %3 = or i1 false, %1
1292  br i1 %3, label %cont, label %falsebb
1293
1294falsebb:
1295  %4 = load ptr, ptr %2, align 8
1296  br label %cont
1297
1298cont:
1299  tail call swiftcc void undef(ptr nocapture swifterror %0)
1300  ret void
1301}
1302
1303define swiftcc void @swifterror_clobber(ptr nocapture swifterror %err) {
1304; CHECK-APPLE-LABEL: swifterror_clobber:
1305; CHECK-APPLE:       ## %bb.0:
1306; CHECK-APPLE-NEXT:    movq %r12, %rax
1307; CHECK-APPLE-NEXT:    ## InlineAsm Start
1308; CHECK-APPLE-NEXT:    nop
1309; CHECK-APPLE-NEXT:    ## InlineAsm End
1310; CHECK-APPLE-NEXT:    movq %rax, %r12
1311; CHECK-APPLE-NEXT:    retq
1312;
1313; CHECK-O0-LABEL: swifterror_clobber:
1314; CHECK-O0:       ## %bb.0:
1315; CHECK-O0-NEXT:    movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1316; CHECK-O0-NEXT:    ## InlineAsm Start
1317; CHECK-O0-NEXT:    nop
1318; CHECK-O0-NEXT:    ## InlineAsm End
1319; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r12 ## 8-byte Reload
1320; CHECK-O0-NEXT:    retq
1321;
1322; CHECK-i386-LABEL: swifterror_clobber:
1323; CHECK-i386:       ## %bb.0:
1324; CHECK-i386-NEXT:    ## InlineAsm Start
1325; CHECK-i386-NEXT:    nop
1326; CHECK-i386-NEXT:    ## InlineAsm End
1327; CHECK-i386-NEXT:    retl
1328  call void asm sideeffect "nop", "~{r12}"()
1329  ret void
1330}
1331
1332define swiftcc void @swifterror_reg_clobber(ptr nocapture %err) {
1333; CHECK-APPLE-LABEL: swifterror_reg_clobber:
1334; CHECK-APPLE:       ## %bb.0:
1335; CHECK-APPLE-NEXT:    pushq %r12
1336; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 16
1337; CHECK-APPLE-NEXT:    .cfi_offset %r12, -16
1338; CHECK-APPLE-NEXT:    ## InlineAsm Start
1339; CHECK-APPLE-NEXT:    nop
1340; CHECK-APPLE-NEXT:    ## InlineAsm End
1341; CHECK-APPLE-NEXT:    popq %r12
1342; CHECK-APPLE-NEXT:    retq
1343;
1344; CHECK-O0-LABEL: swifterror_reg_clobber:
1345; CHECK-O0:       ## %bb.0:
1346; CHECK-O0-NEXT:    pushq %r12
1347; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
1348; CHECK-O0-NEXT:    .cfi_offset %r12, -16
1349; CHECK-O0-NEXT:    ## InlineAsm Start
1350; CHECK-O0-NEXT:    nop
1351; CHECK-O0-NEXT:    ## InlineAsm End
1352; CHECK-O0-NEXT:    popq %r12
1353; CHECK-O0-NEXT:    retq
1354;
1355; CHECK-i386-LABEL: swifterror_reg_clobber:
1356; CHECK-i386:       ## %bb.0:
1357; CHECK-i386-NEXT:    ## InlineAsm Start
1358; CHECK-i386-NEXT:    nop
1359; CHECK-i386-NEXT:    ## InlineAsm End
1360; CHECK-i386-NEXT:    retl
1361  call void asm sideeffect "nop", "~{r12}"()
1362  ret void
1363}
1364
1365define swiftcc void @params_in_reg(i64, i64, i64, i64, i64, i64, ptr swiftself, ptr nocapture swifterror %err) {
1366; CHECK-APPLE-LABEL: params_in_reg:
1367; CHECK-APPLE:       ## %bb.0:
1368; CHECK-APPLE-NEXT:    pushq %rbp
1369; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 16
1370; CHECK-APPLE-NEXT:    pushq %r15
1371; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 24
1372; CHECK-APPLE-NEXT:    pushq %r14
1373; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 32
1374; CHECK-APPLE-NEXT:    pushq %r13
1375; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 40
1376; CHECK-APPLE-NEXT:    pushq %rbx
1377; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 48
1378; CHECK-APPLE-NEXT:    subq $48, %rsp
1379; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 96
1380; CHECK-APPLE-NEXT:    .cfi_offset %rbx, -48
1381; CHECK-APPLE-NEXT:    .cfi_offset %r13, -40
1382; CHECK-APPLE-NEXT:    .cfi_offset %r14, -32
1383; CHECK-APPLE-NEXT:    .cfi_offset %r15, -24
1384; CHECK-APPLE-NEXT:    .cfi_offset %rbp, -16
1385; CHECK-APPLE-NEXT:    movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1386; CHECK-APPLE-NEXT:    movq %r13, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1387; CHECK-APPLE-NEXT:    movq %r9, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1388; CHECK-APPLE-NEXT:    movq %r8, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1389; CHECK-APPLE-NEXT:    movq %rcx, %rbx
1390; CHECK-APPLE-NEXT:    movq %rdx, %r14
1391; CHECK-APPLE-NEXT:    movq %rsi, %r15
1392; CHECK-APPLE-NEXT:    movq %rdi, %rbp
1393; CHECK-APPLE-NEXT:    movl $1, %edi
1394; CHECK-APPLE-NEXT:    movl $2, %esi
1395; CHECK-APPLE-NEXT:    movl $3, %edx
1396; CHECK-APPLE-NEXT:    movl $4, %ecx
1397; CHECK-APPLE-NEXT:    movl $5, %r8d
1398; CHECK-APPLE-NEXT:    movl $6, %r9d
1399; CHECK-APPLE-NEXT:    xorl %r13d, %r13d
1400; CHECK-APPLE-NEXT:    xorl %r12d, %r12d
1401; CHECK-APPLE-NEXT:    callq _params_in_reg2
1402; CHECK-APPLE-NEXT:    movq %rbp, %rdi
1403; CHECK-APPLE-NEXT:    movq %r15, %rsi
1404; CHECK-APPLE-NEXT:    movq %r14, %rdx
1405; CHECK-APPLE-NEXT:    movq %rbx, %rcx
1406; CHECK-APPLE-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r8 ## 8-byte Reload
1407; CHECK-APPLE-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r9 ## 8-byte Reload
1408; CHECK-APPLE-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r13 ## 8-byte Reload
1409; CHECK-APPLE-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r12 ## 8-byte Reload
1410; CHECK-APPLE-NEXT:    callq _params_in_reg2
1411; CHECK-APPLE-NEXT:    addq $48, %rsp
1412; CHECK-APPLE-NEXT:    popq %rbx
1413; CHECK-APPLE-NEXT:    popq %r13
1414; CHECK-APPLE-NEXT:    popq %r14
1415; CHECK-APPLE-NEXT:    popq %r15
1416; CHECK-APPLE-NEXT:    popq %rbp
1417; CHECK-APPLE-NEXT:    retq
1418;
1419; CHECK-O0-LABEL: params_in_reg:
1420; CHECK-O0:       ## %bb.0:
1421; CHECK-O0-NEXT:    pushq %r13
1422; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
1423; CHECK-O0-NEXT:    subq $80, %rsp
1424; CHECK-O0-NEXT:    .cfi_def_cfa_offset 96
1425; CHECK-O0-NEXT:    .cfi_offset %r13, -16
1426; CHECK-O0-NEXT:    movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1427; CHECK-O0-NEXT:    movq %r13, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1428; CHECK-O0-NEXT:    movq %r9, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1429; CHECK-O0-NEXT:    movq %r8, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1430; CHECK-O0-NEXT:    movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1431; CHECK-O0-NEXT:    movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1432; CHECK-O0-NEXT:    movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1433; CHECK-O0-NEXT:    movq %rdi, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1434; CHECK-O0-NEXT:    ## implicit-def: $rax
1435; CHECK-O0-NEXT:    xorl %eax, %eax
1436; CHECK-O0-NEXT:    movl %eax, %r12d
1437; CHECK-O0-NEXT:    movl $1, %edi
1438; CHECK-O0-NEXT:    movl $2, %esi
1439; CHECK-O0-NEXT:    movl $3, %edx
1440; CHECK-O0-NEXT:    movl $4, %ecx
1441; CHECK-O0-NEXT:    movl $5, %r8d
1442; CHECK-O0-NEXT:    movl $6, %r9d
1443; CHECK-O0-NEXT:    movq %r12, %r13
1444; CHECK-O0-NEXT:    callq _params_in_reg2
1445; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r13 ## 8-byte Reload
1446; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rdi ## 8-byte Reload
1447; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rsi ## 8-byte Reload
1448; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rdx ## 8-byte Reload
1449; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx ## 8-byte Reload
1450; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r8 ## 8-byte Reload
1451; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r9 ## 8-byte Reload
1452; CHECK-O0-NEXT:    movq %r12, %rax
1453; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r12 ## 8-byte Reload
1454; CHECK-O0-NEXT:    callq _params_in_reg2
1455; CHECK-O0-NEXT:    addq $80, %rsp
1456; CHECK-O0-NEXT:    popq %r13
1457; CHECK-O0-NEXT:    retq
1458;
1459; CHECK-i386-LABEL: params_in_reg:
1460; CHECK-i386:       ## %bb.0:
1461; CHECK-i386-NEXT:    pushl %ebp
1462; CHECK-i386-NEXT:    .cfi_def_cfa_offset 8
1463; CHECK-i386-NEXT:    pushl %ebx
1464; CHECK-i386-NEXT:    .cfi_def_cfa_offset 12
1465; CHECK-i386-NEXT:    pushl %edi
1466; CHECK-i386-NEXT:    .cfi_def_cfa_offset 16
1467; CHECK-i386-NEXT:    pushl %esi
1468; CHECK-i386-NEXT:    .cfi_def_cfa_offset 20
1469; CHECK-i386-NEXT:    subl $60, %esp
1470; CHECK-i386-NEXT:    .cfi_def_cfa_offset 80
1471; CHECK-i386-NEXT:    .cfi_offset %esi, -20
1472; CHECK-i386-NEXT:    .cfi_offset %edi, -16
1473; CHECK-i386-NEXT:    .cfi_offset %ebx, -12
1474; CHECK-i386-NEXT:    .cfi_offset %ebp, -8
1475; CHECK-i386-NEXT:    movl $0, 56(%esp)
1476; CHECK-i386-NEXT:    movl 120(%esp), %ebx
1477; CHECK-i386-NEXT:    movl 124(%esp), %ebp
1478; CHECK-i386-NEXT:    movl 128(%esp), %esi
1479; CHECK-i386-NEXT:    movl 132(%esp), %edi
1480; CHECK-i386-NEXT:    leal 56(%esp), %eax
1481; CHECK-i386-NEXT:    movl %eax, 52(%esp)
1482; CHECK-i386-NEXT:    movl $0, 48(%esp)
1483; CHECK-i386-NEXT:    movl $0, 44(%esp)
1484; CHECK-i386-NEXT:    movl $6, 40(%esp)
1485; CHECK-i386-NEXT:    movl $0, 36(%esp)
1486; CHECK-i386-NEXT:    movl $5, 32(%esp)
1487; CHECK-i386-NEXT:    movl $0, 28(%esp)
1488; CHECK-i386-NEXT:    movl $4, 24(%esp)
1489; CHECK-i386-NEXT:    movl $0, 20(%esp)
1490; CHECK-i386-NEXT:    movl $3, 16(%esp)
1491; CHECK-i386-NEXT:    movl $0, 12(%esp)
1492; CHECK-i386-NEXT:    movl $2, 8(%esp)
1493; CHECK-i386-NEXT:    movl $0, 4(%esp)
1494; CHECK-i386-NEXT:    movl $1, (%esp)
1495; CHECK-i386-NEXT:    calll _params_in_reg2
1496; CHECK-i386-NEXT:    movl %edi, 52(%esp)
1497; CHECK-i386-NEXT:    movl %esi, 48(%esp)
1498; CHECK-i386-NEXT:    movl %ebp, 44(%esp)
1499; CHECK-i386-NEXT:    movl %ebx, 40(%esp)
1500; CHECK-i386-NEXT:    movl 116(%esp), %eax
1501; CHECK-i386-NEXT:    movl %eax, 36(%esp)
1502; CHECK-i386-NEXT:    movl 112(%esp), %eax
1503; CHECK-i386-NEXT:    movl %eax, 32(%esp)
1504; CHECK-i386-NEXT:    movl 108(%esp), %eax
1505; CHECK-i386-NEXT:    movl %eax, 28(%esp)
1506; CHECK-i386-NEXT:    movl 104(%esp), %eax
1507; CHECK-i386-NEXT:    movl %eax, 24(%esp)
1508; CHECK-i386-NEXT:    movl 100(%esp), %eax
1509; CHECK-i386-NEXT:    movl %eax, 20(%esp)
1510; CHECK-i386-NEXT:    movl 96(%esp), %eax
1511; CHECK-i386-NEXT:    movl %eax, 16(%esp)
1512; CHECK-i386-NEXT:    movl 92(%esp), %eax
1513; CHECK-i386-NEXT:    movl %eax, 12(%esp)
1514; CHECK-i386-NEXT:    movl 88(%esp), %eax
1515; CHECK-i386-NEXT:    movl %eax, 8(%esp)
1516; CHECK-i386-NEXT:    movl 84(%esp), %eax
1517; CHECK-i386-NEXT:    movl %eax, 4(%esp)
1518; CHECK-i386-NEXT:    movl 80(%esp), %eax
1519; CHECK-i386-NEXT:    movl %eax, (%esp)
1520; CHECK-i386-NEXT:    calll _params_in_reg2
1521; CHECK-i386-NEXT:    addl $60, %esp
1522; CHECK-i386-NEXT:    popl %esi
1523; CHECK-i386-NEXT:    popl %edi
1524; CHECK-i386-NEXT:    popl %ebx
1525; CHECK-i386-NEXT:    popl %ebp
1526; CHECK-i386-NEXT:    retl
1527  %error_ptr_ref = alloca swifterror ptr, align 8
1528  store ptr null, ptr %error_ptr_ref
1529  call swiftcc void @params_in_reg2(i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, ptr swiftself null, ptr nocapture swifterror %error_ptr_ref)
1530  call swiftcc void @params_in_reg2(i64 %0, i64 %1, i64 %2, i64 %3, i64 %4, i64 %5, ptr swiftself %6, ptr nocapture swifterror %err)
1531  ret void
1532}
1533declare swiftcc void @params_in_reg2(i64, i64, i64, i64, i64, i64, ptr swiftself, ptr nocapture swifterror %err)
1534
1535define swiftcc { i64, i64, i64, i64} @params_and_return_in_reg(i64, i64, i64, i64, i64, i64, ptr swiftself, ptr nocapture swifterror %err) {
1536; CHECK-APPLE-LABEL: params_and_return_in_reg:
1537; CHECK-APPLE:       ## %bb.0:
1538; CHECK-APPLE-NEXT:    pushq %rbp
1539; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 16
1540; CHECK-APPLE-NEXT:    pushq %r15
1541; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 24
1542; CHECK-APPLE-NEXT:    pushq %r14
1543; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 32
1544; CHECK-APPLE-NEXT:    pushq %r13
1545; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 40
1546; CHECK-APPLE-NEXT:    pushq %rbx
1547; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 48
1548; CHECK-APPLE-NEXT:    subq $48, %rsp
1549; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 96
1550; CHECK-APPLE-NEXT:    .cfi_offset %rbx, -48
1551; CHECK-APPLE-NEXT:    .cfi_offset %r13, -40
1552; CHECK-APPLE-NEXT:    .cfi_offset %r14, -32
1553; CHECK-APPLE-NEXT:    .cfi_offset %r15, -24
1554; CHECK-APPLE-NEXT:    .cfi_offset %rbp, -16
1555; CHECK-APPLE-NEXT:    movq %r12, (%rsp) ## 8-byte Spill
1556; CHECK-APPLE-NEXT:    movq %r13, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1557; CHECK-APPLE-NEXT:    movq %r9, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1558; CHECK-APPLE-NEXT:    movq %r8, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1559; CHECK-APPLE-NEXT:    movq %rcx, %rbx
1560; CHECK-APPLE-NEXT:    movq %rdx, %r14
1561; CHECK-APPLE-NEXT:    movq %rsi, %r15
1562; CHECK-APPLE-NEXT:    movq %rdi, %rbp
1563; CHECK-APPLE-NEXT:    movl $1, %edi
1564; CHECK-APPLE-NEXT:    movl $2, %esi
1565; CHECK-APPLE-NEXT:    movl $3, %edx
1566; CHECK-APPLE-NEXT:    movl $4, %ecx
1567; CHECK-APPLE-NEXT:    movl $5, %r8d
1568; CHECK-APPLE-NEXT:    movl $6, %r9d
1569; CHECK-APPLE-NEXT:    xorl %r13d, %r13d
1570; CHECK-APPLE-NEXT:    xorl %r12d, %r12d
1571; CHECK-APPLE-NEXT:    callq _params_in_reg2
1572; CHECK-APPLE-NEXT:    movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1573; CHECK-APPLE-NEXT:    movq %rbp, %rdi
1574; CHECK-APPLE-NEXT:    movq %r15, %rsi
1575; CHECK-APPLE-NEXT:    movq %r14, %rdx
1576; CHECK-APPLE-NEXT:    movq %rbx, %rcx
1577; CHECK-APPLE-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r8 ## 8-byte Reload
1578; CHECK-APPLE-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r9 ## 8-byte Reload
1579; CHECK-APPLE-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r13 ## 8-byte Reload
1580; CHECK-APPLE-NEXT:    movq (%rsp), %r12 ## 8-byte Reload
1581; CHECK-APPLE-NEXT:    callq _params_and_return_in_reg2
1582; CHECK-APPLE-NEXT:    movq %rax, %rbx
1583; CHECK-APPLE-NEXT:    movq %rdx, %r14
1584; CHECK-APPLE-NEXT:    movq %rcx, %r15
1585; CHECK-APPLE-NEXT:    movq %r8, %rbp
1586; CHECK-APPLE-NEXT:    movq %r12, (%rsp) ## 8-byte Spill
1587; CHECK-APPLE-NEXT:    movl $1, %edi
1588; CHECK-APPLE-NEXT:    movl $2, %esi
1589; CHECK-APPLE-NEXT:    movl $3, %edx
1590; CHECK-APPLE-NEXT:    movl $4, %ecx
1591; CHECK-APPLE-NEXT:    movl $5, %r8d
1592; CHECK-APPLE-NEXT:    movl $6, %r9d
1593; CHECK-APPLE-NEXT:    xorl %r13d, %r13d
1594; CHECK-APPLE-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r12 ## 8-byte Reload
1595; CHECK-APPLE-NEXT:    callq _params_in_reg2
1596; CHECK-APPLE-NEXT:    movq %rbx, %rax
1597; CHECK-APPLE-NEXT:    movq %r14, %rdx
1598; CHECK-APPLE-NEXT:    movq %r15, %rcx
1599; CHECK-APPLE-NEXT:    movq %rbp, %r8
1600; CHECK-APPLE-NEXT:    movq (%rsp), %r12 ## 8-byte Reload
1601; CHECK-APPLE-NEXT:    addq $48, %rsp
1602; CHECK-APPLE-NEXT:    popq %rbx
1603; CHECK-APPLE-NEXT:    popq %r13
1604; CHECK-APPLE-NEXT:    popq %r14
1605; CHECK-APPLE-NEXT:    popq %r15
1606; CHECK-APPLE-NEXT:    popq %rbp
1607; CHECK-APPLE-NEXT:    retq
1608;
1609; CHECK-O0-LABEL: params_and_return_in_reg:
1610; CHECK-O0:       ## %bb.0:
1611; CHECK-O0-NEXT:    pushq %r13
1612; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
1613; CHECK-O0-NEXT:    subq $176, %rsp
1614; CHECK-O0-NEXT:    .cfi_def_cfa_offset 192
1615; CHECK-O0-NEXT:    .cfi_offset %r13, -16
1616; CHECK-O0-NEXT:    movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1617; CHECK-O0-NEXT:    movq %r13, (%rsp) ## 8-byte Spill
1618; CHECK-O0-NEXT:    movq %r9, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1619; CHECK-O0-NEXT:    movq %r8, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1620; CHECK-O0-NEXT:    movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1621; CHECK-O0-NEXT:    movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1622; CHECK-O0-NEXT:    movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1623; CHECK-O0-NEXT:    movq %rdi, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1624; CHECK-O0-NEXT:    ## implicit-def: $rax
1625; CHECK-O0-NEXT:    xorl %eax, %eax
1626; CHECK-O0-NEXT:    movl %eax, %r12d
1627; CHECK-O0-NEXT:    movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1628; CHECK-O0-NEXT:    movl $1, %edi
1629; CHECK-O0-NEXT:    movq %rdi, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1630; CHECK-O0-NEXT:    movl $2, %esi
1631; CHECK-O0-NEXT:    movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1632; CHECK-O0-NEXT:    movl $3, %edx
1633; CHECK-O0-NEXT:    movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1634; CHECK-O0-NEXT:    movl $4, %ecx
1635; CHECK-O0-NEXT:    movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1636; CHECK-O0-NEXT:    movl $5, %r8d
1637; CHECK-O0-NEXT:    movq %r8, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1638; CHECK-O0-NEXT:    movl $6, %r9d
1639; CHECK-O0-NEXT:    movq %r9, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1640; CHECK-O0-NEXT:    movq %r12, %r13
1641; CHECK-O0-NEXT:    callq _params_in_reg2
1642; CHECK-O0-NEXT:    movq (%rsp), %r13 ## 8-byte Reload
1643; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rdi ## 8-byte Reload
1644; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rsi ## 8-byte Reload
1645; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rdx ## 8-byte Reload
1646; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx ## 8-byte Reload
1647; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r8 ## 8-byte Reload
1648; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r9 ## 8-byte Reload
1649; CHECK-O0-NEXT:    movq %r12, %rax
1650; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r12 ## 8-byte Reload
1651; CHECK-O0-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1652; CHECK-O0-NEXT:    callq _params_and_return_in_reg2
1653; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r13 ## 8-byte Reload
1654; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rdi ## 8-byte Reload
1655; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rsi ## 8-byte Reload
1656; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r9 ## 8-byte Reload
1657; CHECK-O0-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1658; CHECK-O0-NEXT:    movq %rdx, %rax
1659; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rdx ## 8-byte Reload
1660; CHECK-O0-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1661; CHECK-O0-NEXT:    movq %rcx, %rax
1662; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx ## 8-byte Reload
1663; CHECK-O0-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1664; CHECK-O0-NEXT:    movq %r8, %rax
1665; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r8 ## 8-byte Reload
1666; CHECK-O0-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1667; CHECK-O0-NEXT:    movq %r12, %rax
1668; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r12 ## 8-byte Reload
1669; CHECK-O0-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1670; CHECK-O0-NEXT:    callq _params_in_reg2
1671; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rax ## 8-byte Reload
1672; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rdx ## 8-byte Reload
1673; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx ## 8-byte Reload
1674; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r8 ## 8-byte Reload
1675; CHECK-O0-NEXT:    movq %r12, %rsi
1676; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r12 ## 8-byte Reload
1677; CHECK-O0-NEXT:    addq $176, %rsp
1678; CHECK-O0-NEXT:    popq %r13
1679; CHECK-O0-NEXT:    retq
1680;
1681; CHECK-i386-LABEL: params_and_return_in_reg:
1682; CHECK-i386:       ## %bb.0:
1683; CHECK-i386-NEXT:    pushl %ebp
1684; CHECK-i386-NEXT:    .cfi_def_cfa_offset 8
1685; CHECK-i386-NEXT:    pushl %ebx
1686; CHECK-i386-NEXT:    .cfi_def_cfa_offset 12
1687; CHECK-i386-NEXT:    pushl %edi
1688; CHECK-i386-NEXT:    .cfi_def_cfa_offset 16
1689; CHECK-i386-NEXT:    pushl %esi
1690; CHECK-i386-NEXT:    .cfi_def_cfa_offset 20
1691; CHECK-i386-NEXT:    subl $124, %esp
1692; CHECK-i386-NEXT:    .cfi_def_cfa_offset 144
1693; CHECK-i386-NEXT:    .cfi_offset %esi, -20
1694; CHECK-i386-NEXT:    .cfi_offset %edi, -16
1695; CHECK-i386-NEXT:    .cfi_offset %ebx, -12
1696; CHECK-i386-NEXT:    .cfi_offset %ebp, -8
1697; CHECK-i386-NEXT:    movl 148(%esp), %esi
1698; CHECK-i386-NEXT:    movl $0, 64(%esp)
1699; CHECK-i386-NEXT:    movl 192(%esp), %ebx
1700; CHECK-i386-NEXT:    movl 196(%esp), %ebp
1701; CHECK-i386-NEXT:    movl 200(%esp), %edi
1702; CHECK-i386-NEXT:    leal 64(%esp), %eax
1703; CHECK-i386-NEXT:    movl %eax, 52(%esp)
1704; CHECK-i386-NEXT:    movl $0, 48(%esp)
1705; CHECK-i386-NEXT:    movl $0, 44(%esp)
1706; CHECK-i386-NEXT:    movl $6, 40(%esp)
1707; CHECK-i386-NEXT:    movl $0, 36(%esp)
1708; CHECK-i386-NEXT:    movl $5, 32(%esp)
1709; CHECK-i386-NEXT:    movl $0, 28(%esp)
1710; CHECK-i386-NEXT:    movl $4, 24(%esp)
1711; CHECK-i386-NEXT:    movl $0, 20(%esp)
1712; CHECK-i386-NEXT:    movl $3, 16(%esp)
1713; CHECK-i386-NEXT:    movl $0, 12(%esp)
1714; CHECK-i386-NEXT:    movl $2, 8(%esp)
1715; CHECK-i386-NEXT:    movl $0, 4(%esp)
1716; CHECK-i386-NEXT:    movl $1, (%esp)
1717; CHECK-i386-NEXT:    calll _params_in_reg2
1718; CHECK-i386-NEXT:    movl %edi, 56(%esp)
1719; CHECK-i386-NEXT:    movl %ebp, 52(%esp)
1720; CHECK-i386-NEXT:    movl %ebx, 48(%esp)
1721; CHECK-i386-NEXT:    movl 188(%esp), %eax
1722; CHECK-i386-NEXT:    movl %eax, 44(%esp)
1723; CHECK-i386-NEXT:    movl 184(%esp), %eax
1724; CHECK-i386-NEXT:    movl %eax, 40(%esp)
1725; CHECK-i386-NEXT:    movl 180(%esp), %eax
1726; CHECK-i386-NEXT:    movl %eax, 36(%esp)
1727; CHECK-i386-NEXT:    movl 176(%esp), %eax
1728; CHECK-i386-NEXT:    movl %eax, 32(%esp)
1729; CHECK-i386-NEXT:    movl 172(%esp), %eax
1730; CHECK-i386-NEXT:    movl %eax, 28(%esp)
1731; CHECK-i386-NEXT:    movl 168(%esp), %eax
1732; CHECK-i386-NEXT:    movl %eax, 24(%esp)
1733; CHECK-i386-NEXT:    movl 164(%esp), %eax
1734; CHECK-i386-NEXT:    movl %eax, 20(%esp)
1735; CHECK-i386-NEXT:    movl 160(%esp), %eax
1736; CHECK-i386-NEXT:    movl %eax, 16(%esp)
1737; CHECK-i386-NEXT:    movl 156(%esp), %eax
1738; CHECK-i386-NEXT:    movl %eax, 12(%esp)
1739; CHECK-i386-NEXT:    movl 152(%esp), %eax
1740; CHECK-i386-NEXT:    movl %eax, 8(%esp)
1741; CHECK-i386-NEXT:    movl %esi, 4(%esp)
1742; CHECK-i386-NEXT:    leal 88(%esp), %eax
1743; CHECK-i386-NEXT:    movl %eax, (%esp)
1744; CHECK-i386-NEXT:    calll _params_and_return_in_reg2
1745; CHECK-i386-NEXT:    subl $4, %esp
1746; CHECK-i386-NEXT:    movl 88(%esp), %eax
1747; CHECK-i386-NEXT:    movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) ## 4-byte Spill
1748; CHECK-i386-NEXT:    movl 92(%esp), %eax
1749; CHECK-i386-NEXT:    movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) ## 4-byte Spill
1750; CHECK-i386-NEXT:    movl 96(%esp), %eax
1751; CHECK-i386-NEXT:    movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) ## 4-byte Spill
1752; CHECK-i386-NEXT:    movl 100(%esp), %eax
1753; CHECK-i386-NEXT:    movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) ## 4-byte Spill
1754; CHECK-i386-NEXT:    movl 104(%esp), %ebp
1755; CHECK-i386-NEXT:    movl 108(%esp), %edi
1756; CHECK-i386-NEXT:    movl 112(%esp), %esi
1757; CHECK-i386-NEXT:    movl 116(%esp), %ebx
1758; CHECK-i386-NEXT:    leal 64(%esp), %eax
1759; CHECK-i386-NEXT:    movl %eax, 52(%esp)
1760; CHECK-i386-NEXT:    movl $0, 48(%esp)
1761; CHECK-i386-NEXT:    movl $0, 44(%esp)
1762; CHECK-i386-NEXT:    movl $6, 40(%esp)
1763; CHECK-i386-NEXT:    movl $0, 36(%esp)
1764; CHECK-i386-NEXT:    movl $5, 32(%esp)
1765; CHECK-i386-NEXT:    movl $0, 28(%esp)
1766; CHECK-i386-NEXT:    movl $4, 24(%esp)
1767; CHECK-i386-NEXT:    movl $0, 20(%esp)
1768; CHECK-i386-NEXT:    movl $3, 16(%esp)
1769; CHECK-i386-NEXT:    movl $0, 12(%esp)
1770; CHECK-i386-NEXT:    movl $2, 8(%esp)
1771; CHECK-i386-NEXT:    movl $0, 4(%esp)
1772; CHECK-i386-NEXT:    movl $1, (%esp)
1773; CHECK-i386-NEXT:    calll _params_in_reg2
1774; CHECK-i386-NEXT:    movl 144(%esp), %eax
1775; CHECK-i386-NEXT:    movl %ebx, 28(%eax)
1776; CHECK-i386-NEXT:    movl %esi, 24(%eax)
1777; CHECK-i386-NEXT:    movl %edi, 20(%eax)
1778; CHECK-i386-NEXT:    movl %ebp, 16(%eax)
1779; CHECK-i386-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx ## 4-byte Reload
1780; CHECK-i386-NEXT:    movl %ecx, 12(%eax)
1781; CHECK-i386-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx ## 4-byte Reload
1782; CHECK-i386-NEXT:    movl %ecx, 8(%eax)
1783; CHECK-i386-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx ## 4-byte Reload
1784; CHECK-i386-NEXT:    movl %ecx, 4(%eax)
1785; CHECK-i386-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx ## 4-byte Reload
1786; CHECK-i386-NEXT:    movl %ecx, (%eax)
1787; CHECK-i386-NEXT:    addl $124, %esp
1788; CHECK-i386-NEXT:    popl %esi
1789; CHECK-i386-NEXT:    popl %edi
1790; CHECK-i386-NEXT:    popl %ebx
1791; CHECK-i386-NEXT:    popl %ebp
1792; CHECK-i386-NEXT:    retl $4
1793  %error_ptr_ref = alloca swifterror ptr, align 8
1794  store ptr null, ptr %error_ptr_ref
1795  call swiftcc void @params_in_reg2(i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, ptr swiftself null, ptr nocapture swifterror %error_ptr_ref)
1796  %val = call swiftcc  { i64, i64, i64, i64 } @params_and_return_in_reg2(i64 %0, i64 %1, i64 %2, i64 %3, i64 %4, i64 %5, ptr swiftself %6, ptr nocapture swifterror %err)
1797  call swiftcc void @params_in_reg2(i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, ptr swiftself null, ptr nocapture swifterror %error_ptr_ref)
1798  ret { i64, i64, i64, i64 }%val
1799}
1800
1801declare swiftcc { i64, i64, i64, i64 } @params_and_return_in_reg2(i64, i64, i64, i64, i64, i64, ptr swiftself, ptr nocapture swifterror %err)
1802
1803
1804declare void @acallee(ptr)
1805
1806; Make sure we don't tail call if the caller returns a swifterror value. We
1807; would have to move into the swifterror register before the tail call.
1808define swiftcc void @tailcall_from_swifterror(ptr swifterror %error_ptr_ref) {
1809; CHECK-APPLE-LABEL: tailcall_from_swifterror:
1810; CHECK-APPLE:       ## %bb.0: ## %entry
1811; CHECK-APPLE-NEXT:    pushq %rbx
1812; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 16
1813; CHECK-APPLE-NEXT:    .cfi_offset %rbx, -16
1814; CHECK-APPLE-NEXT:    movq %r12, %rbx
1815; CHECK-APPLE-NEXT:    xorl %edi, %edi
1816; CHECK-APPLE-NEXT:    callq _acallee
1817; CHECK-APPLE-NEXT:    movq %rbx, %r12
1818; CHECK-APPLE-NEXT:    popq %rbx
1819; CHECK-APPLE-NEXT:    retq
1820;
1821; CHECK-O0-LABEL: tailcall_from_swifterror:
1822; CHECK-O0:       ## %bb.0: ## %entry
1823; CHECK-O0-NEXT:    pushq %rax
1824; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
1825; CHECK-O0-NEXT:    movq %r12, (%rsp) ## 8-byte Spill
1826; CHECK-O0-NEXT:    xorl %eax, %eax
1827; CHECK-O0-NEXT:    movl %eax, %edi
1828; CHECK-O0-NEXT:    callq _acallee
1829; CHECK-O0-NEXT:    movq (%rsp), %r12 ## 8-byte Reload
1830; CHECK-O0-NEXT:    popq %rax
1831; CHECK-O0-NEXT:    retq
1832;
1833; CHECK-i386-LABEL: tailcall_from_swifterror:
1834; CHECK-i386:       ## %bb.0: ## %entry
1835; CHECK-i386-NEXT:    subl $12, %esp
1836; CHECK-i386-NEXT:    .cfi_def_cfa_offset 16
1837; CHECK-i386-NEXT:    movl $0, (%esp)
1838; CHECK-i386-NEXT:    calll _acallee
1839; CHECK-i386-NEXT:    addl $12, %esp
1840; CHECK-i386-NEXT:    retl
1841entry:
1842  tail call void @acallee(ptr null)
1843  ret void
1844}
1845
1846; Make sure we don't crash on this function during -O0.
1847; We used to crash because we would insert an IMPLICIT_DEF for the swifterror at
1848; beginning of the machine basic block but did not inform FastISel of the
1849; inserted instruction. When computing the InsertPoint in the entry block
1850; FastISel would choose an insertion point before the IMPLICIT_DEF causing a
1851; crash later on.
1852declare hidden swiftcc ptr @testFunA()
1853
1854%TSb = type <{ i1 }>
1855
1856define swiftcc void @dontCrash()  {
1857; CHECK-APPLE-LABEL: dontCrash:
1858; CHECK-APPLE:       ## %bb.0: ## %entry
1859; CHECK-APPLE-NEXT:    pushq %rax
1860; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 16
1861; CHECK-APPLE-NEXT:    callq _testFunA
1862; CHECK-APPLE-NEXT:    cmpb $1, (%rax)
1863; CHECK-APPLE-NEXT:    popq %rax
1864; CHECK-APPLE-NEXT:    retq
1865;
1866; CHECK-O0-LABEL: dontCrash:
1867; CHECK-O0:       ## %bb.0: ## %entry
1868; CHECK-O0-NEXT:    pushq %rax
1869; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
1870; CHECK-O0-NEXT:    ## implicit-def: $rax
1871; CHECK-O0-NEXT:    xorl %eax, %eax
1872; CHECK-O0-NEXT:    ## kill: def $rax killed $eax
1873; CHECK-O0-NEXT:    callq _testFunA
1874; CHECK-O0-NEXT:    testb $1, (%rax)
1875; CHECK-O0-NEXT:    jne LBB21_1
1876; CHECK-O0-NEXT:    jmp LBB21_2
1877; CHECK-O0-NEXT:  LBB21_1: ## %trueBB
1878; CHECK-O0-NEXT:    popq %rax
1879; CHECK-O0-NEXT:    retq
1880; CHECK-O0-NEXT:  LBB21_2: ## %falseBB
1881; CHECK-O0-NEXT:    popq %rax
1882; CHECK-O0-NEXT:    retq
1883;
1884; CHECK-i386-LABEL: dontCrash:
1885; CHECK-i386:       ## %bb.0: ## %entry
1886; CHECK-i386-NEXT:    subl $12, %esp
1887; CHECK-i386-NEXT:    .cfi_def_cfa_offset 16
1888; CHECK-i386-NEXT:    movl $0, 8(%esp)
1889; CHECK-i386-NEXT:    calll _testFunA
1890; CHECK-i386-NEXT:    cmpb $1, (%eax)
1891; CHECK-i386-NEXT:    addl $12, %esp
1892; CHECK-i386-NEXT:    retl
1893entry:
1894  %swifterror = alloca swifterror ptr, align 8
1895  store ptr null, ptr %swifterror, align 8
1896  %a = call ptr @testFunA()
1897  %c = load i1, ptr %a, align 1
1898  br i1 %c, label %trueBB, label %falseBB
1899
1900trueBB:
1901  ret void
1902
1903falseBB:
1904  ret void
1905}
1906
1907
1908declare swiftcc void @foo2(ptr swifterror)
1909
1910; Make sure we properly assign registers during fast-isel.
1911define swiftcc ptr @testAssign(ptr %error_ref) {
1912; CHECK-APPLE-LABEL: testAssign:
1913; CHECK-APPLE:       ## %bb.0: ## %entry
1914; CHECK-APPLE-NEXT:    pushq %r12
1915; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 16
1916; CHECK-APPLE-NEXT:    subq $16, %rsp
1917; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 32
1918; CHECK-APPLE-NEXT:    .cfi_offset %r12, -16
1919; CHECK-APPLE-NEXT:    xorl %r12d, %r12d
1920; CHECK-APPLE-NEXT:    callq _foo2
1921; CHECK-APPLE-NEXT:    movq %r12, %rax
1922; CHECK-APPLE-NEXT:    addq $16, %rsp
1923; CHECK-APPLE-NEXT:    popq %r12
1924; CHECK-APPLE-NEXT:    retq
1925;
1926; CHECK-O0-LABEL: testAssign:
1927; CHECK-O0:       ## %bb.0: ## %entry
1928; CHECK-O0-NEXT:    pushq %r12
1929; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
1930; CHECK-O0-NEXT:    subq $16, %rsp
1931; CHECK-O0-NEXT:    .cfi_def_cfa_offset 32
1932; CHECK-O0-NEXT:    .cfi_offset %r12, -16
1933; CHECK-O0-NEXT:    ## implicit-def: $rax
1934; CHECK-O0-NEXT:    xorl %eax, %eax
1935; CHECK-O0-NEXT:    movl %eax, %r12d
1936; CHECK-O0-NEXT:    callq _foo2
1937; CHECK-O0-NEXT:    movq %r12, (%rsp) ## 8-byte Spill
1938; CHECK-O0-NEXT:  ## %bb.1: ## %a
1939; CHECK-O0-NEXT:    movq (%rsp), %rax ## 8-byte Reload
1940; CHECK-O0-NEXT:    addq $16, %rsp
1941; CHECK-O0-NEXT:    popq %r12
1942; CHECK-O0-NEXT:    retq
1943;
1944; CHECK-i386-LABEL: testAssign:
1945; CHECK-i386:       ## %bb.0: ## %entry
1946; CHECK-i386-NEXT:    subl $12, %esp
1947; CHECK-i386-NEXT:    .cfi_def_cfa_offset 16
1948; CHECK-i386-NEXT:    movl $0, 8(%esp)
1949; CHECK-i386-NEXT:    leal 8(%esp), %eax
1950; CHECK-i386-NEXT:    movl %eax, (%esp)
1951; CHECK-i386-NEXT:    calll _foo2
1952; CHECK-i386-NEXT:    movl 8(%esp), %eax
1953; CHECK-i386-NEXT:    addl $12, %esp
1954; CHECK-i386-NEXT:    retl
1955entry:
1956  %error_ptr = alloca swifterror ptr
1957  store ptr null, ptr %error_ptr
1958  call swiftcc void @foo2(ptr swifterror %error_ptr)
1959  br label %a
1960
1961a:
1962  %error = load ptr, ptr %error_ptr
1963  ret ptr %error
1964}
1965
1966define swiftcc ptr @testAssign2(ptr %error_ref, ptr swifterror %err) {
1967; CHECK-APPLE-LABEL: testAssign2:
1968; CHECK-APPLE:       ## %bb.0: ## %entry
1969; CHECK-APPLE-NEXT:    movq %r12, %rax
1970; CHECK-APPLE-NEXT:    retq
1971;
1972; CHECK-O0-LABEL: testAssign2:
1973; CHECK-O0:       ## %bb.0: ## %entry
1974; CHECK-O0-NEXT:    movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
1975; CHECK-O0-NEXT:    jmp LBB23_1
1976; CHECK-O0-NEXT:  LBB23_1: ## %a
1977; CHECK-O0-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %r12 ## 8-byte Reload
1978; CHECK-O0-NEXT:    movq %r12, %rax
1979; CHECK-O0-NEXT:    retq
1980;
1981; CHECK-i386-LABEL: testAssign2:
1982; CHECK-i386:       ## %bb.0: ## %entry
1983; CHECK-i386-NEXT:    movl 8(%esp), %eax
1984; CHECK-i386-NEXT:    movl (%eax), %eax
1985; CHECK-i386-NEXT:    retl
1986entry:
1987  br label %a
1988
1989a:
1990  %error = load ptr, ptr %err
1991  ret ptr %error
1992}
1993
1994define swiftcc ptr @testAssign3(ptr %error_ref, ptr swifterror %err) {
1995; CHECK-APPLE-LABEL: testAssign3:
1996; CHECK-APPLE:       ## %bb.0: ## %entry
1997; CHECK-APPLE-NEXT:    pushq %rax
1998; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 16
1999; CHECK-APPLE-NEXT:    callq _foo2
2000; CHECK-APPLE-NEXT:    movq %r12, %rax
2001; CHECK-APPLE-NEXT:    popq %rcx
2002; CHECK-APPLE-NEXT:    retq
2003;
2004; CHECK-O0-LABEL: testAssign3:
2005; CHECK-O0:       ## %bb.0: ## %entry
2006; CHECK-O0-NEXT:    pushq %rax
2007; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
2008; CHECK-O0-NEXT:    callq _foo2
2009; CHECK-O0-NEXT:    movq %r12, (%rsp) ## 8-byte Spill
2010; CHECK-O0-NEXT:  ## %bb.1: ## %a
2011; CHECK-O0-NEXT:    movq (%rsp), %r12 ## 8-byte Reload
2012; CHECK-O0-NEXT:    movq %r12, %rax
2013; CHECK-O0-NEXT:    popq %rcx
2014; CHECK-O0-NEXT:    retq
2015;
2016; CHECK-i386-LABEL: testAssign3:
2017; CHECK-i386:       ## %bb.0: ## %entry
2018; CHECK-i386-NEXT:    pushl %esi
2019; CHECK-i386-NEXT:    .cfi_def_cfa_offset 8
2020; CHECK-i386-NEXT:    subl $8, %esp
2021; CHECK-i386-NEXT:    .cfi_def_cfa_offset 16
2022; CHECK-i386-NEXT:    .cfi_offset %esi, -8
2023; CHECK-i386-NEXT:    movl 20(%esp), %esi
2024; CHECK-i386-NEXT:    movl %esi, (%esp)
2025; CHECK-i386-NEXT:    calll _foo2
2026; CHECK-i386-NEXT:    movl (%esi), %eax
2027; CHECK-i386-NEXT:    addl $8, %esp
2028; CHECK-i386-NEXT:    popl %esi
2029; CHECK-i386-NEXT:    retl
2030entry:
2031  call swiftcc void @foo2(ptr swifterror %err)
2032  br label %a
2033
2034a:
2035  %error = load ptr, ptr %err
2036  ret ptr %error
2037}
2038
2039define swiftcc ptr @testAssign4(ptr %error_ref, ptr swifterror %err) {
2040; CHECK-APPLE-LABEL: testAssign4:
2041; CHECK-APPLE:       ## %bb.0: ## %entry
2042; CHECK-APPLE-NEXT:    pushq %rax
2043; CHECK-APPLE-NEXT:    .cfi_def_cfa_offset 16
2044; CHECK-APPLE-NEXT:    callq _foo2
2045; CHECK-APPLE-NEXT:    xorl %eax, %eax
2046; CHECK-APPLE-NEXT:    xorl %r12d, %r12d
2047; CHECK-APPLE-NEXT:    popq %rcx
2048; CHECK-APPLE-NEXT:    retq
2049;
2050; CHECK-O0-LABEL: testAssign4:
2051; CHECK-O0:       ## %bb.0: ## %entry
2052; CHECK-O0-NEXT:    pushq %rax
2053; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
2054; CHECK-O0-NEXT:    callq _foo2
2055; CHECK-O0-NEXT:    xorl %eax, %eax
2056; CHECK-O0-NEXT:    ## kill: def $rax killed $eax
2057; CHECK-O0-NEXT:    movq %rax, (%rsp) ## 8-byte Spill
2058; CHECK-O0-NEXT:  ## %bb.1: ## %a
2059; CHECK-O0-NEXT:    movq (%rsp), %r12 ## 8-byte Reload
2060; CHECK-O0-NEXT:    movq %r12, %rax
2061; CHECK-O0-NEXT:    popq %rcx
2062; CHECK-O0-NEXT:    retq
2063;
2064; CHECK-i386-LABEL: testAssign4:
2065; CHECK-i386:       ## %bb.0: ## %entry
2066; CHECK-i386-NEXT:    pushl %esi
2067; CHECK-i386-NEXT:    .cfi_def_cfa_offset 8
2068; CHECK-i386-NEXT:    subl $8, %esp
2069; CHECK-i386-NEXT:    .cfi_def_cfa_offset 16
2070; CHECK-i386-NEXT:    .cfi_offset %esi, -8
2071; CHECK-i386-NEXT:    movl 20(%esp), %esi
2072; CHECK-i386-NEXT:    movl %esi, (%esp)
2073; CHECK-i386-NEXT:    calll _foo2
2074; CHECK-i386-NEXT:    movl $0, (%esi)
2075; CHECK-i386-NEXT:    movl (%esi), %eax
2076; CHECK-i386-NEXT:    addl $8, %esp
2077; CHECK-i386-NEXT:    popl %esi
2078; CHECK-i386-NEXT:    retl
2079entry:
2080  call swiftcc void @foo2(ptr swifterror %err)
2081  store ptr null, ptr %err
2082  br label %a
2083
2084a:
2085  %error = load ptr, ptr %err
2086  ret ptr %error
2087}
2088