• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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-prefixes=DARWIN,COMMON
3; RUN: llc %s -stop-after=irtranslator -verify-machineinstrs -mtriple aarch64-windows -global-isel -o - 2>&1 | FileCheck %s --check-prefixes=WINDOWS,COMMON
4
5declare void @simple_fn()
6define void @tail_call() {
7  ; COMMON-LABEL: name: tail_call
8  ; COMMON: bb.1 (%ir-block.0):
9  ; COMMON:   TCRETURNdi @simple_fn, 0, csr{{.*}}aarch64_aapcs, implicit $sp
10  tail call void @simple_fn()
11  ret void
12}
13
14; We should get a TCRETURNri here.
15; FIXME: We don't need the COPY.
16define void @indirect_tail_call(void()* %func) {
17  ; COMMON-LABEL: name: indirect_tail_call
18  ; COMMON: bb.1 (%ir-block.0):
19  ; COMMON:   liveins: $x0
20  ; COMMON:   [[COPY:%[0-9]+]]:tcgpr64(p0) = COPY $x0
21  ; COMMON:   TCRETURNri [[COPY]](p0), 0, csr{{.*}}aarch64_aapcs, implicit $sp
22  tail call void %func()
23  ret void
24}
25
26declare void @outgoing_args_fn(i32)
27define void @test_outgoing_args(i32 %a) {
28  ; COMMON-LABEL: name: test_outgoing_args
29  ; COMMON: bb.1 (%ir-block.0):
30  ; COMMON:   liveins: $w0
31  ; COMMON:   [[COPY:%[0-9]+]]:_(s32) = COPY $w0
32  ; COMMON:   $w0 = COPY [[COPY]](s32)
33  ; COMMON:   TCRETURNdi @outgoing_args_fn, 0, csr{{.*}}aarch64_aapcs, implicit $sp, implicit $w0
34  tail call void @outgoing_args_fn(i32 %a)
35  ret void
36}
37
38; Verify that we create frame indices for memory arguments in tail calls.
39; We get a bunch of copies here which are unused and thus eliminated. So, let's
40; just focus on what matters, which is that we get a G_FRAME_INDEX.
41declare void @outgoing_stack_args_fn(<4 x half>)
42define void @test_outgoing_stack_args([8 x <2 x double>], <4 x half> %arg) {
43  ; COMMON-LABEL: name: test_outgoing_stack_args
44  ; COMMON:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
45  ; COMMON:   [[LOAD:%[0-9]+]]:_(<4 x s16>) = G_LOAD [[FRAME_INDEX]](p0) :: (invariant load 8 from %fixed-stack.0, align 16)
46  ; COMMON:   $d0 = COPY [[LOAD]](<4 x s16>)
47  ; COMMON:   TCRETURNdi @outgoing_stack_args_fn, 0, csr{{.*}}aarch64_aapcs, implicit $sp, implicit $d0
48  tail call void @outgoing_stack_args_fn(<4 x half> %arg)
49  ret void
50}
51
52; Verify that we don't tail call when we cannot fit arguments on the caller's
53; stack.
54declare i32 @too_big_stack(i64 %x0, i64 %x1, i64 %x2, i64 %x3, i64 %x4, i64 %x5, i64 %x6, i64 %x7, i8 %c, i16 %s)
55define i32 @test_too_big_stack() {
56  ; COMMON-LABEL: name: test_too_big_stack
57  ; COMMON-NOT: TCRETURNdi
58  ; COMMON-NOT: TCRETURNri
59  ; COMMON: BL @too_big_stack
60  ; COMMON-DAG: RET_ReallyLR
61entry:
62  %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)
63  ret i32 %call
64}
65
66; Right now, we don't want to tail call callees with nonvoid return types, since
67; call lowering will insert COPYs after the call.
68; TODO: Support this.
69declare i32 @nonvoid_ret()
70define i32 @test_nonvoid_ret() {
71  ; COMMON-LABEL: name: test_nonvoid_ret
72  ; COMMON: bb.1 (%ir-block.0):
73  ; COMMON:   TCRETURNdi @nonvoid_ret, 0, csr{{.*}}aarch64_aapcs, implicit $sp
74  %call = tail call i32 @nonvoid_ret()
75  ret i32 %call
76}
77
78declare void @varargs(i32, double, i64, ...)
79define void @test_varargs() {
80  ; COMMON-LABEL: name: test_varargs
81  ; COMMON: bb.1 (%ir-block.0):
82  ; COMMON:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
83  ; COMMON:   [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
84  ; COMMON:   [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
85  ; COMMON:   $w0 = COPY [[C]](s32)
86  ; COMMON:   $d0 = COPY [[C1]](s64)
87  ; COMMON:   $x1 = COPY [[C2]](s64)
88  ; COMMON:   TCRETURNdi @varargs, 0, csr{{.*}}aarch64_aapcs, implicit $sp, implicit $w0, implicit $d0, implicit $x1
89  tail call void(i32, double, i64, ...) @varargs(i32 42, double 1.0, i64 12)
90  ret void
91}
92
93; Darwin should not tail call here, because the last parameter to @varargs is
94; not fixed. So, it's passed on the stack, which will make us not fit. On
95; Windows, it's passed in a register, so it's safe to tail call.
96define void @test_varargs_2() {
97  ; DARWIN-LABEL: name: test_varargs_2
98  ; DARWIN-NOT: TCRETURNdi @varargs
99  ; DARWIN:   BL @varargs, csr_darwin_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $w0, implicit $d0, implicit $x1
100  ; DARWIN:   ADJCALLSTACKUP 8, 0, implicit-def $sp, implicit $sp
101  ; DARWIN:   RET_ReallyLR
102
103  ; WINDOWS-LABEL: name: test_varargs_2
104  ; WINDOWS: bb.1 (%ir-block.0):
105  ; WINDOWS:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
106  ; WINDOWS:   [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
107  ; WINDOWS:   [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
108  ; WINDOWS:   [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 314
109  ; WINDOWS:   $w0 = COPY [[C]](s32)
110  ; WINDOWS:   $d0 = COPY [[C1]](s64)
111  ; WINDOWS:   $x1 = COPY [[C2]](s64)
112  ; WINDOWS:   $x2 = COPY [[C3]](s64)
113  ; WINDOWS:   TCRETURNdi @varargs, 0, csr_aarch64_aapcs, implicit $sp, implicit $w0, implicit $d0, implicit $x1, implicit $x2
114  tail call void(i32, double, i64, ...) @varargs(i32 42, double 1.0, i64 12, i64 314)
115  ret void
116}
117
118; Same deal here, even though we have enough room to fit. On Darwin, we'll pass
119; the last argument to @varargs on the stack. We don't allow tail calling
120; varargs arguments that are on the stack.
121define void @test_varargs_3([8 x <2 x double>], <4 x half> %arg) {
122  ; DARWIN-LABEL: name: test_varargs_3
123  ; DARWIN-NOT: TCRETURNdi @varargs
124  ; DARWIN:   BL @varargs, csr_darwin_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $w0, implicit $d0, implicit $x1
125  ; DARWIN:   ADJCALLSTACKUP 8, 0, implicit-def $sp, implicit $sp
126  ; DARWIN:   RET_ReallyLR
127
128  ; WINDOWS-LABEL: name: test_varargs_3
129  ; WINDOWS: bb.1 (%ir-block.1):
130  ; WINDOWS:   liveins: $q0, $q1, $q2, $q3, $q4, $q5, $q6, $q7
131  ; WINDOWS:   [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0
132  ; WINDOWS:   [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $q1
133  ; WINDOWS:   [[COPY2:%[0-9]+]]:_(<2 x s64>) = COPY $q2
134  ; WINDOWS:   [[COPY3:%[0-9]+]]:_(<2 x s64>) = COPY $q3
135  ; WINDOWS:   [[COPY4:%[0-9]+]]:_(<2 x s64>) = COPY $q4
136  ; WINDOWS:   [[COPY5:%[0-9]+]]:_(<2 x s64>) = COPY $q5
137  ; WINDOWS:   [[COPY6:%[0-9]+]]:_(<2 x s64>) = COPY $q6
138  ; WINDOWS:   [[COPY7:%[0-9]+]]:_(<2 x s64>) = COPY $q7
139  ; WINDOWS:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
140  ; WINDOWS:   [[LOAD:%[0-9]+]]:_(<4 x s16>) = G_LOAD [[FRAME_INDEX]](p0) :: (invariant load 8 from %fixed-stack.0, align 16)
141  ; WINDOWS:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
142  ; WINDOWS:   [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
143  ; WINDOWS:   [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
144  ; WINDOWS:   [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 314
145  ; WINDOWS:   $w0 = COPY [[C]](s32)
146  ; WINDOWS:   $d0 = COPY [[C1]](s64)
147  ; WINDOWS:   $x1 = COPY [[C2]](s64)
148  ; WINDOWS:   $x2 = COPY [[C3]](s64)
149  ; WINDOWS:   TCRETURNdi @varargs, 0, csr_aarch64_aapcs, implicit $sp, implicit $w0, implicit $d0, implicit $x1, implicit $x2
150  tail call void(i32, double, i64, ...) @varargs(i32 42, double 1.0, i64 12, i64 314)
151  ret void
152}
153
154; Unsupported calling convention for tail calls. Make sure we never tail call
155; it.
156declare ghccc void @bad_call_conv_fn()
157define void @test_bad_call_conv() {
158  ; COMMON-LABEL: name: test_bad_call_conv
159  ; COMMON: bb.1 (%ir-block.0):
160  ; COMMON:   ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
161  ; COMMON:   BL @bad_call_conv_fn, csr_aarch64_noregs, implicit-def $lr, implicit $sp
162  ; COMMON:   ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
163  ; COMMON:   RET_ReallyLR
164  tail call ghccc void @bad_call_conv_fn()
165  ret void
166}
167
168; Shouldn't tail call when the caller has byval arguments.
169define void @test_byval(i8* byval(i8) %ptr) {
170  ; COMMON-LABEL: name: test_byval
171  ; COMMON: bb.1 (%ir-block.0):
172  ; COMMON:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
173  ; COMMON:   [[LOAD:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX]](p0) :: (invariant load 8 from %fixed-stack.0, align 16)
174  ; COMMON:   ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
175  ; COMMON:   BL @simple_fn, csr{{.*}}aarch64_aapcs, implicit-def $lr, implicit $sp
176  ; COMMON:   ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
177  ; COMMON:   RET_ReallyLR
178  tail call void @simple_fn()
179  ret void
180}
181
182; Shouldn't tail call when the caller has inreg arguments.
183define void @test_inreg(i8* inreg %ptr) {
184  ; COMMON-LABEL: name: test_inreg
185  ; COMMON: bb.1 (%ir-block.0):
186  ; COMMON:   liveins: $x0
187  ; COMMON:   [[COPY:%[0-9]+]]:_(p0) = COPY $x0
188  ; COMMON:   ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
189  ; COMMON:   BL @simple_fn, csr{{.*}}aarch64_aapcs, implicit-def $lr, implicit $sp
190  ; COMMON:   ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
191  ; COMMON:   RET_ReallyLR
192  tail call void @simple_fn()
193  ret void
194}
195
196declare fastcc void @fast_fn()
197define void @test_mismatched_caller() {
198  ; COMMON-LABEL: name: test_mismatched_caller
199  ; COMMON: bb.1 (%ir-block.0):
200  ; COMMON:   TCRETURNdi @fast_fn, 0, csr{{.*}}aarch64_aapcs, implicit $sp
201  tail call fastcc void @fast_fn()
202  ret void
203}
204
205; Verify that lifetime markers and llvm.assume don't impact tail calling.
206declare void @llvm.assume(i1)
207define void @test_assume() local_unnamed_addr {
208  ; COMMON-LABEL: name: test_assume
209  ; COMMON: bb.1.entry:
210  ; COMMON:   TCRETURNdi @nonvoid_ret, 0, csr{{.*}}aarch64_aapcs, implicit $sp
211entry:
212  %x = tail call i32 @nonvoid_ret()
213  %y = icmp ne i32 %x, 0
214  tail call void @llvm.assume(i1 %y)
215  ret void
216}
217
218declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
219declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
220define void @test_lifetime() local_unnamed_addr {
221  ; COMMON-LABEL: name: test_lifetime
222  ; COMMON: bb.1.entry:
223  ; COMMON:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.t
224  ; COMMON:   LIFETIME_START %stack.0.t
225  ; COMMON:   TCRETURNdi @nonvoid_ret, 0, csr{{.*}}aarch64_aapcs, implicit $sp
226entry:
227  %t = alloca i8, align 1
228  call void @llvm.lifetime.start.p0i8(i64 1, i8* %t)
229  %x = tail call i32 @nonvoid_ret()
230  %y = icmp ne i32 %x, 0
231  tail call void @llvm.lifetime.end.p0i8(i64 1, i8* %t)
232  ret void
233}
234
235; We can tail call when the callee swiftself is the same as the caller one.
236; It would be nice to move this to swiftself.ll, but it's important to verify
237; that we get the COPY that makes this safe in the first place.
238declare i8* @pluto()
239define hidden swiftcc i64 @swiftself_indirect_tail(i64* swiftself %arg) {
240  ; COMMON-LABEL: name: swiftself_indirect_tail
241  ; COMMON: bb.1 (%ir-block.0):
242  ; COMMON:   liveins: $x20
243  ; COMMON:   [[COPY:%[0-9]+]]:_(p0) = COPY $x20
244  ; COMMON:   ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
245  ; COMMON:   BL @pluto, csr{{.*}}aarch64_aapcs, implicit-def $lr, implicit $sp, implicit-def $x0
246  ; COMMON:   [[COPY1:%[0-9]+]]:tcgpr64(p0) = COPY $x0
247  ; COMMON:   ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
248  ; COMMON:   $x20 = COPY [[COPY]](p0)
249  ; COMMON:   TCRETURNri [[COPY1]](p0), 0, csr{{.*}}aarch64_aapcs, implicit $sp, implicit $x20
250  %tmp = call i8* @pluto()
251  %tmp1 = bitcast i8* %tmp to i64 (i64*)*
252  %tmp2 = tail call swiftcc i64 %tmp1(i64* swiftself %arg)
253  ret i64 %tmp2
254}
255
256; Verify that we can tail call musttail callees.
257declare void @must_callee(i8*)
258define void @foo(i32*) {
259  ; COMMON-LABEL: name: foo
260  ; COMMON: bb.1 (%ir-block.1):
261  ; COMMON:   liveins: $x0
262  ; COMMON:   [[COPY:%[0-9]+]]:_(p0) = COPY $x0
263  ; COMMON:   [[C:%[0-9]+]]:_(p0) = G_CONSTANT i64 0
264  ; COMMON:   $x0 = COPY [[C]](p0)
265  ; COMMON:   TCRETURNdi @must_callee, 0, csr{{.*}}aarch64_aapcs, implicit $sp, implicit $x0
266  musttail call void @must_callee(i8* null)
267  ret void
268}
269