blob: 20f1062a44dc93cdea027ceb3b57c7ab03841e83 [file] [log] [blame]
Tim Northovere3d42362013-02-01 11:40:47 +00001; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s
Tim Northovere0e3aef2013-01-31 12:12:40 +00002
3declare void @callee_stack0()
4declare void @callee_stack8([8 x i32], i64)
5declare void @callee_stack16([8 x i32], i64, i64)
6
7define void @caller_to0_from0() nounwind {
Stephen Lind24ab202013-07-14 06:24:09 +00008; CHECK-LABEL: caller_to0_from0:
Tim Northovere0e3aef2013-01-31 12:12:40 +00009; CHECK-NEXT: // BB
10 tail call void @callee_stack0()
11 ret void
12; CHECK-NEXT: b callee_stack0
13}
14
15define void @caller_to0_from8([8 x i32], i64) nounwind{
Stephen Lind24ab202013-07-14 06:24:09 +000016; CHECK-LABEL: caller_to0_from8:
Tim Northovere0e3aef2013-01-31 12:12:40 +000017; CHECK-NEXT: // BB
18
19 tail call void @callee_stack0()
20 ret void
21; CHECK-NEXT: b callee_stack0
22}
23
24define void @caller_to8_from0() {
Stephen Lind24ab202013-07-14 06:24:09 +000025; CHECK-LABEL: caller_to8_from0:
Tim Northovere0e3aef2013-01-31 12:12:40 +000026
27; Caller isn't going to clean up any extra stack we allocate, so it
28; can't be a tail call.
29 tail call void @callee_stack8([8 x i32] undef, i64 42)
30 ret void
31; CHECK: bl callee_stack8
32}
33
34define void @caller_to8_from8([8 x i32], i64 %a) {
Stephen Lind24ab202013-07-14 06:24:09 +000035; CHECK-LABEL: caller_to8_from8:
Tim Northovere0e3aef2013-01-31 12:12:40 +000036; CHECK-NOT: sub sp, sp,
37
38; This should reuse our stack area for the 42
39 tail call void @callee_stack8([8 x i32] undef, i64 42)
40 ret void
41; CHECK: str {{x[0-9]+}}, [sp]
42; CHECK-NEXT: b callee_stack8
43}
44
45define void @caller_to16_from8([8 x i32], i64 %a) {
Stephen Lind24ab202013-07-14 06:24:09 +000046; CHECK-LABEL: caller_to16_from8:
Tim Northovere0e3aef2013-01-31 12:12:40 +000047
48; Shouldn't be a tail call: we can't use SP+8 because our caller might
49; have something there. This may sound obvious but implementation does
50; some funky aligning.
51 tail call void @callee_stack16([8 x i32] undef, i64 undef, i64 undef)
52; CHECK: bl callee_stack16
53 ret void
54}
55
56define void @caller_to8_from24([8 x i32], i64 %a, i64 %b, i64 %c) {
Stephen Lind24ab202013-07-14 06:24:09 +000057; CHECK-LABEL: caller_to8_from24:
Tim Northovere0e3aef2013-01-31 12:12:40 +000058; CHECK-NOT: sub sp, sp
59
60; Reuse our area, putting "42" at incoming sp
61 tail call void @callee_stack8([8 x i32] undef, i64 42)
62 ret void
63; CHECK: str {{x[0-9]+}}, [sp]
64; CHECK-NEXT: b callee_stack8
65}
66
67define void @caller_to16_from16([8 x i32], i64 %a, i64 %b) {
Stephen Lind24ab202013-07-14 06:24:09 +000068; CHECK-LABEL: caller_to16_from16:
Tim Northovere0e3aef2013-01-31 12:12:40 +000069; CHECK-NOT: sub sp, sp,
70
71; Here we want to make sure that both loads happen before the stores:
72; otherwise either %a or %b will be wrongly clobbered.
73 tail call void @callee_stack16([8 x i32] undef, i64 %b, i64 %a)
74 ret void
75
76; CHECK: ldr x0,
77; CHECK: ldr x1,
78; CHECK: str x1,
79; CHECK: str x0,
80
81; CHECK-NOT: add sp, sp,
82; CHECK: b callee_stack16
83}
84
85@func = global void(i32)* null
86
87define void @indirect_tail() {
Stephen Lind24ab202013-07-14 06:24:09 +000088; CHECK-LABEL: indirect_tail:
Tim Northovere0e3aef2013-01-31 12:12:40 +000089; CHECK-NOT: sub sp, sp
90
91 %fptr = load void(i32)** @func
92 tail call void %fptr(i32 42)
93 ret void
Tim Northovere0e3aef2013-01-31 12:12:40 +000094; CHECK: ldr [[FPTR:x[1-9]+]], [{{x[0-9]+}}, #:lo12:func]
Tim Northoverb65f6b02013-05-29 19:32:06 +000095; CHECK: movz w0, #42
Tim Northovere0e3aef2013-01-31 12:12:40 +000096; CHECK: br [[FPTR]]
Tim Northoverb65f6b02013-05-29 19:32:06 +000097}