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