xref: /aosp_15_r20/external/llvm/test/CodeGen/X86/musttail-varargs.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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