• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -disable-fp-elim -tailcallopt | FileCheck %s -check-prefix CHECK-TAIL
2; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -disable-fp-elim | FileCheck %s
3; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -disable-fp-elim -tailcallopt -aarch64-redzone | FileCheck %s -check-prefix CHECK-TAIL-RZ
4
5; Without tailcallopt fastcc still means the caller cleans up the
6; stack, so try to make sure this is respected.
7
8define fastcc void @func_stack0() {
9; CHECK-LABEL: func_stack0:
10; CHECK: sub sp, sp, #48
11; CHECK: add x29, sp, #32
12; CHECK: str w{{[0-9]+}}, [sp]
13
14; CHECK-TAIL-LABEL: func_stack0:
15; CHECK-TAIL: sub sp, sp, #48
16; CHECK-TAIL-NEXT: stp x29, x30, [sp, #32]
17; CHECK-TAIL-NEXT: add x29, sp, #32
18; CHECK-TAIL: str w{{[0-9]+}}, [sp]
19
20
21  call fastcc void @func_stack8([8 x i32] undef, i32 42)
22; CHECK:  bl func_stack8
23; CHECK-NOT: sub sp, sp,
24
25; CHECK-TAIL: bl func_stack8
26; CHECK-TAIL: sub sp, sp, #16
27
28
29  call fastcc void @func_stack32([8 x i32] undef, i128 0, i128 9)
30; CHECK: bl func_stack32
31; CHECK-NOT: sub sp, sp,
32
33
34; CHECK-TAIL: bl func_stack32
35; CHECK-TAIL: sub sp, sp, #32
36
37
38  call fastcc void @func_stack0()
39; CHECK: bl func_stack0
40; CHECK-NOT: sub sp, sp
41
42
43; CHECK-TAIL: bl func_stack0
44; CHECK-TAIL-NOT: sub sp, sp
45
46  ret void
47; CHECK: ldp     x29, x30, [sp, #32]
48; CHECK-NEXT: add sp, sp, #48
49; CHECK-NEXT: ret
50
51
52; CHECK-TAIL: ldp     x29, x30, [sp, #32]
53; CHECK-TAIL-NEXT: add sp, sp, #48
54; CHECK-TAIL-NEXT: ret
55}
56
57define fastcc void @func_stack8([8 x i32], i32 %stacked) {
58; CHECK-LABEL: func_stack8:
59; CHECK: sub sp, sp, #48
60; CHECK: stp x29, x30, [sp, #32]
61; CHECK: add x29, sp, #32
62; CHECK: str w{{[0-9]+}}, [sp]
63
64
65; CHECK-TAIL-LABEL: func_stack8:
66; CHECK-TAIL: sub sp, sp, #48
67; CHECK-TAIL: stp x29, x30, [sp, #32]
68; CHECK-TAIL: add x29, sp, #32
69; CHECK-TAIL: str w{{[0-9]+}}, [sp]
70
71
72  call fastcc void @func_stack8([8 x i32] undef, i32 42)
73; CHECK:  bl func_stack8
74; CHECK-NOT: sub sp, sp,
75
76
77; CHECK-TAIL: bl func_stack8
78; CHECK-TAIL: sub sp, sp, #16
79
80
81  call fastcc void @func_stack32([8 x i32] undef, i128 0, i128 9)
82; CHECK: bl func_stack32
83; CHECK-NOT: sub sp, sp,
84
85
86; CHECK-TAIL: bl func_stack32
87; CHECK-TAIL: sub sp, sp, #32
88
89
90  call fastcc void @func_stack0()
91; CHECK: bl func_stack0
92; CHECK-NOT: sub sp, sp
93
94; CHECK-TAIL: bl func_stack0
95; CHECK-TAIL-NOT: sub sp, sp
96
97  ret void
98; CHECK-NEXT: ldp     x29, x30, [sp, #32]
99; CHECK: add sp, sp, #48
100; CHECK-NEXT: ret
101
102
103; CHECK-TAIL: ldp     x29, x30, [sp, #32]
104; CHECK-TAIL-NEXT: add     sp, sp, #64
105; CHECK-TAIL-NEXT: ret
106}
107
108define fastcc void @func_stack32([8 x i32], i128 %stacked0, i128 %stacked1) {
109; CHECK-LABEL: func_stack32:
110; CHECK: add x29, sp, #32
111
112; CHECK-TAIL-LABEL: func_stack32:
113; CHECK-TAIL: add x29, sp, #32
114
115
116  call fastcc void @func_stack8([8 x i32] undef, i32 42)
117; CHECK:  bl func_stack8
118; CHECK-NOT: sub sp, sp,
119
120; CHECK-TAIL: bl func_stack8
121; CHECK-TAIL: sub sp, sp, #16
122
123
124  call fastcc void @func_stack32([8 x i32] undef, i128 0, i128 9)
125; CHECK: bl func_stack32
126; CHECK-NOT: sub sp, sp,
127
128
129; CHECK-TAIL: bl func_stack32
130; CHECK-TAIL: sub sp, sp, #32
131
132
133  call fastcc void @func_stack0()
134; CHECK: bl func_stack0
135; CHECK-NOT: sub sp, sp
136
137
138; CHECK-TAIL: bl func_stack0
139; CHECK-TAIL-NOT: sub sp, sp
140
141  ret void
142; CHECK: ldp     x29, x30, [sp, #32]
143; CHECK-NEXT: add sp, sp, #48
144; CHECK-NEXT: ret
145
146; CHECK-TAIL: ldp     x29, x30, [sp, #32]
147; CHECK-TAIL-NEXT: add     sp, sp, #80
148; CHECK-TAIL-NEXT: ret
149}
150
151; Check that arg stack pop is done after callee-save restore when no frame pointer is used.
152define fastcc void @func_stack32_leaf([8 x i32], i128 %stacked0, i128 %stacked1) {
153; CHECK-LABEL: func_stack32_leaf:
154; CHECK: str     x20, [sp, #-16]!
155; CHECK: nop
156; CHECK-NEXT: //NO_APP
157; CHECK-NEXT: ldr     x20, [sp], #16
158; CHECK-NEXT: ret
159
160; CHECK-TAIL-LABEL: func_stack32_leaf:
161; CHECK-TAIL: str     x20, [sp, #-16]!
162; CHECK-TAIL: nop
163; CHECK-TAIL-NEXT: //NO_APP
164; CHECK-TAIL-NEXT: ldr     x20, [sp], #16
165; CHECK-TAIL-NEXT: add     sp, sp, #32
166; CHECK-TAIL-NEXT: ret
167
168; CHECK-TAIL-RZ-LABEL: func_stack32_leaf:
169; CHECK-TAIL-RZ: str     x20, [sp, #-16]!
170; CHECK-TAIL-RZ-NOT: sub     sp, sp
171; CHECK-TAIL-RZ: nop
172; CHECK-TAIL-RZ-NEXT: //NO_APP
173; CHECK-TAIL-RZ-NEXT: ldr     x20, [sp], #16
174; CHECK-TAIL-RZ-NEXT: add     sp, sp, #32
175; CHECK-TAIL-RZ-NEXT: ret
176
177  ; Make sure there is a callee-save register to save/restore.
178  call void asm sideeffect "nop", "~{x20}"() nounwind
179  ret void
180}
181
182; Check that arg stack pop is done after callee-save restore when no frame pointer is used.
183define fastcc void @func_stack32_leaf_local([8 x i32], i128 %stacked0, i128 %stacked1) {
184; CHECK-LABEL: func_stack32_leaf_local:
185; CHECK: sub     sp, sp, #32
186; CHECK-NEXT: str     x20, [sp, #16]
187; CHECK: nop
188; CHECK-NEXT: //NO_APP
189; CHECK-NEXT: ldr     x20, [sp, #16]
190; CHECK-NEXT: add     sp, sp, #32
191; CHECK-NEXT: ret
192
193; CHECK-TAIL-LABEL: func_stack32_leaf_local:
194; CHECK-TAIL: sub     sp, sp, #32
195; CHECK-TAIL-NEXT: str     x20, [sp, #16]
196; CHECK-TAIL: nop
197; CHECK-TAIL-NEXT: //NO_APP
198; CHECK-TAIL-NEXT: ldr     x20, [sp, #16]
199; CHECK-TAIL-NEXT: add     sp, sp, #64
200; CHECK-TAIL-NEXT: ret
201
202; CHECK-TAIL-RZ-LABEL: func_stack32_leaf_local:
203; CHECK-TAIL-RZ: str     x20, [sp, #-16]!
204; CHECK-TAIL-RZ-NOT: sub     sp, sp
205; CHECK-TAIL-RZ: nop
206; CHECK-TAIL-RZ-NEXT: //NO_APP
207; CHECK-TAIL-RZ-NEXT: ldr     x20, [sp], #16
208; CHECK-TAIL-RZ-NEXT: add     sp, sp, #32
209; CHECK-TAIL-RZ-NEXT: ret
210
211  %val0 = alloca [2 x i64], align 8
212
213  ; Make sure there is a callee-save register to save/restore.
214  call void asm sideeffect "nop", "~{x20}"() nounwind
215  ret void
216}
217
218; Check that arg stack pop is done after callee-save restore when no frame pointer is used.
219define fastcc void @func_stack32_leaf_local_nocs([8 x i32], i128 %stacked0, i128 %stacked1) {
220; CHECK-LABEL: func_stack32_leaf_local_nocs:
221; CHECK: sub     sp, sp, #16
222; CHECK: add     sp, sp, #16
223; CHECK-NEXT: ret
224
225; CHECK-TAIL-LABEL: func_stack32_leaf_local_nocs:
226; CHECK-TAIL: sub     sp, sp, #16
227; CHECK-TAIL: add     sp, sp, #48
228; CHECK-TAIL-NEXT: ret
229
230; CHECK-TAIL-RZ-LABEL: func_stack32_leaf_local_nocs:
231; CHECK-TAIL-RZ: add     sp, sp, #32
232; CHECK-TAIL-RZ-NEXT: ret
233
234  %val0 = alloca [2 x i64], align 8
235
236  ret void
237}
238