llvm/llvm/test/CodeGen/X86/swifterror.ll

; 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
}