Revert " [LoongArch][ISel] Check the number of sign bits in `PatGprGpr_32` (#107432)"
[llvm-project.git] / llvm / test / CodeGen / X86 / sibcall.ll
blob4a0a68ee3224343b20b76610eff8cfb8aef4351a
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -verify-machineinstrs < %s -mtriple=i686-linux   -mcpu=core2 -mattr=+sse2 | FileCheck %s --check-prefix=X86
3 ; RUN: llc -verify-machineinstrs < %s -mtriple=x86_64-linux -mcpu=core2 -mattr=+sse2 | FileCheck %s --check-prefix=X64
4 ; RUN: llc -verify-machineinstrs < %s -mtriple=x86_64-linux-gnux32 -mcpu=core2 -mattr=+sse2  | FileCheck %s --check-prefix=X32
6 define dso_local void @t1(i32 %x) nounwind ssp {
7 ; X86-LABEL: t1:
8 ; X86:       # %bb.0:
9 ; X86-NEXT:    jmp foo # TAILCALL
11 ; X64-LABEL: t1:
12 ; X64:       # %bb.0:
13 ; X64-NEXT:    jmp foo # TAILCALL
15 ; X32-LABEL: t1:
16 ; X32:       # %bb.0:
17 ; X32-NEXT:    jmp foo # TAILCALL
18   tail call void @foo() nounwind
19   ret void
22 declare dso_local void @foo()
24 define dso_local void @t2() nounwind ssp {
25 ; X86-LABEL: t2:
26 ; X86:       # %bb.0:
27 ; X86-NEXT:    jmp foo2 # TAILCALL
29 ; X64-LABEL: t2:
30 ; X64:       # %bb.0:
31 ; X64-NEXT:    jmp foo2 # TAILCALL
33 ; X32-LABEL: t2:
34 ; X32:       # %bb.0:
35 ; X32-NEXT:    jmp foo2 # TAILCALL
36   %t0 = tail call i32 @foo2() nounwind
37   ret void
40 declare dso_local i32 @foo2()
42 define dso_local void @t3() nounwind ssp {
43 ; X86-LABEL: t3:
44 ; X86:       # %bb.0:
45 ; X86-NEXT:    jmp foo3 # TAILCALL
47 ; X64-LABEL: t3:
48 ; X64:       # %bb.0:
49 ; X64-NEXT:    jmp foo3 # TAILCALL
51 ; X32-LABEL: t3:
52 ; X32:       # %bb.0:
53 ; X32-NEXT:    jmp foo3 # TAILCALL
54   %t0 = tail call i32 @foo3() nounwind
55   ret void
58 declare dso_local i32 @foo3()
60 define dso_local void @t4(ptr nocapture %x) nounwind ssp {
61 ; X86-LABEL: t4:
62 ; X86:       # %bb.0:
63 ; X86-NEXT:    subl $12, %esp
64 ; X86-NEXT:    movl $0, (%esp)
65 ; X86-NEXT:    calll *{{[0-9]+}}(%esp)
66 ; X86-NEXT:    addl $12, %esp
67 ; X86-NEXT:    retl
69 ; X64-LABEL: t4:
70 ; X64:       # %bb.0:
71 ; X64-NEXT:    movq %rdi, %rax
72 ; X64-NEXT:    xorl %edi, %edi
73 ; X64-NEXT:    jmpq *%rax # TAILCALL
75 ; X32-LABEL: t4:
76 ; X32:       # %bb.0:
77 ; X32-NEXT:    movq %rdi, %rax
78 ; X32-NEXT:    xorl %edi, %edi
79 ; X32-NEXT:    jmpq *%rax # TAILCALL
80   tail call void %x(i32 0) nounwind
81   ret void
84 define dso_local void @t5(ptr nocapture %x) nounwind ssp {
85 ; X86-LABEL: t5:
86 ; X86:       # %bb.0:
87 ; X86-NEXT:    jmpl *{{[0-9]+}}(%esp) # TAILCALL
89 ; X64-LABEL: t5:
90 ; X64:       # %bb.0:
91 ; X64-NEXT:    jmpq *%rdi # TAILCALL
93 ; X32-LABEL: t5:
94 ; X32:       # %bb.0:
95 ; X32-NEXT:    jmpq *%rdi # TAILCALL
96   tail call void %x() nounwind
97   ret void
100 ; Basically the same test as t5, except pass the function pointer on the stack
101 ; for x86_64.
103 define dso_local void @t5_x64(i32, i32, i32, i32, i32, i32, ptr nocapture %x) nounwind ssp {
104 ; X86-LABEL: t5_x64:
105 ; X86:       # %bb.0:
106 ; X86-NEXT:    jmpl *{{[0-9]+}}(%esp) # TAILCALL
108 ; X64-LABEL: t5_x64:
109 ; X64:       # %bb.0:
110 ; X64-NEXT:    jmpq *{{[0-9]+}}(%rsp) # TAILCALL
112 ; X32-LABEL: t5_x64:
113 ; X32:       # %bb.0:
114 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
115 ; X32-NEXT:    jmpq *%rax # TAILCALL
116   tail call void %x() nounwind
117   ret void
121 define dso_local i32 @t6(i32 %x) nounwind ssp {
122 ; X86-LABEL: t6:
123 ; X86:       # %bb.0:
124 ; X86-NEXT:    subl $12, %esp
125 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
126 ; X86-NEXT:    cmpl $9, %eax
127 ; X86-NEXT:    jg .LBB6_2
128 ; X86-NEXT:  # %bb.1: # %bb
129 ; X86-NEXT:    decl %eax
130 ; X86-NEXT:    movl %eax, (%esp)
131 ; X86-NEXT:    calll t6
132 ; X86-NEXT:    addl $12, %esp
133 ; X86-NEXT:    retl
134 ; X86-NEXT:  .LBB6_2: # %bb1
135 ; X86-NEXT:    addl $12, %esp
136 ; X86-NEXT:    jmp bar # TAILCALL
138 ; X64-LABEL: t6:
139 ; X64:       # %bb.0:
140 ; X64-NEXT:    cmpl $9, %edi
141 ; X64-NEXT:    jg bar # TAILCALL
142 ; X64-NEXT:  # %bb.1: # %bb
143 ; X64-NEXT:    decl %edi
144 ; X64-NEXT:    jmp t6 # TAILCALL
146 ; X32-LABEL: t6:
147 ; X32:       # %bb.0:
148 ; X32-NEXT:    cmpl $9, %edi
149 ; X32-NEXT:    jg bar # TAILCALL
150 ; X32-NEXT:  # %bb.1: # %bb
151 ; X32-NEXT:    decl %edi
152 ; X32-NEXT:    jmp t6 # TAILCALL
153   %t0 = icmp slt i32 %x, 10
154   br i1 %t0, label %bb, label %bb1
157   %t1 = add nsw i32 %x, -1
158   %t2 = tail call i32 @t6(i32 %t1) nounwind ssp
159   ret i32 %t2
161 bb1:
162   %t3 = tail call i32 @bar(i32 %x) nounwind
163   ret i32 %t3
166 declare dso_local i32 @bar(i32)
168 define dso_local i32 @t7(i32 %a, i32 %b, i32 %c) nounwind ssp {
169 ; X86-LABEL: t7:
170 ; X86:       # %bb.0:
171 ; X86-NEXT:    jmp bar2 # TAILCALL
173 ; X64-LABEL: t7:
174 ; X64:       # %bb.0:
175 ; X64-NEXT:    jmp bar2 # TAILCALL
177 ; X32-LABEL: t7:
178 ; X32:       # %bb.0:
179 ; X32-NEXT:    jmp bar2 # TAILCALL
180   %t0 = tail call i32 @bar2(i32 %a, i32 %b, i32 %c) nounwind
181   ret i32 %t0
184 declare dso_local i32 @bar2(i32, i32, i32)
186 define signext i16 @t8() nounwind ssp {
187 ; X86-LABEL: t8:
188 ; X86:       # %bb.0: # %entry
189 ; X86-NEXT:    jmp bar3 # TAILCALL
191 ; X64-LABEL: t8:
192 ; X64:       # %bb.0: # %entry
193 ; X64-NEXT:    jmp bar3 # TAILCALL
195 ; X32-LABEL: t8:
196 ; X32:       # %bb.0: # %entry
197 ; X32-NEXT:    jmp bar3 # TAILCALL
198 entry:
199   %0 = tail call signext i16 @bar3() nounwind      ; <i16> [#uses=1]
200   ret i16 %0
203 declare dso_local signext i16 @bar3()
205 define signext i16 @t9(ptr nocapture %x) nounwind ssp {
206 ; X86-LABEL: t9:
207 ; X86:       # %bb.0: # %entry
208 ; X86-NEXT:    subl $12, %esp
209 ; X86-NEXT:    movl $0, (%esp)
210 ; X86-NEXT:    calll *{{[0-9]+}}(%esp)
211 ; X86-NEXT:    addl $12, %esp
212 ; X86-NEXT:    retl
214 ; X64-LABEL: t9:
215 ; X64:       # %bb.0: # %entry
216 ; X64-NEXT:    movq %rdi, %rax
217 ; X64-NEXT:    xorl %edi, %edi
218 ; X64-NEXT:    jmpq *%rax # TAILCALL
220 ; X32-LABEL: t9:
221 ; X32:       # %bb.0: # %entry
222 ; X32-NEXT:    movq %rdi, %rax
223 ; X32-NEXT:    xorl %edi, %edi
224 ; X32-NEXT:    jmpq *%rax # TAILCALL
225 entry:
226   %0 = tail call signext i16 %x(i32 0) nounwind
227   ret i16 %0
230 define dso_local void @t10() nounwind ssp {
231 ; X86-LABEL: t10:
232 ; X86:       # %bb.0: # %entry
233 ; X86-NEXT:    subl $12, %esp
234 ; X86-NEXT:    calll foo4
236 ; X64-LABEL: t10:
237 ; X64:       # %bb.0: # %entry
238 ; X64-NEXT:    pushq %rax
239 ; X64-NEXT:    callq foo4
241 ; X32-LABEL: t10:
242 ; X32:       # %bb.0: # %entry
243 ; X32-NEXT:    pushq %rax
244 ; X32-NEXT:    callq foo4
245 entry:
246   %0 = tail call i32 @foo4() noreturn nounwind
247   unreachable
250 declare dso_local i32 @foo4()
252 ; In 32-bit mode, it's emitting a bunch of dead loads that are not being
253 ; eliminated currently.
255 define dso_local i32 @t11(i32 %x, i32 %y, i32 %z.0, i32 %z.1, i32 %z.2) nounwind ssp {
256 ; X86-LABEL: t11:
257 ; X86:       # %bb.0: # %entry
258 ; X86-NEXT:    cmpl $0, {{[0-9]+}}(%esp)
259 ; X86-NEXT:    jne foo5 # TAILCALL
260 ; X86-NEXT:  # %bb.1: # %bb6
261 ; X86-NEXT:    xorl %eax, %eax
262 ; X86-NEXT:    retl
264 ; X64-LABEL: t11:
265 ; X64:       # %bb.0: # %entry
266 ; X64-NEXT:    testl %edi, %edi
267 ; X64-NEXT:    jne foo5 # TAILCALL
268 ; X64-NEXT:  # %bb.1: # %bb6
269 ; X64-NEXT:    xorl %eax, %eax
270 ; X64-NEXT:    retq
272 ; X32-LABEL: t11:
273 ; X32:       # %bb.0: # %entry
274 ; X32-NEXT:    testl %edi, %edi
275 ; X32-NEXT:    jne foo5 # TAILCALL
276 ; X32-NEXT:  # %bb.1: # %bb6
277 ; X32-NEXT:    xorl %eax, %eax
278 ; X32-NEXT:    retq
279 entry:
280   %0 = icmp eq i32 %x, 0
281   br i1 %0, label %bb6, label %bb
284   %1 = tail call i32 @foo5(i32 %x, i32 %y, i32 %z.0, i32 %z.1, i32 %z.2) nounwind
285   ret i32 %1
287 bb6:
288   ret i32 0
291 declare dso_local i32 @foo5(i32, i32, i32, i32, i32)
293 %struct.t = type { i32, i32, i32, i32, i32 }
295 define dso_local i32 @t12(i32 %x, i32 %y, ptr byval(%struct.t) align 4 %z) nounwind ssp {
296 ; X86-LABEL: t12:
297 ; X86:       # %bb.0: # %entry
298 ; X86-NEXT:    cmpl $0, {{[0-9]+}}(%esp)
299 ; X86-NEXT:    jne foo6 # TAILCALL
300 ; X86-NEXT:  # %bb.1: # %bb2
301 ; X86-NEXT:    xorl %eax, %eax
302 ; X86-NEXT:    retl
304 ; X64-LABEL: t12:
305 ; X64:       # %bb.0: # %entry
306 ; X64-NEXT:    testl %edi, %edi
307 ; X64-NEXT:    jne foo6 # TAILCALL
308 ; X64-NEXT:  # %bb.1: # %bb2
309 ; X64-NEXT:    xorl %eax, %eax
310 ; X64-NEXT:    retq
312 ; X32-LABEL: t12:
313 ; X32:       # %bb.0: # %entry
314 ; X32-NEXT:    testl %edi, %edi
315 ; X32-NEXT:    jne foo6 # TAILCALL
316 ; X32-NEXT:  # %bb.1: # %bb2
317 ; X32-NEXT:    xorl %eax, %eax
318 ; X32-NEXT:    retq
319 entry:
320   %0 = icmp eq i32 %x, 0
321   br i1 %0, label %bb2, label %bb
324   %1 = tail call i32 @foo6(i32 %x, i32 %y, ptr byval(%struct.t) align 4 %z) nounwind
325   ret i32 %1
327 bb2:
328   ret i32 0
331 declare dso_local i32 @foo6(i32, i32, ptr byval(%struct.t) align 4)
333 ; rdar://r7717598
334 %struct.ns = type { i32, i32 }
335 %struct.cp = type { float, float, float, float, float }
337 define ptr @t13(ptr %yy) nounwind ssp {
338 ; X86-LABEL: t13:
339 ; X86:       # %bb.0: # %entry
340 ; X86-NEXT:    subl $28, %esp
341 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
342 ; X86-NEXT:    movl 16(%eax), %ecx
343 ; X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
344 ; X86-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
345 ; X86-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
346 ; X86-NEXT:    movsd %xmm1, {{[0-9]+}}(%esp)
347 ; X86-NEXT:    movsd %xmm0, (%esp)
348 ; X86-NEXT:    xorl %ecx, %ecx
349 ; X86-NEXT:    calll foo7
350 ; X86-NEXT:    addl $28, %esp
351 ; X86-NEXT:    retl
353 ; X64-LABEL: t13:
354 ; X64:       # %bb.0: # %entry
355 ; X64-NEXT:    pushq %rax
356 ; X64-NEXT:    subq $8, %rsp
357 ; X64-NEXT:    movl 16(%rdi), %eax
358 ; X64-NEXT:    movq (%rdi), %rcx
359 ; X64-NEXT:    movq 8(%rdi), %rdx
360 ; X64-NEXT:    xorl %edi, %edi
361 ; X64-NEXT:    pushq %rax
362 ; X64-NEXT:    pushq %rdx
363 ; X64-NEXT:    pushq %rcx
364 ; X64-NEXT:    callq foo7
365 ; X64-NEXT:    addq $32, %rsp
366 ; X64-NEXT:    popq %rcx
367 ; X64-NEXT:    retq
369 ; X32-LABEL: t13:
370 ; X32:       # %bb.0: # %entry
371 ; X32-NEXT:    pushq %rax
372 ; X32-NEXT:    subl $8, %esp
373 ; X32-NEXT:    movl 16(%edi), %eax
374 ; X32-NEXT:    movq (%edi), %rcx
375 ; X32-NEXT:    movq 8(%edi), %rdx
376 ; X32-NEXT:    xorl %edi, %edi
377 ; X32-NEXT:    pushq %rax
378 ; X32-NEXT:    pushq %rdx
379 ; X32-NEXT:    pushq %rcx
380 ; X32-NEXT:    callq foo7
381 ; X32-NEXT:    addl $32, %esp
382 ; X32-NEXT:    movl %eax, %eax
383 ; X32-NEXT:    popq %rcx
384 ; X32-NEXT:    retq
385 entry:
386   %0 = tail call fastcc ptr @foo7(ptr byval(%struct.cp) align 4 %yy, i8 signext 0) nounwind
387   ret ptr %0
390 ; rdar://6195379
391 ; llvm can't do sibcall for this in 32-bit mode (yet).
392 declare dso_local fastcc ptr @foo7(ptr byval(%struct.cp) align 4, i8 signext) nounwind ssp
394 %struct.__block_descriptor = type { i64, i64 }
395 %struct.__block_descriptor_withcopydispose = type { i64, i64, ptr, ptr }
396 %struct.__block_literal_1 = type { ptr, i32, i32, ptr, ptr }
397 %struct.__block_literal_2 = type { ptr, i32, i32, ptr, ptr, ptr }
399 define dso_local void @t14(ptr nocapture %.block_descriptor) nounwind ssp {
400 ; X86-LABEL: t14:
401 ; X86:       # %bb.0: # %entry
402 ; X86-NEXT:    subl $12, %esp
403 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
404 ; X86-NEXT:    movl 20(%eax), %eax
405 ; X86-NEXT:    movl %eax, (%esp)
406 ; X86-NEXT:    calll *12(%eax)
407 ; X86-NEXT:    addl $12, %esp
408 ; X86-NEXT:    retl
410 ; X64-LABEL: t14:
411 ; X64:       # %bb.0: # %entry
412 ; X64-NEXT:    movq 32(%rdi), %rdi
413 ; X64-NEXT:    jmpq *16(%rdi) # TAILCALL
415 ; X32-LABEL: t14:
416 ; X32:       # %bb.0: # %entry
417 ; X32-NEXT:    movl 20(%edi), %edi
418 ; X32-NEXT:    movl 12(%edi), %eax
419 ; X32-NEXT:    jmpq *%rax # TAILCALL
420 entry:
421   %0 = getelementptr inbounds %struct.__block_literal_2, ptr %.block_descriptor, i64 0, i32 5 ; <ptr> [#uses=1]
422   %1 = load ptr, ptr %0, align 8                 ; <ptr> [#uses=2]
423   %2 = getelementptr inbounds %struct.__block_literal_1, ptr %1, i64 0, i32 3 ; <ptr> [#uses=1]
424   %3 = load ptr, ptr %2, align 8                      ; <ptr> [#uses=1]
425   tail call void %3(ptr %1) nounwind
426   ret void
429 ; rdar://7726868
430 %struct.foo = type { [4 x i32] }
432 define dso_local void @t15(ptr noalias sret(%struct.foo) %agg.result) nounwind  {
433 ; X86-LABEL: t15:
434 ; X86:       # %bb.0:
435 ; X86-NEXT:    pushl %esi
436 ; X86-NEXT:    subl $8, %esp
437 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
438 ; X86-NEXT:    movl %esi, %ecx
439 ; X86-NEXT:    calll f
440 ; X86-NEXT:    movl %esi, %eax
441 ; X86-NEXT:    addl $8, %esp
442 ; X86-NEXT:    popl %esi
443 ; X86-NEXT:    retl $4
445 ; X64-LABEL: t15:
446 ; X64:       # %bb.0:
447 ; X64-NEXT:    pushq %rbx
448 ; X64-NEXT:    movq %rdi, %rbx
449 ; X64-NEXT:    callq f
450 ; X64-NEXT:    movq %rbx, %rax
451 ; X64-NEXT:    popq %rbx
452 ; X64-NEXT:    retq
454 ; X32-LABEL: t15:
455 ; X32:       # %bb.0:
456 ; X32-NEXT:    pushq %rbx
457 ; X32-NEXT:    movq %rdi, %rbx
458 ; X32-NEXT:    callq f
459 ; X32-NEXT:    movl %ebx, %eax
460 ; X32-NEXT:    popq %rbx
461 ; X32-NEXT:    retq
462   tail call fastcc void @f(ptr noalias sret(%struct.foo) %agg.result) nounwind
463   ret void
466 declare dso_local void @f(ptr noalias sret(%struct.foo)) nounwind
468 define dso_local void @t16() nounwind ssp {
469 ; X86-LABEL: t16:
470 ; X86:       # %bb.0: # %entry
471 ; X86-NEXT:    subl $12, %esp
472 ; X86-NEXT:    calll bar4
473 ; X86-NEXT:    fstp %st(0)
474 ; X86-NEXT:    addl $12, %esp
475 ; X86-NEXT:    retl
477 ; X64-LABEL: t16:
478 ; X64:       # %bb.0: # %entry
479 ; X64-NEXT:    jmp bar4 # TAILCALL
481 ; X32-LABEL: t16:
482 ; X32:       # %bb.0: # %entry
483 ; X32-NEXT:    jmp bar4 # TAILCALL
484 entry:
485   %0 = tail call double @bar4() nounwind
486   ret void
489 declare dso_local double @bar4()
491 ; rdar://6283267
492 define dso_local void @t17() nounwind ssp {
493 ; X86-LABEL: t17:
494 ; X86:       # %bb.0: # %entry
495 ; X86-NEXT:    jmp bar5 # TAILCALL
497 ; X64-LABEL: t17:
498 ; X64:       # %bb.0: # %entry
499 ; X64-NEXT:    xorl %eax, %eax
500 ; X64-NEXT:    jmp bar5 # TAILCALL
502 ; X32-LABEL: t17:
503 ; X32:       # %bb.0: # %entry
504 ; X32-NEXT:    xorl %eax, %eax
505 ; X32-NEXT:    jmp bar5 # TAILCALL
506 entry:
507   tail call void (...) @bar5() nounwind
508   ret void
511 declare dso_local void @bar5(...)
513 ; rdar://7774847
514 define dso_local void @t18() nounwind ssp {
515 ; X86-LABEL: t18:
516 ; X86:       # %bb.0: # %entry
517 ; X86-NEXT:    subl $12, %esp
518 ; X86-NEXT:    calll bar6
519 ; X86-NEXT:    fstp %st(0)
520 ; X86-NEXT:    addl $12, %esp
521 ; X86-NEXT:    retl
523 ; X64-LABEL: t18:
524 ; X64:       # %bb.0: # %entry
525 ; X64-NEXT:    xorl %eax, %eax
526 ; X64-NEXT:    jmp bar6 # TAILCALL
528 ; X32-LABEL: t18:
529 ; X32:       # %bb.0: # %entry
530 ; X32-NEXT:    xorl %eax, %eax
531 ; X32-NEXT:    jmp bar6 # TAILCALL
532 entry:
533   %0 = tail call double (...) @bar6() nounwind
534   ret void
537 declare dso_local double @bar6(...)
539 define dso_local void @t19() alignstack(32) nounwind {
540 ; X86-LABEL: t19:
541 ; X86:       # %bb.0: # %entry
542 ; X86-NEXT:    pushl %ebp
543 ; X86-NEXT:    movl %esp, %ebp
544 ; X86-NEXT:    andl $-32, %esp
545 ; X86-NEXT:    subl $32, %esp
546 ; X86-NEXT:    calll foo
547 ; X86-NEXT:    movl %ebp, %esp
548 ; X86-NEXT:    popl %ebp
549 ; X86-NEXT:    retl
551 ; X64-LABEL: t19:
552 ; X64:       # %bb.0: # %entry
553 ; X64-NEXT:    pushq %rbp
554 ; X64-NEXT:    movq %rsp, %rbp
555 ; X64-NEXT:    andq $-32, %rsp
556 ; X64-NEXT:    subq $32, %rsp
557 ; X64-NEXT:    callq foo
558 ; X64-NEXT:    movq %rbp, %rsp
559 ; X64-NEXT:    popq %rbp
560 ; X64-NEXT:    retq
562 ; X32-LABEL: t19:
563 ; X32:       # %bb.0: # %entry
564 ; X32-NEXT:    pushq %rbp
565 ; X32-NEXT:    movl %esp, %ebp
566 ; X32-NEXT:    andl $-32, %esp
567 ; X32-NEXT:    subl $32, %esp
568 ; X32-NEXT:    callq foo
569 ; X32-NEXT:    movl %ebp, %esp
570 ; X32-NEXT:    popq %rbp
571 ; X32-NEXT:    retq
572 entry:
573   tail call void @foo() nounwind
574   ret void
577 ; If caller / callee calling convention mismatch then check if the return
578 ; values are returned in the same registers.
579 ; rdar://7874780
581 define dso_local double @t20(double %x) nounwind {
582 ; X86-LABEL: t20:
583 ; X86:       # %bb.0: # %entry
584 ; X86-NEXT:    subl $12, %esp
585 ; X86-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
586 ; X86-NEXT:    calll foo20
587 ; X86-NEXT:    movsd %xmm0, (%esp)
588 ; X86-NEXT:    fldl (%esp)
589 ; X86-NEXT:    addl $12, %esp
590 ; X86-NEXT:    retl
592 ; X64-LABEL: t20:
593 ; X64:       # %bb.0: # %entry
594 ; X64-NEXT:    jmp foo20 # TAILCALL
596 ; X32-LABEL: t20:
597 ; X32:       # %bb.0: # %entry
598 ; X32-NEXT:    jmp foo20 # TAILCALL
599 entry:
600   %0 = tail call fastcc double @foo20(double %x) nounwind
601   ret double %0
604 declare dso_local fastcc double @foo20(double) nounwind
606 ; bug 28417
607 define fastcc void @t21_sret_to_sret(ptr noalias sret(%struct.foo) %agg.result) nounwind  {
608 ; X86-LABEL: t21_sret_to_sret:
609 ; X86:       # %bb.0:
610 ; X86-NEXT:    pushl %esi
611 ; X86-NEXT:    subl $8, %esp
612 ; X86-NEXT:    movl %ecx, %esi
613 ; X86-NEXT:    calll t21_f_sret
614 ; X86-NEXT:    movl %esi, %eax
615 ; X86-NEXT:    addl $8, %esp
616 ; X86-NEXT:    popl %esi
617 ; X86-NEXT:    retl
619 ; X64-LABEL: t21_sret_to_sret:
620 ; X64:       # %bb.0:
621 ; X64-NEXT:    pushq %rbx
622 ; X64-NEXT:    movq %rdi, %rbx
623 ; X64-NEXT:    callq t21_f_sret
624 ; X64-NEXT:    movq %rbx, %rax
625 ; X64-NEXT:    popq %rbx
626 ; X64-NEXT:    retq
628 ; X32-LABEL: t21_sret_to_sret:
629 ; X32:       # %bb.0:
630 ; X32-NEXT:    pushq %rbx
631 ; X32-NEXT:    movq %rdi, %rbx
632 ; X32-NEXT:    callq t21_f_sret
633 ; X32-NEXT:    movl %ebx, %eax
634 ; X32-NEXT:    popq %rbx
635 ; X32-NEXT:    retq
636   tail call fastcc void @t21_f_sret(ptr noalias sret(%struct.foo) %agg.result) nounwind
637   ret void
640 define fastcc void @t21_sret_to_sret_more_args(ptr noalias sret(%struct.foo) %agg.result, i32 %a, i32 %b) nounwind  {
641 ; X86-LABEL: t21_sret_to_sret_more_args:
642 ; X86:       # %bb.0:
643 ; X86-NEXT:    pushl %esi
644 ; X86-NEXT:    subl $8, %esp
645 ; X86-NEXT:    movl %ecx, %esi
646 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
647 ; X86-NEXT:    movl %eax, (%esp)
648 ; X86-NEXT:    calll f_sret@PLT
649 ; X86-NEXT:    movl %esi, %eax
650 ; X86-NEXT:    addl $8, %esp
651 ; X86-NEXT:    popl %esi
652 ; X86-NEXT:    retl
654 ; X64-LABEL: t21_sret_to_sret_more_args:
655 ; X64:       # %bb.0:
656 ; X64-NEXT:    pushq %rbx
657 ; X64-NEXT:    movq %rdi, %rbx
658 ; X64-NEXT:    callq f_sret@PLT
659 ; X64-NEXT:    movq %rbx, %rax
660 ; X64-NEXT:    popq %rbx
661 ; X64-NEXT:    retq
663 ; X32-LABEL: t21_sret_to_sret_more_args:
664 ; X32:       # %bb.0:
665 ; X32-NEXT:    pushq %rbx
666 ; X32-NEXT:    movq %rdi, %rbx
667 ; X32-NEXT:    callq f_sret@PLT
668 ; X32-NEXT:    movl %ebx, %eax
669 ; X32-NEXT:    popq %rbx
670 ; X32-NEXT:    retq
671   tail call fastcc void @f_sret(ptr noalias sret(%struct.foo) %agg.result, i32 %a, i32 %b) nounwind
672   ret void
675 define fastcc void @t21_sret_to_sret_second_arg_sret(ptr noalias %agg.result, ptr noalias sret(%struct.foo) %ret) nounwind  {
676 ; X86-LABEL: t21_sret_to_sret_second_arg_sret:
677 ; X86:       # %bb.0:
678 ; X86-NEXT:    pushl %esi
679 ; X86-NEXT:    subl $8, %esp
680 ; X86-NEXT:    movl %edx, %esi
681 ; X86-NEXT:    movl %edx, %ecx
682 ; X86-NEXT:    calll t21_f_sret
683 ; X86-NEXT:    movl %esi, %eax
684 ; X86-NEXT:    addl $8, %esp
685 ; X86-NEXT:    popl %esi
686 ; X86-NEXT:    retl
688 ; X64-LABEL: t21_sret_to_sret_second_arg_sret:
689 ; X64:       # %bb.0:
690 ; X64-NEXT:    pushq %rbx
691 ; X64-NEXT:    movq %rsi, %rbx
692 ; X64-NEXT:    movq %rsi, %rdi
693 ; X64-NEXT:    callq t21_f_sret
694 ; X64-NEXT:    movq %rbx, %rax
695 ; X64-NEXT:    popq %rbx
696 ; X64-NEXT:    retq
698 ; X32-LABEL: t21_sret_to_sret_second_arg_sret:
699 ; X32:       # %bb.0:
700 ; X32-NEXT:    pushq %rbx
701 ; X32-NEXT:    movq %rsi, %rbx
702 ; X32-NEXT:    movq %rsi, %rdi
703 ; X32-NEXT:    callq t21_f_sret
704 ; X32-NEXT:    movl %ebx, %eax
705 ; X32-NEXT:    popq %rbx
706 ; X32-NEXT:    retq
707   tail call fastcc void @t21_f_sret(ptr noalias sret(%struct.foo) %ret) nounwind
708   ret void
711 define fastcc void @t21_sret_to_sret_more_args2(ptr noalias sret(%struct.foo) %agg.result, i32 %a, i32 %b) nounwind  {
712 ; X86-LABEL: t21_sret_to_sret_more_args2:
713 ; X86:       # %bb.0:
714 ; X86-NEXT:    pushl %esi
715 ; X86-NEXT:    subl $8, %esp
716 ; X86-NEXT:    movl %ecx, %esi
717 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
718 ; X86-NEXT:    movl %edx, (%esp)
719 ; X86-NEXT:    movl %eax, %edx
720 ; X86-NEXT:    calll f_sret@PLT
721 ; X86-NEXT:    movl %esi, %eax
722 ; X86-NEXT:    addl $8, %esp
723 ; X86-NEXT:    popl %esi
724 ; X86-NEXT:    retl
726 ; X64-LABEL: t21_sret_to_sret_more_args2:
727 ; X64:       # %bb.0:
728 ; X64-NEXT:    pushq %rbx
729 ; X64-NEXT:    movl %esi, %eax
730 ; X64-NEXT:    movq %rdi, %rbx
731 ; X64-NEXT:    movl %edx, %esi
732 ; X64-NEXT:    movl %eax, %edx
733 ; X64-NEXT:    callq f_sret@PLT
734 ; X64-NEXT:    movq %rbx, %rax
735 ; X64-NEXT:    popq %rbx
736 ; X64-NEXT:    retq
738 ; X32-LABEL: t21_sret_to_sret_more_args2:
739 ; X32:       # %bb.0:
740 ; X32-NEXT:    pushq %rbx
741 ; X32-NEXT:    movl %esi, %eax
742 ; X32-NEXT:    movq %rdi, %rbx
743 ; X32-NEXT:    movl %edx, %esi
744 ; X32-NEXT:    movl %eax, %edx
745 ; X32-NEXT:    callq f_sret@PLT
746 ; X32-NEXT:    movl %ebx, %eax
747 ; X32-NEXT:    popq %rbx
748 ; X32-NEXT:    retq
749   tail call fastcc void @f_sret(ptr noalias sret(%struct.foo) %agg.result, i32 %b, i32 %a) nounwind
750   ret void
754 define fastcc void @t21_sret_to_sret_args_mismatch(ptr noalias sret(%struct.foo) %agg.result, ptr noalias %ret) nounwind  {
755 ; X86-LABEL: t21_sret_to_sret_args_mismatch:
756 ; X86:       # %bb.0:
757 ; X86-NEXT:    pushl %esi
758 ; X86-NEXT:    subl $8, %esp
759 ; X86-NEXT:    movl %ecx, %esi
760 ; X86-NEXT:    movl %edx, %ecx
761 ; X86-NEXT:    calll t21_f_sret
762 ; X86-NEXT:    movl %esi, %eax
763 ; X86-NEXT:    addl $8, %esp
764 ; X86-NEXT:    popl %esi
765 ; X86-NEXT:    retl
767 ; X64-LABEL: t21_sret_to_sret_args_mismatch:
768 ; X64:       # %bb.0:
769 ; X64-NEXT:    pushq %rbx
770 ; X64-NEXT:    movq %rdi, %rbx
771 ; X64-NEXT:    movq %rsi, %rdi
772 ; X64-NEXT:    callq t21_f_sret
773 ; X64-NEXT:    movq %rbx, %rax
774 ; X64-NEXT:    popq %rbx
775 ; X64-NEXT:    retq
777 ; X32-LABEL: t21_sret_to_sret_args_mismatch:
778 ; X32:       # %bb.0:
779 ; X32-NEXT:    pushq %rbx
780 ; X32-NEXT:    movq %rdi, %rbx
781 ; X32-NEXT:    movq %rsi, %rdi
782 ; X32-NEXT:    callq t21_f_sret
783 ; X32-NEXT:    movl %ebx, %eax
784 ; X32-NEXT:    popq %rbx
785 ; X32-NEXT:    retq
786   tail call fastcc void @t21_f_sret(ptr noalias sret(%struct.foo) %ret) nounwind
787   ret void
790 define fastcc void @t21_sret_to_sret_args_mismatch2(ptr noalias sret(%struct.foo) %agg.result, ptr noalias %ret) nounwind  {
791 ; X86-LABEL: t21_sret_to_sret_args_mismatch2:
792 ; X86:       # %bb.0:
793 ; X86-NEXT:    pushl %esi
794 ; X86-NEXT:    subl $8, %esp
795 ; X86-NEXT:    movl %ecx, %esi
796 ; X86-NEXT:    movl %edx, %ecx
797 ; X86-NEXT:    calll t21_f_sret
798 ; X86-NEXT:    movl %esi, %eax
799 ; X86-NEXT:    addl $8, %esp
800 ; X86-NEXT:    popl %esi
801 ; X86-NEXT:    retl
803 ; X64-LABEL: t21_sret_to_sret_args_mismatch2:
804 ; X64:       # %bb.0:
805 ; X64-NEXT:    pushq %rbx
806 ; X64-NEXT:    movq %rdi, %rbx
807 ; X64-NEXT:    movq %rsi, %rdi
808 ; X64-NEXT:    callq t21_f_sret
809 ; X64-NEXT:    movq %rbx, %rax
810 ; X64-NEXT:    popq %rbx
811 ; X64-NEXT:    retq
813 ; X32-LABEL: t21_sret_to_sret_args_mismatch2:
814 ; X32:       # %bb.0:
815 ; X32-NEXT:    pushq %rbx
816 ; X32-NEXT:    movq %rdi, %rbx
817 ; X32-NEXT:    movq %rsi, %rdi
818 ; X32-NEXT:    callq t21_f_sret
819 ; X32-NEXT:    movl %ebx, %eax
820 ; X32-NEXT:    popq %rbx
821 ; X32-NEXT:    retq
822   tail call fastcc void @t21_f_sret(ptr noalias sret(%struct.foo) %ret) nounwind
823   ret void
826 define fastcc void @t21_sret_to_sret_arg_mismatch(ptr noalias sret(%struct.foo) %agg.result) nounwind  {
827 ; X86-LABEL: t21_sret_to_sret_arg_mismatch:
828 ; X86:       # %bb.0:
829 ; X86-NEXT:    pushl %esi
830 ; X86-NEXT:    subl $8, %esp
831 ; X86-NEXT:    movl %ecx, %esi
832 ; X86-NEXT:    calll ret_struct@PLT
833 ; X86-NEXT:    movl %eax, %ecx
834 ; X86-NEXT:    calll t21_f_sret
835 ; X86-NEXT:    movl %esi, %eax
836 ; X86-NEXT:    addl $8, %esp
837 ; X86-NEXT:    popl %esi
838 ; X86-NEXT:    retl
840 ; X64-LABEL: t21_sret_to_sret_arg_mismatch:
841 ; X64:       # %bb.0:
842 ; X64-NEXT:    pushq %rbx
843 ; X64-NEXT:    movq %rdi, %rbx
844 ; X64-NEXT:    callq ret_struct@PLT
845 ; X64-NEXT:    movq %rax, %rdi
846 ; X64-NEXT:    callq t21_f_sret
847 ; X64-NEXT:    movq %rbx, %rax
848 ; X64-NEXT:    popq %rbx
849 ; X64-NEXT:    retq
851 ; X32-LABEL: t21_sret_to_sret_arg_mismatch:
852 ; X32:       # %bb.0:
853 ; X32-NEXT:    pushq %rbx
854 ; X32-NEXT:    movq %rdi, %rbx
855 ; X32-NEXT:    callq ret_struct@PLT
856 ; X32-NEXT:    movl %eax, %edi
857 ; X32-NEXT:    callq t21_f_sret
858 ; X32-NEXT:    movl %ebx, %eax
859 ; X32-NEXT:    popq %rbx
860 ; X32-NEXT:    retq
861   %a = call fastcc ptr @ret_struct()
862   tail call fastcc void @t21_f_sret(ptr noalias sret(%struct.foo) %a) nounwind
863   ret void
866 define fastcc void @t21_sret_to_sret_structs_mismatch(ptr noalias sret(%struct.foo) %agg.result, ptr noalias %a) nounwind  {
867 ; X86-LABEL: t21_sret_to_sret_structs_mismatch:
868 ; X86:       # %bb.0:
869 ; X86-NEXT:    pushl %edi
870 ; X86-NEXT:    pushl %esi
871 ; X86-NEXT:    pushl %eax
872 ; X86-NEXT:    movl %edx, %esi
873 ; X86-NEXT:    movl %ecx, %edi
874 ; X86-NEXT:    calll ret_struct@PLT
875 ; X86-NEXT:    movl %esi, %ecx
876 ; X86-NEXT:    movl %eax, %edx
877 ; X86-NEXT:    calll t21_f_sret2
878 ; X86-NEXT:    movl %edi, %eax
879 ; X86-NEXT:    addl $4, %esp
880 ; X86-NEXT:    popl %esi
881 ; X86-NEXT:    popl %edi
882 ; X86-NEXT:    retl
884 ; X64-LABEL: t21_sret_to_sret_structs_mismatch:
885 ; X64:       # %bb.0:
886 ; X64-NEXT:    pushq %r14
887 ; X64-NEXT:    pushq %rbx
888 ; X64-NEXT:    pushq %rax
889 ; X64-NEXT:    movq %rsi, %rbx
890 ; X64-NEXT:    movq %rdi, %r14
891 ; X64-NEXT:    callq ret_struct@PLT
892 ; X64-NEXT:    movq %rbx, %rdi
893 ; X64-NEXT:    movq %rax, %rsi
894 ; X64-NEXT:    callq t21_f_sret2
895 ; X64-NEXT:    movq %r14, %rax
896 ; X64-NEXT:    addq $8, %rsp
897 ; X64-NEXT:    popq %rbx
898 ; X64-NEXT:    popq %r14
899 ; X64-NEXT:    retq
901 ; X32-LABEL: t21_sret_to_sret_structs_mismatch:
902 ; X32:       # %bb.0:
903 ; X32-NEXT:    pushq %r14
904 ; X32-NEXT:    pushq %rbx
905 ; X32-NEXT:    pushq %rax
906 ; X32-NEXT:    movq %rsi, %rbx
907 ; X32-NEXT:    movq %rdi, %r14
908 ; X32-NEXT:    callq ret_struct@PLT
909 ; X32-NEXT:    movl %eax, %esi
910 ; X32-NEXT:    movq %rbx, %rdi
911 ; X32-NEXT:    callq t21_f_sret2
912 ; X32-NEXT:    movl %r14d, %eax
913 ; X32-NEXT:    addl $8, %esp
914 ; X32-NEXT:    popq %rbx
915 ; X32-NEXT:    popq %r14
916 ; X32-NEXT:    retq
917   %b = call fastcc ptr @ret_struct()
918   tail call fastcc void @t21_f_sret2(ptr noalias sret(%struct.foo) %a, ptr noalias %b) nounwind
919   ret void
922 declare ccc ptr @ret_struct() nounwind
925 define fastcc void @t21_sret_to_non_sret(ptr noalias sret(%struct.foo) %agg.result) nounwind  {
926 ; X86-LABEL: t21_sret_to_non_sret:
927 ; X86:       # %bb.0:
928 ; X86-NEXT:    pushl %esi
929 ; X86-NEXT:    subl $8, %esp
930 ; X86-NEXT:    movl %ecx, %esi
931 ; X86-NEXT:    calll t21_f_non_sret
932 ; X86-NEXT:    movl %esi, %eax
933 ; X86-NEXT:    addl $8, %esp
934 ; X86-NEXT:    popl %esi
935 ; X86-NEXT:    retl
937 ; X64-LABEL: t21_sret_to_non_sret:
938 ; X64:       # %bb.0:
939 ; X64-NEXT:    pushq %rbx
940 ; X64-NEXT:    movq %rdi, %rbx
941 ; X64-NEXT:    callq t21_f_non_sret
942 ; X64-NEXT:    movq %rbx, %rax
943 ; X64-NEXT:    popq %rbx
944 ; X64-NEXT:    retq
946 ; X32-LABEL: t21_sret_to_non_sret:
947 ; X32:       # %bb.0:
948 ; X32-NEXT:    pushq %rbx
949 ; X32-NEXT:    movq %rdi, %rbx
950 ; X32-NEXT:    callq t21_f_non_sret
951 ; X32-NEXT:    movl %ebx, %eax
952 ; X32-NEXT:    popq %rbx
953 ; X32-NEXT:    retq
954   tail call fastcc void @t21_f_non_sret(ptr %agg.result) nounwind
955   ret void
958 define ccc void @t22_non_sret_to_sret(ptr %agg.result) nounwind  {
959 ; i686 not tailcallable, as sret is callee-pop here.
960 ; X86-LABEL: t22_non_sret_to_sret:
961 ; X86:       # %bb.0:
962 ; X86-NEXT:    subl $12, %esp
963 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
964 ; X86-NEXT:    movl %eax, (%esp)
965 ; X86-NEXT:    calll t22_f_sret@PLT
966 ; X86-NEXT:    addl $8, %esp
967 ; X86-NEXT:    retl
969 ; X64-LABEL: t22_non_sret_to_sret:
970 ; X64:       # %bb.0:
971 ; X64-NEXT:    jmp t22_f_sret@PLT # TAILCALL
973 ; X32-LABEL: t22_non_sret_to_sret:
974 ; X32:       # %bb.0:
975 ; X32-NEXT:    jmp t22_f_sret@PLT # TAILCALL
976   tail call ccc void @t22_f_sret(ptr noalias sret(%struct.foo) %agg.result) nounwind
977   ret void
980 declare dso_local fastcc void @t21_f_sret(ptr noalias sret(%struct.foo)) nounwind
981 declare dso_local fastcc void @t21_f_sret2(ptr noalias sret(%struct.foo), ptr noalias) nounwind
982 declare dso_local fastcc void @t21_f_non_sret(ptr) nounwind
984 declare ccc void @t22_f_sret(ptr noalias sret(%struct.foo)) nounwind
986 declare ccc void @f_sret(ptr noalias sret(%struct.foo), i32, i32) nounwind