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