1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -verify-machineinstrs < %s -enable-tail-merge=0 -mtriple=x86_64-linux | FileCheck %s --check-prefix=LINUX
3 ; RUN: llc -verify-machineinstrs < %s -enable-tail-merge=0 -mtriple=x86_64-linux-gnux32 | FileCheck %s --check-prefix=LINUX-X32
4 ; RUN: llc -verify-machineinstrs < %s -enable-tail-merge=0 -mtriple=x86_64-windows | FileCheck %s --check-prefix=WINDOWS
5 ; RUN: llc -verify-machineinstrs < %s -enable-tail-merge=0 -mtriple=i686-windows | FileCheck %s --check-prefix=X86 --check-prefix=X86-NOSSE
6 ; RUN: llc -verify-machineinstrs < %s -enable-tail-merge=0 -mtriple=i686-windows -mattr=+sse2 | FileCheck %s --check-prefix=X86 --check-prefix=X86-SSE
8 ; Test that we actually spill and reload all arguments in the variadic argument
9 ; pack. Doing a normal call will clobber all argument registers, and we will
10 ; spill around it. A simple adjustment should not require any XMM spills.
12 declare void @llvm.va_start(ptr) nounwind
14 declare ptr @get_f(ptr %this)
16 define void @f_thunk(ptr %this, ...) {
17 ; Use va_start so that we exercise the combination.
18 ; LINUX-LABEL: f_thunk:
20 ; LINUX-NEXT: pushq %rbp
21 ; LINUX-NEXT: .cfi_def_cfa_offset 16
22 ; LINUX-NEXT: pushq %r15
23 ; LINUX-NEXT: .cfi_def_cfa_offset 24
24 ; LINUX-NEXT: pushq %r14
25 ; LINUX-NEXT: .cfi_def_cfa_offset 32
26 ; LINUX-NEXT: pushq %r13
27 ; LINUX-NEXT: .cfi_def_cfa_offset 40
28 ; LINUX-NEXT: pushq %r12
29 ; LINUX-NEXT: .cfi_def_cfa_offset 48
30 ; LINUX-NEXT: pushq %rbx
31 ; LINUX-NEXT: .cfi_def_cfa_offset 56
32 ; LINUX-NEXT: subq $360, %rsp # imm = 0x168
33 ; LINUX-NEXT: .cfi_def_cfa_offset 416
34 ; LINUX-NEXT: .cfi_offset %rbx, -56
35 ; LINUX-NEXT: .cfi_offset %r12, -48
36 ; LINUX-NEXT: .cfi_offset %r13, -40
37 ; LINUX-NEXT: .cfi_offset %r14, -32
38 ; LINUX-NEXT: .cfi_offset %r15, -24
39 ; LINUX-NEXT: .cfi_offset %rbp, -16
40 ; LINUX-NEXT: movb %al, {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Spill
41 ; LINUX-NEXT: movaps %xmm7, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
42 ; LINUX-NEXT: movaps %xmm6, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
43 ; LINUX-NEXT: movaps %xmm5, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
44 ; LINUX-NEXT: movaps %xmm4, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
45 ; LINUX-NEXT: movaps %xmm3, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
46 ; LINUX-NEXT: movaps %xmm2, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
47 ; LINUX-NEXT: movaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
48 ; LINUX-NEXT: movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
49 ; LINUX-NEXT: movq %r9, %r14
50 ; LINUX-NEXT: movq %r8, %r15
51 ; LINUX-NEXT: movq %rcx, %r12
52 ; LINUX-NEXT: movq %rdx, %r13
53 ; LINUX-NEXT: movq %rsi, %rbp
54 ; LINUX-NEXT: movq %rdi, %rbx
55 ; LINUX-NEXT: movq %rsi, {{[0-9]+}}(%rsp)
56 ; LINUX-NEXT: movq %rdx, {{[0-9]+}}(%rsp)
57 ; LINUX-NEXT: movq %rcx, {{[0-9]+}}(%rsp)
58 ; LINUX-NEXT: movq %r8, {{[0-9]+}}(%rsp)
59 ; LINUX-NEXT: movq %r9, {{[0-9]+}}(%rsp)
60 ; LINUX-NEXT: testb %al, %al
61 ; LINUX-NEXT: je .LBB0_2
62 ; LINUX-NEXT: # %bb.1:
63 ; LINUX-NEXT: movaps %xmm0, {{[0-9]+}}(%rsp)
64 ; LINUX-NEXT: movaps %xmm1, {{[0-9]+}}(%rsp)
65 ; LINUX-NEXT: movaps %xmm2, {{[0-9]+}}(%rsp)
66 ; LINUX-NEXT: movaps %xmm3, {{[0-9]+}}(%rsp)
67 ; LINUX-NEXT: movaps %xmm4, {{[0-9]+}}(%rsp)
68 ; LINUX-NEXT: movaps %xmm5, {{[0-9]+}}(%rsp)
69 ; LINUX-NEXT: movaps %xmm6, {{[0-9]+}}(%rsp)
70 ; LINUX-NEXT: movaps %xmm7, {{[0-9]+}}(%rsp)
71 ; LINUX-NEXT: .LBB0_2:
72 ; LINUX-NEXT: leaq {{[0-9]+}}(%rsp), %rax
73 ; LINUX-NEXT: movq %rax, {{[0-9]+}}(%rsp)
74 ; LINUX-NEXT: leaq {{[0-9]+}}(%rsp), %rax
75 ; LINUX-NEXT: movq %rax, {{[0-9]+}}(%rsp)
76 ; LINUX-NEXT: movabsq $206158430216, %rax # imm = 0x3000000008
77 ; LINUX-NEXT: movq %rax, {{[0-9]+}}(%rsp)
78 ; LINUX-NEXT: callq get_f@PLT
79 ; LINUX-NEXT: movq %rax, %r11
80 ; LINUX-NEXT: movq %rbx, %rdi
81 ; LINUX-NEXT: movq %rbp, %rsi
82 ; LINUX-NEXT: movq %r13, %rdx
83 ; LINUX-NEXT: movq %r12, %rcx
84 ; LINUX-NEXT: movq %r15, %r8
85 ; LINUX-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 1-byte Folded Reload
86 ; LINUX-NEXT: movq %r14, %r9
87 ; LINUX-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
88 ; LINUX-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
89 ; LINUX-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm2 # 16-byte Reload
90 ; LINUX-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm3 # 16-byte Reload
91 ; LINUX-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm4 # 16-byte Reload
92 ; LINUX-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm5 # 16-byte Reload
93 ; LINUX-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm6 # 16-byte Reload
94 ; LINUX-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm7 # 16-byte Reload
95 ; LINUX-NEXT: addq $360, %rsp # imm = 0x168
96 ; LINUX-NEXT: .cfi_def_cfa_offset 56
97 ; LINUX-NEXT: popq %rbx
98 ; LINUX-NEXT: .cfi_def_cfa_offset 48
99 ; LINUX-NEXT: popq %r12
100 ; LINUX-NEXT: .cfi_def_cfa_offset 40
101 ; LINUX-NEXT: popq %r13
102 ; LINUX-NEXT: .cfi_def_cfa_offset 32
103 ; LINUX-NEXT: popq %r14
104 ; LINUX-NEXT: .cfi_def_cfa_offset 24
105 ; LINUX-NEXT: popq %r15
106 ; LINUX-NEXT: .cfi_def_cfa_offset 16
107 ; LINUX-NEXT: popq %rbp
108 ; LINUX-NEXT: .cfi_def_cfa_offset 8
109 ; LINUX-NEXT: jmpq *%r11 # TAILCALL
111 ; LINUX-X32-LABEL: f_thunk:
112 ; LINUX-X32: # %bb.0:
113 ; LINUX-X32-NEXT: pushq %rbp
114 ; LINUX-X32-NEXT: .cfi_def_cfa_offset 16
115 ; LINUX-X32-NEXT: pushq %r15
116 ; LINUX-X32-NEXT: .cfi_def_cfa_offset 24
117 ; LINUX-X32-NEXT: pushq %r14
118 ; LINUX-X32-NEXT: .cfi_def_cfa_offset 32
119 ; LINUX-X32-NEXT: pushq %r13
120 ; LINUX-X32-NEXT: .cfi_def_cfa_offset 40
121 ; LINUX-X32-NEXT: pushq %r12
122 ; LINUX-X32-NEXT: .cfi_def_cfa_offset 48
123 ; LINUX-X32-NEXT: pushq %rbx
124 ; LINUX-X32-NEXT: .cfi_def_cfa_offset 56
125 ; LINUX-X32-NEXT: subl $344, %esp # imm = 0x158
126 ; LINUX-X32-NEXT: .cfi_def_cfa_offset 400
127 ; LINUX-X32-NEXT: .cfi_offset %rbx, -56
128 ; LINUX-X32-NEXT: .cfi_offset %r12, -48
129 ; LINUX-X32-NEXT: .cfi_offset %r13, -40
130 ; LINUX-X32-NEXT: .cfi_offset %r14, -32
131 ; LINUX-X32-NEXT: .cfi_offset %r15, -24
132 ; LINUX-X32-NEXT: .cfi_offset %rbp, -16
133 ; LINUX-X32-NEXT: movb %al, {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Spill
134 ; LINUX-X32-NEXT: movaps %xmm7, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
135 ; LINUX-X32-NEXT: movaps %xmm6, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
136 ; LINUX-X32-NEXT: movaps %xmm5, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
137 ; LINUX-X32-NEXT: movaps %xmm4, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
138 ; LINUX-X32-NEXT: movaps %xmm3, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
139 ; LINUX-X32-NEXT: movaps %xmm2, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
140 ; LINUX-X32-NEXT: movaps %xmm1, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
141 ; LINUX-X32-NEXT: movaps %xmm0, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
142 ; LINUX-X32-NEXT: movq %r9, %r14
143 ; LINUX-X32-NEXT: movq %r8, %r15
144 ; LINUX-X32-NEXT: movq %rcx, %r12
145 ; LINUX-X32-NEXT: movq %rdx, %r13
146 ; LINUX-X32-NEXT: movq %rsi, %rbp
147 ; LINUX-X32-NEXT: movq %rdi, %rbx
148 ; LINUX-X32-NEXT: movq %rsi, {{[0-9]+}}(%esp)
149 ; LINUX-X32-NEXT: movq %rdx, {{[0-9]+}}(%esp)
150 ; LINUX-X32-NEXT: movq %rcx, {{[0-9]+}}(%esp)
151 ; LINUX-X32-NEXT: movq %r8, {{[0-9]+}}(%esp)
152 ; LINUX-X32-NEXT: movq %r9, {{[0-9]+}}(%esp)
153 ; LINUX-X32-NEXT: testb %al, %al
154 ; LINUX-X32-NEXT: je .LBB0_2
155 ; LINUX-X32-NEXT: # %bb.1:
156 ; LINUX-X32-NEXT: movaps %xmm0, {{[0-9]+}}(%esp)
157 ; LINUX-X32-NEXT: movaps %xmm1, {{[0-9]+}}(%esp)
158 ; LINUX-X32-NEXT: movaps %xmm2, {{[0-9]+}}(%esp)
159 ; LINUX-X32-NEXT: movaps %xmm3, {{[0-9]+}}(%esp)
160 ; LINUX-X32-NEXT: movaps %xmm4, {{[0-9]+}}(%esp)
161 ; LINUX-X32-NEXT: movaps %xmm5, {{[0-9]+}}(%esp)
162 ; LINUX-X32-NEXT: movaps %xmm6, {{[0-9]+}}(%esp)
163 ; LINUX-X32-NEXT: movaps %xmm7, {{[0-9]+}}(%esp)
164 ; LINUX-X32-NEXT: .LBB0_2:
165 ; LINUX-X32-NEXT: leal {{[0-9]+}}(%rsp), %eax
166 ; LINUX-X32-NEXT: movl %eax, {{[0-9]+}}(%esp)
167 ; LINUX-X32-NEXT: leal {{[0-9]+}}(%rsp), %eax
168 ; LINUX-X32-NEXT: movl %eax, {{[0-9]+}}(%esp)
169 ; LINUX-X32-NEXT: movabsq $206158430216, %rax # imm = 0x3000000008
170 ; LINUX-X32-NEXT: movq %rax, {{[0-9]+}}(%esp)
171 ; LINUX-X32-NEXT: callq get_f@PLT
172 ; LINUX-X32-NEXT: movl %eax, %r11d
173 ; LINUX-X32-NEXT: movq %rbx, %rdi
174 ; LINUX-X32-NEXT: movq %rbp, %rsi
175 ; LINUX-X32-NEXT: movq %r13, %rdx
176 ; LINUX-X32-NEXT: movq %r12, %rcx
177 ; LINUX-X32-NEXT: movq %r15, %r8
178 ; LINUX-X32-NEXT: movzbl {{[-0-9]+}}(%e{{[sb]}}p), %eax # 1-byte Folded Reload
179 ; LINUX-X32-NEXT: movq %r14, %r9
180 ; LINUX-X32-NEXT: movaps {{[-0-9]+}}(%e{{[sb]}}p), %xmm0 # 16-byte Reload
181 ; LINUX-X32-NEXT: movaps {{[-0-9]+}}(%e{{[sb]}}p), %xmm1 # 16-byte Reload
182 ; LINUX-X32-NEXT: movaps {{[-0-9]+}}(%e{{[sb]}}p), %xmm2 # 16-byte Reload
183 ; LINUX-X32-NEXT: movaps {{[-0-9]+}}(%e{{[sb]}}p), %xmm3 # 16-byte Reload
184 ; LINUX-X32-NEXT: movaps {{[-0-9]+}}(%e{{[sb]}}p), %xmm4 # 16-byte Reload
185 ; LINUX-X32-NEXT: movaps {{[-0-9]+}}(%e{{[sb]}}p), %xmm5 # 16-byte Reload
186 ; LINUX-X32-NEXT: movaps {{[-0-9]+}}(%e{{[sb]}}p), %xmm6 # 16-byte Reload
187 ; LINUX-X32-NEXT: movaps {{[-0-9]+}}(%e{{[sb]}}p), %xmm7 # 16-byte Reload
188 ; LINUX-X32-NEXT: addl $344, %esp # imm = 0x158
189 ; LINUX-X32-NEXT: .cfi_def_cfa_offset 56
190 ; LINUX-X32-NEXT: popq %rbx
191 ; LINUX-X32-NEXT: .cfi_def_cfa_offset 48
192 ; LINUX-X32-NEXT: popq %r12
193 ; LINUX-X32-NEXT: .cfi_def_cfa_offset 40
194 ; LINUX-X32-NEXT: popq %r13
195 ; LINUX-X32-NEXT: .cfi_def_cfa_offset 32
196 ; LINUX-X32-NEXT: popq %r14
197 ; LINUX-X32-NEXT: .cfi_def_cfa_offset 24
198 ; LINUX-X32-NEXT: popq %r15
199 ; LINUX-X32-NEXT: .cfi_def_cfa_offset 16
200 ; LINUX-X32-NEXT: popq %rbp
201 ; LINUX-X32-NEXT: .cfi_def_cfa_offset 8
202 ; LINUX-X32-NEXT: jmpq *%r11 # TAILCALL
204 ; WINDOWS-LABEL: f_thunk:
206 ; WINDOWS-NEXT: pushq %r14
207 ; WINDOWS-NEXT: .seh_pushreg %r14
208 ; WINDOWS-NEXT: pushq %rsi
209 ; WINDOWS-NEXT: .seh_pushreg %rsi
210 ; WINDOWS-NEXT: pushq %rdi
211 ; WINDOWS-NEXT: .seh_pushreg %rdi
212 ; WINDOWS-NEXT: pushq %rbx
213 ; WINDOWS-NEXT: .seh_pushreg %rbx
214 ; WINDOWS-NEXT: subq $72, %rsp
215 ; WINDOWS-NEXT: .seh_stackalloc 72
216 ; WINDOWS-NEXT: .seh_endprologue
217 ; WINDOWS-NEXT: movq %r9, %rsi
218 ; WINDOWS-NEXT: movq %r8, %rdi
219 ; WINDOWS-NEXT: movq %rdx, %rbx
220 ; WINDOWS-NEXT: movq %rcx, %r14
221 ; WINDOWS-NEXT: movq %rdx, {{[0-9]+}}(%rsp)
222 ; WINDOWS-NEXT: movq %r8, {{[0-9]+}}(%rsp)
223 ; WINDOWS-NEXT: movq %r9, {{[0-9]+}}(%rsp)
224 ; WINDOWS-NEXT: leaq {{[0-9]+}}(%rsp), %rax
225 ; WINDOWS-NEXT: movq %rax, {{[0-9]+}}(%rsp)
226 ; WINDOWS-NEXT: callq get_f
227 ; WINDOWS-NEXT: movq %r14, %rcx
228 ; WINDOWS-NEXT: movq %rbx, %rdx
229 ; WINDOWS-NEXT: movq %rdi, %r8
230 ; WINDOWS-NEXT: movq %rsi, %r9
231 ; WINDOWS-NEXT: addq $72, %rsp
232 ; WINDOWS-NEXT: popq %rbx
233 ; WINDOWS-NEXT: popq %rdi
234 ; WINDOWS-NEXT: popq %rsi
235 ; WINDOWS-NEXT: popq %r14
236 ; WINDOWS-NEXT: rex64 jmpq *%rax # TAILCALL
237 ; WINDOWS-NEXT: .seh_endproc
239 ; X86-NOSSE-LABEL: f_thunk:
240 ; X86-NOSSE: # %bb.0:
241 ; X86-NOSSE-NEXT: pushl %ebp
242 ; X86-NOSSE-NEXT: movl %esp, %ebp
243 ; X86-NOSSE-NEXT: pushl %esi
244 ; X86-NOSSE-NEXT: andl $-16, %esp
245 ; X86-NOSSE-NEXT: subl $32, %esp
246 ; X86-NOSSE-NEXT: movl 8(%ebp), %esi
247 ; X86-NOSSE-NEXT: leal 12(%ebp), %eax
248 ; X86-NOSSE-NEXT: movl %eax, (%esp)
249 ; X86-NOSSE-NEXT: pushl %esi
250 ; X86-NOSSE-NEXT: calll _get_f
251 ; X86-NOSSE-NEXT: addl $4, %esp
252 ; X86-NOSSE-NEXT: movl %esi, 8(%ebp)
253 ; X86-NOSSE-NEXT: leal -4(%ebp), %esp
254 ; X86-NOSSE-NEXT: popl %esi
255 ; X86-NOSSE-NEXT: popl %ebp
256 ; X86-NOSSE-NEXT: jmpl *%eax # TAILCALL
258 ; X86-SSE-LABEL: f_thunk:
260 ; X86-SSE-NEXT: pushl %ebp
261 ; X86-SSE-NEXT: movl %esp, %ebp
262 ; X86-SSE-NEXT: pushl %esi
263 ; X86-SSE-NEXT: andl $-16, %esp
264 ; X86-SSE-NEXT: subl $80, %esp
265 ; X86-SSE-NEXT: movaps %xmm2, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
266 ; X86-SSE-NEXT: movaps %xmm1, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
267 ; X86-SSE-NEXT: movaps %xmm0, (%esp) # 16-byte Spill
268 ; X86-SSE-NEXT: movl 8(%ebp), %esi
269 ; X86-SSE-NEXT: leal 12(%ebp), %eax
270 ; X86-SSE-NEXT: movl %eax, {{[0-9]+}}(%esp)
271 ; X86-SSE-NEXT: pushl %esi
272 ; X86-SSE-NEXT: calll _get_f
273 ; X86-SSE-NEXT: addl $4, %esp
274 ; X86-SSE-NEXT: movl %esi, 8(%ebp)
275 ; X86-SSE-NEXT: movaps (%esp), %xmm0 # 16-byte Reload
276 ; X86-SSE-NEXT: movaps {{[-0-9]+}}(%e{{[sb]}}p), %xmm1 # 16-byte Reload
277 ; X86-SSE-NEXT: movaps {{[-0-9]+}}(%e{{[sb]}}p), %xmm2 # 16-byte Reload
278 ; X86-SSE-NEXT: leal -4(%ebp), %esp
279 ; X86-SSE-NEXT: popl %esi
280 ; X86-SSE-NEXT: popl %ebp
281 ; X86-SSE-NEXT: jmpl *%eax # TAILCALL
282 %ap = alloca [4 x ptr], align 16
283 call void @llvm.va_start(ptr %ap)
285 %fptr = call ptr(ptr) @get_f(ptr %this)
286 musttail call void (ptr, ...) %fptr(ptr %this, ...)
290 ; Save and restore 6 GPRs, 8 XMMs, and AL around the call.
292 ; No regparms on normal x86 conventions.
294 ; This thunk shouldn't require any spills and reloads, assuming the register
295 ; allocator knows what it's doing.
297 define void @g_thunk(ptr %fptr_i8, ...) {
298 ; LINUX-LABEL: g_thunk:
300 ; LINUX-NEXT: jmpq *%rdi # TAILCALL
302 ; LINUX-X32-LABEL: g_thunk:
303 ; LINUX-X32: # %bb.0:
304 ; LINUX-X32-NEXT: jmpq *%rdi # TAILCALL
306 ; WINDOWS-LABEL: g_thunk:
308 ; WINDOWS-NEXT: rex64 jmpq *%rcx # TAILCALL
310 ; X86-LABEL: g_thunk:
312 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
313 ; X86-NEXT: movl %eax, {{[0-9]+}}(%esp)
314 ; X86-NEXT: jmpl *%eax # TAILCALL
315 musttail call void (ptr, ...) %fptr_i8(ptr %fptr_i8, ...)
319 ; Do a simple multi-exit multi-bb test.
321 %struct.Foo = type { i1, ptr, ptr }
323 @g = external dso_local global i32
325 define void @h_thunk(ptr %this, ...) {
326 ; LINUX-LABEL: h_thunk:
328 ; LINUX-NEXT: cmpb $1, (%rdi)
329 ; LINUX-NEXT: jne .LBB2_2
330 ; LINUX-NEXT: # %bb.1: # %then
331 ; LINUX-NEXT: movq 8(%rdi), %r11
332 ; LINUX-NEXT: jmpq *%r11 # TAILCALL
333 ; LINUX-NEXT: .LBB2_2: # %else
334 ; LINUX-NEXT: movq 16(%rdi), %r11
335 ; LINUX-NEXT: movl $42, g(%rip)
336 ; LINUX-NEXT: jmpq *%r11 # TAILCALL
338 ; LINUX-X32-LABEL: h_thunk:
339 ; LINUX-X32: # %bb.0:
340 ; LINUX-X32-NEXT: cmpb $1, (%edi)
341 ; LINUX-X32-NEXT: jne .LBB2_2
342 ; LINUX-X32-NEXT: # %bb.1: # %then
343 ; LINUX-X32-NEXT: movl 4(%edi), %r11d
344 ; LINUX-X32-NEXT: movl %edi, %edi
345 ; LINUX-X32-NEXT: jmpq *%r11 # TAILCALL
346 ; LINUX-X32-NEXT: .LBB2_2: # %else
347 ; LINUX-X32-NEXT: movl 8(%edi), %r11d
348 ; LINUX-X32-NEXT: movl $42, g(%rip)
349 ; LINUX-X32-NEXT: movl %edi, %edi
350 ; LINUX-X32-NEXT: jmpq *%r11 # TAILCALL
352 ; WINDOWS-LABEL: h_thunk:
354 ; WINDOWS-NEXT: cmpb $1, (%rcx)
355 ; WINDOWS-NEXT: jne .LBB2_2
356 ; WINDOWS-NEXT: # %bb.1: # %then
357 ; WINDOWS-NEXT: movq 8(%rcx), %rax
358 ; WINDOWS-NEXT: rex64 jmpq *%rax # TAILCALL
359 ; WINDOWS-NEXT: .LBB2_2: # %else
360 ; WINDOWS-NEXT: movq 16(%rcx), %rax
361 ; WINDOWS-NEXT: movl $42, g(%rip)
362 ; WINDOWS-NEXT: rex64 jmpq *%rax # TAILCALL
364 ; X86-LABEL: h_thunk:
366 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
367 ; X86-NEXT: cmpb $1, (%eax)
368 ; X86-NEXT: jne LBB2_2
369 ; X86-NEXT: # %bb.1: # %then
370 ; X86-NEXT: movl 4(%eax), %ecx
371 ; X86-NEXT: movl %eax, {{[0-9]+}}(%esp)
372 ; X86-NEXT: jmpl *%ecx # TAILCALL
373 ; X86-NEXT: LBB2_2: # %else
374 ; X86-NEXT: movl 8(%eax), %ecx
375 ; X86-NEXT: movl $42, _g
376 ; X86-NEXT: movl %eax, {{[0-9]+}}(%esp)
377 ; X86-NEXT: jmpl *%ecx # TAILCALL
378 %cond = load i1, ptr %this
379 br i1 %cond, label %then, label %else
382 %a_p = getelementptr %struct.Foo, ptr %this, i32 0, i32 1
383 %a_i8 = load ptr, ptr %a_p
384 musttail call void (ptr, ...) %a_i8(ptr %this, ...)
388 %b_p = getelementptr %struct.Foo, ptr %this, i32 0, i32 2
389 %b_i8 = load ptr, ptr %b_p
391 musttail call void (ptr, ...) %b_i8(ptr %this, ...)