; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --no_x86_scrub_sp
; RUN: llc -verify-machineinstrs < %s -mtriple=x86_64-apple-darwin -disable-block-placement | FileCheck --check-prefix=CHECK-APPLE %s
; RUN: llc -verify-machineinstrs -O0 < %s -mtriple=x86_64-apple-darwin -disable-block-placement | FileCheck --check-prefix=CHECK-O0 %s
; RUN: llc -verify-machineinstrs < %s -mtriple=i386-apple-darwin -disable-block-placement | FileCheck --check-prefix=CHECK-i386 %s
declare ptr @malloc(i64)
declare void @free(ptr)
%swift_error = type {i64, i8}
; This tests the basic usage of a swifterror parameter. "foo" is the function
; that takes a swifterror parameter and "caller" is the caller of "foo".
define float @foo(ptr swifterror %error_ptr_ref) {
; CHECK-APPLE-LABEL: foo:
; CHECK-APPLE: ## %bb.0: ## %entry
; CHECK-APPLE-NEXT: pushq %rax
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 16
; CHECK-APPLE-NEXT: movl $16, %edi
; CHECK-APPLE-NEXT: callq _malloc
; CHECK-APPLE-NEXT: movb $1, 8(%rax)
; CHECK-APPLE-NEXT: movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
; CHECK-APPLE-NEXT: movq %rax, %r12
; CHECK-APPLE-NEXT: popq %rax
; CHECK-APPLE-NEXT: retq
;
; CHECK-O0-LABEL: foo:
; CHECK-O0: ## %bb.0: ## %entry
; CHECK-O0-NEXT: pushq %rax
; CHECK-O0-NEXT: .cfi_def_cfa_offset 16
; CHECK-O0-NEXT: movl $16, %edi
; CHECK-O0-NEXT: callq _malloc
; CHECK-O0-NEXT: movq %rax, %r12
; CHECK-O0-NEXT: movb $1, 8(%rax)
; CHECK-O0-NEXT: movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
; CHECK-O0-NEXT: popq %rax
; CHECK-O0-NEXT: retq
;
; CHECK-i386-LABEL: foo:
; CHECK-i386: ## %bb.0: ## %entry
; CHECK-i386-NEXT: pushl %esi
; CHECK-i386-NEXT: .cfi_def_cfa_offset 8
; CHECK-i386-NEXT: subl $8, %esp
; CHECK-i386-NEXT: .cfi_def_cfa_offset 16
; CHECK-i386-NEXT: .cfi_offset %esi, -8
; CHECK-i386-NEXT: movl 16(%esp), %esi
; CHECK-i386-NEXT: movl $0, 4(%esp)
; CHECK-i386-NEXT: movl $16, (%esp)
; CHECK-i386-NEXT: calll _malloc
; CHECK-i386-NEXT: movl %eax, (%esi)
; CHECK-i386-NEXT: movb $1, 8(%eax)
; CHECK-i386-NEXT: fld1
; CHECK-i386-NEXT: addl $8, %esp
; CHECK-i386-NEXT: popl %esi
; CHECK-i386-NEXT: retl
entry:
%call = call ptr @malloc(i64 16)
store ptr %call, ptr %error_ptr_ref
%tmp = getelementptr inbounds i8, ptr %call, i64 8
store i8 1, ptr %tmp
ret float 1.0
}
; "caller" calls "foo" that takes a swifterror parameter.
define float @caller(ptr %error_ref) {
; CHECK-APPLE-LABEL: caller:
; CHECK-APPLE: ## %bb.0: ## %entry
; CHECK-APPLE-NEXT: pushq %r12
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 16
; CHECK-APPLE-NEXT: pushq %rbx
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 24
; CHECK-APPLE-NEXT: pushq %rax
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 32
; CHECK-APPLE-NEXT: .cfi_offset %rbx, -24
; CHECK-APPLE-NEXT: .cfi_offset %r12, -16
; CHECK-APPLE-NEXT: movq %rdi, %rbx
; CHECK-APPLE-NEXT: xorl %r12d, %r12d
; CHECK-APPLE-NEXT: callq _foo
; CHECK-APPLE-NEXT: movq %r12, %rdi
; CHECK-APPLE-NEXT: testq %r12, %r12
; CHECK-APPLE-NEXT: jne LBB1_2
; CHECK-APPLE-NEXT: ## %bb.1: ## %cont
; CHECK-APPLE-NEXT: movzbl 8(%rdi), %eax
; CHECK-APPLE-NEXT: movb %al, (%rbx)
; CHECK-APPLE-NEXT: LBB1_2: ## %handler
; CHECK-APPLE-NEXT: callq _free
; CHECK-APPLE-NEXT: movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
; CHECK-APPLE-NEXT: addq $8, %rsp
; CHECK-APPLE-NEXT: popq %rbx
; CHECK-APPLE-NEXT: popq %r12
; CHECK-APPLE-NEXT: retq
;
; CHECK-O0-LABEL: caller:
; CHECK-O0: ## %bb.0: ## %entry
; CHECK-O0-NEXT: pushq %r12
; CHECK-O0-NEXT: .cfi_def_cfa_offset 16
; CHECK-O0-NEXT: subq $32, %rsp
; CHECK-O0-NEXT: .cfi_def_cfa_offset 48
; CHECK-O0-NEXT: .cfi_offset %r12, -16
; CHECK-O0-NEXT: ## implicit-def: $rax
; CHECK-O0-NEXT: movq %rdi, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: xorl %eax, %eax
; CHECK-O0-NEXT: movl %eax, %r12d
; CHECK-O0-NEXT: callq _foo
; CHECK-O0-NEXT: movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: cmpq $0, %r12
; CHECK-O0-NEXT: jne LBB1_2
; CHECK-O0-NEXT: ## %bb.1: ## %cont
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax ## 8-byte Reload
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx ## 8-byte Reload
; CHECK-O0-NEXT: movb 8(%rcx), %cl
; CHECK-O0-NEXT: movb %cl, (%rax)
; CHECK-O0-NEXT: LBB1_2: ## %handler
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdi ## 8-byte Reload
; CHECK-O0-NEXT: callq _free
; CHECK-O0-NEXT: movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
; CHECK-O0-NEXT: addq $32, %rsp
; CHECK-O0-NEXT: popq %r12
; CHECK-O0-NEXT: retq
;
; CHECK-i386-LABEL: caller:
; CHECK-i386: ## %bb.0: ## %entry
; CHECK-i386-NEXT: subl $12, %esp
; CHECK-i386-NEXT: .cfi_def_cfa_offset 16
; CHECK-i386-NEXT: movl $0, 8(%esp)
; CHECK-i386-NEXT: leal 8(%esp), %eax
; CHECK-i386-NEXT: movl %eax, (%esp)
; CHECK-i386-NEXT: calll _foo
; CHECK-i386-NEXT: fstp %st(0)
; CHECK-i386-NEXT: movl 8(%esp), %eax
; CHECK-i386-NEXT: testl %eax, %eax
; CHECK-i386-NEXT: jne LBB1_2
; CHECK-i386-NEXT: ## %bb.1: ## %cont
; CHECK-i386-NEXT: movl 16(%esp), %ecx
; CHECK-i386-NEXT: movzbl 8(%eax), %edx
; CHECK-i386-NEXT: movb %dl, (%ecx)
; CHECK-i386-NEXT: LBB1_2: ## %handler
; CHECK-i386-NEXT: movl %eax, (%esp)
; CHECK-i386-NEXT: calll _free
; CHECK-i386-NEXT: fld1
; CHECK-i386-NEXT: addl $12, %esp
; CHECK-i386-NEXT: retl
; Access part of the error object and save it to error_ref
entry:
%error_ptr_ref = alloca swifterror ptr
store ptr null, ptr %error_ptr_ref
%call = call float @foo(ptr swifterror %error_ptr_ref)
%error_from_foo = load ptr, ptr %error_ptr_ref
%had_error_from_foo = icmp ne ptr %error_from_foo, null
br i1 %had_error_from_foo, label %handler, label %cont
cont:
%v1 = getelementptr inbounds %swift_error, ptr %error_from_foo, i64 0, i32 1
%t = load i8, ptr %v1
store i8 %t, ptr %error_ref
br label %handler
handler:
call void @free(ptr %error_from_foo)
ret float 1.0
}
; "caller2" is the caller of "foo", it calls "foo" inside a loop.
define float @caller2(ptr %error_ref) {
; CHECK-APPLE-LABEL: caller2:
; CHECK-APPLE: ## %bb.0: ## %entry
; CHECK-APPLE-NEXT: pushq %r12
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 16
; CHECK-APPLE-NEXT: pushq %rbx
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 24
; CHECK-APPLE-NEXT: pushq %rax
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 32
; CHECK-APPLE-NEXT: .cfi_offset %rbx, -24
; CHECK-APPLE-NEXT: .cfi_offset %r12, -16
; CHECK-APPLE-NEXT: movq %rdi, %rbx
; CHECK-APPLE-NEXT: LBB2_1: ## %bb_loop
; CHECK-APPLE-NEXT: ## =>This Inner Loop Header: Depth=1
; CHECK-APPLE-NEXT: xorl %r12d, %r12d
; CHECK-APPLE-NEXT: callq _foo
; CHECK-APPLE-NEXT: testq %r12, %r12
; CHECK-APPLE-NEXT: jne LBB2_4
; CHECK-APPLE-NEXT: ## %bb.2: ## %cont
; CHECK-APPLE-NEXT: ## in Loop: Header=BB2_1 Depth=1
; CHECK-APPLE-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
; CHECK-APPLE-NEXT: jbe LBB2_1
; CHECK-APPLE-NEXT: ## %bb.3: ## %bb_end
; CHECK-APPLE-NEXT: movzbl 8(%r12), %eax
; CHECK-APPLE-NEXT: movb %al, (%rbx)
; CHECK-APPLE-NEXT: LBB2_4: ## %handler
; CHECK-APPLE-NEXT: movq %r12, %rdi
; CHECK-APPLE-NEXT: callq _free
; CHECK-APPLE-NEXT: movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
; CHECK-APPLE-NEXT: addq $8, %rsp
; CHECK-APPLE-NEXT: popq %rbx
; CHECK-APPLE-NEXT: popq %r12
; CHECK-APPLE-NEXT: retq
;
; CHECK-O0-LABEL: caller2:
; CHECK-O0: ## %bb.0: ## %entry
; CHECK-O0-NEXT: pushq %r12
; CHECK-O0-NEXT: .cfi_def_cfa_offset 16
; CHECK-O0-NEXT: subq $32, %rsp
; CHECK-O0-NEXT: .cfi_def_cfa_offset 48
; CHECK-O0-NEXT: .cfi_offset %r12, -16
; CHECK-O0-NEXT: ## implicit-def: $rax
; CHECK-O0-NEXT: movq %rdi, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: LBB2_1: ## %bb_loop
; CHECK-O0-NEXT: ## =>This Inner Loop Header: Depth=1
; CHECK-O0-NEXT: xorl %eax, %eax
; CHECK-O0-NEXT: movl %eax, %r12d
; CHECK-O0-NEXT: callq _foo
; CHECK-O0-NEXT: movss %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) ## 4-byte Spill
; CHECK-O0-NEXT: movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: cmpq $0, %r12
; CHECK-O0-NEXT: jne LBB2_4
; CHECK-O0-NEXT: ## %bb.2: ## %cont
; CHECK-O0-NEXT: ## in Loop: Header=BB2_1 Depth=1
; CHECK-O0-NEXT: movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 ## 4-byte Reload
; CHECK-O0-NEXT: ## xmm0 = mem[0],zero,zero,zero
; CHECK-O0-NEXT: movss {{.*#+}} xmm1 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
; CHECK-O0-NEXT: ucomiss %xmm1, %xmm0
; CHECK-O0-NEXT: jbe LBB2_1
; CHECK-O0-NEXT: ## %bb.3: ## %bb_end
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax ## 8-byte Reload
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx ## 8-byte Reload
; CHECK-O0-NEXT: movb 8(%rcx), %cl
; CHECK-O0-NEXT: movb %cl, (%rax)
; CHECK-O0-NEXT: LBB2_4: ## %handler
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdi ## 8-byte Reload
; CHECK-O0-NEXT: callq _free
; CHECK-O0-NEXT: movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
; CHECK-O0-NEXT: addq $32, %rsp
; CHECK-O0-NEXT: popq %r12
; CHECK-O0-NEXT: retq
;
; CHECK-i386-LABEL: caller2:
; CHECK-i386: ## %bb.0: ## %entry
; CHECK-i386-NEXT: pushl %edi
; CHECK-i386-NEXT: .cfi_def_cfa_offset 8
; CHECK-i386-NEXT: pushl %esi
; CHECK-i386-NEXT: .cfi_def_cfa_offset 12
; CHECK-i386-NEXT: subl $20, %esp
; CHECK-i386-NEXT: .cfi_def_cfa_offset 32
; CHECK-i386-NEXT: .cfi_offset %esi, -12
; CHECK-i386-NEXT: .cfi_offset %edi, -8
; CHECK-i386-NEXT: movl 32(%esp), %esi
; CHECK-i386-NEXT: leal 16(%esp), %edi
; CHECK-i386-NEXT: LBB2_1: ## %bb_loop
; CHECK-i386-NEXT: ## =>This Inner Loop Header: Depth=1
; CHECK-i386-NEXT: movl $0, 16(%esp)
; CHECK-i386-NEXT: movl %edi, (%esp)
; CHECK-i386-NEXT: calll _foo
; CHECK-i386-NEXT: movl 16(%esp), %ecx
; CHECK-i386-NEXT: testl %ecx, %ecx
; CHECK-i386-NEXT: jne LBB2_4
; CHECK-i386-NEXT: ## %bb.2: ## %cont
; CHECK-i386-NEXT: ## in Loop: Header=BB2_1 Depth=1
; CHECK-i386-NEXT: fld1
; CHECK-i386-NEXT: fxch %st(1)
; CHECK-i386-NEXT: fucompp
; CHECK-i386-NEXT: fnstsw %ax
; CHECK-i386-NEXT: ## kill: def $ah killed $ah killed $ax
; CHECK-i386-NEXT: sahf
; CHECK-i386-NEXT: jbe LBB2_1
; CHECK-i386-NEXT: ## %bb.3: ## %bb_end
; CHECK-i386-NEXT: movzbl 8(%ecx), %eax
; CHECK-i386-NEXT: movb %al, (%esi)
; CHECK-i386-NEXT: fldz
; CHECK-i386-NEXT: LBB2_4: ## %handler
; CHECK-i386-NEXT: fstp %st(0)
; CHECK-i386-NEXT: movl %ecx, (%esp)
; CHECK-i386-NEXT: calll _free
; CHECK-i386-NEXT: fld1
; CHECK-i386-NEXT: addl $20, %esp
; CHECK-i386-NEXT: popl %esi
; CHECK-i386-NEXT: popl %edi
; CHECK-i386-NEXT: retl
; Access part of the error object and save it to error_ref
entry:
%error_ptr_ref = alloca swifterror ptr
br label %bb_loop
bb_loop:
store ptr null, ptr %error_ptr_ref
%call = call float @foo(ptr swifterror %error_ptr_ref)
%error_from_foo = load ptr, ptr %error_ptr_ref
%had_error_from_foo = icmp ne ptr %error_from_foo, null
br i1 %had_error_from_foo, label %handler, label %cont
cont:
%cmp = fcmp ogt float %call, 1.000000e+00
br i1 %cmp, label %bb_end, label %bb_loop
bb_end:
%v1 = getelementptr inbounds %swift_error, ptr %error_from_foo, i64 0, i32 1
%t = load i8, ptr %v1
store i8 %t, ptr %error_ref
br label %handler
handler:
call void @free(ptr %error_from_foo)
ret float 1.0
}
; "foo_if" is a function that takes a swifterror parameter, it sets swifterror
; under a certain condition.
define float @foo_if(ptr swifterror %error_ptr_ref, i32 %cc) {
; CHECK-APPLE-LABEL: foo_if:
; CHECK-APPLE: ## %bb.0: ## %entry
; CHECK-APPLE-NEXT: testl %edi, %edi
; CHECK-APPLE-NEXT: je LBB3_2
; CHECK-APPLE-NEXT: ## %bb.1: ## %gen_error
; CHECK-APPLE-NEXT: pushq %rax
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 16
; CHECK-APPLE-NEXT: movl $16, %edi
; CHECK-APPLE-NEXT: callq _malloc
; CHECK-APPLE-NEXT: movb $1, 8(%rax)
; CHECK-APPLE-NEXT: movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
; CHECK-APPLE-NEXT: movq %rax, %r12
; CHECK-APPLE-NEXT: popq %rax
; CHECK-APPLE-NEXT: retq
; CHECK-APPLE-NEXT: LBB3_2: ## %normal
; CHECK-APPLE-NEXT: xorps %xmm0, %xmm0
; CHECK-APPLE-NEXT: retq
;
; CHECK-O0-LABEL: foo_if:
; CHECK-O0: ## %bb.0: ## %entry
; CHECK-O0-NEXT: pushq %rax
; CHECK-O0-NEXT: .cfi_def_cfa_offset 16
; CHECK-O0-NEXT: movq %r12, (%rsp) ## 8-byte Spill
; CHECK-O0-NEXT: cmpl $0, %edi
; CHECK-O0-NEXT: je LBB3_2
; CHECK-O0-NEXT: ## %bb.1: ## %gen_error
; CHECK-O0-NEXT: movl $16, %edi
; CHECK-O0-NEXT: callq _malloc
; CHECK-O0-NEXT: movq %rax, %r12
; CHECK-O0-NEXT: movb $1, 8(%rax)
; CHECK-O0-NEXT: movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
; CHECK-O0-NEXT: popq %rax
; CHECK-O0-NEXT: retq
; CHECK-O0-NEXT: LBB3_2: ## %normal
; CHECK-O0-NEXT: movq (%rsp), %r12 ## 8-byte Reload
; CHECK-O0-NEXT: xorps %xmm0, %xmm0
; CHECK-O0-NEXT: popq %rax
; CHECK-O0-NEXT: retq
;
; CHECK-i386-LABEL: foo_if:
; CHECK-i386: ## %bb.0: ## %entry
; CHECK-i386-NEXT: pushl %esi
; CHECK-i386-NEXT: .cfi_def_cfa_offset 8
; CHECK-i386-NEXT: subl $8, %esp
; CHECK-i386-NEXT: .cfi_def_cfa_offset 16
; CHECK-i386-NEXT: .cfi_offset %esi, -8
; CHECK-i386-NEXT: cmpl $0, 20(%esp)
; CHECK-i386-NEXT: je LBB3_2
; CHECK-i386-NEXT: ## %bb.1: ## %gen_error
; CHECK-i386-NEXT: movl 16(%esp), %esi
; CHECK-i386-NEXT: movl $0, 4(%esp)
; CHECK-i386-NEXT: movl $16, (%esp)
; CHECK-i386-NEXT: calll _malloc
; CHECK-i386-NEXT: movl %eax, (%esi)
; CHECK-i386-NEXT: movb $1, 8(%eax)
; CHECK-i386-NEXT: fld1
; CHECK-i386-NEXT: jmp LBB3_3
; CHECK-i386-NEXT: LBB3_2: ## %normal
; CHECK-i386-NEXT: fldz
; CHECK-i386-NEXT: LBB3_3: ## %normal
; CHECK-i386-NEXT: addl $8, %esp
; CHECK-i386-NEXT: popl %esi
; CHECK-i386-NEXT: retl
; spill to stack
; reload from stack
entry:
%cond = icmp ne i32 %cc, 0
br i1 %cond, label %gen_error, label %normal
gen_error:
%call = call ptr @malloc(i64 16)
store ptr %call, ptr %error_ptr_ref
%tmp = getelementptr inbounds i8, ptr %call, i64 8
store i8 1, ptr %tmp
ret float 1.0
normal:
ret float 0.0
}
; "foo_loop" is a function that takes a swifterror parameter, it sets swifterror
; under a certain condition inside a loop.
define float @foo_loop(ptr swifterror %error_ptr_ref, i32 %cc, float %cc2) {
; CHECK-APPLE-LABEL: foo_loop:
; CHECK-APPLE: ## %bb.0: ## %entry
; CHECK-APPLE-NEXT: pushq %rbx
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 16
; CHECK-APPLE-NEXT: subq $16, %rsp
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 32
; CHECK-APPLE-NEXT: .cfi_offset %rbx, -16
; CHECK-APPLE-NEXT: movss %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) ## 4-byte Spill
; CHECK-APPLE-NEXT: movl %edi, %ebx
; CHECK-APPLE-NEXT: movq %r12, %rax
; CHECK-APPLE-NEXT: LBB4_1: ## %bb_loop
; CHECK-APPLE-NEXT: ## =>This Inner Loop Header: Depth=1
; CHECK-APPLE-NEXT: testl %ebx, %ebx
; CHECK-APPLE-NEXT: je LBB4_3
; CHECK-APPLE-NEXT: ## %bb.2: ## %gen_error
; CHECK-APPLE-NEXT: ## in Loop: Header=BB4_1 Depth=1
; CHECK-APPLE-NEXT: movl $16, %edi
; CHECK-APPLE-NEXT: callq _malloc
; CHECK-APPLE-NEXT: movb $1, 8(%rax)
; CHECK-APPLE-NEXT: LBB4_3: ## %bb_cont
; CHECK-APPLE-NEXT: ## in Loop: Header=BB4_1 Depth=1
; CHECK-APPLE-NEXT: movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 ## 4-byte Reload
; CHECK-APPLE-NEXT: ## xmm0 = mem[0],zero,zero,zero
; CHECK-APPLE-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
; CHECK-APPLE-NEXT: jbe LBB4_1
; CHECK-APPLE-NEXT: ## %bb.4: ## %bb_end
; CHECK-APPLE-NEXT: xorps %xmm0, %xmm0
; CHECK-APPLE-NEXT: movq %rax, %r12
; CHECK-APPLE-NEXT: addq $16, %rsp
; CHECK-APPLE-NEXT: popq %rbx
; CHECK-APPLE-NEXT: retq
;
; CHECK-O0-LABEL: foo_loop:
; CHECK-O0: ## %bb.0: ## %entry
; CHECK-O0-NEXT: subq $40, %rsp
; CHECK-O0-NEXT: .cfi_def_cfa_offset 48
; CHECK-O0-NEXT: movss %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) ## 4-byte Spill
; CHECK-O0-NEXT: movl %edi, {{[-0-9]+}}(%r{{[sb]}}p) ## 4-byte Spill
; CHECK-O0-NEXT: movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: jmp LBB4_1
; CHECK-O0-NEXT: LBB4_1: ## %bb_loop
; CHECK-O0-NEXT: ## =>This Inner Loop Header: Depth=1
; CHECK-O0-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %ecx ## 4-byte Reload
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax ## 8-byte Reload
; CHECK-O0-NEXT: cmpl $0, %ecx
; CHECK-O0-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: je LBB4_3
; CHECK-O0-NEXT: ## %bb.2: ## %gen_error
; CHECK-O0-NEXT: ## in Loop: Header=BB4_1 Depth=1
; CHECK-O0-NEXT: movl $16, %edi
; CHECK-O0-NEXT: callq _malloc
; CHECK-O0-NEXT: movq %rax, %rcx
; CHECK-O0-NEXT: movb $1, 8(%rcx)
; CHECK-O0-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: LBB4_3: ## %bb_cont
; CHECK-O0-NEXT: ## in Loop: Header=BB4_1 Depth=1
; CHECK-O0-NEXT: movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 ## 4-byte Reload
; CHECK-O0-NEXT: ## xmm0 = mem[0],zero,zero,zero
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax ## 8-byte Reload
; CHECK-O0-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: movss {{.*#+}} xmm1 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
; CHECK-O0-NEXT: ucomiss %xmm1, %xmm0
; CHECK-O0-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: jbe LBB4_1
; CHECK-O0-NEXT: ## %bb.4: ## %bb_end
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r12 ## 8-byte Reload
; CHECK-O0-NEXT: xorps %xmm0, %xmm0
; CHECK-O0-NEXT: addq $40, %rsp
; CHECK-O0-NEXT: retq
;
; CHECK-i386-LABEL: foo_loop:
; CHECK-i386: ## %bb.0: ## %entry
; CHECK-i386-NEXT: pushl %edi
; CHECK-i386-NEXT: .cfi_def_cfa_offset 8
; CHECK-i386-NEXT: pushl %esi
; CHECK-i386-NEXT: .cfi_def_cfa_offset 12
; CHECK-i386-NEXT: subl $20, %esp
; CHECK-i386-NEXT: .cfi_def_cfa_offset 32
; CHECK-i386-NEXT: .cfi_offset %esi, -12
; CHECK-i386-NEXT: .cfi_offset %edi, -8
; CHECK-i386-NEXT: flds 40(%esp)
; CHECK-i386-NEXT: fstps {{[-0-9]+}}(%e{{[sb]}}p) ## 4-byte Folded Spill
; CHECK-i386-NEXT: movl 36(%esp), %esi
; CHECK-i386-NEXT: movl 32(%esp), %edi
; CHECK-i386-NEXT: LBB4_1: ## %bb_loop
; CHECK-i386-NEXT: ## =>This Inner Loop Header: Depth=1
; CHECK-i386-NEXT: testl %esi, %esi
; CHECK-i386-NEXT: je LBB4_3
; CHECK-i386-NEXT: ## %bb.2: ## %gen_error
; CHECK-i386-NEXT: ## in Loop: Header=BB4_1 Depth=1
; CHECK-i386-NEXT: movl $0, 4(%esp)
; CHECK-i386-NEXT: movl $16, (%esp)
; CHECK-i386-NEXT: calll _malloc
; CHECK-i386-NEXT: movl %eax, (%edi)
; CHECK-i386-NEXT: movb $1, 8(%eax)
; CHECK-i386-NEXT: LBB4_3: ## %bb_cont
; CHECK-i386-NEXT: ## in Loop: Header=BB4_1 Depth=1
; CHECK-i386-NEXT: flds {{[-0-9]+}}(%e{{[sb]}}p) ## 4-byte Folded Reload
; CHECK-i386-NEXT: fld1
; CHECK-i386-NEXT: fxch %st(1)
; CHECK-i386-NEXT: fucompp
; CHECK-i386-NEXT: fnstsw %ax
; CHECK-i386-NEXT: ## kill: def $ah killed $ah killed $ax
; CHECK-i386-NEXT: sahf
; CHECK-i386-NEXT: jbe LBB4_1
; CHECK-i386-NEXT: ## %bb.4: ## %bb_end
; CHECK-i386-NEXT: fldz
; CHECK-i386-NEXT: addl $20, %esp
; CHECK-i386-NEXT: popl %esi
; CHECK-i386-NEXT: popl %edi
; CHECK-i386-NEXT: retl
; spill to stack
; reload from stack
entry:
br label %bb_loop
bb_loop:
%cond = icmp ne i32 %cc, 0
br i1 %cond, label %gen_error, label %bb_cont
gen_error:
%call = call ptr @malloc(i64 16)
store ptr %call, ptr %error_ptr_ref
%tmp = getelementptr inbounds i8, ptr %call, i64 8
store i8 1, ptr %tmp
br label %bb_cont
bb_cont:
%cmp = fcmp ogt float %cc2, 1.000000e+00
br i1 %cmp, label %bb_end, label %bb_loop
bb_end:
ret float 0.0
}
%struct.S = type { i32, i32, i32, i32, i32, i32 }
; "foo_sret" is a function that takes a swifterror parameter, it also has a sret
; parameter.
define void @foo_sret(ptr sret(%struct.S) %agg.result, i32 %val1, ptr swifterror %error_ptr_ref) {
; CHECK-APPLE-LABEL: foo_sret:
; CHECK-APPLE: ## %bb.0: ## %entry
; CHECK-APPLE-NEXT: pushq %r14
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 16
; CHECK-APPLE-NEXT: pushq %rbx
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 24
; CHECK-APPLE-NEXT: pushq %rax
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 32
; CHECK-APPLE-NEXT: .cfi_offset %rbx, -24
; CHECK-APPLE-NEXT: .cfi_offset %r14, -16
; CHECK-APPLE-NEXT: movl %esi, %ebx
; CHECK-APPLE-NEXT: movq %rdi, %r14
; CHECK-APPLE-NEXT: movl $16, %edi
; CHECK-APPLE-NEXT: callq _malloc
; CHECK-APPLE-NEXT: movb $1, 8(%rax)
; CHECK-APPLE-NEXT: movl %ebx, 4(%r14)
; CHECK-APPLE-NEXT: movq %rax, %r12
; CHECK-APPLE-NEXT: movq %r14, %rax
; CHECK-APPLE-NEXT: addq $8, %rsp
; CHECK-APPLE-NEXT: popq %rbx
; CHECK-APPLE-NEXT: popq %r14
; CHECK-APPLE-NEXT: retq
;
; CHECK-O0-LABEL: foo_sret:
; CHECK-O0: ## %bb.0: ## %entry
; CHECK-O0-NEXT: subq $24, %rsp
; CHECK-O0-NEXT: .cfi_def_cfa_offset 32
; CHECK-O0-NEXT: movl %esi, {{[-0-9]+}}(%r{{[sb]}}p) ## 4-byte Spill
; CHECK-O0-NEXT: movq %rdi, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: movq %rdi, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: movl $16, %edi
; CHECK-O0-NEXT: callq _malloc
; CHECK-O0-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %esi ## 4-byte Reload
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdi ## 8-byte Reload
; CHECK-O0-NEXT: movq %rax, %rcx
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax ## 8-byte Reload
; CHECK-O0-NEXT: movq %rcx, %r12
; CHECK-O0-NEXT: movb $1, 8(%rcx)
; CHECK-O0-NEXT: movl %esi, 4(%rdi)
; CHECK-O0-NEXT: addq $24, %rsp
; CHECK-O0-NEXT: retq
;
; CHECK-i386-LABEL: foo_sret:
; CHECK-i386: ## %bb.0: ## %entry
; CHECK-i386-NEXT: pushl %ebx
; CHECK-i386-NEXT: .cfi_def_cfa_offset 8
; CHECK-i386-NEXT: pushl %edi
; CHECK-i386-NEXT: .cfi_def_cfa_offset 12
; CHECK-i386-NEXT: pushl %esi
; CHECK-i386-NEXT: .cfi_def_cfa_offset 16
; CHECK-i386-NEXT: subl $16, %esp
; CHECK-i386-NEXT: .cfi_def_cfa_offset 32
; CHECK-i386-NEXT: .cfi_offset %esi, -16
; CHECK-i386-NEXT: .cfi_offset %edi, -12
; CHECK-i386-NEXT: .cfi_offset %ebx, -8
; CHECK-i386-NEXT: movl 32(%esp), %esi
; CHECK-i386-NEXT: movl 36(%esp), %edi
; CHECK-i386-NEXT: movl 40(%esp), %ebx
; CHECK-i386-NEXT: movl $0, 4(%esp)
; CHECK-i386-NEXT: movl $16, (%esp)
; CHECK-i386-NEXT: calll _malloc
; CHECK-i386-NEXT: movl %eax, (%ebx)
; CHECK-i386-NEXT: movb $1, 8(%eax)
; CHECK-i386-NEXT: movl %edi, 4(%esi)
; CHECK-i386-NEXT: movl %esi, %eax
; CHECK-i386-NEXT: addl $16, %esp
; CHECK-i386-NEXT: popl %esi
; CHECK-i386-NEXT: popl %edi
; CHECK-i386-NEXT: popl %ebx
; CHECK-i386-NEXT: retl $4
; spill sret to stack
; reload sret from stack
entry:
%call = call ptr @malloc(i64 16)
store ptr %call, ptr %error_ptr_ref
%tmp = getelementptr inbounds i8, ptr %call, i64 8
store i8 1, ptr %tmp
%v2 = getelementptr inbounds %struct.S, ptr %agg.result, i32 0, i32 1
store i32 %val1, ptr %v2
ret void
}
; "caller3" calls "foo_sret" that takes a swifterror parameter.
define float @caller3(ptr %error_ref) {
; CHECK-APPLE-LABEL: caller3:
; CHECK-APPLE: ## %bb.0: ## %entry
; CHECK-APPLE-NEXT: pushq %r12
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 16
; CHECK-APPLE-NEXT: pushq %rbx
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 24
; CHECK-APPLE-NEXT: subq $40, %rsp
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 64
; CHECK-APPLE-NEXT: .cfi_offset %rbx, -24
; CHECK-APPLE-NEXT: .cfi_offset %r12, -16
; CHECK-APPLE-NEXT: movq %rdi, %rbx
; CHECK-APPLE-NEXT: leaq 8(%rsp), %rdi
; CHECK-APPLE-NEXT: movl $1, %esi
; CHECK-APPLE-NEXT: xorl %r12d, %r12d
; CHECK-APPLE-NEXT: callq _foo_sret
; CHECK-APPLE-NEXT: movq %r12, %rdi
; CHECK-APPLE-NEXT: testq %r12, %r12
; CHECK-APPLE-NEXT: jne LBB6_2
; CHECK-APPLE-NEXT: ## %bb.1: ## %cont
; CHECK-APPLE-NEXT: movzbl 8(%rdi), %eax
; CHECK-APPLE-NEXT: movb %al, (%rbx)
; CHECK-APPLE-NEXT: LBB6_2: ## %handler
; CHECK-APPLE-NEXT: callq _free
; CHECK-APPLE-NEXT: movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
; CHECK-APPLE-NEXT: addq $40, %rsp
; CHECK-APPLE-NEXT: popq %rbx
; CHECK-APPLE-NEXT: popq %r12
; CHECK-APPLE-NEXT: retq
;
; CHECK-O0-LABEL: caller3:
; CHECK-O0: ## %bb.0: ## %entry
; CHECK-O0-NEXT: pushq %r12
; CHECK-O0-NEXT: .cfi_def_cfa_offset 16
; CHECK-O0-NEXT: subq $48, %rsp
; CHECK-O0-NEXT: .cfi_def_cfa_offset 64
; CHECK-O0-NEXT: .cfi_offset %r12, -16
; CHECK-O0-NEXT: ## implicit-def: $rax
; CHECK-O0-NEXT: movq %rdi, (%rsp) ## 8-byte Spill
; CHECK-O0-NEXT: xorl %eax, %eax
; CHECK-O0-NEXT: movl %eax, %r12d
; CHECK-O0-NEXT: leaq 24(%rsp), %rdi
; CHECK-O0-NEXT: movl $1, %esi
; CHECK-O0-NEXT: callq _foo_sret
; CHECK-O0-NEXT: movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: cmpq $0, %r12
; CHECK-O0-NEXT: jne LBB6_2
; CHECK-O0-NEXT: ## %bb.1: ## %cont
; CHECK-O0-NEXT: movq (%rsp), %rax ## 8-byte Reload
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx ## 8-byte Reload
; CHECK-O0-NEXT: movb 8(%rcx), %cl
; CHECK-O0-NEXT: movb %cl, (%rax)
; CHECK-O0-NEXT: LBB6_2: ## %handler
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdi ## 8-byte Reload
; CHECK-O0-NEXT: callq _free
; CHECK-O0-NEXT: movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
; CHECK-O0-NEXT: addq $48, %rsp
; CHECK-O0-NEXT: popq %r12
; CHECK-O0-NEXT: retq
;
; CHECK-i386-LABEL: caller3:
; CHECK-i386: ## %bb.0: ## %entry
; CHECK-i386-NEXT: subl $44, %esp
; CHECK-i386-NEXT: .cfi_def_cfa_offset 48
; CHECK-i386-NEXT: movl $0, 12(%esp)
; CHECK-i386-NEXT: leal 12(%esp), %eax
; CHECK-i386-NEXT: movl %eax, 8(%esp)
; CHECK-i386-NEXT: leal 16(%esp), %eax
; CHECK-i386-NEXT: movl %eax, (%esp)
; CHECK-i386-NEXT: movl $1, 4(%esp)
; CHECK-i386-NEXT: calll _foo_sret
; CHECK-i386-NEXT: subl $4, %esp
; CHECK-i386-NEXT: movl 12(%esp), %eax
; CHECK-i386-NEXT: testl %eax, %eax
; CHECK-i386-NEXT: jne LBB6_2
; CHECK-i386-NEXT: ## %bb.1: ## %cont
; CHECK-i386-NEXT: movl 48(%esp), %ecx
; CHECK-i386-NEXT: movzbl 8(%eax), %edx
; CHECK-i386-NEXT: movb %dl, (%ecx)
; CHECK-i386-NEXT: LBB6_2: ## %handler
; CHECK-i386-NEXT: movl %eax, (%esp)
; CHECK-i386-NEXT: calll _free
; CHECK-i386-NEXT: fld1
; CHECK-i386-NEXT: addl $44, %esp
; CHECK-i386-NEXT: retl
; Access part of the error object and save it to error_ref
; Access part of the error object and save it to error_ref
; reload from stack
entry:
%s = alloca %struct.S, align 8
%error_ptr_ref = alloca swifterror ptr
store ptr null, ptr %error_ptr_ref
call void @foo_sret(ptr sret(%struct.S) %s, i32 1, ptr swifterror %error_ptr_ref)
%error_from_foo = load ptr, ptr %error_ptr_ref
%had_error_from_foo = icmp ne ptr %error_from_foo, null
br i1 %had_error_from_foo, label %handler, label %cont
cont:
%v1 = getelementptr inbounds %swift_error, ptr %error_from_foo, i64 0, i32 1
%t = load i8, ptr %v1
store i8 %t, ptr %error_ref
br label %handler
handler:
call void @free(ptr %error_from_foo)
ret float 1.0
}
; This is a caller with multiple swifterror values, it calls "foo" twice, each
; time with a different swifterror value, from "alloca swifterror".
define float @caller_with_multiple_swifterror_values(ptr %error_ref, ptr %error_ref2) {
; CHECK-APPLE-LABEL: caller_with_multiple_swifterror_values:
; CHECK-APPLE: ## %bb.0: ## %entry
; CHECK-APPLE-NEXT: pushq %rbp
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 16
; CHECK-APPLE-NEXT: .cfi_offset %rbp, -16
; CHECK-APPLE-NEXT: movq %rsp, %rbp
; CHECK-APPLE-NEXT: .cfi_def_cfa_register %rbp
; CHECK-APPLE-NEXT: pushq %r14
; CHECK-APPLE-NEXT: pushq %r12
; CHECK-APPLE-NEXT: pushq %rbx
; CHECK-APPLE-NEXT: pushq %rax
; CHECK-APPLE-NEXT: .cfi_offset %rbx, -40
; CHECK-APPLE-NEXT: .cfi_offset %r12, -32
; CHECK-APPLE-NEXT: .cfi_offset %r14, -24
; CHECK-APPLE-NEXT: movq %rsi, %rbx
; CHECK-APPLE-NEXT: movq %rdi, %r14
; CHECK-APPLE-NEXT: xorl %r12d, %r12d
; CHECK-APPLE-NEXT: callq _foo
; CHECK-APPLE-NEXT: movq %r12, %rdi
; CHECK-APPLE-NEXT: testq %r12, %r12
; CHECK-APPLE-NEXT: jne LBB7_2
; CHECK-APPLE-NEXT: ## %bb.1: ## %cont
; CHECK-APPLE-NEXT: movzbl 8(%rdi), %eax
; CHECK-APPLE-NEXT: movb %al, (%r14)
; CHECK-APPLE-NEXT: LBB7_2: ## %handler
; CHECK-APPLE-NEXT: callq _free
; CHECK-APPLE-NEXT: movq %rsp, %rax
; CHECK-APPLE-NEXT: addq $-16, %rax
; CHECK-APPLE-NEXT: movq %rax, %rsp
; CHECK-APPLE-NEXT: xorl %r12d, %r12d
; CHECK-APPLE-NEXT: callq _foo
; CHECK-APPLE-NEXT: movq %r12, %rdi
; CHECK-APPLE-NEXT: testq %r12, %r12
; CHECK-APPLE-NEXT: jne LBB7_4
; CHECK-APPLE-NEXT: ## %bb.3: ## %cont2
; CHECK-APPLE-NEXT: movzbl 8(%rdi), %eax
; CHECK-APPLE-NEXT: movb %al, (%rbx)
; CHECK-APPLE-NEXT: LBB7_4: ## %handler2
; CHECK-APPLE-NEXT: callq _free
; CHECK-APPLE-NEXT: movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
; CHECK-APPLE-NEXT: leaq -24(%rbp), %rsp
; CHECK-APPLE-NEXT: popq %rbx
; CHECK-APPLE-NEXT: popq %r12
; CHECK-APPLE-NEXT: popq %r14
; CHECK-APPLE-NEXT: popq %rbp
; CHECK-APPLE-NEXT: retq
;
; CHECK-O0-LABEL: caller_with_multiple_swifterror_values:
; CHECK-O0: ## %bb.0: ## %entry
; CHECK-O0-NEXT: pushq %rbp
; CHECK-O0-NEXT: .cfi_def_cfa_offset 16
; CHECK-O0-NEXT: .cfi_offset %rbp, -16
; CHECK-O0-NEXT: movq %rsp, %rbp
; CHECK-O0-NEXT: .cfi_def_cfa_register %rbp
; CHECK-O0-NEXT: pushq %r12
; CHECK-O0-NEXT: subq $40, %rsp
; CHECK-O0-NEXT: .cfi_offset %r12, -24
; CHECK-O0-NEXT: ## implicit-def: $rax
; CHECK-O0-NEXT: ## implicit-def: $rax
; CHECK-O0-NEXT: movq %rdi, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: xorl %eax, %eax
; CHECK-O0-NEXT: movl %eax, %r12d
; CHECK-O0-NEXT: callq _foo
; CHECK-O0-NEXT: movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: cmpq $0, %r12
; CHECK-O0-NEXT: jne LBB7_2
; CHECK-O0-NEXT: ## %bb.1: ## %cont
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax ## 8-byte Reload
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx ## 8-byte Reload
; CHECK-O0-NEXT: movb 8(%rcx), %cl
; CHECK-O0-NEXT: movb %cl, (%rax)
; CHECK-O0-NEXT: LBB7_2: ## %handler
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdi ## 8-byte Reload
; CHECK-O0-NEXT: callq _free
; CHECK-O0-NEXT: movq %rsp, %rax
; CHECK-O0-NEXT: addq $-16, %rax
; CHECK-O0-NEXT: movq %rax, %rsp
; CHECK-O0-NEXT: xorl %eax, %eax
; CHECK-O0-NEXT: movl %eax, %r12d
; CHECK-O0-NEXT: callq _foo
; CHECK-O0-NEXT: movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: cmpq $0, %r12
; CHECK-O0-NEXT: jne LBB7_4
; CHECK-O0-NEXT: ## %bb.3: ## %cont2
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax ## 8-byte Reload
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx ## 8-byte Reload
; CHECK-O0-NEXT: movb 8(%rcx), %cl
; CHECK-O0-NEXT: movb %cl, (%rax)
; CHECK-O0-NEXT: LBB7_4: ## %handler2
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdi ## 8-byte Reload
; CHECK-O0-NEXT: callq _free
; CHECK-O0-NEXT: movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
; CHECK-O0-NEXT: leaq -8(%rbp), %rsp
; CHECK-O0-NEXT: popq %r12
; CHECK-O0-NEXT: popq %rbp
; CHECK-O0-NEXT: retq
;
; CHECK-i386-LABEL: caller_with_multiple_swifterror_values:
; CHECK-i386: ## %bb.0: ## %entry
; CHECK-i386-NEXT: pushl %ebp
; CHECK-i386-NEXT: .cfi_def_cfa_offset 8
; CHECK-i386-NEXT: .cfi_offset %ebp, -8
; CHECK-i386-NEXT: movl %esp, %ebp
; CHECK-i386-NEXT: .cfi_def_cfa_register %ebp
; CHECK-i386-NEXT: pushl %esi
; CHECK-i386-NEXT: pushl %eax
; CHECK-i386-NEXT: .cfi_offset %esi, -12
; CHECK-i386-NEXT: movl $0, -8(%ebp)
; CHECK-i386-NEXT: subl $12, %esp
; CHECK-i386-NEXT: leal -8(%ebp), %eax
; CHECK-i386-NEXT: pushl %eax
; CHECK-i386-NEXT: calll _foo
; CHECK-i386-NEXT: fstp %st(0)
; CHECK-i386-NEXT: addl $16, %esp
; CHECK-i386-NEXT: movl -8(%ebp), %eax
; CHECK-i386-NEXT: testl %eax, %eax
; CHECK-i386-NEXT: jne LBB7_2
; CHECK-i386-NEXT: ## %bb.1: ## %cont
; CHECK-i386-NEXT: movl 8(%ebp), %ecx
; CHECK-i386-NEXT: movzbl 8(%eax), %edx
; CHECK-i386-NEXT: movb %dl, (%ecx)
; CHECK-i386-NEXT: LBB7_2: ## %handler
; CHECK-i386-NEXT: subl $12, %esp
; CHECK-i386-NEXT: pushl %eax
; CHECK-i386-NEXT: calll _free
; CHECK-i386-NEXT: addl $16, %esp
; CHECK-i386-NEXT: movl %esp, %esi
; CHECK-i386-NEXT: leal -16(%esi), %eax
; CHECK-i386-NEXT: movl %eax, %esp
; CHECK-i386-NEXT: movl $0, -16(%esi)
; CHECK-i386-NEXT: subl $12, %esp
; CHECK-i386-NEXT: pushl %eax
; CHECK-i386-NEXT: calll _foo
; CHECK-i386-NEXT: fstp %st(0)
; CHECK-i386-NEXT: addl $16, %esp
; CHECK-i386-NEXT: movl -16(%esi), %eax
; CHECK-i386-NEXT: testl %eax, %eax
; CHECK-i386-NEXT: jne LBB7_4
; CHECK-i386-NEXT: ## %bb.3: ## %cont2
; CHECK-i386-NEXT: movl 12(%ebp), %ecx
; CHECK-i386-NEXT: movzbl 8(%eax), %edx
; CHECK-i386-NEXT: movb %dl, (%ecx)
; CHECK-i386-NEXT: LBB7_4: ## %handler2
; CHECK-i386-NEXT: subl $12, %esp
; CHECK-i386-NEXT: pushl %eax
; CHECK-i386-NEXT: calll _free
; CHECK-i386-NEXT: addl $16, %esp
; CHECK-i386-NEXT: fld1
; CHECK-i386-NEXT: leal -4(%ebp), %esp
; CHECK-i386-NEXT: popl %esi
; CHECK-i386-NEXT: popl %ebp
; CHECK-i386-NEXT: retl
; The first swifterror value:
; Access part of the error object and save it to error_ref
; The second swifterror value:
; Access part of the error object and save it to error_ref
; The first swifterror value:
; The second swifterror value:
entry:
%error_ptr_ref = alloca swifterror ptr
store ptr null, ptr %error_ptr_ref
%call = call float @foo(ptr swifterror %error_ptr_ref)
%error_from_foo = load ptr, ptr %error_ptr_ref
%had_error_from_foo = icmp ne ptr %error_from_foo, null
br i1 %had_error_from_foo, label %handler, label %cont
cont:
%v1 = getelementptr inbounds %swift_error, ptr %error_from_foo, i64 0, i32 1
%t = load i8, ptr %v1
store i8 %t, ptr %error_ref
br label %handler
handler:
call void @free(ptr %error_from_foo)
%error_ptr_ref2 = alloca swifterror ptr
store ptr null, ptr %error_ptr_ref2
%call2 = call float @foo(ptr swifterror %error_ptr_ref2)
%error_from_foo2 = load ptr, ptr %error_ptr_ref2
%had_error_from_foo2 = icmp ne ptr %error_from_foo2, null
br i1 %had_error_from_foo2, label %handler2, label %cont2
cont2:
%v2 = getelementptr inbounds %swift_error, ptr %error_from_foo2, i64 0, i32 1
%t2 = load i8, ptr %v2
store i8 %t2, ptr %error_ref2
br label %handler2
handler2:
call void @free(ptr %error_from_foo2)
ret float 1.0
}
%swift.refcounted = type opaque
; This test checks that we don't create bad phi nodes as part of swifterror
; isel. We used to fail machine ir verification.
; CHECK-APPLE: _swifterror_isel
; CHECK-O0: _swifterror_isel
define void @swifterror_isel(ptr) {
; CHECK-APPLE-LABEL: swifterror_isel:
; CHECK-APPLE: ## %bb.0: ## %entry
; CHECK-APPLE-NEXT: pushq %r13
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 16
; CHECK-APPLE-NEXT: pushq %r12
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 24
; CHECK-APPLE-NEXT: pushq %rax
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 32
; CHECK-APPLE-NEXT: .cfi_offset %r12, -24
; CHECK-APPLE-NEXT: .cfi_offset %r13, -16
; CHECK-APPLE-NEXT: xorl %eax, %eax
; CHECK-APPLE-NEXT: testb %al, %al
; CHECK-APPLE-NEXT: jne LBB8_3
; CHECK-APPLE-NEXT: ## %bb.1: ## %.preheader
; CHECK-APPLE-NEXT: movq %rdi, %r13
; CHECK-APPLE-NEXT: ## implicit-def: $di
; CHECK-APPLE-NEXT: ## implicit-def: $r12
; CHECK-APPLE-NEXT: LBB8_2: ## =>This Inner Loop Header: Depth=1
; CHECK-APPLE-NEXT: callq *%rax
; CHECK-APPLE-NEXT: movzwl (%rax), %edi
; CHECK-APPLE-NEXT: jmp LBB8_2
; CHECK-APPLE-NEXT: LBB8_3:
; CHECK-APPLE-NEXT: addq $8, %rsp
; CHECK-APPLE-NEXT: popq %r12
; CHECK-APPLE-NEXT: popq %r13
; CHECK-APPLE-NEXT: retq
;
; CHECK-O0-LABEL: swifterror_isel:
; CHECK-O0: ## %bb.0: ## %entry
; CHECK-O0-NEXT: pushq %r13
; CHECK-O0-NEXT: .cfi_def_cfa_offset 16
; CHECK-O0-NEXT: pushq %r12
; CHECK-O0-NEXT: .cfi_def_cfa_offset 24
; CHECK-O0-NEXT: subq $40, %rsp
; CHECK-O0-NEXT: .cfi_def_cfa_offset 64
; CHECK-O0-NEXT: .cfi_offset %r12, -24
; CHECK-O0-NEXT: .cfi_offset %r13, -16
; CHECK-O0-NEXT: movq %rdi, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: ## implicit-def: $al
; CHECK-O0-NEXT: testb $1, %al
; CHECK-O0-NEXT: ## implicit-def: $ax
; CHECK-O0-NEXT: ## implicit-def: $r12
; CHECK-O0-NEXT: jne LBB8_2
; CHECK-O0-NEXT: LBB8_1: ## =>This Inner Loop Header: Depth=1
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r12 ## 8-byte Reload
; CHECK-O0-NEXT: movw {{[-0-9]+}}(%r{{[sb]}}p), %ax ## 2-byte Reload
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r13 ## 8-byte Reload
; CHECK-O0-NEXT: ## implicit-def: $edi
; CHECK-O0-NEXT: movw %ax, %di
; CHECK-O0-NEXT: ## implicit-def: $rax
; CHECK-O0-NEXT: callq *%rax
; CHECK-O0-NEXT: ## implicit-def: $rax
; CHECK-O0-NEXT: movw (%rax), %ax
; CHECK-O0-NEXT: movw %ax, {{[-0-9]+}}(%r{{[sb]}}p) ## 2-byte Spill
; CHECK-O0-NEXT: movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: jmp LBB8_1
; CHECK-O0-NEXT: LBB8_2:
; CHECK-O0-NEXT: addq $40, %rsp
; CHECK-O0-NEXT: popq %r12
; CHECK-O0-NEXT: popq %r13
; CHECK-O0-NEXT: retq
;
; CHECK-i386-LABEL: swifterror_isel:
; CHECK-i386: ## %bb.0: ## %entry
; CHECK-i386-NEXT: pushl %edi
; CHECK-i386-NEXT: .cfi_def_cfa_offset 8
; CHECK-i386-NEXT: pushl %esi
; CHECK-i386-NEXT: .cfi_def_cfa_offset 12
; CHECK-i386-NEXT: subl $20, %esp
; CHECK-i386-NEXT: .cfi_def_cfa_offset 32
; CHECK-i386-NEXT: .cfi_offset %esi, -12
; CHECK-i386-NEXT: .cfi_offset %edi, -8
; CHECK-i386-NEXT: xorl %eax, %eax
; CHECK-i386-NEXT: testb %al, %al
; CHECK-i386-NEXT: jne LBB8_3
; CHECK-i386-NEXT: ## %bb.1: ## %.preheader
; CHECK-i386-NEXT: movl 32(%esp), %esi
; CHECK-i386-NEXT: leal 16(%esp), %edi
; CHECK-i386-NEXT: ## implicit-def: $ax
; CHECK-i386-NEXT: LBB8_2: ## =>This Inner Loop Header: Depth=1
; CHECK-i386-NEXT: movl %edi, 8(%esp)
; CHECK-i386-NEXT: movl %esi, 4(%esp)
; CHECK-i386-NEXT: movl %eax, (%esp)
; CHECK-i386-NEXT: calll *%eax
; CHECK-i386-NEXT: movzwl (%eax), %eax
; CHECK-i386-NEXT: jmp LBB8_2
; CHECK-i386-NEXT: LBB8_3:
; CHECK-i386-NEXT: addl $20, %esp
; CHECK-i386-NEXT: popl %esi
; CHECK-i386-NEXT: popl %edi
; CHECK-i386-NEXT: retl
entry:
%swifterror = alloca swifterror ptr, align 8
br i1 undef, label %5, label %1
%2 = phi i16 [ %4, %1 ], [ undef, %entry ]
%3 = call i1 undef(i16 %2, ptr swiftself %0, ptr nocapture swifterror %swifterror)
%4 = load i16, ptr undef, align 2
br label %1
ret void
}
; This tests the basic usage of a swifterror parameter with swiftcc.
define swiftcc float @foo_swiftcc(ptr swifterror %error_ptr_ref) {
; CHECK-APPLE-LABEL: foo_swiftcc:
; CHECK-APPLE: ## %bb.0: ## %entry
; CHECK-APPLE-NEXT: pushq %rax
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 16
; CHECK-APPLE-NEXT: movl $16, %edi
; CHECK-APPLE-NEXT: callq _malloc
; CHECK-APPLE-NEXT: movb $1, 8(%rax)
; CHECK-APPLE-NEXT: movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
; CHECK-APPLE-NEXT: movq %rax, %r12
; CHECK-APPLE-NEXT: popq %rax
; CHECK-APPLE-NEXT: retq
;
; CHECK-O0-LABEL: foo_swiftcc:
; CHECK-O0: ## %bb.0: ## %entry
; CHECK-O0-NEXT: pushq %rax
; CHECK-O0-NEXT: .cfi_def_cfa_offset 16
; CHECK-O0-NEXT: movl $16, %edi
; CHECK-O0-NEXT: callq _malloc
; CHECK-O0-NEXT: movq %rax, %r12
; CHECK-O0-NEXT: movb $1, 8(%rax)
; CHECK-O0-NEXT: movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
; CHECK-O0-NEXT: popq %rax
; CHECK-O0-NEXT: retq
;
; CHECK-i386-LABEL: foo_swiftcc:
; CHECK-i386: ## %bb.0: ## %entry
; CHECK-i386-NEXT: pushl %esi
; CHECK-i386-NEXT: .cfi_def_cfa_offset 8
; CHECK-i386-NEXT: subl $8, %esp
; CHECK-i386-NEXT: .cfi_def_cfa_offset 16
; CHECK-i386-NEXT: .cfi_offset %esi, -8
; CHECK-i386-NEXT: movl 16(%esp), %esi
; CHECK-i386-NEXT: movl $0, 4(%esp)
; CHECK-i386-NEXT: movl $16, (%esp)
; CHECK-i386-NEXT: calll _malloc
; CHECK-i386-NEXT: movl %eax, (%esi)
; CHECK-i386-NEXT: movb $1, 8(%eax)
; CHECK-i386-NEXT: fld1
; CHECK-i386-NEXT: addl $8, %esp
; CHECK-i386-NEXT: popl %esi
; CHECK-i386-NEXT: retl
entry:
%call = call ptr @malloc(i64 16)
store ptr %call, ptr %error_ptr_ref
%tmp = getelementptr inbounds i8, ptr %call, i64 8
store i8 1, ptr %tmp
ret float 1.0
}
declare swiftcc float @moo(ptr swifterror)
; Test parameter forwarding.
define swiftcc float @forward_swifterror(ptr swifterror %error_ptr_ref) {
; CHECK-APPLE-LABEL: forward_swifterror:
; CHECK-APPLE: ## %bb.0: ## %entry
; CHECK-APPLE-NEXT: pushq %rax
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 16
; CHECK-APPLE-NEXT: callq _moo
; CHECK-APPLE-NEXT: popq %rax
; CHECK-APPLE-NEXT: retq
;
; CHECK-O0-LABEL: forward_swifterror:
; CHECK-O0: ## %bb.0: ## %entry
; CHECK-O0-NEXT: pushq %rax
; CHECK-O0-NEXT: .cfi_def_cfa_offset 16
; CHECK-O0-NEXT: callq _moo
; CHECK-O0-NEXT: popq %rax
; CHECK-O0-NEXT: retq
;
; CHECK-i386-LABEL: forward_swifterror:
; CHECK-i386: ## %bb.0: ## %entry
; CHECK-i386-NEXT: subl $12, %esp
; CHECK-i386-NEXT: .cfi_def_cfa_offset 16
; CHECK-i386-NEXT: movl 16(%esp), %eax
; CHECK-i386-NEXT: movl %eax, (%esp)
; CHECK-i386-NEXT: calll _moo
; CHECK-i386-NEXT: addl $12, %esp
; CHECK-i386-NEXT: retl
entry:
%call = call swiftcc float @moo(ptr swifterror %error_ptr_ref)
ret float %call
}
define swiftcc float @conditionally_forward_swifterror(ptr swifterror %error_ptr_ref, i32 %cc) {
; CHECK-APPLE-LABEL: conditionally_forward_swifterror:
; CHECK-APPLE: ## %bb.0: ## %entry
; CHECK-APPLE-NEXT: testl %edi, %edi
; CHECK-APPLE-NEXT: je LBB11_2
; CHECK-APPLE-NEXT: ## %bb.1: ## %gen_error
; CHECK-APPLE-NEXT: pushq %rax
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 16
; CHECK-APPLE-NEXT: callq _moo
; CHECK-APPLE-NEXT: popq %rax
; CHECK-APPLE-NEXT: retq
; CHECK-APPLE-NEXT: LBB11_2: ## %normal
; CHECK-APPLE-NEXT: xorps %xmm0, %xmm0
; CHECK-APPLE-NEXT: retq
;
; CHECK-O0-LABEL: conditionally_forward_swifterror:
; CHECK-O0: ## %bb.0: ## %entry
; CHECK-O0-NEXT: pushq %rax
; CHECK-O0-NEXT: .cfi_def_cfa_offset 16
; CHECK-O0-NEXT: movq %r12, (%rsp) ## 8-byte Spill
; CHECK-O0-NEXT: cmpl $0, %edi
; CHECK-O0-NEXT: je LBB11_2
; CHECK-O0-NEXT: ## %bb.1: ## %gen_error
; CHECK-O0-NEXT: movq (%rsp), %r12 ## 8-byte Reload
; CHECK-O0-NEXT: callq _moo
; CHECK-O0-NEXT: popq %rax
; CHECK-O0-NEXT: retq
; CHECK-O0-NEXT: LBB11_2: ## %normal
; CHECK-O0-NEXT: movq (%rsp), %r12 ## 8-byte Reload
; CHECK-O0-NEXT: xorps %xmm0, %xmm0
; CHECK-O0-NEXT: popq %rax
; CHECK-O0-NEXT: retq
;
; CHECK-i386-LABEL: conditionally_forward_swifterror:
; CHECK-i386: ## %bb.0: ## %entry
; CHECK-i386-NEXT: subl $12, %esp
; CHECK-i386-NEXT: .cfi_def_cfa_offset 16
; CHECK-i386-NEXT: cmpl $0, 20(%esp)
; CHECK-i386-NEXT: je LBB11_2
; CHECK-i386-NEXT: ## %bb.1: ## %gen_error
; CHECK-i386-NEXT: movl 16(%esp), %eax
; CHECK-i386-NEXT: movl %eax, (%esp)
; CHECK-i386-NEXT: calll _moo
; CHECK-i386-NEXT: addl $12, %esp
; CHECK-i386-NEXT: retl
; CHECK-i386-NEXT: LBB11_2: ## %normal
; CHECK-i386-NEXT: fldz
; CHECK-i386-NEXT: addl $12, %esp
; CHECK-i386-NEXT: retl
entry:
%cond = icmp ne i32 %cc, 0
br i1 %cond, label %gen_error, label %normal
gen_error:
%call = call swiftcc float @moo(ptr swifterror %error_ptr_ref)
ret float %call
normal:
ret float 0.0
}
; Check that we don't blow up on tail calling swifterror argument functions.
define float @tailcallswifterror(ptr swifterror %error_ptr_ref) {
; CHECK-APPLE-LABEL: tailcallswifterror:
; CHECK-APPLE: ## %bb.0: ## %entry
; CHECK-APPLE-NEXT: pushq %rax
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 16
; CHECK-APPLE-NEXT: callq _tailcallswifterror
; CHECK-APPLE-NEXT: popq %rax
; CHECK-APPLE-NEXT: retq
;
; CHECK-O0-LABEL: tailcallswifterror:
; CHECK-O0: ## %bb.0: ## %entry
; CHECK-O0-NEXT: pushq %rax
; CHECK-O0-NEXT: .cfi_def_cfa_offset 16
; CHECK-O0-NEXT: callq _tailcallswifterror
; CHECK-O0-NEXT: popq %rax
; CHECK-O0-NEXT: retq
;
; CHECK-i386-LABEL: tailcallswifterror:
; CHECK-i386: ## %bb.0: ## %entry
; CHECK-i386-NEXT: jmp _tailcallswifterror ## TAILCALL
entry:
%0 = tail call float @tailcallswifterror(ptr swifterror %error_ptr_ref)
ret float %0
}
define swiftcc float @tailcallswifterror_swiftcc(ptr swifterror %error_ptr_ref) {
; CHECK-APPLE-LABEL: tailcallswifterror_swiftcc:
; CHECK-APPLE: ## %bb.0: ## %entry
; CHECK-APPLE-NEXT: pushq %rax
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 16
; CHECK-APPLE-NEXT: callq _tailcallswifterror_swiftcc
; CHECK-APPLE-NEXT: popq %rax
; CHECK-APPLE-NEXT: retq
;
; CHECK-O0-LABEL: tailcallswifterror_swiftcc:
; CHECK-O0: ## %bb.0: ## %entry
; CHECK-O0-NEXT: pushq %rax
; CHECK-O0-NEXT: .cfi_def_cfa_offset 16
; CHECK-O0-NEXT: callq _tailcallswifterror_swiftcc
; CHECK-O0-NEXT: popq %rax
; CHECK-O0-NEXT: retq
;
; CHECK-i386-LABEL: tailcallswifterror_swiftcc:
; CHECK-i386: ## %bb.0: ## %entry
; CHECK-i386-NEXT: jmp _tailcallswifterror_swiftcc ## TAILCALL
entry:
%0 = tail call swiftcc float @tailcallswifterror_swiftcc(ptr swifterror %error_ptr_ref)
ret float %0
}
; Check that we can handle an empty function with swifterror argument.
define swiftcc {i32, i32, i32} @empty_swiftcc({i32, i32, i32} , ptr swifterror %error_ptr_ref) {
; CHECK-APPLE-LABEL: empty_swiftcc:
; CHECK-APPLE: ## %bb.0: ## %entry
; CHECK-APPLE-NEXT: movl %edx, %ecx
; CHECK-APPLE-NEXT: movl %esi, %edx
; CHECK-APPLE-NEXT: movl %edi, %eax
; CHECK-APPLE-NEXT: retq
;
; CHECK-O0-LABEL: empty_swiftcc:
; CHECK-O0: ## %bb.0: ## %entry
; CHECK-O0-NEXT: movl %edx, %ecx
; CHECK-O0-NEXT: movl %esi, %edx
; CHECK-O0-NEXT: movl %edi, %eax
; CHECK-O0-NEXT: retq
;
; CHECK-i386-LABEL: empty_swiftcc:
; CHECK-i386: ## %bb.0: ## %entry
; CHECK-i386-NEXT: movl 4(%esp), %eax
; CHECK-i386-NEXT: movl 8(%esp), %edx
; CHECK-i386-NEXT: movl 12(%esp), %ecx
; CHECK-i386-NEXT: retl
entry:
ret {i32, i32, i32} %0
}
; Make sure we can handle the case when isel generates new machine basic blocks.
define swiftcc void @dont_crash_on_new_isel_blocks(ptr nocapture swifterror, i1, ptr) {
; CHECK-APPLE-LABEL: dont_crash_on_new_isel_blocks:
; CHECK-APPLE: ## %bb.0: ## %entry
; CHECK-APPLE-NEXT: testb $1, %dil
; CHECK-APPLE-NEXT: pushq %rax
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 16
; CHECK-APPLE-NEXT: callq *%rax
; CHECK-APPLE-NEXT: popq %rax
; CHECK-APPLE-NEXT: retq
;
; CHECK-O0-LABEL: dont_crash_on_new_isel_blocks:
; CHECK-O0: ## %bb.0: ## %entry
; CHECK-O0-NEXT: pushq %rax
; CHECK-O0-NEXT: .cfi_def_cfa_offset 16
; CHECK-O0-NEXT: movq %r12, (%rsp) ## 8-byte Spill
; CHECK-O0-NEXT: movb %dil, %al
; CHECK-O0-NEXT: orb $0, %al
; CHECK-O0-NEXT: testb $1, %al
; CHECK-O0-NEXT: jne LBB15_2
; CHECK-O0-NEXT: ## %bb.1: ## %falsebb
; CHECK-O0-NEXT: LBB15_2: ## %cont
; CHECK-O0-NEXT: movq (%rsp), %r12 ## 8-byte Reload
; CHECK-O0-NEXT: ## implicit-def: $rax
; CHECK-O0-NEXT: callq *%rax
; CHECK-O0-NEXT: popq %rax
; CHECK-O0-NEXT: retq
;
; CHECK-i386-LABEL: dont_crash_on_new_isel_blocks:
; CHECK-i386: ## %bb.0: ## %entry
; CHECK-i386-NEXT: testb $1, 8(%esp)
; CHECK-i386-NEXT: jmpl *%eax ## TAILCALL
entry:
%3 = or i1 false, %1
br i1 %3, label %cont, label %falsebb
falsebb:
%4 = load ptr, ptr %2, align 8
br label %cont
cont:
tail call swiftcc void undef(ptr nocapture swifterror %0)
ret void
}
define swiftcc void @swifterror_clobber(ptr nocapture swifterror %err) {
; CHECK-APPLE-LABEL: swifterror_clobber:
; CHECK-APPLE: ## %bb.0:
; CHECK-APPLE-NEXT: movq %r12, %rax
; CHECK-APPLE-NEXT: ## InlineAsm Start
; CHECK-APPLE-NEXT: nop
; CHECK-APPLE-NEXT: ## InlineAsm End
; CHECK-APPLE-NEXT: movq %rax, %r12
; CHECK-APPLE-NEXT: retq
;
; CHECK-O0-LABEL: swifterror_clobber:
; CHECK-O0: ## %bb.0:
; CHECK-O0-NEXT: movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: ## InlineAsm Start
; CHECK-O0-NEXT: nop
; CHECK-O0-NEXT: ## InlineAsm End
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r12 ## 8-byte Reload
; CHECK-O0-NEXT: retq
;
; CHECK-i386-LABEL: swifterror_clobber:
; CHECK-i386: ## %bb.0:
; CHECK-i386-NEXT: ## InlineAsm Start
; CHECK-i386-NEXT: nop
; CHECK-i386-NEXT: ## InlineAsm End
; CHECK-i386-NEXT: retl
call void asm sideeffect "nop", "~{r12}"()
ret void
}
define swiftcc void @swifterror_reg_clobber(ptr nocapture %err) {
; CHECK-APPLE-LABEL: swifterror_reg_clobber:
; CHECK-APPLE: ## %bb.0:
; CHECK-APPLE-NEXT: pushq %r12
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 16
; CHECK-APPLE-NEXT: .cfi_offset %r12, -16
; CHECK-APPLE-NEXT: ## InlineAsm Start
; CHECK-APPLE-NEXT: nop
; CHECK-APPLE-NEXT: ## InlineAsm End
; CHECK-APPLE-NEXT: popq %r12
; CHECK-APPLE-NEXT: retq
;
; CHECK-O0-LABEL: swifterror_reg_clobber:
; CHECK-O0: ## %bb.0:
; CHECK-O0-NEXT: pushq %r12
; CHECK-O0-NEXT: .cfi_def_cfa_offset 16
; CHECK-O0-NEXT: .cfi_offset %r12, -16
; CHECK-O0-NEXT: ## InlineAsm Start
; CHECK-O0-NEXT: nop
; CHECK-O0-NEXT: ## InlineAsm End
; CHECK-O0-NEXT: popq %r12
; CHECK-O0-NEXT: retq
;
; CHECK-i386-LABEL: swifterror_reg_clobber:
; CHECK-i386: ## %bb.0:
; CHECK-i386-NEXT: ## InlineAsm Start
; CHECK-i386-NEXT: nop
; CHECK-i386-NEXT: ## InlineAsm End
; CHECK-i386-NEXT: retl
call void asm sideeffect "nop", "~{r12}"()
ret void
}
define swiftcc void @params_in_reg(i64, i64, i64, i64, i64, i64, ptr swiftself, ptr nocapture swifterror %err) {
; CHECK-APPLE-LABEL: params_in_reg:
; CHECK-APPLE: ## %bb.0:
; CHECK-APPLE-NEXT: pushq %rbp
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 16
; CHECK-APPLE-NEXT: pushq %r15
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 24
; CHECK-APPLE-NEXT: pushq %r14
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 32
; CHECK-APPLE-NEXT: pushq %r13
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 40
; CHECK-APPLE-NEXT: pushq %rbx
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 48
; CHECK-APPLE-NEXT: subq $48, %rsp
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 96
; CHECK-APPLE-NEXT: .cfi_offset %rbx, -48
; CHECK-APPLE-NEXT: .cfi_offset %r13, -40
; CHECK-APPLE-NEXT: .cfi_offset %r14, -32
; CHECK-APPLE-NEXT: .cfi_offset %r15, -24
; CHECK-APPLE-NEXT: .cfi_offset %rbp, -16
; CHECK-APPLE-NEXT: movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-APPLE-NEXT: movq %r13, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-APPLE-NEXT: movq %r9, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-APPLE-NEXT: movq %r8, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-APPLE-NEXT: movq %rcx, %rbx
; CHECK-APPLE-NEXT: movq %rdx, %r14
; CHECK-APPLE-NEXT: movq %rsi, %r15
; CHECK-APPLE-NEXT: movq %rdi, %rbp
; CHECK-APPLE-NEXT: movl $1, %edi
; CHECK-APPLE-NEXT: movl $2, %esi
; CHECK-APPLE-NEXT: movl $3, %edx
; CHECK-APPLE-NEXT: movl $4, %ecx
; CHECK-APPLE-NEXT: movl $5, %r8d
; CHECK-APPLE-NEXT: movl $6, %r9d
; CHECK-APPLE-NEXT: xorl %r13d, %r13d
; CHECK-APPLE-NEXT: xorl %r12d, %r12d
; CHECK-APPLE-NEXT: callq _params_in_reg2
; CHECK-APPLE-NEXT: movq %rbp, %rdi
; CHECK-APPLE-NEXT: movq %r15, %rsi
; CHECK-APPLE-NEXT: movq %r14, %rdx
; CHECK-APPLE-NEXT: movq %rbx, %rcx
; CHECK-APPLE-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r8 ## 8-byte Reload
; CHECK-APPLE-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r9 ## 8-byte Reload
; CHECK-APPLE-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r13 ## 8-byte Reload
; CHECK-APPLE-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r12 ## 8-byte Reload
; CHECK-APPLE-NEXT: callq _params_in_reg2
; CHECK-APPLE-NEXT: addq $48, %rsp
; CHECK-APPLE-NEXT: popq %rbx
; CHECK-APPLE-NEXT: popq %r13
; CHECK-APPLE-NEXT: popq %r14
; CHECK-APPLE-NEXT: popq %r15
; CHECK-APPLE-NEXT: popq %rbp
; CHECK-APPLE-NEXT: retq
;
; CHECK-O0-LABEL: params_in_reg:
; CHECK-O0: ## %bb.0:
; CHECK-O0-NEXT: pushq %r13
; CHECK-O0-NEXT: .cfi_def_cfa_offset 16
; CHECK-O0-NEXT: subq $80, %rsp
; CHECK-O0-NEXT: .cfi_def_cfa_offset 96
; CHECK-O0-NEXT: .cfi_offset %r13, -16
; CHECK-O0-NEXT: movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: movq %r13, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: movq %r9, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: movq %r8, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: movq %rdi, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: ## implicit-def: $rax
; CHECK-O0-NEXT: xorl %eax, %eax
; CHECK-O0-NEXT: movl %eax, %r12d
; CHECK-O0-NEXT: movl $1, %edi
; CHECK-O0-NEXT: movl $2, %esi
; CHECK-O0-NEXT: movl $3, %edx
; CHECK-O0-NEXT: movl $4, %ecx
; CHECK-O0-NEXT: movl $5, %r8d
; CHECK-O0-NEXT: movl $6, %r9d
; CHECK-O0-NEXT: movq %r12, %r13
; CHECK-O0-NEXT: callq _params_in_reg2
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r13 ## 8-byte Reload
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdi ## 8-byte Reload
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rsi ## 8-byte Reload
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdx ## 8-byte Reload
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx ## 8-byte Reload
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r8 ## 8-byte Reload
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r9 ## 8-byte Reload
; CHECK-O0-NEXT: movq %r12, %rax
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r12 ## 8-byte Reload
; CHECK-O0-NEXT: callq _params_in_reg2
; CHECK-O0-NEXT: addq $80, %rsp
; CHECK-O0-NEXT: popq %r13
; CHECK-O0-NEXT: retq
;
; CHECK-i386-LABEL: params_in_reg:
; CHECK-i386: ## %bb.0:
; CHECK-i386-NEXT: pushl %ebp
; CHECK-i386-NEXT: .cfi_def_cfa_offset 8
; CHECK-i386-NEXT: pushl %ebx
; CHECK-i386-NEXT: .cfi_def_cfa_offset 12
; CHECK-i386-NEXT: pushl %edi
; CHECK-i386-NEXT: .cfi_def_cfa_offset 16
; CHECK-i386-NEXT: pushl %esi
; CHECK-i386-NEXT: .cfi_def_cfa_offset 20
; CHECK-i386-NEXT: subl $60, %esp
; CHECK-i386-NEXT: .cfi_def_cfa_offset 80
; CHECK-i386-NEXT: .cfi_offset %esi, -20
; CHECK-i386-NEXT: .cfi_offset %edi, -16
; CHECK-i386-NEXT: .cfi_offset %ebx, -12
; CHECK-i386-NEXT: .cfi_offset %ebp, -8
; CHECK-i386-NEXT: movl $0, 56(%esp)
; CHECK-i386-NEXT: movl 120(%esp), %ebx
; CHECK-i386-NEXT: movl 124(%esp), %ebp
; CHECK-i386-NEXT: movl 128(%esp), %esi
; CHECK-i386-NEXT: movl 132(%esp), %edi
; CHECK-i386-NEXT: leal 56(%esp), %eax
; CHECK-i386-NEXT: movl %eax, 52(%esp)
; CHECK-i386-NEXT: movl $0, 48(%esp)
; CHECK-i386-NEXT: movl $0, 44(%esp)
; CHECK-i386-NEXT: movl $6, 40(%esp)
; CHECK-i386-NEXT: movl $0, 36(%esp)
; CHECK-i386-NEXT: movl $5, 32(%esp)
; CHECK-i386-NEXT: movl $0, 28(%esp)
; CHECK-i386-NEXT: movl $4, 24(%esp)
; CHECK-i386-NEXT: movl $0, 20(%esp)
; CHECK-i386-NEXT: movl $3, 16(%esp)
; CHECK-i386-NEXT: movl $0, 12(%esp)
; CHECK-i386-NEXT: movl $2, 8(%esp)
; CHECK-i386-NEXT: movl $0, 4(%esp)
; CHECK-i386-NEXT: movl $1, (%esp)
; CHECK-i386-NEXT: calll _params_in_reg2
; CHECK-i386-NEXT: movl %edi, 52(%esp)
; CHECK-i386-NEXT: movl %esi, 48(%esp)
; CHECK-i386-NEXT: movl %ebp, 44(%esp)
; CHECK-i386-NEXT: movl %ebx, 40(%esp)
; CHECK-i386-NEXT: movl 116(%esp), %eax
; CHECK-i386-NEXT: movl %eax, 36(%esp)
; CHECK-i386-NEXT: movl 112(%esp), %eax
; CHECK-i386-NEXT: movl %eax, 32(%esp)
; CHECK-i386-NEXT: movl 108(%esp), %eax
; CHECK-i386-NEXT: movl %eax, 28(%esp)
; CHECK-i386-NEXT: movl 104(%esp), %eax
; CHECK-i386-NEXT: movl %eax, 24(%esp)
; CHECK-i386-NEXT: movl 100(%esp), %eax
; CHECK-i386-NEXT: movl %eax, 20(%esp)
; CHECK-i386-NEXT: movl 96(%esp), %eax
; CHECK-i386-NEXT: movl %eax, 16(%esp)
; CHECK-i386-NEXT: movl 92(%esp), %eax
; CHECK-i386-NEXT: movl %eax, 12(%esp)
; CHECK-i386-NEXT: movl 88(%esp), %eax
; CHECK-i386-NEXT: movl %eax, 8(%esp)
; CHECK-i386-NEXT: movl 84(%esp), %eax
; CHECK-i386-NEXT: movl %eax, 4(%esp)
; CHECK-i386-NEXT: movl 80(%esp), %eax
; CHECK-i386-NEXT: movl %eax, (%esp)
; CHECK-i386-NEXT: calll _params_in_reg2
; CHECK-i386-NEXT: addl $60, %esp
; CHECK-i386-NEXT: popl %esi
; CHECK-i386-NEXT: popl %edi
; CHECK-i386-NEXT: popl %ebx
; CHECK-i386-NEXT: popl %ebp
; CHECK-i386-NEXT: retl
%error_ptr_ref = alloca swifterror ptr, align 8
store ptr null, ptr %error_ptr_ref
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)
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)
ret void
}
declare swiftcc void @params_in_reg2(i64, i64, i64, i64, i64, i64, ptr swiftself, ptr nocapture swifterror %err)
define swiftcc { i64, i64, i64, i64} @params_and_return_in_reg(i64, i64, i64, i64, i64, i64, ptr swiftself, ptr nocapture swifterror %err) {
; CHECK-APPLE-LABEL: params_and_return_in_reg:
; CHECK-APPLE: ## %bb.0:
; CHECK-APPLE-NEXT: pushq %rbp
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 16
; CHECK-APPLE-NEXT: pushq %r15
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 24
; CHECK-APPLE-NEXT: pushq %r14
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 32
; CHECK-APPLE-NEXT: pushq %r13
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 40
; CHECK-APPLE-NEXT: pushq %rbx
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 48
; CHECK-APPLE-NEXT: subq $48, %rsp
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 96
; CHECK-APPLE-NEXT: .cfi_offset %rbx, -48
; CHECK-APPLE-NEXT: .cfi_offset %r13, -40
; CHECK-APPLE-NEXT: .cfi_offset %r14, -32
; CHECK-APPLE-NEXT: .cfi_offset %r15, -24
; CHECK-APPLE-NEXT: .cfi_offset %rbp, -16
; CHECK-APPLE-NEXT: movq %r12, (%rsp) ## 8-byte Spill
; CHECK-APPLE-NEXT: movq %r13, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-APPLE-NEXT: movq %r9, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-APPLE-NEXT: movq %r8, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-APPLE-NEXT: movq %rcx, %rbx
; CHECK-APPLE-NEXT: movq %rdx, %r14
; CHECK-APPLE-NEXT: movq %rsi, %r15
; CHECK-APPLE-NEXT: movq %rdi, %rbp
; CHECK-APPLE-NEXT: movl $1, %edi
; CHECK-APPLE-NEXT: movl $2, %esi
; CHECK-APPLE-NEXT: movl $3, %edx
; CHECK-APPLE-NEXT: movl $4, %ecx
; CHECK-APPLE-NEXT: movl $5, %r8d
; CHECK-APPLE-NEXT: movl $6, %r9d
; CHECK-APPLE-NEXT: xorl %r13d, %r13d
; CHECK-APPLE-NEXT: xorl %r12d, %r12d
; CHECK-APPLE-NEXT: callq _params_in_reg2
; CHECK-APPLE-NEXT: movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-APPLE-NEXT: movq %rbp, %rdi
; CHECK-APPLE-NEXT: movq %r15, %rsi
; CHECK-APPLE-NEXT: movq %r14, %rdx
; CHECK-APPLE-NEXT: movq %rbx, %rcx
; CHECK-APPLE-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r8 ## 8-byte Reload
; CHECK-APPLE-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r9 ## 8-byte Reload
; CHECK-APPLE-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r13 ## 8-byte Reload
; CHECK-APPLE-NEXT: movq (%rsp), %r12 ## 8-byte Reload
; CHECK-APPLE-NEXT: callq _params_and_return_in_reg2
; CHECK-APPLE-NEXT: movq %rax, %rbx
; CHECK-APPLE-NEXT: movq %rdx, %r14
; CHECK-APPLE-NEXT: movq %rcx, %r15
; CHECK-APPLE-NEXT: movq %r8, %rbp
; CHECK-APPLE-NEXT: movq %r12, (%rsp) ## 8-byte Spill
; CHECK-APPLE-NEXT: movl $1, %edi
; CHECK-APPLE-NEXT: movl $2, %esi
; CHECK-APPLE-NEXT: movl $3, %edx
; CHECK-APPLE-NEXT: movl $4, %ecx
; CHECK-APPLE-NEXT: movl $5, %r8d
; CHECK-APPLE-NEXT: movl $6, %r9d
; CHECK-APPLE-NEXT: xorl %r13d, %r13d
; CHECK-APPLE-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r12 ## 8-byte Reload
; CHECK-APPLE-NEXT: callq _params_in_reg2
; CHECK-APPLE-NEXT: movq %rbx, %rax
; CHECK-APPLE-NEXT: movq %r14, %rdx
; CHECK-APPLE-NEXT: movq %r15, %rcx
; CHECK-APPLE-NEXT: movq %rbp, %r8
; CHECK-APPLE-NEXT: movq (%rsp), %r12 ## 8-byte Reload
; CHECK-APPLE-NEXT: addq $48, %rsp
; CHECK-APPLE-NEXT: popq %rbx
; CHECK-APPLE-NEXT: popq %r13
; CHECK-APPLE-NEXT: popq %r14
; CHECK-APPLE-NEXT: popq %r15
; CHECK-APPLE-NEXT: popq %rbp
; CHECK-APPLE-NEXT: retq
;
; CHECK-O0-LABEL: params_and_return_in_reg:
; CHECK-O0: ## %bb.0:
; CHECK-O0-NEXT: pushq %r13
; CHECK-O0-NEXT: .cfi_def_cfa_offset 16
; CHECK-O0-NEXT: subq $176, %rsp
; CHECK-O0-NEXT: .cfi_def_cfa_offset 192
; CHECK-O0-NEXT: .cfi_offset %r13, -16
; CHECK-O0-NEXT: movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: movq %r13, (%rsp) ## 8-byte Spill
; CHECK-O0-NEXT: movq %r9, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: movq %r8, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: movq %rdi, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: ## implicit-def: $rax
; CHECK-O0-NEXT: xorl %eax, %eax
; CHECK-O0-NEXT: movl %eax, %r12d
; CHECK-O0-NEXT: movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: movl $1, %edi
; CHECK-O0-NEXT: movq %rdi, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: movl $2, %esi
; CHECK-O0-NEXT: movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: movl $3, %edx
; CHECK-O0-NEXT: movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: movl $4, %ecx
; CHECK-O0-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: movl $5, %r8d
; CHECK-O0-NEXT: movq %r8, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: movl $6, %r9d
; CHECK-O0-NEXT: movq %r9, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: movq %r12, %r13
; CHECK-O0-NEXT: callq _params_in_reg2
; CHECK-O0-NEXT: movq (%rsp), %r13 ## 8-byte Reload
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdi ## 8-byte Reload
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rsi ## 8-byte Reload
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdx ## 8-byte Reload
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx ## 8-byte Reload
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r8 ## 8-byte Reload
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r9 ## 8-byte Reload
; CHECK-O0-NEXT: movq %r12, %rax
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r12 ## 8-byte Reload
; CHECK-O0-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: callq _params_and_return_in_reg2
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r13 ## 8-byte Reload
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdi ## 8-byte Reload
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rsi ## 8-byte Reload
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r9 ## 8-byte Reload
; CHECK-O0-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: movq %rdx, %rax
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdx ## 8-byte Reload
; CHECK-O0-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: movq %rcx, %rax
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx ## 8-byte Reload
; CHECK-O0-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: movq %r8, %rax
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r8 ## 8-byte Reload
; CHECK-O0-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: movq %r12, %rax
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r12 ## 8-byte Reload
; CHECK-O0-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: callq _params_in_reg2
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax ## 8-byte Reload
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdx ## 8-byte Reload
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx ## 8-byte Reload
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r8 ## 8-byte Reload
; CHECK-O0-NEXT: movq %r12, %rsi
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r12 ## 8-byte Reload
; CHECK-O0-NEXT: addq $176, %rsp
; CHECK-O0-NEXT: popq %r13
; CHECK-O0-NEXT: retq
;
; CHECK-i386-LABEL: params_and_return_in_reg:
; CHECK-i386: ## %bb.0:
; CHECK-i386-NEXT: pushl %ebp
; CHECK-i386-NEXT: .cfi_def_cfa_offset 8
; CHECK-i386-NEXT: pushl %ebx
; CHECK-i386-NEXT: .cfi_def_cfa_offset 12
; CHECK-i386-NEXT: pushl %edi
; CHECK-i386-NEXT: .cfi_def_cfa_offset 16
; CHECK-i386-NEXT: pushl %esi
; CHECK-i386-NEXT: .cfi_def_cfa_offset 20
; CHECK-i386-NEXT: subl $124, %esp
; CHECK-i386-NEXT: .cfi_def_cfa_offset 144
; CHECK-i386-NEXT: .cfi_offset %esi, -20
; CHECK-i386-NEXT: .cfi_offset %edi, -16
; CHECK-i386-NEXT: .cfi_offset %ebx, -12
; CHECK-i386-NEXT: .cfi_offset %ebp, -8
; CHECK-i386-NEXT: movl 148(%esp), %esi
; CHECK-i386-NEXT: movl $0, 64(%esp)
; CHECK-i386-NEXT: movl 192(%esp), %ebx
; CHECK-i386-NEXT: movl 196(%esp), %ebp
; CHECK-i386-NEXT: movl 200(%esp), %edi
; CHECK-i386-NEXT: leal 64(%esp), %eax
; CHECK-i386-NEXT: movl %eax, 52(%esp)
; CHECK-i386-NEXT: movl $0, 48(%esp)
; CHECK-i386-NEXT: movl $0, 44(%esp)
; CHECK-i386-NEXT: movl $6, 40(%esp)
; CHECK-i386-NEXT: movl $0, 36(%esp)
; CHECK-i386-NEXT: movl $5, 32(%esp)
; CHECK-i386-NEXT: movl $0, 28(%esp)
; CHECK-i386-NEXT: movl $4, 24(%esp)
; CHECK-i386-NEXT: movl $0, 20(%esp)
; CHECK-i386-NEXT: movl $3, 16(%esp)
; CHECK-i386-NEXT: movl $0, 12(%esp)
; CHECK-i386-NEXT: movl $2, 8(%esp)
; CHECK-i386-NEXT: movl $0, 4(%esp)
; CHECK-i386-NEXT: movl $1, (%esp)
; CHECK-i386-NEXT: calll _params_in_reg2
; CHECK-i386-NEXT: movl %edi, 56(%esp)
; CHECK-i386-NEXT: movl %ebp, 52(%esp)
; CHECK-i386-NEXT: movl %ebx, 48(%esp)
; CHECK-i386-NEXT: movl 188(%esp), %eax
; CHECK-i386-NEXT: movl %eax, 44(%esp)
; CHECK-i386-NEXT: movl 184(%esp), %eax
; CHECK-i386-NEXT: movl %eax, 40(%esp)
; CHECK-i386-NEXT: movl 180(%esp), %eax
; CHECK-i386-NEXT: movl %eax, 36(%esp)
; CHECK-i386-NEXT: movl 176(%esp), %eax
; CHECK-i386-NEXT: movl %eax, 32(%esp)
; CHECK-i386-NEXT: movl 172(%esp), %eax
; CHECK-i386-NEXT: movl %eax, 28(%esp)
; CHECK-i386-NEXT: movl 168(%esp), %eax
; CHECK-i386-NEXT: movl %eax, 24(%esp)
; CHECK-i386-NEXT: movl 164(%esp), %eax
; CHECK-i386-NEXT: movl %eax, 20(%esp)
; CHECK-i386-NEXT: movl 160(%esp), %eax
; CHECK-i386-NEXT: movl %eax, 16(%esp)
; CHECK-i386-NEXT: movl 156(%esp), %eax
; CHECK-i386-NEXT: movl %eax, 12(%esp)
; CHECK-i386-NEXT: movl 152(%esp), %eax
; CHECK-i386-NEXT: movl %eax, 8(%esp)
; CHECK-i386-NEXT: movl %esi, 4(%esp)
; CHECK-i386-NEXT: leal 88(%esp), %eax
; CHECK-i386-NEXT: movl %eax, (%esp)
; CHECK-i386-NEXT: calll _params_and_return_in_reg2
; CHECK-i386-NEXT: subl $4, %esp
; CHECK-i386-NEXT: movl 88(%esp), %eax
; CHECK-i386-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) ## 4-byte Spill
; CHECK-i386-NEXT: movl 92(%esp), %eax
; CHECK-i386-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) ## 4-byte Spill
; CHECK-i386-NEXT: movl 96(%esp), %eax
; CHECK-i386-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) ## 4-byte Spill
; CHECK-i386-NEXT: movl 100(%esp), %eax
; CHECK-i386-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) ## 4-byte Spill
; CHECK-i386-NEXT: movl 104(%esp), %ebp
; CHECK-i386-NEXT: movl 108(%esp), %edi
; CHECK-i386-NEXT: movl 112(%esp), %esi
; CHECK-i386-NEXT: movl 116(%esp), %ebx
; CHECK-i386-NEXT: leal 64(%esp), %eax
; CHECK-i386-NEXT: movl %eax, 52(%esp)
; CHECK-i386-NEXT: movl $0, 48(%esp)
; CHECK-i386-NEXT: movl $0, 44(%esp)
; CHECK-i386-NEXT: movl $6, 40(%esp)
; CHECK-i386-NEXT: movl $0, 36(%esp)
; CHECK-i386-NEXT: movl $5, 32(%esp)
; CHECK-i386-NEXT: movl $0, 28(%esp)
; CHECK-i386-NEXT: movl $4, 24(%esp)
; CHECK-i386-NEXT: movl $0, 20(%esp)
; CHECK-i386-NEXT: movl $3, 16(%esp)
; CHECK-i386-NEXT: movl $0, 12(%esp)
; CHECK-i386-NEXT: movl $2, 8(%esp)
; CHECK-i386-NEXT: movl $0, 4(%esp)
; CHECK-i386-NEXT: movl $1, (%esp)
; CHECK-i386-NEXT: calll _params_in_reg2
; CHECK-i386-NEXT: movl 144(%esp), %eax
; CHECK-i386-NEXT: movl %ebx, 28(%eax)
; CHECK-i386-NEXT: movl %esi, 24(%eax)
; CHECK-i386-NEXT: movl %edi, 20(%eax)
; CHECK-i386-NEXT: movl %ebp, 16(%eax)
; CHECK-i386-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx ## 4-byte Reload
; CHECK-i386-NEXT: movl %ecx, 12(%eax)
; CHECK-i386-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx ## 4-byte Reload
; CHECK-i386-NEXT: movl %ecx, 8(%eax)
; CHECK-i386-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx ## 4-byte Reload
; CHECK-i386-NEXT: movl %ecx, 4(%eax)
; CHECK-i386-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx ## 4-byte Reload
; CHECK-i386-NEXT: movl %ecx, (%eax)
; CHECK-i386-NEXT: addl $124, %esp
; CHECK-i386-NEXT: popl %esi
; CHECK-i386-NEXT: popl %edi
; CHECK-i386-NEXT: popl %ebx
; CHECK-i386-NEXT: popl %ebp
; CHECK-i386-NEXT: retl $4
%error_ptr_ref = alloca swifterror ptr, align 8
store ptr null, ptr %error_ptr_ref
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)
%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)
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)
ret { i64, i64, i64, i64 }%val
}
declare swiftcc { i64, i64, i64, i64 } @params_and_return_in_reg2(i64, i64, i64, i64, i64, i64, ptr swiftself, ptr nocapture swifterror %err)
declare void @acallee(ptr)
; Make sure we don't tail call if the caller returns a swifterror value. We
; would have to move into the swifterror register before the tail call.
define swiftcc void @tailcall_from_swifterror(ptr swifterror %error_ptr_ref) {
; CHECK-APPLE-LABEL: tailcall_from_swifterror:
; CHECK-APPLE: ## %bb.0: ## %entry
; CHECK-APPLE-NEXT: pushq %rbx
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 16
; CHECK-APPLE-NEXT: .cfi_offset %rbx, -16
; CHECK-APPLE-NEXT: movq %r12, %rbx
; CHECK-APPLE-NEXT: xorl %edi, %edi
; CHECK-APPLE-NEXT: callq _acallee
; CHECK-APPLE-NEXT: movq %rbx, %r12
; CHECK-APPLE-NEXT: popq %rbx
; CHECK-APPLE-NEXT: retq
;
; CHECK-O0-LABEL: tailcall_from_swifterror:
; CHECK-O0: ## %bb.0: ## %entry
; CHECK-O0-NEXT: pushq %rax
; CHECK-O0-NEXT: .cfi_def_cfa_offset 16
; CHECK-O0-NEXT: movq %r12, (%rsp) ## 8-byte Spill
; CHECK-O0-NEXT: xorl %eax, %eax
; CHECK-O0-NEXT: movl %eax, %edi
; CHECK-O0-NEXT: callq _acallee
; CHECK-O0-NEXT: movq (%rsp), %r12 ## 8-byte Reload
; CHECK-O0-NEXT: popq %rax
; CHECK-O0-NEXT: retq
;
; CHECK-i386-LABEL: tailcall_from_swifterror:
; CHECK-i386: ## %bb.0: ## %entry
; CHECK-i386-NEXT: subl $12, %esp
; CHECK-i386-NEXT: .cfi_def_cfa_offset 16
; CHECK-i386-NEXT: movl $0, (%esp)
; CHECK-i386-NEXT: calll _acallee
; CHECK-i386-NEXT: addl $12, %esp
; CHECK-i386-NEXT: retl
entry:
tail call void @acallee(ptr null)
ret void
}
; Make sure we don't crash on this function during -O0.
; We used to crash because we would insert an IMPLICIT_DEF for the swifterror at
; beginning of the machine basic block but did not inform FastISel of the
; inserted instruction. When computing the InsertPoint in the entry block
; FastISel would choose an insertion point before the IMPLICIT_DEF causing a
; crash later on.
declare hidden swiftcc ptr @testFunA()
%TSb = type <{ i1 }>
define swiftcc void @dontCrash() {
; CHECK-APPLE-LABEL: dontCrash:
; CHECK-APPLE: ## %bb.0: ## %entry
; CHECK-APPLE-NEXT: pushq %rax
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 16
; CHECK-APPLE-NEXT: callq _testFunA
; CHECK-APPLE-NEXT: cmpb $1, (%rax)
; CHECK-APPLE-NEXT: popq %rax
; CHECK-APPLE-NEXT: retq
;
; CHECK-O0-LABEL: dontCrash:
; CHECK-O0: ## %bb.0: ## %entry
; CHECK-O0-NEXT: pushq %rax
; CHECK-O0-NEXT: .cfi_def_cfa_offset 16
; CHECK-O0-NEXT: ## implicit-def: $rax
; CHECK-O0-NEXT: xorl %eax, %eax
; CHECK-O0-NEXT: ## kill: def $rax killed $eax
; CHECK-O0-NEXT: callq _testFunA
; CHECK-O0-NEXT: testb $1, (%rax)
; CHECK-O0-NEXT: jne LBB21_1
; CHECK-O0-NEXT: jmp LBB21_2
; CHECK-O0-NEXT: LBB21_1: ## %trueBB
; CHECK-O0-NEXT: popq %rax
; CHECK-O0-NEXT: retq
; CHECK-O0-NEXT: LBB21_2: ## %falseBB
; CHECK-O0-NEXT: popq %rax
; CHECK-O0-NEXT: retq
;
; CHECK-i386-LABEL: dontCrash:
; CHECK-i386: ## %bb.0: ## %entry
; CHECK-i386-NEXT: subl $12, %esp
; CHECK-i386-NEXT: .cfi_def_cfa_offset 16
; CHECK-i386-NEXT: movl $0, 8(%esp)
; CHECK-i386-NEXT: calll _testFunA
; CHECK-i386-NEXT: cmpb $1, (%eax)
; CHECK-i386-NEXT: addl $12, %esp
; CHECK-i386-NEXT: retl
entry:
%swifterror = alloca swifterror ptr, align 8
store ptr null, ptr %swifterror, align 8
%a = call ptr @testFunA()
%c = load i1, ptr %a, align 1
br i1 %c, label %trueBB, label %falseBB
trueBB:
ret void
falseBB:
ret void
}
declare swiftcc void @foo2(ptr swifterror)
; Make sure we properly assign registers during fast-isel.
define swiftcc ptr @testAssign(ptr %error_ref) {
; CHECK-APPLE-LABEL: testAssign:
; CHECK-APPLE: ## %bb.0: ## %entry
; CHECK-APPLE-NEXT: pushq %r12
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 16
; CHECK-APPLE-NEXT: subq $16, %rsp
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 32
; CHECK-APPLE-NEXT: .cfi_offset %r12, -16
; CHECK-APPLE-NEXT: xorl %r12d, %r12d
; CHECK-APPLE-NEXT: callq _foo2
; CHECK-APPLE-NEXT: movq %r12, %rax
; CHECK-APPLE-NEXT: addq $16, %rsp
; CHECK-APPLE-NEXT: popq %r12
; CHECK-APPLE-NEXT: retq
;
; CHECK-O0-LABEL: testAssign:
; CHECK-O0: ## %bb.0: ## %entry
; CHECK-O0-NEXT: pushq %r12
; CHECK-O0-NEXT: .cfi_def_cfa_offset 16
; CHECK-O0-NEXT: subq $16, %rsp
; CHECK-O0-NEXT: .cfi_def_cfa_offset 32
; CHECK-O0-NEXT: .cfi_offset %r12, -16
; CHECK-O0-NEXT: ## implicit-def: $rax
; CHECK-O0-NEXT: xorl %eax, %eax
; CHECK-O0-NEXT: movl %eax, %r12d
; CHECK-O0-NEXT: callq _foo2
; CHECK-O0-NEXT: movq %r12, (%rsp) ## 8-byte Spill
; CHECK-O0-NEXT: ## %bb.1: ## %a
; CHECK-O0-NEXT: movq (%rsp), %rax ## 8-byte Reload
; CHECK-O0-NEXT: addq $16, %rsp
; CHECK-O0-NEXT: popq %r12
; CHECK-O0-NEXT: retq
;
; CHECK-i386-LABEL: testAssign:
; CHECK-i386: ## %bb.0: ## %entry
; CHECK-i386-NEXT: subl $12, %esp
; CHECK-i386-NEXT: .cfi_def_cfa_offset 16
; CHECK-i386-NEXT: movl $0, 8(%esp)
; CHECK-i386-NEXT: leal 8(%esp), %eax
; CHECK-i386-NEXT: movl %eax, (%esp)
; CHECK-i386-NEXT: calll _foo2
; CHECK-i386-NEXT: movl 8(%esp), %eax
; CHECK-i386-NEXT: addl $12, %esp
; CHECK-i386-NEXT: retl
entry:
%error_ptr = alloca swifterror ptr
store ptr null, ptr %error_ptr
call swiftcc void @foo2(ptr swifterror %error_ptr)
br label %a
a:
%error = load ptr, ptr %error_ptr
ret ptr %error
}
define swiftcc ptr @testAssign2(ptr %error_ref, ptr swifterror %err) {
; CHECK-APPLE-LABEL: testAssign2:
; CHECK-APPLE: ## %bb.0: ## %entry
; CHECK-APPLE-NEXT: movq %r12, %rax
; CHECK-APPLE-NEXT: retq
;
; CHECK-O0-LABEL: testAssign2:
; CHECK-O0: ## %bb.0: ## %entry
; CHECK-O0-NEXT: movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-O0-NEXT: jmp LBB23_1
; CHECK-O0-NEXT: LBB23_1: ## %a
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r12 ## 8-byte Reload
; CHECK-O0-NEXT: movq %r12, %rax
; CHECK-O0-NEXT: retq
;
; CHECK-i386-LABEL: testAssign2:
; CHECK-i386: ## %bb.0: ## %entry
; CHECK-i386-NEXT: movl 8(%esp), %eax
; CHECK-i386-NEXT: movl (%eax), %eax
; CHECK-i386-NEXT: retl
entry:
br label %a
a:
%error = load ptr, ptr %err
ret ptr %error
}
define swiftcc ptr @testAssign3(ptr %error_ref, ptr swifterror %err) {
; CHECK-APPLE-LABEL: testAssign3:
; CHECK-APPLE: ## %bb.0: ## %entry
; CHECK-APPLE-NEXT: pushq %rax
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 16
; CHECK-APPLE-NEXT: callq _foo2
; CHECK-APPLE-NEXT: movq %r12, %rax
; CHECK-APPLE-NEXT: popq %rcx
; CHECK-APPLE-NEXT: retq
;
; CHECK-O0-LABEL: testAssign3:
; CHECK-O0: ## %bb.0: ## %entry
; CHECK-O0-NEXT: pushq %rax
; CHECK-O0-NEXT: .cfi_def_cfa_offset 16
; CHECK-O0-NEXT: callq _foo2
; CHECK-O0-NEXT: movq %r12, (%rsp) ## 8-byte Spill
; CHECK-O0-NEXT: ## %bb.1: ## %a
; CHECK-O0-NEXT: movq (%rsp), %r12 ## 8-byte Reload
; CHECK-O0-NEXT: movq %r12, %rax
; CHECK-O0-NEXT: popq %rcx
; CHECK-O0-NEXT: retq
;
; CHECK-i386-LABEL: testAssign3:
; CHECK-i386: ## %bb.0: ## %entry
; CHECK-i386-NEXT: pushl %esi
; CHECK-i386-NEXT: .cfi_def_cfa_offset 8
; CHECK-i386-NEXT: subl $8, %esp
; CHECK-i386-NEXT: .cfi_def_cfa_offset 16
; CHECK-i386-NEXT: .cfi_offset %esi, -8
; CHECK-i386-NEXT: movl 20(%esp), %esi
; CHECK-i386-NEXT: movl %esi, (%esp)
; CHECK-i386-NEXT: calll _foo2
; CHECK-i386-NEXT: movl (%esi), %eax
; CHECK-i386-NEXT: addl $8, %esp
; CHECK-i386-NEXT: popl %esi
; CHECK-i386-NEXT: retl
entry:
call swiftcc void @foo2(ptr swifterror %err)
br label %a
a:
%error = load ptr, ptr %err
ret ptr %error
}
define swiftcc ptr @testAssign4(ptr %error_ref, ptr swifterror %err) {
; CHECK-APPLE-LABEL: testAssign4:
; CHECK-APPLE: ## %bb.0: ## %entry
; CHECK-APPLE-NEXT: pushq %rax
; CHECK-APPLE-NEXT: .cfi_def_cfa_offset 16
; CHECK-APPLE-NEXT: callq _foo2
; CHECK-APPLE-NEXT: xorl %eax, %eax
; CHECK-APPLE-NEXT: xorl %r12d, %r12d
; CHECK-APPLE-NEXT: popq %rcx
; CHECK-APPLE-NEXT: retq
;
; CHECK-O0-LABEL: testAssign4:
; CHECK-O0: ## %bb.0: ## %entry
; CHECK-O0-NEXT: pushq %rax
; CHECK-O0-NEXT: .cfi_def_cfa_offset 16
; CHECK-O0-NEXT: callq _foo2
; CHECK-O0-NEXT: xorl %eax, %eax
; CHECK-O0-NEXT: ## kill: def $rax killed $eax
; CHECK-O0-NEXT: movq %rax, (%rsp) ## 8-byte Spill
; CHECK-O0-NEXT: ## %bb.1: ## %a
; CHECK-O0-NEXT: movq (%rsp), %r12 ## 8-byte Reload
; CHECK-O0-NEXT: movq %r12, %rax
; CHECK-O0-NEXT: popq %rcx
; CHECK-O0-NEXT: retq
;
; CHECK-i386-LABEL: testAssign4:
; CHECK-i386: ## %bb.0: ## %entry
; CHECK-i386-NEXT: pushl %esi
; CHECK-i386-NEXT: .cfi_def_cfa_offset 8
; CHECK-i386-NEXT: subl $8, %esp
; CHECK-i386-NEXT: .cfi_def_cfa_offset 16
; CHECK-i386-NEXT: .cfi_offset %esi, -8
; CHECK-i386-NEXT: movl 20(%esp), %esi
; CHECK-i386-NEXT: movl %esi, (%esp)
; CHECK-i386-NEXT: calll _foo2
; CHECK-i386-NEXT: movl $0, (%esi)
; CHECK-i386-NEXT: movl (%esi), %eax
; CHECK-i386-NEXT: addl $8, %esp
; CHECK-i386-NEXT: popl %esi
; CHECK-i386-NEXT: retl
entry:
call swiftcc void @foo2(ptr swifterror %err)
store ptr null, ptr %err
br label %a
a:
%error = load ptr, ptr %err
ret ptr %error
}