1 ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2 ; RUN: llc %s -stop-after=irtranslator -verify-machineinstrs -mtriple aarch64-apple-darwin -global-isel -o - 2>&1 | FileCheck %s --check-prefix=DARWIN
3 ; RUN: llc %s -stop-after=irtranslator -verify-machineinstrs -mtriple aarch64-windows -global-isel -o - 2>&1 | FileCheck %s --check-prefix=WINDOWS
5 declare void @simple_fn()
6 define void @tail_call() {
7 ; DARWIN-LABEL: name: tail_call
8 ; DARWIN: bb.1 (%ir-block.0):
9 ; DARWIN: TCRETURNdi @simple_fn, 0, csr_darwin_aarch64_aapcs, implicit $sp
10 ; WINDOWS-LABEL: name: tail_call
11 ; WINDOWS: bb.1 (%ir-block.0):
12 ; WINDOWS: TCRETURNdi @simple_fn, 0, csr_aarch64_aapcs, implicit $sp
13 tail call void @simple_fn()
17 ; We should get a TCRETURNri here.
18 ; FIXME: We don't need the COPY.
19 define void @indirect_tail_call(void()* %func) {
20 ; DARWIN-LABEL: name: indirect_tail_call
21 ; DARWIN: bb.1 (%ir-block.0):
22 ; DARWIN: liveins: $x0
23 ; DARWIN: [[COPY:%[0-9]+]]:tcgpr64(p0) = COPY $x0
24 ; DARWIN: TCRETURNri [[COPY]](p0), 0, csr_darwin_aarch64_aapcs, implicit $sp
25 ; WINDOWS-LABEL: name: indirect_tail_call
26 ; WINDOWS: bb.1 (%ir-block.0):
27 ; WINDOWS: liveins: $x0
28 ; WINDOWS: [[COPY:%[0-9]+]]:tcgpr64(p0) = COPY $x0
29 ; WINDOWS: TCRETURNri [[COPY]](p0), 0, csr_aarch64_aapcs, implicit $sp
30 tail call void %func()
34 declare void @outgoing_args_fn(i32)
35 define void @test_outgoing_args(i32 %a) {
36 ; DARWIN-LABEL: name: test_outgoing_args
37 ; DARWIN: bb.1 (%ir-block.0):
38 ; DARWIN: liveins: $w0
39 ; DARWIN: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
40 ; DARWIN: $w0 = COPY [[COPY]](s32)
41 ; DARWIN: TCRETURNdi @outgoing_args_fn, 0, csr_darwin_aarch64_aapcs, implicit $sp, implicit $w0
42 ; WINDOWS-LABEL: name: test_outgoing_args
43 ; WINDOWS: bb.1 (%ir-block.0):
44 ; WINDOWS: liveins: $w0
45 ; WINDOWS: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
46 ; WINDOWS: $w0 = COPY [[COPY]](s32)
47 ; WINDOWS: TCRETURNdi @outgoing_args_fn, 0, csr_aarch64_aapcs, implicit $sp, implicit $w0
48 tail call void @outgoing_args_fn(i32 %a)
52 ; Verify that we create frame indices for memory arguments in tail calls.
53 ; We get a bunch of copies here which are unused and thus eliminated. So, let's
54 ; just focus on what matters, which is that we get a G_FRAME_INDEX.
55 declare void @outgoing_stack_args_fn(<4 x half>)
56 define void @test_outgoing_stack_args([8 x <2 x double>], <4 x half> %arg) {
57 ; DARWIN-LABEL: name: test_outgoing_stack_args
58 ; DARWIN: bb.1 (%ir-block.1):
59 ; DARWIN: liveins: $q0, $q1, $q2, $q3, $q4, $q5, $q6, $q7
60 ; DARWIN: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0
61 ; DARWIN: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $q1
62 ; DARWIN: [[COPY2:%[0-9]+]]:_(<2 x s64>) = COPY $q2
63 ; DARWIN: [[COPY3:%[0-9]+]]:_(<2 x s64>) = COPY $q3
64 ; DARWIN: [[COPY4:%[0-9]+]]:_(<2 x s64>) = COPY $q4
65 ; DARWIN: [[COPY5:%[0-9]+]]:_(<2 x s64>) = COPY $q5
66 ; DARWIN: [[COPY6:%[0-9]+]]:_(<2 x s64>) = COPY $q6
67 ; DARWIN: [[COPY7:%[0-9]+]]:_(<2 x s64>) = COPY $q7
68 ; DARWIN: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
69 ; DARWIN: [[LOAD:%[0-9]+]]:_(<4 x s16>) = G_LOAD [[FRAME_INDEX]](p0) :: (invariant load (<4 x s16>) from %fixed-stack.0, align 16)
70 ; DARWIN: $d0 = COPY [[LOAD]](<4 x s16>)
71 ; DARWIN: TCRETURNdi @outgoing_stack_args_fn, 0, csr_darwin_aarch64_aapcs, implicit $sp, implicit $d0
72 ; WINDOWS-LABEL: name: test_outgoing_stack_args
73 ; WINDOWS: bb.1 (%ir-block.1):
74 ; WINDOWS: liveins: $q0, $q1, $q2, $q3, $q4, $q5, $q6, $q7
75 ; WINDOWS: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0
76 ; WINDOWS: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $q1
77 ; WINDOWS: [[COPY2:%[0-9]+]]:_(<2 x s64>) = COPY $q2
78 ; WINDOWS: [[COPY3:%[0-9]+]]:_(<2 x s64>) = COPY $q3
79 ; WINDOWS: [[COPY4:%[0-9]+]]:_(<2 x s64>) = COPY $q4
80 ; WINDOWS: [[COPY5:%[0-9]+]]:_(<2 x s64>) = COPY $q5
81 ; WINDOWS: [[COPY6:%[0-9]+]]:_(<2 x s64>) = COPY $q6
82 ; WINDOWS: [[COPY7:%[0-9]+]]:_(<2 x s64>) = COPY $q7
83 ; WINDOWS: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
84 ; WINDOWS: [[LOAD:%[0-9]+]]:_(<4 x s16>) = G_LOAD [[FRAME_INDEX]](p0) :: (invariant load (<4 x s16>) from %fixed-stack.0, align 16)
85 ; WINDOWS: $d0 = COPY [[LOAD]](<4 x s16>)
86 ; WINDOWS: TCRETURNdi @outgoing_stack_args_fn, 0, csr_aarch64_aapcs, implicit $sp, implicit $d0
87 tail call void @outgoing_stack_args_fn(<4 x half> %arg)
91 ; Verify that we don't tail call when we cannot fit arguments on the caller's
93 declare i32 @too_big_stack(i64 %x0, i64 %x1, i64 %x2, i64 %x3, i64 %x4, i64 %x5, i64 %x6, i64 %x7, i8 %c, i16 %s)
94 define i32 @test_too_big_stack() {
95 ; DARWIN-LABEL: name: test_too_big_stack
97 ; DARWIN: [[DEF:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF
98 ; DARWIN: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 8
99 ; DARWIN: [[C1:%[0-9]+]]:_(s16) = G_CONSTANT i16 9
100 ; DARWIN: ADJCALLSTACKDOWN 4, 0, implicit-def $sp, implicit $sp
101 ; DARWIN: $x0 = COPY [[DEF]](s64)
102 ; DARWIN: $x1 = COPY [[DEF]](s64)
103 ; DARWIN: $x2 = COPY [[DEF]](s64)
104 ; DARWIN: $x3 = COPY [[DEF]](s64)
105 ; DARWIN: $x4 = COPY [[DEF]](s64)
106 ; DARWIN: $x5 = COPY [[DEF]](s64)
107 ; DARWIN: $x6 = COPY [[DEF]](s64)
108 ; DARWIN: $x7 = COPY [[DEF]](s64)
109 ; DARWIN: [[COPY:%[0-9]+]]:_(p0) = COPY $sp
110 ; DARWIN: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
111 ; DARWIN: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C2]](s64)
112 ; DARWIN: G_STORE [[C]](s8), [[PTR_ADD]](p0) :: (store (s8) into stack)
113 ; DARWIN: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
114 ; DARWIN: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C3]](s64)
115 ; DARWIN: G_STORE [[C1]](s16), [[PTR_ADD1]](p0) :: (store (s16) into stack + 2, align 1)
116 ; DARWIN: BL @too_big_stack, csr_darwin_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x0, implicit $x1, implicit $x2, implicit $x3, implicit $x4, implicit $x5, implicit $x6, implicit $x7, implicit-def $w0
117 ; DARWIN: [[COPY1:%[0-9]+]]:_(s32) = COPY $w0
118 ; DARWIN: ADJCALLSTACKUP 4, 0, implicit-def $sp, implicit $sp
119 ; DARWIN: $w0 = COPY [[COPY1]](s32)
120 ; DARWIN: RET_ReallyLR implicit $w0
121 ; WINDOWS-LABEL: name: test_too_big_stack
122 ; WINDOWS: bb.1.entry:
123 ; WINDOWS: [[DEF:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF
124 ; WINDOWS: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 8
125 ; WINDOWS: [[C1:%[0-9]+]]:_(s16) = G_CONSTANT i16 9
126 ; WINDOWS: ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
127 ; WINDOWS: $x0 = COPY [[DEF]](s64)
128 ; WINDOWS: $x1 = COPY [[DEF]](s64)
129 ; WINDOWS: $x2 = COPY [[DEF]](s64)
130 ; WINDOWS: $x3 = COPY [[DEF]](s64)
131 ; WINDOWS: $x4 = COPY [[DEF]](s64)
132 ; WINDOWS: $x5 = COPY [[DEF]](s64)
133 ; WINDOWS: $x6 = COPY [[DEF]](s64)
134 ; WINDOWS: $x7 = COPY [[DEF]](s64)
135 ; WINDOWS: [[COPY:%[0-9]+]]:_(p0) = COPY $sp
136 ; WINDOWS: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
137 ; WINDOWS: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C2]](s64)
138 ; WINDOWS: G_STORE [[C]](s8), [[PTR_ADD]](p0) :: (store (s8) into stack)
139 ; WINDOWS: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
140 ; WINDOWS: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C3]](s64)
141 ; WINDOWS: G_STORE [[C1]](s16), [[PTR_ADD1]](p0) :: (store (s16) into stack + 8, align 1)
142 ; WINDOWS: BL @too_big_stack, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x0, implicit $x1, implicit $x2, implicit $x3, implicit $x4, implicit $x5, implicit $x6, implicit $x7, implicit-def $w0
143 ; WINDOWS: [[COPY1:%[0-9]+]]:_(s32) = COPY $w0
144 ; WINDOWS: ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
145 ; WINDOWS: $w0 = COPY [[COPY1]](s32)
146 ; WINDOWS: RET_ReallyLR implicit $w0
148 %call = tail call i32 @too_big_stack(i64 undef, i64 undef, i64 undef, i64 undef, i64 undef, i64 undef, i64 undef, i64 undef, i8 8, i16 9)
152 ; Right now, we don't want to tail call callees with nonvoid return types, since
153 ; call lowering will insert COPYs after the call.
154 ; TODO: Support this.
155 declare i32 @nonvoid_ret()
156 define i32 @test_nonvoid_ret() {
157 ; DARWIN-LABEL: name: test_nonvoid_ret
158 ; DARWIN: bb.1 (%ir-block.0):
159 ; DARWIN: TCRETURNdi @nonvoid_ret, 0, csr_darwin_aarch64_aapcs, implicit $sp
160 ; WINDOWS-LABEL: name: test_nonvoid_ret
161 ; WINDOWS: bb.1 (%ir-block.0):
162 ; WINDOWS: TCRETURNdi @nonvoid_ret, 0, csr_aarch64_aapcs, implicit $sp
163 %call = tail call i32 @nonvoid_ret()
167 declare void @varargs(i32, double, i64, ...)
168 define void @test_varargs() {
169 ; DARWIN-LABEL: name: test_varargs
170 ; DARWIN: bb.1 (%ir-block.0):
171 ; DARWIN: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
172 ; DARWIN: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
173 ; DARWIN: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
174 ; DARWIN: $w0 = COPY [[C]](s32)
175 ; DARWIN: $d0 = COPY [[C1]](s64)
176 ; DARWIN: $x1 = COPY [[C2]](s64)
177 ; DARWIN: TCRETURNdi @varargs, 0, csr_darwin_aarch64_aapcs, implicit $sp, implicit $w0, implicit $d0, implicit $x1
178 ; WINDOWS-LABEL: name: test_varargs
179 ; WINDOWS: bb.1 (%ir-block.0):
180 ; WINDOWS: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
181 ; WINDOWS: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
182 ; WINDOWS: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
183 ; WINDOWS: $w0 = COPY [[C]](s32)
184 ; WINDOWS: $x1 = COPY [[C1]](s64)
185 ; WINDOWS: $x2 = COPY [[C2]](s64)
186 ; WINDOWS: TCRETURNdi @varargs, 0, csr_aarch64_aapcs, implicit $sp, implicit $w0, implicit $x1, implicit $x2
187 tail call void(i32, double, i64, ...) @varargs(i32 42, double 1.0, i64 12)
191 ; Darwin should not tail call here, because the last parameter to @varargs is
192 ; not fixed. So, it's passed on the stack, which will make us not fit. On
193 ; Windows, it's passed in a register, so it's safe to tail call.
194 define void @test_varargs_2() {
196 ; DARWIN-LABEL: name: test_varargs_2
197 ; DARWIN: bb.1 (%ir-block.0):
198 ; DARWIN: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
199 ; DARWIN: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
200 ; DARWIN: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
201 ; DARWIN: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 314
202 ; DARWIN: ADJCALLSTACKDOWN 8, 0, implicit-def $sp, implicit $sp
203 ; DARWIN: $w0 = COPY [[C]](s32)
204 ; DARWIN: $d0 = COPY [[C1]](s64)
205 ; DARWIN: $x1 = COPY [[C2]](s64)
206 ; DARWIN: [[COPY:%[0-9]+]]:_(p0) = COPY $sp
207 ; DARWIN: [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
208 ; DARWIN: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C4]](s64)
209 ; DARWIN: G_STORE [[C3]](s64), [[PTR_ADD]](p0) :: (store (s64) into stack, align 1)
210 ; DARWIN: BL @varargs, csr_darwin_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $w0, implicit $d0, implicit $x1
211 ; DARWIN: ADJCALLSTACKUP 8, 0, implicit-def $sp, implicit $sp
212 ; DARWIN: RET_ReallyLR
213 ; WINDOWS-LABEL: name: test_varargs_2
214 ; WINDOWS: bb.1 (%ir-block.0):
215 ; WINDOWS: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
216 ; WINDOWS: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
217 ; WINDOWS: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
218 ; WINDOWS: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 314
219 ; WINDOWS: $w0 = COPY [[C]](s32)
220 ; WINDOWS: $x1 = COPY [[C1]](s64)
221 ; WINDOWS: $x2 = COPY [[C2]](s64)
222 ; WINDOWS: $x3 = COPY [[C3]](s64)
223 ; WINDOWS: TCRETURNdi @varargs, 0, csr_aarch64_aapcs, implicit $sp, implicit $w0, implicit $x1, implicit $x2, implicit $x3
224 tail call void(i32, double, i64, ...) @varargs(i32 42, double 1.0, i64 12, i64 314)
228 ; Same deal here, even though we have enough room to fit. On Darwin, we'll pass
229 ; the last argument to @varargs on the stack. We don't allow tail calling
230 ; varargs arguments that are on the stack.
231 define void @test_varargs_3([8 x <2 x double>], <4 x half> %arg) {
233 ; DARWIN-LABEL: name: test_varargs_3
234 ; DARWIN: bb.1 (%ir-block.1):
235 ; DARWIN: liveins: $q0, $q1, $q2, $q3, $q4, $q5, $q6, $q7
236 ; DARWIN: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0
237 ; DARWIN: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $q1
238 ; DARWIN: [[COPY2:%[0-9]+]]:_(<2 x s64>) = COPY $q2
239 ; DARWIN: [[COPY3:%[0-9]+]]:_(<2 x s64>) = COPY $q3
240 ; DARWIN: [[COPY4:%[0-9]+]]:_(<2 x s64>) = COPY $q4
241 ; DARWIN: [[COPY5:%[0-9]+]]:_(<2 x s64>) = COPY $q5
242 ; DARWIN: [[COPY6:%[0-9]+]]:_(<2 x s64>) = COPY $q6
243 ; DARWIN: [[COPY7:%[0-9]+]]:_(<2 x s64>) = COPY $q7
244 ; DARWIN: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
245 ; DARWIN: [[LOAD:%[0-9]+]]:_(<4 x s16>) = G_LOAD [[FRAME_INDEX]](p0) :: (invariant load (<4 x s16>) from %fixed-stack.0, align 16)
246 ; DARWIN: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
247 ; DARWIN: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
248 ; DARWIN: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
249 ; DARWIN: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 314
250 ; DARWIN: ADJCALLSTACKDOWN 8, 0, implicit-def $sp, implicit $sp
251 ; DARWIN: $w0 = COPY [[C]](s32)
252 ; DARWIN: $d0 = COPY [[C1]](s64)
253 ; DARWIN: $x1 = COPY [[C2]](s64)
254 ; DARWIN: [[COPY8:%[0-9]+]]:_(p0) = COPY $sp
255 ; DARWIN: [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
256 ; DARWIN: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY8]], [[C4]](s64)
257 ; DARWIN: G_STORE [[C3]](s64), [[PTR_ADD]](p0) :: (store (s64) into stack, align 1)
258 ; DARWIN: BL @varargs, csr_darwin_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $w0, implicit $d0, implicit $x1
259 ; DARWIN: ADJCALLSTACKUP 8, 0, implicit-def $sp, implicit $sp
260 ; DARWIN: RET_ReallyLR
261 ; WINDOWS-LABEL: name: test_varargs_3
262 ; WINDOWS: bb.1 (%ir-block.1):
263 ; WINDOWS: liveins: $q0, $q1, $q2, $q3, $q4, $q5, $q6, $q7
264 ; WINDOWS: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0
265 ; WINDOWS: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $q1
266 ; WINDOWS: [[COPY2:%[0-9]+]]:_(<2 x s64>) = COPY $q2
267 ; WINDOWS: [[COPY3:%[0-9]+]]:_(<2 x s64>) = COPY $q3
268 ; WINDOWS: [[COPY4:%[0-9]+]]:_(<2 x s64>) = COPY $q4
269 ; WINDOWS: [[COPY5:%[0-9]+]]:_(<2 x s64>) = COPY $q5
270 ; WINDOWS: [[COPY6:%[0-9]+]]:_(<2 x s64>) = COPY $q6
271 ; WINDOWS: [[COPY7:%[0-9]+]]:_(<2 x s64>) = COPY $q7
272 ; WINDOWS: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
273 ; WINDOWS: [[LOAD:%[0-9]+]]:_(<4 x s16>) = G_LOAD [[FRAME_INDEX]](p0) :: (invariant load (<4 x s16>) from %fixed-stack.0, align 16)
274 ; WINDOWS: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
275 ; WINDOWS: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
276 ; WINDOWS: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
277 ; WINDOWS: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 314
278 ; WINDOWS: $w0 = COPY [[C]](s32)
279 ; WINDOWS: $x1 = COPY [[C1]](s64)
280 ; WINDOWS: $x2 = COPY [[C2]](s64)
281 ; WINDOWS: $x3 = COPY [[C3]](s64)
282 ; WINDOWS: TCRETURNdi @varargs, 0, csr_aarch64_aapcs, implicit $sp, implicit $w0, implicit $x1, implicit $x2, implicit $x3
283 tail call void(i32, double, i64, ...) @varargs(i32 42, double 1.0, i64 12, i64 314)
287 ; Unsupported calling convention for tail calls. Make sure we never tail call
289 declare ghccc void @bad_call_conv_fn()
290 define void @test_bad_call_conv() {
291 ; DARWIN-LABEL: name: test_bad_call_conv
292 ; DARWIN: bb.1 (%ir-block.0):
293 ; DARWIN: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
294 ; DARWIN: BL @bad_call_conv_fn, csr_aarch64_noregs, implicit-def $lr, implicit $sp
295 ; DARWIN: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
296 ; DARWIN: RET_ReallyLR
297 ; WINDOWS-LABEL: name: test_bad_call_conv
298 ; WINDOWS: bb.1 (%ir-block.0):
299 ; WINDOWS: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
300 ; WINDOWS: BL @bad_call_conv_fn, csr_aarch64_noregs, implicit-def $lr, implicit $sp
301 ; WINDOWS: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
302 ; WINDOWS: RET_ReallyLR
303 tail call ghccc void @bad_call_conv_fn()
307 ; Shouldn't tail call when the caller has byval arguments.
308 define void @test_byval(i8* byval(i8) %ptr) {
309 ; DARWIN-LABEL: name: test_byval
310 ; DARWIN: bb.1 (%ir-block.0):
311 ; DARWIN: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
312 ; DARWIN: [[COPY:%[0-9]+]]:_(p0) = COPY [[FRAME_INDEX]](p0)
313 ; DARWIN: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
314 ; DARWIN: BL @simple_fn, csr_darwin_aarch64_aapcs, implicit-def $lr, implicit $sp
315 ; DARWIN: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
316 ; DARWIN: RET_ReallyLR
317 ; WINDOWS-LABEL: name: test_byval
318 ; WINDOWS: bb.1 (%ir-block.0):
319 ; WINDOWS: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
320 ; WINDOWS: [[COPY:%[0-9]+]]:_(p0) = COPY [[FRAME_INDEX]](p0)
321 ; WINDOWS: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
322 ; WINDOWS: BL @simple_fn, csr_aarch64_aapcs, implicit-def $lr, implicit $sp
323 ; WINDOWS: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
324 ; WINDOWS: RET_ReallyLR
325 tail call void @simple_fn()
329 ; Shouldn't tail call when the caller has inreg arguments.
330 define void @test_inreg(i8* inreg %ptr) {
331 ; DARWIN-LABEL: name: test_inreg
332 ; DARWIN: bb.1 (%ir-block.0):
333 ; DARWIN: liveins: $x0
334 ; DARWIN: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
335 ; DARWIN: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
336 ; DARWIN: BL @simple_fn, csr_darwin_aarch64_aapcs, implicit-def $lr, implicit $sp
337 ; DARWIN: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
338 ; DARWIN: RET_ReallyLR
339 ; WINDOWS-LABEL: name: test_inreg
340 ; WINDOWS: bb.1 (%ir-block.0):
341 ; WINDOWS: liveins: $x0
342 ; WINDOWS: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
343 ; WINDOWS: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
344 ; WINDOWS: BL @simple_fn, csr_aarch64_aapcs, implicit-def $lr, implicit $sp
345 ; WINDOWS: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
346 ; WINDOWS: RET_ReallyLR
347 tail call void @simple_fn()
351 declare fastcc void @fast_fn()
352 define void @test_mismatched_caller() {
353 ; DARWIN-LABEL: name: test_mismatched_caller
354 ; DARWIN: bb.1 (%ir-block.0):
355 ; DARWIN: TCRETURNdi @fast_fn, 0, csr_darwin_aarch64_aapcs, implicit $sp
356 ; WINDOWS-LABEL: name: test_mismatched_caller
357 ; WINDOWS: bb.1 (%ir-block.0):
358 ; WINDOWS: TCRETURNdi @fast_fn, 0, csr_aarch64_aapcs, implicit $sp
359 tail call fastcc void @fast_fn()
363 ; Verify that lifetime markers and llvm.assume don't impact tail calling.
364 declare void @llvm.assume(i1)
365 define void @test_assume() local_unnamed_addr {
366 ; DARWIN-LABEL: name: test_assume
367 ; DARWIN: bb.1.entry:
368 ; DARWIN: TCRETURNdi @nonvoid_ret, 0, csr_darwin_aarch64_aapcs, implicit $sp
369 ; WINDOWS-LABEL: name: test_assume
370 ; WINDOWS: bb.1.entry:
371 ; WINDOWS: TCRETURNdi @nonvoid_ret, 0, csr_aarch64_aapcs, implicit $sp
373 %x = tail call i32 @nonvoid_ret()
374 %y = icmp ne i32 %x, 0
375 tail call void @llvm.assume(i1 %y)
379 declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
380 declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
381 define void @test_lifetime() local_unnamed_addr {
382 ; DARWIN-LABEL: name: test_lifetime
383 ; DARWIN: bb.1.entry:
384 ; DARWIN: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.t
385 ; DARWIN: LIFETIME_START %stack.0.t
386 ; DARWIN: TCRETURNdi @nonvoid_ret, 0, csr_darwin_aarch64_aapcs, implicit $sp
387 ; WINDOWS-LABEL: name: test_lifetime
388 ; WINDOWS: bb.1.entry:
389 ; WINDOWS: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.t
390 ; WINDOWS: LIFETIME_START %stack.0.t
391 ; WINDOWS: TCRETURNdi @nonvoid_ret, 0, csr_aarch64_aapcs, implicit $sp
393 %t = alloca i8, align 1
394 call void @llvm.lifetime.start.p0i8(i64 1, i8* %t)
395 %x = tail call i32 @nonvoid_ret()
396 %y = icmp ne i32 %x, 0
397 tail call void @llvm.lifetime.end.p0i8(i64 1, i8* %t)
401 ; We can tail call when the callee swiftself is the same as the caller one.
402 ; It would be nice to move this to swiftself.ll, but it's important to verify
403 ; that we get the COPY that makes this safe in the first place.
405 define hidden swiftcc i64 @swiftself_indirect_tail(i64* swiftself %arg) {
406 ; DARWIN-LABEL: name: swiftself_indirect_tail
407 ; DARWIN: bb.1 (%ir-block.0):
408 ; DARWIN: liveins: $x20
409 ; DARWIN: [[COPY:%[0-9]+]]:_(p0) = COPY $x20
410 ; DARWIN: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
411 ; DARWIN: BL @pluto, csr_darwin_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit-def $x0
412 ; DARWIN: [[COPY1:%[0-9]+]]:tcgpr64(p0) = COPY $x0
413 ; DARWIN: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
414 ; DARWIN: $x20 = COPY [[COPY]](p0)
415 ; DARWIN: TCRETURNri [[COPY1]](p0), 0, csr_darwin_aarch64_aapcs, implicit $sp, implicit $x20
416 ; WINDOWS-LABEL: name: swiftself_indirect_tail
417 ; WINDOWS: bb.1 (%ir-block.0):
418 ; WINDOWS: liveins: $x20
419 ; WINDOWS: [[COPY:%[0-9]+]]:_(p0) = COPY $x20
420 ; WINDOWS: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
421 ; WINDOWS: BL @pluto, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit-def $x0
422 ; WINDOWS: [[COPY1:%[0-9]+]]:tcgpr64(p0) = COPY $x0
423 ; WINDOWS: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
424 ; WINDOWS: $x20 = COPY [[COPY]](p0)
425 ; WINDOWS: TCRETURNri [[COPY1]](p0), 0, csr_aarch64_aapcs, implicit $sp, implicit $x20
426 %tmp = call i8* @pluto()
427 %tmp1 = bitcast i8* %tmp to i64 (i64*)*
428 %tmp2 = tail call swiftcc i64 %tmp1(i64* swiftself %arg)
432 ; Verify that we can tail call musttail callees.
433 declare void @must_callee(i8*)
434 define void @foo(i32*) {
435 ; DARWIN-LABEL: name: foo
436 ; DARWIN: bb.1 (%ir-block.1):
437 ; DARWIN: liveins: $x0
438 ; DARWIN: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
439 ; DARWIN: [[C:%[0-9]+]]:_(p0) = G_CONSTANT i64 0
440 ; DARWIN: $x0 = COPY [[C]](p0)
441 ; DARWIN: TCRETURNdi @must_callee, 0, csr_darwin_aarch64_aapcs, implicit $sp, implicit $x0
442 ; WINDOWS-LABEL: name: foo
443 ; WINDOWS: bb.1 (%ir-block.1):
444 ; WINDOWS: liveins: $x0
445 ; WINDOWS: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
446 ; WINDOWS: [[C:%[0-9]+]]:_(p0) = G_CONSTANT i64 0
447 ; WINDOWS: $x0 = COPY [[C]](p0)
448 ; WINDOWS: TCRETURNdi @must_callee, 0, csr_aarch64_aapcs, implicit $sp, implicit $x0
449 musttail call void @must_callee(i8* null)
453 ; Verify we emit a tail call with a type that requires splitting into
454 ; multiple registers.
455 declare void @outgoing_v16f16(<16 x half>)
456 define void @test_tail_call_outgoing_v16f16(<16 x half> %arg) {
457 ; DARWIN-LABEL: name: test_tail_call_outgoing_v16f16
458 ; DARWIN: bb.1 (%ir-block.0):
459 ; DARWIN: liveins: $q0, $q1
460 ; DARWIN: [[COPY:%[0-9]+]]:_(<8 x s16>) = COPY $q0
461 ; DARWIN: [[COPY1:%[0-9]+]]:_(<8 x s16>) = COPY $q1
462 ; DARWIN: [[CONCAT_VECTORS:%[0-9]+]]:_(<16 x s16>) = G_CONCAT_VECTORS [[COPY]](<8 x s16>), [[COPY1]](<8 x s16>)
463 ; DARWIN: [[UV:%[0-9]+]]:_(<8 x s16>), [[UV1:%[0-9]+]]:_(<8 x s16>) = G_UNMERGE_VALUES [[CONCAT_VECTORS]](<16 x s16>)
464 ; DARWIN: $q0 = COPY [[UV]](<8 x s16>)
465 ; DARWIN: $q1 = COPY [[UV1]](<8 x s16>)
466 ; DARWIN: TCRETURNdi @outgoing_v16f16, 0, csr_darwin_aarch64_aapcs, implicit $sp, implicit $q0, implicit $q1
467 ; WINDOWS-LABEL: name: test_tail_call_outgoing_v16f16
468 ; WINDOWS: bb.1 (%ir-block.0):
469 ; WINDOWS: liveins: $q0, $q1
470 ; WINDOWS: [[COPY:%[0-9]+]]:_(<8 x s16>) = COPY $q0
471 ; WINDOWS: [[COPY1:%[0-9]+]]:_(<8 x s16>) = COPY $q1
472 ; WINDOWS: [[CONCAT_VECTORS:%[0-9]+]]:_(<16 x s16>) = G_CONCAT_VECTORS [[COPY]](<8 x s16>), [[COPY1]](<8 x s16>)
473 ; WINDOWS: [[UV:%[0-9]+]]:_(<8 x s16>), [[UV1:%[0-9]+]]:_(<8 x s16>) = G_UNMERGE_VALUES [[CONCAT_VECTORS]](<16 x s16>)
474 ; WINDOWS: $q0 = COPY [[UV]](<8 x s16>)
475 ; WINDOWS: $q1 = COPY [[UV1]](<8 x s16>)
476 ; WINDOWS: TCRETURNdi @outgoing_v16f16, 0, csr_aarch64_aapcs, implicit $sp, implicit $q0, implicit $q1
477 tail call void @outgoing_v16f16(<16 x half> %arg)