1*9880d681SAndroid Build Coastguard Worker; RUN: llc -verify-machineinstrs < %s -enable-tail-merge=0 -mtriple=x86_64-linux | FileCheck %s --check-prefix=LINUX 2*9880d681SAndroid Build Coastguard Worker; RUN: llc -verify-machineinstrs < %s -enable-tail-merge=0 -mtriple=x86_64-linux-gnux32 | FileCheck %s --check-prefix=LINUX-X32 3*9880d681SAndroid Build Coastguard Worker; RUN: llc -verify-machineinstrs < %s -enable-tail-merge=0 -mtriple=x86_64-windows | FileCheck %s --check-prefix=WINDOWS 4*9880d681SAndroid Build Coastguard Worker; RUN: llc -verify-machineinstrs < %s -enable-tail-merge=0 -mtriple=i686-windows | FileCheck %s --check-prefix=X86 5*9880d681SAndroid Build Coastguard Worker; RUN: llc -verify-machineinstrs < %s -enable-tail-merge=0 -mtriple=i686-windows -mattr=+sse2 | FileCheck %s --check-prefix=X86 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard Worker; Test that we actually spill and reload all arguments in the variadic argument 8*9880d681SAndroid Build Coastguard Worker; pack. Doing a normal call will clobber all argument registers, and we will 9*9880d681SAndroid Build Coastguard Worker; spill around it. A simple adjustment should not require any XMM spills. 10*9880d681SAndroid Build Coastguard Worker 11*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.va_start(i8*) nounwind 12*9880d681SAndroid Build Coastguard Worker 13*9880d681SAndroid Build Coastguard Workerdeclare void(i8*, ...)* @get_f(i8* %this) 14*9880d681SAndroid Build Coastguard Worker 15*9880d681SAndroid Build Coastguard Workerdefine void @f_thunk(i8* %this, ...) { 16*9880d681SAndroid Build Coastguard Worker ; Use va_start so that we exercise the combination. 17*9880d681SAndroid Build Coastguard Worker %ap = alloca [4 x i8*], align 16 18*9880d681SAndroid Build Coastguard Worker %ap_i8 = bitcast [4 x i8*]* %ap to i8* 19*9880d681SAndroid Build Coastguard Worker call void @llvm.va_start(i8* %ap_i8) 20*9880d681SAndroid Build Coastguard Worker 21*9880d681SAndroid Build Coastguard Worker %fptr = call void(i8*, ...)*(i8*) @get_f(i8* %this) 22*9880d681SAndroid Build Coastguard Worker musttail call void (i8*, ...) %fptr(i8* %this, ...) 23*9880d681SAndroid Build Coastguard Worker ret void 24*9880d681SAndroid Build Coastguard Worker} 25*9880d681SAndroid Build Coastguard Worker 26*9880d681SAndroid Build Coastguard Worker; Save and restore 6 GPRs, 8 XMMs, and AL around the call. 27*9880d681SAndroid Build Coastguard Worker 28*9880d681SAndroid Build Coastguard Worker; LINUX-LABEL: f_thunk: 29*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movq %rdi, {{.*}} 30*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movq %rsi, {{.*}} 31*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movq %rdx, {{.*}} 32*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movq %rcx, {{.*}} 33*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movq %r8, {{.*}} 34*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movq %r9, {{.*}} 35*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movb %al, {{.*}} 36*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movaps %xmm0, {{[0-9]*}}(%rsp) 37*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movaps %xmm1, {{[0-9]*}}(%rsp) 38*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movaps %xmm2, {{[0-9]*}}(%rsp) 39*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movaps %xmm3, {{[0-9]*}}(%rsp) 40*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movaps %xmm4, {{[0-9]*}}(%rsp) 41*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movaps %xmm5, {{[0-9]*}}(%rsp) 42*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movaps %xmm6, {{[0-9]*}}(%rsp) 43*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movaps %xmm7, {{[0-9]*}}(%rsp) 44*9880d681SAndroid Build Coastguard Worker; LINUX: callq get_f 45*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movaps {{[0-9]*}}(%rsp), %xmm0 46*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movaps {{[0-9]*}}(%rsp), %xmm1 47*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movaps {{[0-9]*}}(%rsp), %xmm2 48*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movaps {{[0-9]*}}(%rsp), %xmm3 49*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movaps {{[0-9]*}}(%rsp), %xmm4 50*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movaps {{[0-9]*}}(%rsp), %xmm5 51*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movaps {{[0-9]*}}(%rsp), %xmm6 52*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movaps {{[0-9]*}}(%rsp), %xmm7 53*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movq {{.*}}, %rdi 54*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movq {{.*}}, %rsi 55*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movq {{.*}}, %rdx 56*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movq {{.*}}, %rcx 57*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movq {{.*}}, %r8 58*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movq {{.*}}, %r9 59*9880d681SAndroid Build Coastguard Worker; LINUX-DAG: movb {{.*}}, %al 60*9880d681SAndroid Build Coastguard Worker; LINUX: jmpq *{{.*}} # TAILCALL 61*9880d681SAndroid Build Coastguard Worker 62*9880d681SAndroid Build Coastguard Worker; LINUX-X32-LABEL: f_thunk: 63*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movl %edi, {{.*}} 64*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movq %rsi, {{.*}} 65*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movq %rdx, {{.*}} 66*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movq %rcx, {{.*}} 67*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movq %r8, {{.*}} 68*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movq %r9, {{.*}} 69*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movb %al, {{.*}} 70*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movaps %xmm0, {{[0-9]*}}(%esp) 71*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movaps %xmm1, {{[0-9]*}}(%esp) 72*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movaps %xmm2, {{[0-9]*}}(%esp) 73*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movaps %xmm3, {{[0-9]*}}(%esp) 74*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movaps %xmm4, {{[0-9]*}}(%esp) 75*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movaps %xmm5, {{[0-9]*}}(%esp) 76*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movaps %xmm6, {{[0-9]*}}(%esp) 77*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movaps %xmm7, {{[0-9]*}}(%esp) 78*9880d681SAndroid Build Coastguard Worker; LINUX-X32: callq get_f 79*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movaps {{[0-9]*}}(%esp), %xmm0 80*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movaps {{[0-9]*}}(%esp), %xmm1 81*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movaps {{[0-9]*}}(%esp), %xmm2 82*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movaps {{[0-9]*}}(%esp), %xmm3 83*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movaps {{[0-9]*}}(%esp), %xmm4 84*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movaps {{[0-9]*}}(%esp), %xmm5 85*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movaps {{[0-9]*}}(%esp), %xmm6 86*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movaps {{[0-9]*}}(%esp), %xmm7 87*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movl {{.*}}, %edi 88*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movq {{.*}}, %rsi 89*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movq {{.*}}, %rdx 90*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movq {{.*}}, %rcx 91*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movq {{.*}}, %r8 92*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movq {{.*}}, %r9 93*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movb {{.*}}, %al 94*9880d681SAndroid Build Coastguard Worker; LINUX-X32: jmpq *{{.*}} # TAILCALL 95*9880d681SAndroid Build Coastguard Worker 96*9880d681SAndroid Build Coastguard Worker; WINDOWS-LABEL: f_thunk: 97*9880d681SAndroid Build Coastguard Worker; WINDOWS-NOT: mov{{.}}ps 98*9880d681SAndroid Build Coastguard Worker; WINDOWS-DAG: movq %rdx, {{.*}} 99*9880d681SAndroid Build Coastguard Worker; WINDOWS-DAG: movq %rcx, {{.*}} 100*9880d681SAndroid Build Coastguard Worker; WINDOWS-DAG: movq %r8, {{.*}} 101*9880d681SAndroid Build Coastguard Worker; WINDOWS-DAG: movq %r9, {{.*}} 102*9880d681SAndroid Build Coastguard Worker; WINDOWS-NOT: mov{{.}}ps 103*9880d681SAndroid Build Coastguard Worker; WINDOWS: callq get_f 104*9880d681SAndroid Build Coastguard Worker; WINDOWS-NOT: mov{{.}}ps 105*9880d681SAndroid Build Coastguard Worker; WINDOWS-DAG: movq {{.*}}, %rdx 106*9880d681SAndroid Build Coastguard Worker; WINDOWS-DAG: movq {{.*}}, %rcx 107*9880d681SAndroid Build Coastguard Worker; WINDOWS-DAG: movq {{.*}}, %r8 108*9880d681SAndroid Build Coastguard Worker; WINDOWS-DAG: movq {{.*}}, %r9 109*9880d681SAndroid Build Coastguard Worker; WINDOWS-NOT: mov{{.}}ps 110*9880d681SAndroid Build Coastguard Worker; WINDOWS: jmpq *{{.*}} # TAILCALL 111*9880d681SAndroid Build Coastguard Worker 112*9880d681SAndroid Build Coastguard Worker; No regparms on normal x86 conventions. 113*9880d681SAndroid Build Coastguard Worker 114*9880d681SAndroid Build Coastguard Worker; X86-LABEL: _f_thunk: 115*9880d681SAndroid Build Coastguard Worker; X86: calll _get_f 116*9880d681SAndroid Build Coastguard Worker; X86: jmpl *{{.*}} # TAILCALL 117*9880d681SAndroid Build Coastguard Worker 118*9880d681SAndroid Build Coastguard Worker; This thunk shouldn't require any spills and reloads, assuming the register 119*9880d681SAndroid Build Coastguard Worker; allocator knows what it's doing. 120*9880d681SAndroid Build Coastguard Worker 121*9880d681SAndroid Build Coastguard Workerdefine void @g_thunk(i8* %fptr_i8, ...) { 122*9880d681SAndroid Build Coastguard Worker %fptr = bitcast i8* %fptr_i8 to void (i8*, ...)* 123*9880d681SAndroid Build Coastguard Worker musttail call void (i8*, ...) %fptr(i8* %fptr_i8, ...) 124*9880d681SAndroid Build Coastguard Worker ret void 125*9880d681SAndroid Build Coastguard Worker} 126*9880d681SAndroid Build Coastguard Worker 127*9880d681SAndroid Build Coastguard Worker; LINUX-LABEL: g_thunk: 128*9880d681SAndroid Build Coastguard Worker; LINUX-NOT: movq 129*9880d681SAndroid Build Coastguard Worker; LINUX: jmpq *%rdi # TAILCALL 130*9880d681SAndroid Build Coastguard Worker 131*9880d681SAndroid Build Coastguard Worker; LINUX-X32-LABEL: g_thunk: 132*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: movl %edi, %[[REG:e[abcd]x|ebp|esi|edi|r8|r9|r1[0-5]]] 133*9880d681SAndroid Build Coastguard Worker; LINUX-X32-DAG: jmpq *%[[REG]] # TAILCALL 134*9880d681SAndroid Build Coastguard Worker 135*9880d681SAndroid Build Coastguard Worker; WINDOWS-LABEL: g_thunk: 136*9880d681SAndroid Build Coastguard Worker; WINDOWS-NOT: movq 137*9880d681SAndroid Build Coastguard Worker; WINDOWS: jmpq *%rcx # TAILCALL 138*9880d681SAndroid Build Coastguard Worker 139*9880d681SAndroid Build Coastguard Worker; X86-LABEL: _g_thunk: 140*9880d681SAndroid Build Coastguard Worker; X86-NOT: push %ebp 141*9880d681SAndroid Build Coastguard Worker; X86-NOT: andl {{.*}}, %esp 142*9880d681SAndroid Build Coastguard Worker; X86: jmpl *%eax # TAILCALL 143*9880d681SAndroid Build Coastguard Worker 144*9880d681SAndroid Build Coastguard Worker; Do a simple multi-exit multi-bb test. 145*9880d681SAndroid Build Coastguard Worker 146*9880d681SAndroid Build Coastguard Worker%struct.Foo = type { i1, i8*, i8* } 147*9880d681SAndroid Build Coastguard Worker 148*9880d681SAndroid Build Coastguard Worker@g = external global i32 149*9880d681SAndroid Build Coastguard Worker 150*9880d681SAndroid Build Coastguard Workerdefine void @h_thunk(%struct.Foo* %this, ...) { 151*9880d681SAndroid Build Coastguard Worker %cond_p = getelementptr %struct.Foo, %struct.Foo* %this, i32 0, i32 0 152*9880d681SAndroid Build Coastguard Worker %cond = load i1, i1* %cond_p 153*9880d681SAndroid Build Coastguard Worker br i1 %cond, label %then, label %else 154*9880d681SAndroid Build Coastguard Worker 155*9880d681SAndroid Build Coastguard Workerthen: 156*9880d681SAndroid Build Coastguard Worker %a_p = getelementptr %struct.Foo, %struct.Foo* %this, i32 0, i32 1 157*9880d681SAndroid Build Coastguard Worker %a_i8 = load i8*, i8** %a_p 158*9880d681SAndroid Build Coastguard Worker %a = bitcast i8* %a_i8 to void (%struct.Foo*, ...)* 159*9880d681SAndroid Build Coastguard Worker musttail call void (%struct.Foo*, ...) %a(%struct.Foo* %this, ...) 160*9880d681SAndroid Build Coastguard Worker ret void 161*9880d681SAndroid Build Coastguard Worker 162*9880d681SAndroid Build Coastguard Workerelse: 163*9880d681SAndroid Build Coastguard Worker %b_p = getelementptr %struct.Foo, %struct.Foo* %this, i32 0, i32 2 164*9880d681SAndroid Build Coastguard Worker %b_i8 = load i8*, i8** %b_p 165*9880d681SAndroid Build Coastguard Worker %b = bitcast i8* %b_i8 to void (%struct.Foo*, ...)* 166*9880d681SAndroid Build Coastguard Worker store i32 42, i32* @g 167*9880d681SAndroid Build Coastguard Worker musttail call void (%struct.Foo*, ...) %b(%struct.Foo* %this, ...) 168*9880d681SAndroid Build Coastguard Worker ret void 169*9880d681SAndroid Build Coastguard Worker} 170*9880d681SAndroid Build Coastguard Worker 171*9880d681SAndroid Build Coastguard Worker; LINUX-LABEL: h_thunk: 172*9880d681SAndroid Build Coastguard Worker; LINUX: jne 173*9880d681SAndroid Build Coastguard Worker; LINUX: jmpq *{{.*}} # TAILCALL 174*9880d681SAndroid Build Coastguard Worker; LINUX: jmpq *{{.*}} # TAILCALL 175*9880d681SAndroid Build Coastguard Worker; LINUX-X32-LABEL: h_thunk: 176*9880d681SAndroid Build Coastguard Worker; LINUX-X32: jne 177*9880d681SAndroid Build Coastguard Worker; LINUX-X32: jmpq *{{.*}} # TAILCALL 178*9880d681SAndroid Build Coastguard Worker; LINUX-X32: jmpq *{{.*}} # TAILCALL 179*9880d681SAndroid Build Coastguard Worker; WINDOWS-LABEL: h_thunk: 180*9880d681SAndroid Build Coastguard Worker; WINDOWS: jne 181*9880d681SAndroid Build Coastguard Worker; WINDOWS: jmpq *{{.*}} # TAILCALL 182*9880d681SAndroid Build Coastguard Worker; WINDOWS: jmpq *{{.*}} # TAILCALL 183*9880d681SAndroid Build Coastguard Worker; X86-LABEL: _h_thunk: 184*9880d681SAndroid Build Coastguard Worker; X86: jne 185*9880d681SAndroid Build Coastguard Worker; X86: jmpl *{{.*}} # TAILCALL 186*9880d681SAndroid Build Coastguard Worker; X86: jmpl *{{.*}} # TAILCALL 187