| ; 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 %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 = 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, %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 = 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, %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, %rbx |
| ; 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, %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 {{[-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 %rbx, %r12 |
| ; CHECK-APPLE-NEXT: callq _params_and_return_in_reg2 |
| ; CHECK-APPLE-NEXT: movq %rax, %r14 |
| ; CHECK-APPLE-NEXT: movq %rdx, %r15 |
| ; CHECK-APPLE-NEXT: movq %rcx, %rbp |
| ; CHECK-APPLE-NEXT: movq %r8, %rbx |
| ; 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 %r14, %rax |
| ; CHECK-APPLE-NEXT: movq %r15, %rdx |
| ; CHECK-APPLE-NEXT: movq %rbp, %rcx |
| ; CHECK-APPLE-NEXT: movq %rbx, %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 |
| } |