1; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -tailcallopt | FileCheck %s
2; RUN: llc -global-isel -global-isel-abort=1 -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -tailcallopt | FileCheck %s
3
4; This test is designed to be run in the situation where the
5; call-frame is not reserved (hence disable-fp-elim), but where
6; callee-pop can occur (hence tailcallopt).
7
8declare fastcc void @will_pop([8 x i64], i32 %val)
9
10define fastcc void @foo(i32 %in) {
11; CHECK-LABEL: foo:
12
13  %addr = alloca i8, i32 %in
14
15; Normal frame setup stuff:
16; CHECK: stp     x29, x30, [sp, #-16]!
17; CHECK: mov     x29, sp
18
19; Reserve space for call-frame:
20; CHECK: str w{{[0-9]+}}, [sp, #-16]!
21
22  call fastcc void @will_pop([8 x i64] undef, i32 42)
23; CHECK: bl will_pop
24
25; Since @will_pop is fastcc with tailcallopt, it will put the stack
26; back where it needs to be, we shouldn't duplicate that
27; CHECK-NOT: sub sp, sp, #16
28; CHECK-NOT: add sp, sp,
29
30; CHECK: mov     sp, x29
31; CHECK: ldp     x29, x30, [sp], #16
32  ret void
33}
34
35declare void @wont_pop([8 x i64], i32 %val)
36
37define void @foo1(i32 %in) {
38; CHECK-LABEL: foo1:
39
40  %addr = alloca i8, i32 %in
41; Normal frame setup again
42; CHECK: stp     x29, x30, [sp, #-16]!
43; CHECK: mov     x29, sp
44
45; Reserve space for call-frame
46; CHECK: str w{{[0-9]+}}, [sp, #-16]!
47
48  call void @wont_pop([8 x i64] undef, i32 42)
49; CHECK: bl wont_pop
50
51; This time we *do* need to unreserve the call-frame
52; CHECK: add sp, sp, #16
53
54; Check for epilogue (primarily to make sure sp spotted above wasn't
55; part of it).
56; CHECK: mov     sp, x29
57; CHECK: ldp     x29, x30, [sp], #16
58  ret void
59}
60