1; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -tailcallopt | FileCheck %s
2
3declare fastcc void @callee_stack0()
4declare fastcc void @callee_stack8([8 x i32], i64)
5declare fastcc void @callee_stack16([8 x i32], i64, i64)
6
7define fastcc void @caller_to0_from0() nounwind {
8; CHECK-LABEL: caller_to0_from0:
9; CHECK-NEXT: // BB
10  tail call fastcc void @callee_stack0()
11  ret void
12; CHECK-NEXT: b callee_stack0
13}
14
15define fastcc void @caller_to0_from8([8 x i32], i64) {
16; CHECK-LABEL: caller_to0_from8:
17
18  tail call fastcc void @callee_stack0()
19  ret void
20; CHECK: add sp, sp, #16
21; CHECK-NEXT: b callee_stack0
22}
23
24define fastcc void @caller_to8_from0() {
25; CHECK-LABEL: caller_to8_from0:
26; CHECK: sub sp, sp, #32
27
28; Key point is that the "42" should go #16 below incoming stack
29; pointer (we didn't have arg space to reuse).
30  tail call fastcc void @callee_stack8([8 x i32] undef, i64 42)
31  ret void
32; CHECK: str {{x[0-9]+}}, [sp, #16]
33; CHECK-NEXT: add sp, sp, #16
34; CHECK-NEXT: b callee_stack8
35}
36
37define fastcc void @caller_to8_from8([8 x i32], i64 %a) {
38; CHECK-LABEL: caller_to8_from8:
39; CHECK: sub sp, sp, #16
40
41; Key point is that the "%a" should go where at SP on entry.
42  tail call fastcc void @callee_stack8([8 x i32] undef, i64 42)
43  ret void
44; CHECK: str {{x[0-9]+}}, [sp, #16]
45; CHECK-NEXT: add sp, sp, #16
46; CHECK-NEXT: b callee_stack8
47}
48
49define fastcc void @caller_to16_from8([8 x i32], i64 %a) {
50; CHECK-LABEL: caller_to16_from8:
51; CHECK: sub sp, sp, #16
52
53; Important point is that the call reuses the "dead" argument space
54; above %a on the stack. If it tries to go below incoming-SP then the
55; callee will not deallocate the space, even in fastcc.
56  tail call fastcc void @callee_stack16([8 x i32] undef, i64 42, i64 2)
57; CHECK: str {{x[0-9]+}}, [sp, #24]
58; CHECK: str {{x[0-9]+}}, [sp, #16]
59; CHECK: add sp, sp, #16
60; CHECK: b callee_stack16
61  ret void
62}
63
64
65define fastcc void @caller_to8_from24([8 x i32], i64 %a, i64 %b, i64 %c) {
66; CHECK-LABEL: caller_to8_from24:
67; CHECK: sub sp, sp, #16
68
69; Key point is that the "%a" should go where at #16 above SP on entry.
70  tail call fastcc void @callee_stack8([8 x i32] undef, i64 42)
71  ret void
72; CHECK: str {{x[0-9]+}}, [sp, #32]
73; CHECK-NEXT: add sp, sp, #32
74; CHECK-NEXT: b callee_stack8
75}
76
77
78define fastcc void @caller_to16_from16([8 x i32], i64 %a, i64 %b) {
79; CHECK-LABEL: caller_to16_from16:
80; CHECK: sub sp, sp, #16
81
82; Here we want to make sure that both loads happen before the stores:
83; otherwise either %a or %b will be wrongly clobbered.
84  tail call fastcc void @callee_stack16([8 x i32] undef, i64 %b, i64 %a)
85  ret void
86
87; CHECK: ldr x0,
88; CHECK: ldr x1,
89; CHECK: str x1,
90; CHECK: str x0,
91
92; CHECK: add sp, sp, #16
93; CHECK: b callee_stack16
94}
95