1 ; RUN: llc < %s -mtriple=x86_64-linux-gnu -tailcallopt -code-model=large | FileCheck %s 2 3 declare fastcc i32 @callee(i32 %arg) 4 define fastcc i32 @directcall(i32 %arg) { 5 entry: 6 ; This is the large code model, so &callee may not fit into the jmp 7 ; instruction. Instead, stick it into a register. 8 ; CHECK: movabsq $callee, [[REGISTER:%r[a-z0-9]+]] 9 ; CHECK: jmpq *[[REGISTER]] # TAILCALL 10 %res = tail call fastcc i32 @callee(i32 %arg) 11 ret i32 %res 12 } 13 14 ; Check that the register used for an indirect tail call doesn't 15 ; clobber any of the arguments. 16 define fastcc i32 @indirect_manyargs(i32(i32,i32,i32,i32,i32,i32,i32)* %target) { 17 ; Adjust the stack to enter the function. (The amount of the 18 ; adjustment may change in the future, in which case the location of 19 ; the stack argument and the return adjustment will change too.) 20 ; CHECK: pushq 21 ; Put the call target into R11, which won't be clobbered while restoring 22 ; callee-saved registers and won't be used for passing arguments. 23 ; CHECK: movq %rdi, %rax 24 ; Pass the stack argument. 25 ; CHECK: movl $7, 16(%rsp) 26 ; Pass the register arguments, in the right registers. 27 ; CHECK: movl $1, %edi 28 ; CHECK: movl $2, %esi 29 ; CHECK: movl $3, %edx 30 ; CHECK: movl $4, %ecx 31 ; CHECK: movl $5, %r8d 32 ; CHECK: movl $6, %r9d 33 ; Adjust the stack to "return". 34 ; CHECK: popq 35 ; And tail-call to the target. 36 ; CHECK: jmpq *%rax # TAILCALL 37 %res = tail call fastcc i32 %target(i32 1, i32 2, i32 3, i32 4, i32 5, 38 i32 6, i32 7) 39 ret i32 %res 40 } 41 42 ; Check that the register used for a direct tail call doesn't clobber 43 ; any of the arguments. 44 declare fastcc i32 @manyargs_callee(i32,i32,i32,i32,i32,i32,i32) 45 define fastcc i32 @direct_manyargs() { 46 ; Adjust the stack to enter the function. (The amount of the 47 ; adjustment may change in the future, in which case the location of 48 ; the stack argument and the return adjustment will change too.) 49 ; CHECK: pushq 50 ; Pass the stack argument. 51 ; CHECK: movl $7, 16(%rsp) 52 ; This is the large code model, so &manyargs_callee may not fit into 53 ; the jmp instruction. Put it into a register which won't be clobbered 54 ; while restoring callee-saved registers and won't be used for passing 55 ; arguments. 56 ; CHECK: movabsq $manyargs_callee, %rax 57 ; Pass the register arguments, in the right registers. 58 ; CHECK: movl $1, %edi 59 ; CHECK: movl $2, %esi 60 ; CHECK: movl $3, %edx 61 ; CHECK: movl $4, %ecx 62 ; CHECK: movl $5, %r8d 63 ; CHECK: movl $6, %r9d 64 ; Adjust the stack to "return". 65 ; CHECK: popq 66 ; And tail-call to the target. 67 ; CHECK: jmpq *%rax # TAILCALL 68 %res = tail call fastcc i32 @manyargs_callee(i32 1, i32 2, i32 3, i32 4, 69 i32 5, i32 6, i32 7) 70 ret i32 %res 71 } 72