xref: /llvm-project/llvm/test/CodeGen/AArch64/fastcc.ll (revision d0ea42a7c1bcd47aa2b8c009b40fc4278d63f5cf)
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() uwtable {
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: .cfi_def_cfa_offset 48
17; CHECK-TAIL-NEXT: stp x29, x30, [sp, #32]
18; CHECK-TAIL-NEXT: add x29, sp, #32
19; CHECK-TAIL: str w{{[0-9]+}}, [sp]
20
21
22  call fastcc void @func_stack8([8 x i64] undef, i32 42)
23; CHECK:  bl func_stack8
24; CHECK-NOT: sub sp, sp,
25; CHECK-NOT: [sp, #{{[-0-9]+}}]!
26; CHECK-NOT: [sp], #{{[-0-9]+}}
27
28; CHECK-TAIL: bl func_stack8
29; CHECK-TAIL: stp xzr, xzr, [sp, #-16]!
30
31
32  call fastcc void @func_stack32([8 x i64] undef, i128 0, i128 9)
33; CHECK: bl func_stack32
34; CHECK-NOT: sub sp, sp,
35
36
37; CHECK-TAIL: bl func_stack32
38; CHECK-TAIL: sub sp, sp, #32
39
40
41  call fastcc void @func_stack0()
42; CHECK: bl func_stack0
43; CHECK-NOT: sub sp, sp
44
45
46; CHECK-TAIL: bl func_stack0
47; CHECK-TAIL-NOT: sub sp, sp
48
49  ret void
50; CHECK: ldp     x29, x30, [sp, #32]
51; CHECK-NEXT: add sp, sp, #48
52; CHECK-NEXT: .cfi_def_cfa_offset 0
53; CHECK-NEXT: .cfi_restore w30
54; CHECK-NEXT: .cfi_restore w29
55; CHECK-NEXT: ret
56
57
58; CHECK-TAIL: ldp     x29, x30, [sp, #32]
59; CHECK-TAIL-NEXT: add sp, sp, #48
60; CHECK-TAIL-NEXT: .cfi_def_cfa_offset 0
61; CHECK-TAIL-NEXT: .cfi_restore w30
62; CHECK-TAIL-NEXT: .cfi_restore w29
63; CHECK-TAIL-NEXT: ret
64}
65
66define fastcc void @func_stack8([8 x i64], i32 %stacked) uwtable {
67; CHECK-LABEL: func_stack8:
68; CHECK: sub sp, sp, #48
69; CHECK: stp x29, x30, [sp, #32]
70; CHECK: add x29, sp, #32
71; CHECK: str w{{[0-9]+}}, [sp]
72
73
74; CHECK-TAIL-LABEL: func_stack8:
75; CHECK-TAIL: sub sp, sp, #48
76; CHECK-TAIL: stp x29, x30, [sp, #32]
77; CHECK-TAIL: add x29, sp, #32
78; CHECK-TAIL: str w{{[0-9]+}}, [sp]
79
80
81  call fastcc void @func_stack8([8 x i64] undef, i32 42)
82; CHECK:  bl func_stack8
83; CHECK-NOT: sub sp, sp,
84; CHECK-NOT: [sp, #{{[-0-9]+}}]!
85; CHECK-NOT: [sp], #{{[-0-9]+}}
86
87
88; CHECK-TAIL: bl func_stack8
89; CHECK-TAIL: stp xzr, xzr, [sp, #-16]!
90
91
92  call fastcc void @func_stack32([8 x i64] undef, i128 0, i128 9)
93; CHECK: bl func_stack32
94; CHECK-NOT: sub sp, sp,
95
96
97; CHECK-TAIL: bl func_stack32
98; CHECK-TAIL: sub sp, sp, #32
99
100
101  call fastcc void @func_stack0()
102; CHECK: bl func_stack0
103; CHECK-NOT: sub sp, sp
104
105; CHECK-TAIL: bl func_stack0
106; CHECK-TAIL-NOT: sub sp, sp
107
108  ret void
109; CHECK-NEXT: .cfi_def_cfa wsp, 48
110; CHECK-NEXT: ldp     x29, x30, [sp, #32]
111; CHECK-NEXT: add sp, sp, #48
112; CHECK-NEXT: .cfi_def_cfa_offset 0
113; CHECK-NEXT: .cfi_restore w30
114; CHECK-NEXT: .cfi_restore w29
115; CHECK-NEXT: ret
116
117
118; CHECK-TAIL: ldp     x29, x30, [sp, #32]
119; CHECK-TAIL-NEXT: add     sp, sp, #64
120; CHECK-TAIL-NEXT: .cfi_def_cfa_offset -16
121; CHECK-TAIL-NEXT: .cfi_restore w30
122; CHECK-TAIL-NEXT: .cfi_restore w29
123; CHECK-TAIL-NEXT: ret
124}
125
126define fastcc void @func_stack32([8 x i64], i128 %stacked0, i128 %stacked1) uwtable {
127; CHECK-LABEL: func_stack32:
128; CHECK: add x29, sp, #32
129
130; CHECK-TAIL-LABEL: func_stack32:
131; CHECK-TAIL: add x29, sp, #32
132
133
134  call fastcc void @func_stack8([8 x i64] undef, i32 42)
135; CHECK:  bl func_stack8
136; CHECK-NOT: sub sp, sp,
137; CHECK-NOT: [sp, #{{[-0-9]+}}]!
138; CHECK-NOT: [sp], #{{[-0-9]+}}
139
140; CHECK-TAIL: bl func_stack8
141; CHECK-TAIL: stp xzr, xzr, [sp, #-16]!
142
143
144  call fastcc void @func_stack32([8 x i64] undef, i128 0, i128 9)
145; CHECK: bl func_stack32
146; CHECK-NOT: sub sp, sp,
147
148
149; CHECK-TAIL: bl func_stack32
150; CHECK-TAIL: sub sp, sp, #32
151
152
153  call fastcc void @func_stack0()
154; CHECK: bl func_stack0
155; CHECK-NOT: sub sp, sp
156
157
158; CHECK-TAIL: bl func_stack0
159; CHECK-TAIL-NOT: sub sp, sp
160
161  ret void
162; CHECK:      .cfi_def_cfa wsp, 48
163; CHECK-NEXT: ldp x29, x30, [sp, #32]
164; CHECK-NEXT: add sp, sp, #48
165; CHECK-NEXT: .cfi_def_cfa_offset 0
166; CHECK-NEXT: .cfi_restore w30
167; CHECK-NEXT: .cfi_restore w29
168; CHECK-NEXT: ret
169
170; CHECK-TAIL: ldp     x29, x30, [sp, #32]
171; CHECK-TAIL-NEXT: add     sp, sp, #80
172; CHECK-TAIL-NEXT: .cfi_def_cfa_offset -32
173; CHECK-TAIL-NEXT: .cfi_restore w30
174; CHECK-TAIL-NEXT: .cfi_restore w29
175; CHECK-TAIL-NEXT: ret
176}
177
178; Check that arg stack pop is done after callee-save restore when no frame pointer is used.
179define fastcc void @func_stack32_leaf([8 x i64], i128 %stacked0, i128 %stacked1) uwtable {
180; CHECK-LABEL: func_stack32_leaf:
181; CHECK: str     x20, [sp, #-16]!
182; CHECK: nop
183; CHECK-NEXT: //NO_APP
184; CHECK-NEXT: ldr     x20, [sp], #16
185; CHECK-NEXT: .cfi_def_cfa_offset 0
186; CHECK-NEXT: .cfi_restore w20
187; CHECK-NEXT: ret
188
189; CHECK-TAIL-LABEL: func_stack32_leaf:
190; CHECK-TAIL: str     x20, [sp, #-16]!
191; CHECK-TAIL: nop
192; CHECK-TAIL-NEXT: //NO_APP
193; CHECK-TAIL-NEXT: ldr     x20, [sp], #16
194; CHECK-TAIL-NEXT: .cfi_def_cfa_offset 0
195; CHECK-TAIL-NEXT: add	sp, sp, #32
196; CHECK-TAIL-NEXT: .cfi_def_cfa_offset -32
197; CHECK-TAIL-NEXT: .cfi_restore w20
198; CHECK-TAIL-NEXT: ret
199
200; CHECK-TAIL-RZ-LABEL: func_stack32_leaf:
201; CHECK-TAIL-RZ: str     x20, [sp, #-16]!
202; CHECK-TAIL-RZ-NOT: sub     sp, sp
203; CHECK-TAIL-RZ: nop
204; CHECK-TAIL-RZ-NEXT: //NO_APP
205; CHECK-TAIL-RZ-NEXT: ldr     x20, [sp], #16
206; CHECK-TAIL-RZ-NEXT: .cfi_def_cfa_offset 0
207; CHECK-TAIL-RZ-NEXT: add	sp, sp, #32
208; CHECK-TAIL-RZ-NEXT: .cfi_def_cfa_offset -32
209; CHECK-TAIL-RZ-NEXT: .cfi_restore w20
210; CHECK-TAIL-RZ-NEXT: ret
211
212  ; Make sure there is a callee-save register to save/restore.
213  call void asm sideeffect "nop", "~{x20}"() nounwind
214  ret void
215}
216
217; Check that arg stack pop is done after callee-save restore when no frame pointer is used.
218define fastcc void @func_stack32_leaf_local([8 x i64], i128 %stacked0, i128 %stacked1) uwtable {
219; CHECK-LABEL: func_stack32_leaf_local:
220; CHECK: sub     sp, sp, #32
221; CHECK-NEXT:  .cfi_def_cfa_offset 32
222; CHECK-NEXT: str     x20, [sp, #16]
223; CHECK: nop
224; CHECK-NEXT: //NO_APP
225; CHECK-NEXT: ldr     x20, [sp, #16]
226; CHECK-NEXT: add     sp, sp, #32
227; CHECK-NEXT: .cfi_def_cfa_offset 0
228; CHECK-NEXT: .cfi_restore w20
229; CHECK-NEXT: ret
230
231; CHECK-TAIL-LABEL: func_stack32_leaf_local:
232; CHECK-TAIL: sub     sp, sp, #32
233; CHECK-TAIL-NEXT: .cfi_def_cfa_offset 32
234; CHECK-TAIL-NEXT: str     x20, [sp, #16]
235; CHECK-TAIL: nop
236; CHECK-TAIL-NEXT: //NO_APP
237; CHECK-TAIL-NEXT: ldr     x20, [sp, #16]
238; CHECK-TAIL-NEXT: add     sp, sp, #64
239; CHECK-TAIL-NEXT: .cfi_def_cfa_offset -32
240; CHECK-TAIL-NEXT: .cfi_restore w20
241; CHECK-TAIL-NEXT: ret
242
243; CHECK-TAIL-RZ-LABEL: func_stack32_leaf_local:
244; CHECK-TAIL-RZ: str     x20, [sp, #-16]!
245; CHECK-TAIL-RZ-NOT: sub     sp, sp
246; CHECK-TAIL-RZ: nop
247; CHECK-TAIL-RZ-NEXT: //NO_APP
248; CHECK-TAIL-RZ-NEXT: ldr     x20, [sp], #16
249; CHECK-TAIL-RZ-NEXT: .cfi_def_cfa_offset 0
250; CHECK-TAIL-RZ-NEXT: add	sp, sp, #32
251; CHECK-TAIL-RZ-NEXT: .cfi_def_cfa_offset -32
252; CHECK-TAIL-RZ-NEXT: .cfi_restore w20
253; CHECK-TAIL-RZ-NEXT: ret
254
255  %val0 = alloca [2 x i64], align 8
256
257  ; Make sure there is a callee-save register to save/restore.
258  call void asm sideeffect "nop", "~{x20}"() nounwind
259  ret void
260}
261
262; Check that arg stack pop is done after callee-save restore when no frame pointer is used.
263define fastcc void @func_stack32_leaf_local_nocs([8 x i64], i128 %stacked0, i128 %stacked1) uwtable {
264; CHECK-LABEL: func_stack32_leaf_local_nocs:
265; CHECK: sub     sp, sp, #16
266; CHECK-NEXT: .cfi_def_cfa_offset 16
267; CHECK-NEXT: add	sp, sp, #16
268; CHECK-NEXT: .cfi_def_cfa_offset 0
269; CHECK-NEXT: ret
270
271; CHECK-TAIL-LABEL: func_stack32_leaf_local_nocs:
272; CHECK-TAIL: sub     sp, sp, #16
273; CHECK-TAIL-NEXT: .cfi_def_cfa_offset 16
274; CHECK-TAIL-NEXT: add	sp, sp, #48
275; CHECK-TAIL-NEXT: .cfi_def_cfa_offset -32
276; CHECK-TAIL-NEXT: ret
277
278; CHECK-TAIL-RZ-LABEL: func_stack32_leaf_local_nocs:
279; CHECK-TAIL-RZ: add     sp, sp, #32
280; CHECK-TAIL-RZ-NEXT: .cfi_def_cfa_offset -32
281; CHECK-TAIL-RZ-NEXT: ret
282
283  %val0 = alloca [2 x i64], align 8
284
285  ret void
286}
287