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