[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / CodeGen / AArch64 / GlobalISel / call-translator-tail-call.ll
bloba0ba7a0d570b067954d2d23673ec39b3c042d44c
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()
14   ret void
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()
31   ret void
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)
49   ret void
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)
88   ret void
91 ; Verify that we don't tail call when we cannot fit arguments on the caller's
92 ; stack.
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
96   ; DARWIN: bb.1.entry:
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
147 entry:
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)
149   ret i32 %call
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()
164   ret i32 %call
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)
188   ret void
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)
225   ret void
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)
284   ret void
287 ; Unsupported calling convention for tail calls. Make sure we never tail call
288 ; it.
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()
304   ret void
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()
326   ret void
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()
348   ret void
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()
360   ret void
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
372 entry:
373   %x = tail call i32 @nonvoid_ret()
374   %y = icmp ne i32 %x, 0
375   tail call void @llvm.assume(i1 %y)
376   ret void
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
392 entry:
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)
398   ret void
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.
404 declare i8* @pluto()
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)
429   ret i64 %tmp2
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)
450   ret void
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)
478   ret void