| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 |
| ; RUN: llc -mtriple=x86_64-unknown-windows-gnu < %s | FileCheck %s |
| |
| ; Check calling convention is correct for win64 when doing a tailcall |
| ; for a pointer loaded from memory. |
| |
| declare void @foo(i64, ptr) |
| |
| define void @do_tailcall(ptr %objp) nounwind { |
| ; CHECK-LABEL: do_tailcall: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: pushq %rsi |
| ; CHECK-NEXT: subq $32, %rsp |
| ; CHECK-NEXT: movq %rcx, %rsi |
| ; CHECK-NEXT: xorl %ecx, %ecx |
| ; CHECK-NEXT: xorl %edx, %edx |
| ; CHECK-NEXT: callq foo |
| ; CHECK-NEXT: xorl %ecx, %ecx |
| ; CHECK-NEXT: movq %rsi, %rax |
| ; CHECK-NEXT: addq $32, %rsp |
| ; CHECK-NEXT: popq %rsi |
| ; CHECK-NEXT: rex64 jmpq *(%rax) # TAILCALL |
| tail call void @foo(i64 0, ptr null) |
| %fptr = load ptr, ptr %objp, align 8 |
| tail call void %fptr(ptr null) |
| ret void |
| } |
| |
| ; Make sure aliases of ccc are also treated as win64 functions |
| define fastcc void @do_tailcall_fastcc(ptr %objp) nounwind { |
| ; CHECK-LABEL: do_tailcall_fastcc: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: pushq %rsi |
| ; CHECK-NEXT: subq $32, %rsp |
| ; CHECK-NEXT: movq %rcx, %rsi |
| ; CHECK-NEXT: xorl %ecx, %ecx |
| ; CHECK-NEXT: xorl %edx, %edx |
| ; CHECK-NEXT: callq foo |
| ; CHECK-NEXT: xorl %ecx, %ecx |
| ; CHECK-NEXT: movq %rsi, %rax |
| ; CHECK-NEXT: addq $32, %rsp |
| ; CHECK-NEXT: popq %rsi |
| ; CHECK-NEXT: rex64 jmpq *(%rax) # TAILCALL |
| tail call void @foo(i64 0, ptr null) |
| %fptr = load ptr, ptr %objp, align 8 |
| tail call fastcc void %fptr(ptr null) |
| ret void |
| } |