; 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 = mem[0],zero,zero,zero ; 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 = mem[0],zero,zero,zero ; 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 = mem[0],zero,zero,zero ; 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 = mem[0],zero,zero,zero ; 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 = mem[0],zero,zero,zero ; 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 = mem[0],zero,zero,zero ; 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 = mem[0],zero,zero,zero ; 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: fld1 ; CHECK-i386-NEXT: fstps {{[-0-9]+}}(%e{{[sb]}}p) ## 4-byte Folded Spill ; 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: flds {{[-0-9]+}}(%e{{[sb]}}p) ## 4-byte Folded Reload ; 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: flds {{[-0-9]+}}(%e{{[sb]}}p) ## 4-byte Folded Reload ; 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 = mem[0],zero,zero,zero ; 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 = mem[0],zero,zero,zero ; 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 = mem[0],zero,zero,zero ; 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: fld1 ; CHECK-i386-NEXT: fstps {{[-0-9]+}}(%e{{[sb]}}p) ## 4-byte Folded Spill ; 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: flds {{[-0-9]+}}(%e{{[sb]}}p) ## 4-byte Folded Reload ; 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 %rbp ; 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 %rbp, -16 ; CHECK-APPLE-NEXT: movl %esi, %ebp ; CHECK-APPLE-NEXT: movq %rdi, %rbx ; CHECK-APPLE-NEXT: movl $16, %edi ; CHECK-APPLE-NEXT: callq _malloc ; CHECK-APPLE-NEXT: movb $1, 8(%rax) ; CHECK-APPLE-NEXT: movl %ebp, 4(%rbx) ; CHECK-APPLE-NEXT: movq %rax, %r12 ; CHECK-APPLE-NEXT: movq %rbx, %rax ; CHECK-APPLE-NEXT: addq $8, %rsp ; CHECK-APPLE-NEXT: popq %rbx ; CHECK-APPLE-NEXT: popq %rbp ; 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 = mem[0],zero,zero,zero ; 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 = mem[0],zero,zero,zero ; 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, %r14 ; 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 LBB7_2 ; CHECK-APPLE-NEXT: ## %bb.1: ## %cont ; CHECK-APPLE-NEXT: movzbl 8(%rdi), %eax ; CHECK-APPLE-NEXT: movb %al, (%rbx) ; 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, (%r14) ; CHECK-APPLE-NEXT: LBB7_4: ## %handler2 ; CHECK-APPLE-NEXT: callq _free ; CHECK-APPLE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero ; 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 = mem[0],zero,zero,zero ; 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 = mem[0],zero,zero,zero ; 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 = mem[0],zero,zero,zero ; 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: xorl %eax, %eax ; CHECK-APPLE-NEXT: testb %al, %al ; CHECK-APPLE-NEXT: jne LBB15_2 ; CHECK-APPLE-NEXT: ## %bb.1: ## %entry ; CHECK-APPLE-NEXT: testb $1, %dil ; CHECK-APPLE-NEXT: LBB15_2: ## %cont ; 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: xorl %eax, %eax ; CHECK-i386-NEXT: testb %al, %al ; CHECK-i386-NEXT: jne LBB15_2 ; CHECK-i386-NEXT: ## %bb.1: ## %entry ; CHECK-i386-NEXT: testb $1, 8(%esp) ; CHECK-i386-NEXT: LBB15_2: ## %cont ; 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, %r14 ; CHECK-APPLE-NEXT: movq %rdx, %r15 ; CHECK-APPLE-NEXT: movq %rsi, %rbx ; 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 %rbx, %rsi ; CHECK-APPLE-NEXT: movq %r15, %rdx ; CHECK-APPLE-NEXT: movq %r14, %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, %r14 ; CHECK-APPLE-NEXT: movq %r13, (%rsp) ## 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, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill ; CHECK-APPLE-NEXT: movq %rdx, %r15 ; CHECK-APPLE-NEXT: movq %rsi, %rbx ; 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 %rbx, %rsi ; CHECK-APPLE-NEXT: movq %r15, %rdx ; CHECK-APPLE-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx ## 8-byte Reload ; 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 (%rsp), %r13 ## 8-byte Reload ; CHECK-APPLE-NEXT: movq %r14, %r12 ; CHECK-APPLE-NEXT: callq _params_and_return_in_reg2 ; CHECK-APPLE-NEXT: movq %rax, %rbx ; CHECK-APPLE-NEXT: movq %rdx, %rbp ; CHECK-APPLE-NEXT: movq %rcx, %r15 ; CHECK-APPLE-NEXT: movq %r8, %r14 ; 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 %rbp, %rdx ; CHECK-APPLE-NEXT: movq %r15, %rcx ; CHECK-APPLE-NEXT: movq %r14, %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 $0, 64(%esp) ; CHECK-i386-NEXT: movl 188(%esp), %ebp ; CHECK-i386-NEXT: movl 192(%esp), %ebx ; CHECK-i386-NEXT: movl 196(%esp), %edi ; CHECK-i386-NEXT: movl 200(%esp), %esi ; 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 %esi, 56(%esp) ; CHECK-i386-NEXT: movl %edi, 52(%esp) ; CHECK-i386-NEXT: movl %ebx, 48(%esp) ; CHECK-i386-NEXT: movl %ebp, 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 148(%esp), %eax ; CHECK-i386-NEXT: movl %eax, 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), %ebx ; CHECK-i386-NEXT: movl 116(%esp), %esi ; 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 %esi, 28(%eax) ; CHECK-i386-NEXT: movl %ebx, 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 }