Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / CodeGen / ARM / swifttailcc-call.ll
blob784ac5d9f05f2d8b53d9c4892a5903c07d60ef5d
1 ; RUN: llc -verify-machineinstrs < %s -mtriple=thumbv7k-apple-watchos | FileCheck %s
3 declare swifttailcc void @callee_stack0()
4 declare swifttailcc void @callee_stack4([4 x i32], i32)
5 declare swifttailcc void @callee_stack20([4 x i32], [5 x i32])
6 declare extern_weak swifttailcc void @callee_weak()
8 define swifttailcc void @caller_to0_from0() nounwind {
9 ; CHECK-LABEL: _caller_to0_from0:
11   tail call swifttailcc void @callee_stack0()
12   ret void
13 ; CHECK-NOT: add
14 ; CHECK-NOT: sub
15 ; CHECK: b.w _callee_stack0
18 define swifttailcc void @caller_to0_from4([4 x i32], i32) {
19 ; CHECK-LABEL: _caller_to0_from4:
21   tail call swifttailcc void @callee_stack0()
22   ret void
24 ; CHECK: add sp, #16
25 ; CHECK-NEXT: b.w _callee_stack0
28 define swifttailcc void @caller_to4_from0() {
29 ; Key point is that the "42" should go #16 below incoming stack
30 ; pointer (we didn't have arg space to reuse).
31   tail call swifttailcc void @callee_stack4([4 x i32] undef, i32 42)
32   ret void
34 ; CHECK-LABEL: _caller_to4_from0:
35 ; CHECK: sub sp, #16
36 ; CHECK: movs [[TMP:r[0-9]+]], #42
37 ; CHECK: str [[TMP]], [sp]
38 ; CHECK-NOT: add sp
39 ; CHECK: b.w _callee_stack4
43 define swifttailcc void @caller_to4_from4([4 x i32], i32 %a) {
44 ; CHECK-LABEL: _caller_to4_from4:
45 ; CHECK-NOT: sub sp
46 ; Key point is that the "%a" should go where at SP on entry.
47   tail call swifttailcc void @callee_stack4([4 x i32] undef, i32 42)
48   ret void
50 ; CHECK: str {{r[0-9]+}}, [sp]
51 ; CHECK-NOT: add sp
52 ; CHECK-NEXT: b.w _callee_stack4
55 define swifttailcc void @caller_to20_from4([4 x i32], i32 %a) {
56 ; CHECK-LABEL: _caller_to20_from4:
57 ; CHECK: sub sp, #16
59 ; Important point is that the call reuses the "dead" argument space
60 ; above %a on the stack. If it tries to go below incoming-SP then the
61 ; _callee will not deallocate the space, even in swifttailcc.
62   tail call swifttailcc void @callee_stack20([4 x i32] undef, [5 x i32] [i32 1, i32 2, i32 3, i32 4, i32 5])
64 ; CHECK: str {{.*}}, [sp]
65 ; CHECK: str {{.*}}, [sp, #4]
66 ; CHECK: str {{.*}}, [sp, #8]
67 ; CHECK: str {{.*}}, [sp, #12]
68 ; CHECK: str {{.*}}, [sp, #16]
69 ; CHECK-NOT: add sp
70 ; CHECK-NOT: sub sp
71 ; CHECK: b.w _callee_stack20
72   ret void
76 define swifttailcc void @caller_to4_from24([4 x i32], i64 %a, i64 %b, i64 %c) {
77 ; CHECK-LABEL: _caller_to4_from24:
80 ; Key point is that the "%a" should go where at #16 above SP on entry.
81   tail call swifttailcc void @callee_stack4([4 x i32] undef, i32 42)
82   ret void
84 ; CHECK: str {{.*}}, [sp, #16]
85 ; CHECK: add sp, #16
86 ; CHECK-NEXT: b.w _callee_stack4
90 define swifttailcc void @caller_to20_from20([4 x i32], [5 x i32] %a) {
91 ; CHECK-LABEL: _caller_to20_from20:
92 ; CHECK-NOT: add sp,
93 ; CHECK-NOT: sub sp,
95 ; Here we want to make sure that both loads happen before the stores:
96 ; otherwise either %a or %b.w will be wrongly clobbered.
97   tail call swifttailcc void @callee_stack20([4 x i32] undef, [5 x i32] %a)
98   ret void
100   ; If these ever get interleaved make sure aliasing slots don't clobber each
101   ; other.
102 ; CHECK: ldrd {{.*}}, {{.*}}, [sp, #12]
103 ; CHECK: ldm.w sp,
104 ; CHECK: stm.w
105 ; CHECK: strd
106 ; CHECK-NEXT: b.w _callee_stack20
109 define swifttailcc void @disable_tail_calls() nounwind "disable-tail-calls"="true" {
110 ; CHECK-LABEL: disable_tail_calls:
112   tail call swifttailcc void @callee_stack0()
113   ret void
115 ; CHECK: bl _callee_stack0
116 ; CHECK: ret
119 define swifttailcc void @normal_ret_with_stack([4 x i32], i32 %a) {
120 ; CHECK: _normal_ret_with_stack:
121 ; CHECK: add sp, #16
122 ; CHECK: bx lr
123   ret void
126 declare { [2 x float] } @get_vec2()
128 define void @fromC_totail() {
129 ; COMMON-LABEL: fromC_totail:
130 ; COMMON: puch {r4, lr}
131 ; COMMON: sub sp, #8
133 ; COMMON-NOT: sub sp,
134 ; COMMON: movs [[TMP:r[0-9]+]], #42
135 ; COMMON: str [[TMP]], [sp]
136 ; COMMON: bl _callee_stack4
137   ; We must reset the stack to where it was before the call by undoing its extra stack pop.
138 ; COMMON: sub sp, #16
139 ; COMMON: str [[TMP]], [sp]
140 ; COMMON: bl callee_stack4
141 ; COMMON: sub sp, #16
143   call swifttailcc void @callee_stack4([4 x i32] undef, i32 42)
144   call swifttailcc void @callee_stack4([4 x i32] undef, i32 42)
145   ret void
148 define void @fromC_totail_noreservedframe(i32 %len) {
149 ; COMMON-LABEL: fromC_totail_noreservedframe:
150 ; COMMON: sub.w sp, sp, r{{.*}}
152 ; COMMON: movs [[TMP:r[0-9]+]], #42
153   ; Note stack is subtracted here to allocate space for arg
154 ; COMMON: sub.w sp, #16
155 ; COMMON: str [[TMP]], [sp]
156 ; COMMON: bl _callee_stack4
157   ; And here.
158 ; COMMON: sub sp, #16
159 ; COMMON: str [[TMP]], [sp]
160 ; COMMON: bl _callee_stack4
161   ; But not restored here because callee_stack8 did that for us.
162 ; COMMON-NOT: sub sp,
164   ; Variable sized allocation prevents reserving frame at start of function so each call must allocate any stack space it needs.
165   %var = alloca i32, i32 %len
167   call swifttailcc void @callee_stack4([4 x i32] undef, i32 42)
168   call swifttailcc void @callee_stack4([4 x i32] undef, i32 42)
169   ret void
172 declare void @Ccallee_stack4([4 x i32], i32)
174 define swifttailcc void @fromtail_toC() {
175 ; COMMON-LABEL: fromtail_toC:
176 ; COMMON: push {r4, lr}
177 ; COMMON: sub sp, #8
179 ; COMMON-NOT: sub sp,
180 ; COMMON: movs [[TMP:r[0-9]+]], #42
181 ; COMMON: str [[TMP]], [sp]
182 ; COMMON: bl _Ccallee_stack4
183   ; C callees will return with the stack exactly where we left it, so we mustn't try to fix anything.
184 ; COMMON-NOT: add sp,
185 ; COMMON-NOT: sub sp,
186 ; COMMON: str [[TMP]], [sp]{{$}}
187 ; COMMON: bl _Ccallee_stack4
188 ; COMMON-NOT: sub sp,
190   call void @Ccallee_stack4([4 x i32] undef, i32 42)
191   call void @Ccallee_stack4([4 x i32] undef, i32 42)
192   ret void
195 declare swifttailcc ptr @SwiftSelf(ptr swiftasync %context, ptr swiftself %closure)
196 define swiftcc ptr @CallSwiftSelf(ptr swiftself %closure, ptr %context) {
197 ; CHECK-LABEL: CallSwiftSelf:
198 ; CHECK: push{{.*}}r10
199   %res = call swifttailcc ptr @SwiftSelf(ptr swiftasync %context, ptr swiftself %closure)
200   ret ptr %res