[Alignment][NFC] Use Align with TargetLowering::setMinFunctionAlignment
[llvm-core.git] / test / CodeGen / X86 / sibcall.ll
blob98e17b1aa601bc90952b9981133ce1e8b1df5db4
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 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 void @foo()
24 define 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 i32 @foo2()
42 define 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 i32 @foo3()
60 define void @t4(void (i32)* 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:    movl %edi, %eax
78 ; X32-NEXT:    xorl %edi, %edi
79 ; X32-NEXT:    jmpq *%rax # TAILCALL
80   tail call void %x(i32 0) nounwind
81   ret void
84 ; FIXME: This isn't needed since x32 psABI specifies that callers must
85 ;        zero-extend pointers passed in registers.
87 define void @t5(void ()* nocapture %x) nounwind ssp {
88 ; X86-LABEL: t5:
89 ; X86:       # %bb.0:
90 ; X86-NEXT:    jmpl *{{[0-9]+}}(%esp) # TAILCALL
92 ; X64-LABEL: t5:
93 ; X64:       # %bb.0:
94 ; X64-NEXT:    jmpq *%rdi # TAILCALL
96 ; X32-LABEL: t5:
97 ; X32:       # %bb.0:
98 ; X32-NEXT:    movl %edi, %eax
99 ; X32-NEXT:    jmpq *%rax # TAILCALL
100   tail call void %x() nounwind
101   ret void
104 ; Basically the same test as t5, except pass the function pointer on the stack
105 ; for x86_64.
107 define void @t5_x64(i32, i32, i32, i32, i32, i32, void ()* nocapture %x) nounwind ssp {
108 ; X86-LABEL: t5_x64:
109 ; X86:       # %bb.0:
110 ; X86-NEXT:    jmpl *{{[0-9]+}}(%esp) # TAILCALL
112 ; X64-LABEL: t5_x64:
113 ; X64:       # %bb.0:
114 ; X64-NEXT:    jmpq *{{[0-9]+}}(%rsp) # TAILCALL
116 ; X32-LABEL: t5_x64:
117 ; X32:       # %bb.0:
118 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
119 ; X32-NEXT:    jmpq *%rax # TAILCALL
120   tail call void %x() nounwind
121   ret void
125 define i32 @t6(i32 %x) nounwind ssp {
126 ; X86-LABEL: t6:
127 ; X86:       # %bb.0:
128 ; X86-NEXT:    subl $12, %esp
129 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
130 ; X86-NEXT:    cmpl $9, %eax
131 ; X86-NEXT:    jg .LBB6_2
132 ; X86-NEXT:  # %bb.1: # %bb
133 ; X86-NEXT:    decl %eax
134 ; X86-NEXT:    movl %eax, (%esp)
135 ; X86-NEXT:    calll t6
136 ; X86-NEXT:    addl $12, %esp
137 ; X86-NEXT:    retl
138 ; X86-NEXT:  .LBB6_2: # %bb1
139 ; X86-NEXT:    addl $12, %esp
140 ; X86-NEXT:    jmp bar # TAILCALL
142 ; X64-LABEL: t6:
143 ; X64:       # %bb.0:
144 ; X64-NEXT:    cmpl $9, %edi
145 ; X64-NEXT:    jg .LBB6_2
146 ; X64-NEXT:  # %bb.1: # %bb
147 ; X64-NEXT:    decl %edi
148 ; X64-NEXT:    jmp t6 # TAILCALL
149 ; X64-NEXT:  .LBB6_2: # %bb1
150 ; X64-NEXT:    jmp bar # TAILCALL
152 ; X32-LABEL: t6:
153 ; X32:       # %bb.0:
154 ; X32-NEXT:    cmpl $9, %edi
155 ; X32-NEXT:    jg .LBB6_2
156 ; X32-NEXT:  # %bb.1: # %bb
157 ; X32-NEXT:    decl %edi
158 ; X32-NEXT:    jmp t6 # TAILCALL
159 ; X32-NEXT:  .LBB6_2: # %bb1
160 ; X32-NEXT:    jmp bar # TAILCALL
161   %t0 = icmp slt i32 %x, 10
162   br i1 %t0, label %bb, label %bb1
165   %t1 = add nsw i32 %x, -1
166   %t2 = tail call i32 @t6(i32 %t1) nounwind ssp
167   ret i32 %t2
169 bb1:
170   %t3 = tail call i32 @bar(i32 %x) nounwind
171   ret i32 %t3
174 declare i32 @bar(i32)
176 define i32 @t7(i32 %a, i32 %b, i32 %c) nounwind ssp {
177 ; X86-LABEL: t7:
178 ; X86:       # %bb.0:
179 ; X86-NEXT:    jmp bar2 # TAILCALL
181 ; X64-LABEL: t7:
182 ; X64:       # %bb.0:
183 ; X64-NEXT:    jmp bar2 # TAILCALL
185 ; X32-LABEL: t7:
186 ; X32:       # %bb.0:
187 ; X32-NEXT:    jmp bar2 # TAILCALL
188   %t0 = tail call i32 @bar2(i32 %a, i32 %b, i32 %c) nounwind
189   ret i32 %t0
192 declare i32 @bar2(i32, i32, i32)
194 define signext i16 @t8() nounwind ssp {
195 ; X86-LABEL: t8:
196 ; X86:       # %bb.0: # %entry
197 ; X86-NEXT:    jmp bar3 # TAILCALL
199 ; X64-LABEL: t8:
200 ; X64:       # %bb.0: # %entry
201 ; X64-NEXT:    jmp bar3 # TAILCALL
203 ; X32-LABEL: t8:
204 ; X32:       # %bb.0: # %entry
205 ; X32-NEXT:    jmp bar3 # TAILCALL
206 entry:
207   %0 = tail call signext i16 @bar3() nounwind      ; <i16> [#uses=1]
208   ret i16 %0
211 declare signext i16 @bar3()
213 define signext i16 @t9(i32 (i32)* nocapture %x) nounwind ssp {
214 ; X86-LABEL: t9:
215 ; X86:       # %bb.0: # %entry
216 ; X86-NEXT:    subl $12, %esp
217 ; X86-NEXT:    movl $0, (%esp)
218 ; X86-NEXT:    calll *{{[0-9]+}}(%esp)
219 ; X86-NEXT:    addl $12, %esp
220 ; X86-NEXT:    retl
222 ; X64-LABEL: t9:
223 ; X64:       # %bb.0: # %entry
224 ; X64-NEXT:    movq %rdi, %rax
225 ; X64-NEXT:    xorl %edi, %edi
226 ; X64-NEXT:    jmpq *%rax # TAILCALL
228 ; X32-LABEL: t9:
229 ; X32:       # %bb.0: # %entry
230 ; X32-NEXT:    movl %edi, %eax
231 ; X32-NEXT:    xorl %edi, %edi
232 ; X32-NEXT:    jmpq *%rax # TAILCALL
233 entry:
234   %0 = bitcast i32 (i32)* %x to i16 (i32)*
235   %1 = tail call signext i16 %0(i32 0) nounwind
236   ret i16 %1
239 define void @t10() nounwind ssp {
240 ; X86-LABEL: t10:
241 ; X86:       # %bb.0: # %entry
242 ; X86-NEXT:    subl $12, %esp
243 ; X86-NEXT:    calll foo4
245 ; X64-LABEL: t10:
246 ; X64:       # %bb.0: # %entry
247 ; X64-NEXT:    pushq %rax
248 ; X64-NEXT:    callq foo4
250 ; X32-LABEL: t10:
251 ; X32:       # %bb.0: # %entry
252 ; X32-NEXT:    pushq %rax
253 ; X32-NEXT:    callq foo4
254 entry:
255   %0 = tail call i32 @foo4() noreturn nounwind
256   unreachable
259 declare i32 @foo4()
261 ; In 32-bit mode, it's emitting a bunch of dead loads that are not being
262 ; eliminated currently.
264 define i32 @t11(i32 %x, i32 %y, i32 %z.0, i32 %z.1, i32 %z.2) nounwind ssp {
265 ; X86-LABEL: t11:
266 ; X86:       # %bb.0: # %entry
267 ; X86-NEXT:    cmpl $0, {{[0-9]+}}(%esp)
268 ; X86-NEXT:    je .LBB11_1
269 ; X86-NEXT:  # %bb.2: # %bb
270 ; X86-NEXT:    jmp foo5 # TAILCALL
271 ; X86-NEXT:  .LBB11_1: # %bb6
272 ; X86-NEXT:    xorl %eax, %eax
273 ; X86-NEXT:    retl
275 ; X64-LABEL: t11:
276 ; X64:       # %bb.0: # %entry
277 ; X64-NEXT:    testl %edi, %edi
278 ; X64-NEXT:    je .LBB11_1
279 ; X64-NEXT:  # %bb.2: # %bb
280 ; X64-NEXT:    jmp foo5 # TAILCALL
281 ; X64-NEXT:  .LBB11_1: # %bb6
282 ; X64-NEXT:    xorl %eax, %eax
283 ; X64-NEXT:    retq
285 ; X32-LABEL: t11:
286 ; X32:       # %bb.0: # %entry
287 ; X32-NEXT:    testl %edi, %edi
288 ; X32-NEXT:    je .LBB11_1
289 ; X32-NEXT:  # %bb.2: # %bb
290 ; X32-NEXT:    jmp foo5 # TAILCALL
291 ; X32-NEXT:  .LBB11_1: # %bb6
292 ; X32-NEXT:    xorl %eax, %eax
293 ; X32-NEXT:    retq
294 entry:
295   %0 = icmp eq i32 %x, 0
296   br i1 %0, label %bb6, label %bb
299   %1 = tail call i32 @foo5(i32 %x, i32 %y, i32 %z.0, i32 %z.1, i32 %z.2) nounwind
300   ret i32 %1
302 bb6:
303   ret i32 0
306 declare i32 @foo5(i32, i32, i32, i32, i32)
308 %struct.t = type { i32, i32, i32, i32, i32 }
310 define i32 @t12(i32 %x, i32 %y, %struct.t* byval align 4 %z) nounwind ssp {
311 ; X86-LABEL: t12:
312 ; X86:       # %bb.0: # %entry
313 ; X86-NEXT:    cmpl $0, {{[0-9]+}}(%esp)
314 ; X86-NEXT:    je .LBB12_1
315 ; X86-NEXT:  # %bb.2: # %bb
316 ; X86-NEXT:    jmp foo6 # TAILCALL
317 ; X86-NEXT:  .LBB12_1: # %bb2
318 ; X86-NEXT:    xorl %eax, %eax
319 ; X86-NEXT:    retl
321 ; X64-LABEL: t12:
322 ; X64:       # %bb.0: # %entry
323 ; X64-NEXT:    testl %edi, %edi
324 ; X64-NEXT:    je .LBB12_1
325 ; X64-NEXT:  # %bb.2: # %bb
326 ; X64-NEXT:    jmp foo6 # TAILCALL
327 ; X64-NEXT:  .LBB12_1: # %bb2
328 ; X64-NEXT:    xorl %eax, %eax
329 ; X64-NEXT:    retq
331 ; X32-LABEL: t12:
332 ; X32:       # %bb.0: # %entry
333 ; X32-NEXT:    testl %edi, %edi
334 ; X32-NEXT:    je .LBB12_1
335 ; X32-NEXT:  # %bb.2: # %bb
336 ; X32-NEXT:    jmp foo6 # TAILCALL
337 ; X32-NEXT:  .LBB12_1: # %bb2
338 ; X32-NEXT:    xorl %eax, %eax
339 ; X32-NEXT:    retq
340 entry:
341   %0 = icmp eq i32 %x, 0
342   br i1 %0, label %bb2, label %bb
345   %1 = tail call i32 @foo6(i32 %x, i32 %y, %struct.t* byval align 4 %z) nounwind
346   ret i32 %1
348 bb2:
349   ret i32 0
352 declare i32 @foo6(i32, i32, %struct.t* byval align 4)
354 ; rdar://r7717598
355 %struct.ns = type { i32, i32 }
356 %struct.cp = type { float, float, float, float, float }
358 define %struct.ns* @t13(%struct.cp* %yy) nounwind ssp {
359 ; X86-LABEL: t13:
360 ; X86:       # %bb.0: # %entry
361 ; X86-NEXT:    subl $28, %esp
362 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
363 ; X86-NEXT:    movl 16(%eax), %ecx
364 ; X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
365 ; X86-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
366 ; X86-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
367 ; X86-NEXT:    movsd %xmm1, {{[0-9]+}}(%esp)
368 ; X86-NEXT:    movsd %xmm0, (%esp)
369 ; X86-NEXT:    xorl %ecx, %ecx
370 ; X86-NEXT:    calll foo7
371 ; X86-NEXT:    addl $28, %esp
372 ; X86-NEXT:    retl
374 ; X64-LABEL: t13:
375 ; X64:       # %bb.0: # %entry
376 ; X64-NEXT:    pushq %rax
377 ; X64-NEXT:    subq $8, %rsp
378 ; X64-NEXT:    movl 16(%rdi), %eax
379 ; X64-NEXT:    movq (%rdi), %rcx
380 ; X64-NEXT:    movq 8(%rdi), %rdx
381 ; X64-NEXT:    xorl %edi, %edi
382 ; X64-NEXT:    pushq %rax
383 ; X64-NEXT:    pushq %rdx
384 ; X64-NEXT:    pushq %rcx
385 ; X64-NEXT:    callq foo7
386 ; X64-NEXT:    addq $32, %rsp
387 ; X64-NEXT:    popq %rcx
388 ; X64-NEXT:    retq
390 ; X32-LABEL: t13:
391 ; X32:       # %bb.0: # %entry
392 ; X32-NEXT:    pushq %rax
393 ; X32-NEXT:    subl $8, %esp
394 ; X32-NEXT:    movl 16(%edi), %eax
395 ; X32-NEXT:    movq (%edi), %rcx
396 ; X32-NEXT:    movq 8(%edi), %rdx
397 ; X32-NEXT:    xorl %edi, %edi
398 ; X32-NEXT:    pushq %rax
399 ; X32-NEXT:    pushq %rdx
400 ; X32-NEXT:    pushq %rcx
401 ; X32-NEXT:    callq foo7
402 ; X32-NEXT:    addl $32, %esp
403 ; X32-NEXT:    popq %rcx
404 ; X32-NEXT:    retq
405 entry:
406   %0 = tail call fastcc %struct.ns* @foo7(%struct.cp* byval align 4 %yy, i8 signext 0) nounwind
407   ret %struct.ns* %0
410 ; rdar://6195379
411 ; llvm can't do sibcall for this in 32-bit mode (yet).
412 declare fastcc %struct.ns* @foo7(%struct.cp* byval align 4, i8 signext) nounwind ssp
414 %struct.__block_descriptor = type { i64, i64 }
415 %struct.__block_descriptor_withcopydispose = type { i64, i64, i8*, i8* }
416 %struct.__block_literal_1 = type { i8*, i32, i32, i8*, %struct.__block_descriptor* }
417 %struct.__block_literal_2 = type { i8*, i32, i32, i8*, %struct.__block_descriptor_withcopydispose*, void ()* }
419 define void @t14(%struct.__block_literal_2* nocapture %.block_descriptor) nounwind ssp {
420 ; X86-LABEL: t14:
421 ; X86:       # %bb.0: # %entry
422 ; X86-NEXT:    subl $12, %esp
423 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
424 ; X86-NEXT:    movl 20(%eax), %eax
425 ; X86-NEXT:    movl %eax, (%esp)
426 ; X86-NEXT:    calll *12(%eax)
427 ; X86-NEXT:    addl $12, %esp
428 ; X86-NEXT:    retl
430 ; X64-LABEL: t14:
431 ; X64:       # %bb.0: # %entry
432 ; X64-NEXT:    movq 32(%rdi), %rdi
433 ; X64-NEXT:    jmpq *16(%rdi) # TAILCALL
435 ; X32-LABEL: t14:
436 ; X32:       # %bb.0: # %entry
437 ; X32-NEXT:    movl 20(%edi), %edi
438 ; X32-NEXT:    movl 12(%edi), %eax
439 ; X32-NEXT:    jmpq *%rax # TAILCALL
440 entry:
441   %0 = getelementptr inbounds %struct.__block_literal_2, %struct.__block_literal_2* %.block_descriptor, i64 0, i32 5 ; <void ()**> [#uses=1]
442   %1 = load void ()*, void ()** %0, align 8                 ; <void ()*> [#uses=2]
443   %2 = bitcast void ()* %1 to %struct.__block_literal_1* ; <%struct.__block_literal_1*> [#uses=1]
444   %3 = getelementptr inbounds %struct.__block_literal_1, %struct.__block_literal_1* %2, i64 0, i32 3 ; <i8**> [#uses=1]
445   %4 = load i8*, i8** %3, align 8                      ; <i8*> [#uses=1]
446   %5 = bitcast i8* %4 to void (i8*)*              ; <void (i8*)*> [#uses=1]
447   %6 = bitcast void ()* %1 to i8*                 ; <i8*> [#uses=1]
448   tail call void %5(i8* %6) nounwind
449   ret void
452 ; rdar://7726868
453 %struct.foo = type { [4 x i32] }
455 define void @t15(%struct.foo* noalias sret %agg.result) nounwind  {
456 ; X86-LABEL: t15:
457 ; X86:       # %bb.0:
458 ; X86-NEXT:    pushl %esi
459 ; X86-NEXT:    subl $8, %esp
460 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
461 ; X86-NEXT:    movl %esi, %ecx
462 ; X86-NEXT:    calll f
463 ; X86-NEXT:    movl %esi, %eax
464 ; X86-NEXT:    addl $8, %esp
465 ; X86-NEXT:    popl %esi
466 ; X86-NEXT:    retl $4
468 ; X64-LABEL: t15:
469 ; X64:       # %bb.0:
470 ; X64-NEXT:    pushq %rbx
471 ; X64-NEXT:    movq %rdi, %rbx
472 ; X64-NEXT:    callq f
473 ; X64-NEXT:    movq %rbx, %rax
474 ; X64-NEXT:    popq %rbx
475 ; X64-NEXT:    retq
477 ; X32-LABEL: t15:
478 ; X32:       # %bb.0:
479 ; X32-NEXT:    pushq %rbx
480 ; X32-NEXT:    movl %edi, %ebx
481 ; X32-NEXT:    callq f
482 ; X32-NEXT:    movl %ebx, %eax
483 ; X32-NEXT:    popq %rbx
484 ; X32-NEXT:    retq
485   tail call fastcc void @f(%struct.foo* noalias sret %agg.result) nounwind
486   ret void
489 declare void @f(%struct.foo* noalias sret) nounwind
491 define void @t16() nounwind ssp {
492 ; X86-LABEL: t16:
493 ; X86:       # %bb.0: # %entry
494 ; X86-NEXT:    subl $12, %esp
495 ; X86-NEXT:    calll bar4
496 ; X86-NEXT:    fstp %st(0)
497 ; X86-NEXT:    addl $12, %esp
498 ; X86-NEXT:    retl
500 ; X64-LABEL: t16:
501 ; X64:       # %bb.0: # %entry
502 ; X64-NEXT:    jmp bar4 # TAILCALL
504 ; X32-LABEL: t16:
505 ; X32:       # %bb.0: # %entry
506 ; X32-NEXT:    jmp bar4 # TAILCALL
507 entry:
508   %0 = tail call double @bar4() nounwind
509   ret void
512 declare double @bar4()
514 ; rdar://6283267
515 define void @t17() nounwind ssp {
516 ; X86-LABEL: t17:
517 ; X86:       # %bb.0: # %entry
518 ; X86-NEXT:    jmp bar5 # TAILCALL
520 ; X64-LABEL: t17:
521 ; X64:       # %bb.0: # %entry
522 ; X64-NEXT:    xorl %eax, %eax
523 ; X64-NEXT:    jmp bar5 # TAILCALL
525 ; X32-LABEL: t17:
526 ; X32:       # %bb.0: # %entry
527 ; X32-NEXT:    xorl %eax, %eax
528 ; X32-NEXT:    jmp bar5 # TAILCALL
529 entry:
530   tail call void (...) @bar5() nounwind
531   ret void
534 declare void @bar5(...)
536 ; rdar://7774847
537 define void @t18() nounwind ssp {
538 ; X86-LABEL: t18:
539 ; X86:       # %bb.0: # %entry
540 ; X86-NEXT:    subl $12, %esp
541 ; X86-NEXT:    calll bar6
542 ; X86-NEXT:    fstp %st(0)
543 ; X86-NEXT:    addl $12, %esp
544 ; X86-NEXT:    retl
546 ; X64-LABEL: t18:
547 ; X64:       # %bb.0: # %entry
548 ; X64-NEXT:    xorl %eax, %eax
549 ; X64-NEXT:    jmp bar6 # TAILCALL
551 ; X32-LABEL: t18:
552 ; X32:       # %bb.0: # %entry
553 ; X32-NEXT:    xorl %eax, %eax
554 ; X32-NEXT:    jmp bar6 # TAILCALL
555 entry:
556   %0 = tail call double (...) @bar6() nounwind
557   ret void
560 declare double @bar6(...)
562 define void @t19() alignstack(32) nounwind {
563 ; X86-LABEL: t19:
564 ; X86:       # %bb.0: # %entry
565 ; X86-NEXT:    pushl %ebp
566 ; X86-NEXT:    movl %esp, %ebp
567 ; X86-NEXT:    andl $-32, %esp
568 ; X86-NEXT:    subl $32, %esp
569 ; X86-NEXT:    calll foo
570 ; X86-NEXT:    movl %ebp, %esp
571 ; X86-NEXT:    popl %ebp
572 ; X86-NEXT:    retl
574 ; X64-LABEL: t19:
575 ; X64:       # %bb.0: # %entry
576 ; X64-NEXT:    pushq %rbp
577 ; X64-NEXT:    movq %rsp, %rbp
578 ; X64-NEXT:    andq $-32, %rsp
579 ; X64-NEXT:    subq $32, %rsp
580 ; X64-NEXT:    callq foo
581 ; X64-NEXT:    movq %rbp, %rsp
582 ; X64-NEXT:    popq %rbp
583 ; X64-NEXT:    retq
585 ; X32-LABEL: t19:
586 ; X32:       # %bb.0: # %entry
587 ; X32-NEXT:    pushq %rbp
588 ; X32-NEXT:    movl %esp, %ebp
589 ; X32-NEXT:    andl $-32, %esp
590 ; X32-NEXT:    subl $32, %esp
591 ; X32-NEXT:    callq foo
592 ; X32-NEXT:    movl %ebp, %esp
593 ; X32-NEXT:    popq %rbp
594 ; X32-NEXT:    retq
595 entry:
596   tail call void @foo() nounwind
597   ret void
600 ; If caller / callee calling convention mismatch then check if the return
601 ; values are returned in the same registers.
602 ; rdar://7874780
604 define double @t20(double %x) nounwind {
605 ; X86-LABEL: t20:
606 ; X86:       # %bb.0: # %entry
607 ; X86-NEXT:    subl $12, %esp
608 ; X86-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
609 ; X86-NEXT:    calll foo20
610 ; X86-NEXT:    movsd %xmm0, (%esp)
611 ; X86-NEXT:    fldl (%esp)
612 ; X86-NEXT:    addl $12, %esp
613 ; X86-NEXT:    retl
615 ; X64-LABEL: t20:
616 ; X64:       # %bb.0: # %entry
617 ; X64-NEXT:    jmp foo20 # TAILCALL
619 ; X32-LABEL: t20:
620 ; X32:       # %bb.0: # %entry
621 ; X32-NEXT:    jmp foo20 # TAILCALL
622 entry:
623   %0 = tail call fastcc double @foo20(double %x) nounwind
624   ret double %0
627 declare fastcc double @foo20(double) nounwind
629 ; bug 28417
630 define fastcc void @t21_sret_to_sret(%struct.foo* noalias sret %agg.result) nounwind  {
631 ; X86-LABEL: t21_sret_to_sret:
632 ; X86:       # %bb.0:
633 ; X86-NEXT:    pushl %esi
634 ; X86-NEXT:    subl $8, %esp
635 ; X86-NEXT:    movl %ecx, %esi
636 ; X86-NEXT:    calll t21_f_sret
637 ; X86-NEXT:    movl %esi, %eax
638 ; X86-NEXT:    addl $8, %esp
639 ; X86-NEXT:    popl %esi
640 ; X86-NEXT:    retl
642 ; X64-LABEL: t21_sret_to_sret:
643 ; X64:       # %bb.0:
644 ; X64-NEXT:    pushq %rbx
645 ; X64-NEXT:    movq %rdi, %rbx
646 ; X64-NEXT:    callq t21_f_sret
647 ; X64-NEXT:    movq %rbx, %rax
648 ; X64-NEXT:    popq %rbx
649 ; X64-NEXT:    retq
651 ; X32-LABEL: t21_sret_to_sret:
652 ; X32:       # %bb.0:
653 ; X32-NEXT:    pushq %rbx
654 ; X32-NEXT:    movl %edi, %ebx
655 ; X32-NEXT:    callq t21_f_sret
656 ; X32-NEXT:    movl %ebx, %eax
657 ; X32-NEXT:    popq %rbx
658 ; X32-NEXT:    retq
659   tail call fastcc void @t21_f_sret(%struct.foo* noalias sret %agg.result) nounwind
660   ret void
663 define fastcc void @t21_sret_to_sret_alloca(%struct.foo* noalias sret %agg.result) nounwind  {
664 ; X86-LABEL: t21_sret_to_sret_alloca:
665 ; X86:       # %bb.0:
666 ; X86-NEXT:    pushl %esi
667 ; X86-NEXT:    subl $24, %esp
668 ; X86-NEXT:    movl %ecx, %esi
669 ; X86-NEXT:    leal {{[0-9]+}}(%esp), %ecx
670 ; X86-NEXT:    calll t21_f_sret
671 ; X86-NEXT:    movl %esi, %eax
672 ; X86-NEXT:    addl $24, %esp
673 ; X86-NEXT:    popl %esi
674 ; X86-NEXT:    retl
676 ; X64-LABEL: t21_sret_to_sret_alloca:
677 ; X64:       # %bb.0:
678 ; X64-NEXT:    pushq %rbx
679 ; X64-NEXT:    subq $16, %rsp
680 ; X64-NEXT:    movq %rdi, %rbx
681 ; X64-NEXT:    movq %rsp, %rdi
682 ; X64-NEXT:    callq t21_f_sret
683 ; X64-NEXT:    movq %rbx, %rax
684 ; X64-NEXT:    addq $16, %rsp
685 ; X64-NEXT:    popq %rbx
686 ; X64-NEXT:    retq
688 ; X32-LABEL: t21_sret_to_sret_alloca:
689 ; X32:       # %bb.0:
690 ; X32-NEXT:    pushq %rbx
691 ; X32-NEXT:    subl $16, %esp
692 ; X32-NEXT:    movl %edi, %ebx
693 ; X32-NEXT:    movl %esp, %edi
694 ; X32-NEXT:    callq t21_f_sret
695 ; X32-NEXT:    movl %ebx, %eax
696 ; X32-NEXT:    addl $16, %esp
697 ; X32-NEXT:    popq %rbx
698 ; X32-NEXT:    retq
699   %a = alloca %struct.foo, align 8
700   tail call fastcc void @t21_f_sret(%struct.foo* noalias sret %a) nounwind
701   ret void
704 define fastcc void @t21_sret_to_sret_more_args(%struct.foo* noalias sret %agg.result, i32 %a, i32 %b) nounwind  {
705 ; X86-LABEL: t21_sret_to_sret_more_args:
706 ; X86:       # %bb.0:
707 ; X86-NEXT:    pushl %esi
708 ; X86-NEXT:    subl $8, %esp
709 ; X86-NEXT:    movl %ecx, %esi
710 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
711 ; X86-NEXT:    movl %eax, (%esp)
712 ; X86-NEXT:    calll f_sret
713 ; X86-NEXT:    movl %esi, %eax
714 ; X86-NEXT:    addl $8, %esp
715 ; X86-NEXT:    popl %esi
716 ; X86-NEXT:    retl
718 ; X64-LABEL: t21_sret_to_sret_more_args:
719 ; X64:       # %bb.0:
720 ; X64-NEXT:    pushq %rbx
721 ; X64-NEXT:    movq %rdi, %rbx
722 ; X64-NEXT:    callq f_sret
723 ; X64-NEXT:    movq %rbx, %rax
724 ; X64-NEXT:    popq %rbx
725 ; X64-NEXT:    retq
727 ; X32-LABEL: t21_sret_to_sret_more_args:
728 ; X32:       # %bb.0:
729 ; X32-NEXT:    pushq %rbx
730 ; X32-NEXT:    movl %edi, %ebx
731 ; X32-NEXT:    callq f_sret
732 ; X32-NEXT:    movl %ebx, %eax
733 ; X32-NEXT:    popq %rbx
734 ; X32-NEXT:    retq
735   tail call fastcc void @f_sret(%struct.foo* noalias sret %agg.result, i32 %a, i32 %b) nounwind
736   ret void
739 define fastcc void @t21_sret_to_sret_second_arg_sret(%struct.foo* noalias %agg.result, %struct.foo* noalias sret %ret) nounwind  {
740 ; X86-LABEL: t21_sret_to_sret_second_arg_sret:
741 ; X86:       # %bb.0:
742 ; X86-NEXT:    pushl %esi
743 ; X86-NEXT:    subl $8, %esp
744 ; X86-NEXT:    movl %edx, %esi
745 ; X86-NEXT:    movl %edx, %ecx
746 ; X86-NEXT:    calll t21_f_sret
747 ; X86-NEXT:    movl %esi, %eax
748 ; X86-NEXT:    addl $8, %esp
749 ; X86-NEXT:    popl %esi
750 ; X86-NEXT:    retl
752 ; X64-LABEL: t21_sret_to_sret_second_arg_sret:
753 ; X64:       # %bb.0:
754 ; X64-NEXT:    pushq %rbx
755 ; X64-NEXT:    movq %rsi, %rbx
756 ; X64-NEXT:    movq %rsi, %rdi
757 ; X64-NEXT:    callq t21_f_sret
758 ; X64-NEXT:    movq %rbx, %rax
759 ; X64-NEXT:    popq %rbx
760 ; X64-NEXT:    retq
762 ; X32-LABEL: t21_sret_to_sret_second_arg_sret:
763 ; X32:       # %bb.0:
764 ; X32-NEXT:    pushq %rbx
765 ; X32-NEXT:    movl %esi, %ebx
766 ; X32-NEXT:    movl %esi, %edi
767 ; X32-NEXT:    callq t21_f_sret
768 ; X32-NEXT:    movl %ebx, %eax
769 ; X32-NEXT:    popq %rbx
770 ; X32-NEXT:    retq
771   tail call fastcc void @t21_f_sret(%struct.foo* noalias sret %ret) nounwind
772   ret void
775 define fastcc void @t21_sret_to_sret_more_args2(%struct.foo* noalias sret %agg.result, i32 %a, i32 %b) nounwind  {
776 ; X86-LABEL: t21_sret_to_sret_more_args2:
777 ; X86:       # %bb.0:
778 ; X86-NEXT:    pushl %esi
779 ; X86-NEXT:    subl $8, %esp
780 ; X86-NEXT:    movl %ecx, %esi
781 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
782 ; X86-NEXT:    movl %edx, (%esp)
783 ; X86-NEXT:    movl %eax, %edx
784 ; X86-NEXT:    calll f_sret
785 ; X86-NEXT:    movl %esi, %eax
786 ; X86-NEXT:    addl $8, %esp
787 ; X86-NEXT:    popl %esi
788 ; X86-NEXT:    retl
790 ; X64-LABEL: t21_sret_to_sret_more_args2:
791 ; X64:       # %bb.0:
792 ; X64-NEXT:    pushq %rbx
793 ; X64-NEXT:    movl %esi, %eax
794 ; X64-NEXT:    movq %rdi, %rbx
795 ; X64-NEXT:    movl %edx, %esi
796 ; X64-NEXT:    movl %eax, %edx
797 ; X64-NEXT:    callq f_sret
798 ; X64-NEXT:    movq %rbx, %rax
799 ; X64-NEXT:    popq %rbx
800 ; X64-NEXT:    retq
802 ; X32-LABEL: t21_sret_to_sret_more_args2:
803 ; X32:       # %bb.0:
804 ; X32-NEXT:    pushq %rbx
805 ; X32-NEXT:    movl %esi, %eax
806 ; X32-NEXT:    movl %edi, %ebx
807 ; X32-NEXT:    movl %edx, %esi
808 ; X32-NEXT:    movl %eax, %edx
809 ; X32-NEXT:    callq f_sret
810 ; X32-NEXT:    movl %ebx, %eax
811 ; X32-NEXT:    popq %rbx
812 ; X32-NEXT:    retq
813   tail call fastcc void @f_sret(%struct.foo* noalias sret %agg.result, i32 %b, i32 %a) nounwind
814   ret void
818 define fastcc void @t21_sret_to_sret_args_mismatch(%struct.foo* noalias sret %agg.result, %struct.foo* noalias %ret) nounwind  {
819 ; X86-LABEL: t21_sret_to_sret_args_mismatch:
820 ; X86:       # %bb.0:
821 ; X86-NEXT:    pushl %esi
822 ; X86-NEXT:    subl $8, %esp
823 ; X86-NEXT:    movl %ecx, %esi
824 ; X86-NEXT:    movl %edx, %ecx
825 ; X86-NEXT:    calll t21_f_sret
826 ; X86-NEXT:    movl %esi, %eax
827 ; X86-NEXT:    addl $8, %esp
828 ; X86-NEXT:    popl %esi
829 ; X86-NEXT:    retl
831 ; X64-LABEL: t21_sret_to_sret_args_mismatch:
832 ; X64:       # %bb.0:
833 ; X64-NEXT:    pushq %rbx
834 ; X64-NEXT:    movq %rdi, %rbx
835 ; X64-NEXT:    movq %rsi, %rdi
836 ; X64-NEXT:    callq t21_f_sret
837 ; X64-NEXT:    movq %rbx, %rax
838 ; X64-NEXT:    popq %rbx
839 ; X64-NEXT:    retq
841 ; X32-LABEL: t21_sret_to_sret_args_mismatch:
842 ; X32:       # %bb.0:
843 ; X32-NEXT:    pushq %rbx
844 ; X32-NEXT:    movl %edi, %ebx
845 ; X32-NEXT:    movl %esi, %edi
846 ; X32-NEXT:    callq t21_f_sret
847 ; X32-NEXT:    movl %ebx, %eax
848 ; X32-NEXT:    popq %rbx
849 ; X32-NEXT:    retq
850   tail call fastcc void @t21_f_sret(%struct.foo* noalias sret %ret) nounwind
851   ret void
854 define fastcc void @t21_sret_to_sret_args_mismatch2(%struct.foo* noalias sret %agg.result, %struct.foo* noalias %ret) nounwind  {
855 ; X86-LABEL: t21_sret_to_sret_args_mismatch2:
856 ; X86:       # %bb.0:
857 ; X86-NEXT:    pushl %esi
858 ; X86-NEXT:    subl $8, %esp
859 ; X86-NEXT:    movl %ecx, %esi
860 ; X86-NEXT:    movl %edx, %ecx
861 ; X86-NEXT:    calll t21_f_sret
862 ; X86-NEXT:    movl %esi, %eax
863 ; X86-NEXT:    addl $8, %esp
864 ; X86-NEXT:    popl %esi
865 ; X86-NEXT:    retl
867 ; X64-LABEL: t21_sret_to_sret_args_mismatch2:
868 ; X64:       # %bb.0:
869 ; X64-NEXT:    pushq %rbx
870 ; X64-NEXT:    movq %rdi, %rbx
871 ; X64-NEXT:    movq %rsi, %rdi
872 ; X64-NEXT:    callq t21_f_sret
873 ; X64-NEXT:    movq %rbx, %rax
874 ; X64-NEXT:    popq %rbx
875 ; X64-NEXT:    retq
877 ; X32-LABEL: t21_sret_to_sret_args_mismatch2:
878 ; X32:       # %bb.0:
879 ; X32-NEXT:    pushq %rbx
880 ; X32-NEXT:    movl %edi, %ebx
881 ; X32-NEXT:    movl %esi, %edi
882 ; X32-NEXT:    callq t21_f_sret
883 ; X32-NEXT:    movl %ebx, %eax
884 ; X32-NEXT:    popq %rbx
885 ; X32-NEXT:    retq
886   tail call fastcc void @t21_f_sret(%struct.foo* noalias sret %ret) nounwind
887   ret void
890 define fastcc void @t21_sret_to_sret_arg_mismatch(%struct.foo* noalias sret %agg.result) nounwind  {
891 ; X86-LABEL: t21_sret_to_sret_arg_mismatch:
892 ; X86:       # %bb.0:
893 ; X86-NEXT:    pushl %esi
894 ; X86-NEXT:    subl $8, %esp
895 ; X86-NEXT:    movl %ecx, %esi
896 ; X86-NEXT:    calll ret_struct
897 ; X86-NEXT:    movl %eax, %ecx
898 ; X86-NEXT:    calll t21_f_sret
899 ; X86-NEXT:    movl %esi, %eax
900 ; X86-NEXT:    addl $8, %esp
901 ; X86-NEXT:    popl %esi
902 ; X86-NEXT:    retl
904 ; X64-LABEL: t21_sret_to_sret_arg_mismatch:
905 ; X64:       # %bb.0:
906 ; X64-NEXT:    pushq %rbx
907 ; X64-NEXT:    movq %rdi, %rbx
908 ; X64-NEXT:    callq ret_struct
909 ; X64-NEXT:    movq %rax, %rdi
910 ; X64-NEXT:    callq t21_f_sret
911 ; X64-NEXT:    movq %rbx, %rax
912 ; X64-NEXT:    popq %rbx
913 ; X64-NEXT:    retq
915 ; X32-LABEL: t21_sret_to_sret_arg_mismatch:
916 ; X32:       # %bb.0:
917 ; X32-NEXT:    pushq %rbx
918 ; X32-NEXT:    movl %edi, %ebx
919 ; X32-NEXT:    callq ret_struct
920 ; X32-NEXT:    movl %eax, %edi
921 ; X32-NEXT:    callq t21_f_sret
922 ; X32-NEXT:    movl %ebx, %eax
923 ; X32-NEXT:    popq %rbx
924 ; X32-NEXT:    retq
925   %a = call fastcc %struct.foo* @ret_struct()
926   tail call fastcc void @t21_f_sret(%struct.foo* noalias sret %a) nounwind
927   ret void
930 define fastcc void @t21_sret_to_sret_structs_mismatch(%struct.foo* noalias sret %agg.result, %struct.foo* noalias %a) nounwind  {
931 ; X86-LABEL: t21_sret_to_sret_structs_mismatch:
932 ; X86:       # %bb.0:
933 ; X86-NEXT:    pushl %edi
934 ; X86-NEXT:    pushl %esi
935 ; X86-NEXT:    pushl %eax
936 ; X86-NEXT:    movl %edx, %esi
937 ; X86-NEXT:    movl %ecx, %edi
938 ; X86-NEXT:    calll ret_struct
939 ; X86-NEXT:    movl %esi, %ecx
940 ; X86-NEXT:    movl %eax, %edx
941 ; X86-NEXT:    calll t21_f_sret2
942 ; X86-NEXT:    movl %edi, %eax
943 ; X86-NEXT:    addl $4, %esp
944 ; X86-NEXT:    popl %esi
945 ; X86-NEXT:    popl %edi
946 ; X86-NEXT:    retl
948 ; X64-LABEL: t21_sret_to_sret_structs_mismatch:
949 ; X64:       # %bb.0:
950 ; X64-NEXT:    pushq %r14
951 ; X64-NEXT:    pushq %rbx
952 ; X64-NEXT:    pushq %rax
953 ; X64-NEXT:    movq %rsi, %rbx
954 ; X64-NEXT:    movq %rdi, %r14
955 ; X64-NEXT:    callq ret_struct
956 ; X64-NEXT:    movq %rbx, %rdi
957 ; X64-NEXT:    movq %rax, %rsi
958 ; X64-NEXT:    callq t21_f_sret2
959 ; X64-NEXT:    movq %r14, %rax
960 ; X64-NEXT:    addq $8, %rsp
961 ; X64-NEXT:    popq %rbx
962 ; X64-NEXT:    popq %r14
963 ; X64-NEXT:    retq
965 ; X32-LABEL: t21_sret_to_sret_structs_mismatch:
966 ; X32:       # %bb.0:
967 ; X32-NEXT:    pushq %rbp
968 ; X32-NEXT:    pushq %rbx
969 ; X32-NEXT:    pushq %rax
970 ; X32-NEXT:    movl %esi, %ebx
971 ; X32-NEXT:    movl %edi, %ebp
972 ; X32-NEXT:    callq ret_struct
973 ; X32-NEXT:    movl %ebx, %edi
974 ; X32-NEXT:    movl %eax, %esi
975 ; X32-NEXT:    callq t21_f_sret2
976 ; X32-NEXT:    movl %ebp, %eax
977 ; X32-NEXT:    addl $8, %esp
978 ; X32-NEXT:    popq %rbx
979 ; X32-NEXT:    popq %rbp
980 ; X32-NEXT:    retq
981   %b = call fastcc %struct.foo* @ret_struct()
982   tail call fastcc void @t21_f_sret2(%struct.foo* noalias sret %a, %struct.foo* noalias %b) nounwind
983   ret void
986 declare ccc %struct.foo* @ret_struct() nounwind
989 define fastcc void @t21_sret_to_non_sret(%struct.foo* noalias sret %agg.result) nounwind  {
990 ; X86-LABEL: t21_sret_to_non_sret:
991 ; X86:       # %bb.0:
992 ; X86-NEXT:    pushl %esi
993 ; X86-NEXT:    subl $8, %esp
994 ; X86-NEXT:    movl %ecx, %esi
995 ; X86-NEXT:    calll t21_f_non_sret
996 ; X86-NEXT:    movl %esi, %eax
997 ; X86-NEXT:    addl $8, %esp
998 ; X86-NEXT:    popl %esi
999 ; X86-NEXT:    retl
1001 ; X64-LABEL: t21_sret_to_non_sret:
1002 ; X64:       # %bb.0:
1003 ; X64-NEXT:    pushq %rbx
1004 ; X64-NEXT:    movq %rdi, %rbx
1005 ; X64-NEXT:    callq t21_f_non_sret
1006 ; X64-NEXT:    movq %rbx, %rax
1007 ; X64-NEXT:    popq %rbx
1008 ; X64-NEXT:    retq
1010 ; X32-LABEL: t21_sret_to_non_sret:
1011 ; X32:       # %bb.0:
1012 ; X32-NEXT:    pushq %rbx
1013 ; X32-NEXT:    movl %edi, %ebx
1014 ; X32-NEXT:    callq t21_f_non_sret
1015 ; X32-NEXT:    movl %ebx, %eax
1016 ; X32-NEXT:    popq %rbx
1017 ; X32-NEXT:    retq
1018   tail call fastcc void @t21_f_non_sret(%struct.foo* %agg.result) nounwind
1019   ret void
1023 define ccc void @t22_non_sret_to_sret(%struct.foo* %agg.result) nounwind  {
1024 ; X86-LABEL: t22_non_sret_to_sret:
1025 ; X86:       # %bb.0:
1026 ; X86-NEXT:    subl $12, %esp
1027 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1028 ; X86-NEXT:    movl %eax, (%esp)
1029 ; X86-NEXT:    calll t22_f_sret
1030 ; X86-NEXT:    addl $8, %esp
1031 ; X86-NEXT:    retl
1033 ; X64-LABEL: t22_non_sret_to_sret:
1034 ; X64:       # %bb.0:
1035 ; X64-NEXT:    pushq %rax
1036 ; X64-NEXT:    callq t22_f_sret
1037 ; X64-NEXT:    popq %rax
1038 ; X64-NEXT:    retq
1040 ; X32-LABEL: t22_non_sret_to_sret:
1041 ; X32:       # %bb.0:
1042 ; X32-NEXT:    pushq %rax
1043 ; X32-NEXT:    callq t22_f_sret
1044 ; X32-NEXT:    popq %rax
1045 ; X32-NEXT:    retq
1046   tail call ccc void @t22_f_sret(%struct.foo* noalias sret %agg.result) nounwind
1047   ret void
1050 declare fastcc void @t21_f_sret(%struct.foo* noalias sret) nounwind
1051 declare fastcc void @t21_f_sret2(%struct.foo* noalias sret, %struct.foo* noalias) nounwind
1052 declare fastcc void @t21_f_non_sret(%struct.foo*) nounwind
1054 declare ccc void @t22_f_sret(%struct.foo* noalias sret) nounwind
1056 declare ccc void @f_sret(%struct.foo* noalias sret, i32, i32) nounwind