[RISCV] Add shrinkwrap test cases showing gaps in current impl
[llvm-project.git] / llvm / test / CodeGen / X86 / preserve_nonecc_call.ll
blob500ebb139811aa70c02dfeb58ecb28a267b2e827
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
2 ; RUN: llc -mtriple=x86_64-unknown-unknown -mcpu=corei7 < %s | FileCheck %s
4 ; This test checks various function call behaviors between preserve_none and
5 ; normal calling conventions.
7 declare preserve_nonecc void @callee(ptr)
9 ; Normal caller calls preserve_none callee. Will not generated tail call because
10 ; of incompatible calling convention. Callee saved registers are saved/restored
11 ; around the call.
12 define void @caller1(ptr %a) {
13 ; CHECK-LABEL: caller1:
14 ; CHECK:       # %bb.0:
15 ; CHECK-NEXT:    pushq %r15
16 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
17 ; CHECK-NEXT:    pushq %r14
18 ; CHECK-NEXT:    .cfi_def_cfa_offset 24
19 ; CHECK-NEXT:    pushq %r13
20 ; CHECK-NEXT:    .cfi_def_cfa_offset 32
21 ; CHECK-NEXT:    pushq %r12
22 ; CHECK-NEXT:    .cfi_def_cfa_offset 40
23 ; CHECK-NEXT:    pushq %rbx
24 ; CHECK-NEXT:    .cfi_def_cfa_offset 48
25 ; CHECK-NEXT:    .cfi_offset %rbx, -48
26 ; CHECK-NEXT:    .cfi_offset %r12, -40
27 ; CHECK-NEXT:    .cfi_offset %r13, -32
28 ; CHECK-NEXT:    .cfi_offset %r14, -24
29 ; CHECK-NEXT:    .cfi_offset %r15, -16
30 ; CHECK-NEXT:    movq %rdi, %r12
31 ; CHECK-NEXT:    callq callee@PLT
32 ; CHECK-NEXT:    popq %rbx
33 ; CHECK-NEXT:    .cfi_def_cfa_offset 40
34 ; CHECK-NEXT:    popq %r12
35 ; CHECK-NEXT:    .cfi_def_cfa_offset 32
36 ; CHECK-NEXT:    popq %r13
37 ; CHECK-NEXT:    .cfi_def_cfa_offset 24
38 ; CHECK-NEXT:    popq %r14
39 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
40 ; CHECK-NEXT:    popq %r15
41 ; CHECK-NEXT:    .cfi_def_cfa_offset 8
42 ; CHECK-NEXT:    retq
43   tail call preserve_nonecc void @callee(ptr %a)
44   ret void
47 ; Preserve_none caller calls preserve_none callee. Same function body.
48 ; The tail call is preserved. No registers are saved/restored around the call.
49 ; Actually a simple jmp instruction is generated.
50 define preserve_nonecc void @caller2(ptr %a) {
51 ; CHECK-LABEL: caller2:
52 ; CHECK:       # %bb.0:
53 ; CHECK-NEXT:    jmp callee@PLT # TAILCALL
54   tail call preserve_nonecc void @callee(ptr %a)
55   ret void
58 ; Preserve_none function can use more registers to pass parameters.
59 declare preserve_nonecc i64 @callee_with_many_param2(i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 %a6, i64 %a7, i64 %a8, i64 %a9, i64 %a10, i64 %a11)
60 define preserve_nonecc i64 @callee_with_many_param(i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 %a6, i64 %a7, i64 %a8, i64 %a9, i64 %a10, i64 %a11, i64 %a12) {
61 ; CHECK-LABEL: callee_with_many_param:
62 ; CHECK:       # %bb.0:
63 ; CHECK-NEXT:    pushq %rax
64 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
65 ; CHECK-NEXT:    movq %r13, %r12
66 ; CHECK-NEXT:    movq %r14, %r13
67 ; CHECK-NEXT:    movq %r15, %r14
68 ; CHECK-NEXT:    movq %rdi, %r15
69 ; CHECK-NEXT:    movq %rsi, %rdi
70 ; CHECK-NEXT:    movq %rdx, %rsi
71 ; CHECK-NEXT:    movq %rcx, %rdx
72 ; CHECK-NEXT:    movq %r8, %rcx
73 ; CHECK-NEXT:    movq %r9, %r8
74 ; CHECK-NEXT:    movq %r11, %r9
75 ; CHECK-NEXT:    movq %rax, %r11
76 ; CHECK-NEXT:    callq callee_with_many_param2@PLT
77 ; CHECK-NEXT:    popq %rcx
78 ; CHECK-NEXT:    .cfi_def_cfa_offset 8
79 ; CHECK-NEXT:    retq
80   %ret = call preserve_nonecc i64 @callee_with_many_param2(i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 %a6, i64 %a7, i64 %a8, i64 %a9, i64 %a10, i64 %a11, i64 %a12)
81   ret i64 %ret
84 define i64 @caller3() {
85 ; CHECK-LABEL: caller3:
86 ; CHECK:       # %bb.0:
87 ; CHECK-NEXT:    pushq %r15
88 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
89 ; CHECK-NEXT:    pushq %r14
90 ; CHECK-NEXT:    .cfi_def_cfa_offset 24
91 ; CHECK-NEXT:    pushq %r13
92 ; CHECK-NEXT:    .cfi_def_cfa_offset 32
93 ; CHECK-NEXT:    pushq %r12
94 ; CHECK-NEXT:    .cfi_def_cfa_offset 40
95 ; CHECK-NEXT:    pushq %rbx
96 ; CHECK-NEXT:    .cfi_def_cfa_offset 48
97 ; CHECK-NEXT:    .cfi_offset %rbx, -48
98 ; CHECK-NEXT:    .cfi_offset %r12, -40
99 ; CHECK-NEXT:    .cfi_offset %r13, -32
100 ; CHECK-NEXT:    .cfi_offset %r14, -24
101 ; CHECK-NEXT:    .cfi_offset %r15, -16
102 ; CHECK-NEXT:    movl $1, %r12d
103 ; CHECK-NEXT:    movl $2, %r13d
104 ; CHECK-NEXT:    movl $3, %r14d
105 ; CHECK-NEXT:    movl $4, %r15d
106 ; CHECK-NEXT:    movl $5, %edi
107 ; CHECK-NEXT:    movl $6, %esi
108 ; CHECK-NEXT:    movl $7, %edx
109 ; CHECK-NEXT:    movl $8, %ecx
110 ; CHECK-NEXT:    movl $9, %r8d
111 ; CHECK-NEXT:    movl $10, %r9d
112 ; CHECK-NEXT:    movl $11, %r11d
113 ; CHECK-NEXT:    movl $12, %eax
114 ; CHECK-NEXT:    callq callee_with_many_param@PLT
115 ; CHECK-NEXT:    popq %rbx
116 ; CHECK-NEXT:    .cfi_def_cfa_offset 40
117 ; CHECK-NEXT:    popq %r12
118 ; CHECK-NEXT:    .cfi_def_cfa_offset 32
119 ; CHECK-NEXT:    popq %r13
120 ; CHECK-NEXT:    .cfi_def_cfa_offset 24
121 ; CHECK-NEXT:    popq %r14
122 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
123 ; CHECK-NEXT:    popq %r15
124 ; CHECK-NEXT:    .cfi_def_cfa_offset 8
125 ; CHECK-NEXT:    retq
126   %ret = call preserve_nonecc i64 @callee_with_many_param(i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, i64 9, i64 10, i64 11, i64 12)
127   ret i64 %ret
130 ; Non-volatile registers are used to pass the first few parameters.
131 declare void @boring()
132 declare preserve_nonecc void @continuation(ptr, ptr, ptr, ptr)
133 define preserve_nonecc void @entry(ptr %r12, ptr %r13, ptr %r14, ptr %r15) {
134 ; CHECK-LABEL: entry:
135 ; CHECK:       # %bb.0:
136 ; CHECK-NEXT:    pushq %rax
137 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
138 ; CHECK-NEXT:    callq boring@PLT
139 ; CHECK-NEXT:    popq %rax
140 ; CHECK-NEXT:    .cfi_def_cfa_offset 8
141 ; CHECK-NEXT:    jmp continuation@PLT # TAILCALL
142   call void @boring()
143   musttail call preserve_nonecc void @continuation(ptr %r12, ptr %r13, ptr %r14, ptr %r15)
144   ret void