Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / CodeGen / AArch64 / sve-calling-convention.ll
blobbfb750517cbf95914971a1a535b7812cea7c46ab
1 ; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve -stop-after=finalize-isel < %s | FileCheck %s
2 ; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve -stop-after=prologepilog < %s | FileCheck %s --check-prefix=CHECKCSR
4 ; CHECK-LABEL: name: nosve_signature
5 define i32 @nosve_signature() nounwind {
6   ret i32 42
9 ; CHECK-LABEL: name: sve_signature_ret_vec
10 define <vscale x 4 x i32> @sve_signature_ret_vec() nounwind {
11   ret <vscale x 4 x i32> undef
14 ; CHECK-LABEL: name: sve_signature_ret_pred
15 define <vscale x 4 x i1> @sve_signature_ret_pred() nounwind {
16   ret <vscale x 4 x i1> undef
19 ; CHECK-LABEL: name: sve_signature_arg_vec
20 define void @sve_signature_arg_vec(<vscale x 4 x i32> %arg) nounwind {
21   ret void
24 ; CHECK-LABEL: name: sve_signature_arg_pred
25 define void @sve_signature_arg_pred(<vscale x 4 x i1> %arg) nounwind {
26   ret void
29 ; CHECK-LABEL: name: caller_nosve_signature
30 ; CHECK: BL @nosve_signature, csr_aarch64_aapcs
31 define i32 @caller_nosve_signature() nounwind {
32   %res = call i32 @nosve_signature()
33   ret i32 %res
36 ; CHECK-LABEL: name: caller_nosve_signature_fastcc
37 ; CHECK: BL @nosve_signature, csr_aarch64_aapcs
38 define i32 @caller_nosve_signature_fastcc() nounwind {
39   %res = call fastcc i32 @nosve_signature()
40   ret i32 %res
43 ; CHECK-LABEL: name: sve_signature_ret_vec_caller
44 ; CHECK: BL @sve_signature_ret_vec, csr_aarch64_sve_aapcs
45 define <vscale x 4 x i32>  @sve_signature_ret_vec_caller() nounwind {
46   %res = call <vscale x 4 x i32> @sve_signature_ret_vec()
47   ret <vscale x 4 x i32> %res
50 ; CHECK-LABEL: name: sve_signature_ret_vec_caller_fastcc
51 ; CHECK: BL @sve_signature_ret_vec, csr_aarch64_sve_aapcs
52 define <vscale x 4 x i32>  @sve_signature_ret_vec_caller_fastcc() nounwind {
53   %res = call fastcc <vscale x 4 x i32> @sve_signature_ret_vec()
54   ret <vscale x 4 x i32> %res
57 ; CHECK-LABEL: name: sve_signature_ret_pred_caller
58 ; CHECK: BL @sve_signature_ret_pred, csr_aarch64_sve_aapcs
59 define <vscale x 4 x i1>  @sve_signature_ret_pred_caller() nounwind {
60   %res = call <vscale x 4 x i1> @sve_signature_ret_pred()
61   ret <vscale x 4 x i1> %res
64 ; CHECK-LABEL: name: sve_signature_ret_pred_caller_fastcc
65 ; CHECK: BL @sve_signature_ret_pred, csr_aarch64_sve_aapcs
66 define <vscale x 4 x i1>  @sve_signature_ret_pred_caller_fastcc() nounwind {
67   %res = call fastcc <vscale x 4 x i1> @sve_signature_ret_pred()
68   ret <vscale x 4 x i1> %res
71 ; CHECK-LABEL: name: sve_signature_arg_vec_caller
72 ; CHECK: BL @sve_signature_arg_vec, csr_aarch64_sve_aapcs
73 define void @sve_signature_arg_vec_caller(<vscale x 4 x i32> %arg) nounwind {
74   call void @sve_signature_arg_vec(<vscale x 4 x i32> %arg)
75   ret void
78 ; CHECK-LABEL: name: sve_signature_arg_vec_caller_fastcc
79 ; CHECK: BL @sve_signature_arg_vec, csr_aarch64_sve_aapcs
80 define void @sve_signature_arg_vec_caller_fastcc(<vscale x 4 x i32> %arg) nounwind {
81   call fastcc void @sve_signature_arg_vec(<vscale x 4 x i32> %arg)
82   ret void
85 ; CHECK-LABEL: name: sve_signature_arg_pred_caller
86 ; CHECK: BL @sve_signature_arg_pred, csr_aarch64_sve_aapcs
87 define void @sve_signature_arg_pred_caller(<vscale x 4 x i1> %arg) nounwind {
88   call void @sve_signature_arg_pred(<vscale x 4 x i1> %arg)
89   ret void
92 ; CHECK-LABEL: name: sve_signature_arg_pred_caller_fastcc
93 ; CHECK: BL @sve_signature_arg_pred, csr_aarch64_sve_aapcs
94 define void @sve_signature_arg_pred_caller_fastcc(<vscale x 4 x i1> %arg) nounwind {
95   call fastcc void @sve_signature_arg_pred(<vscale x 4 x i1> %arg)
96   ret void
99 ; CHECK-LABEL: name: sve_signature_many_arg_vec
100 ; CHECK: [[RES:%[0-9]+]]:zpr = COPY $z7
101 ; CHECK: $z0 = COPY [[RES]]
102 ; CHECK: RET_ReallyLR implicit $z0
103 define <vscale x 4 x i32> @sve_signature_many_arg_vec(<vscale x 4 x i32> %arg1, <vscale x 4 x i32> %arg2, <vscale x 4 x i32> %arg3, <vscale x 4 x i32> %arg4, <vscale x 4 x i32> %arg5, <vscale x 4 x i32> %arg6, <vscale x 4 x i32> %arg7, <vscale x 4 x i32> %arg8) nounwind {
104   ret <vscale x 4 x i32> %arg8
107 ; CHECK-LABEL: name: sve_signature_many_arg_pred
108 ; CHECK: [[RES:%[0-9]+]]:ppr = COPY $p3
109 ; CHECK: $p0 = COPY [[RES]]
110 ; CHECK: RET_ReallyLR implicit $p0
111 define <vscale x 4 x i1> @sve_signature_many_arg_pred(<vscale x 4 x i1> %arg1, <vscale x 4 x i1> %arg2, <vscale x 4 x i1> %arg3, <vscale x 4 x i1> %arg4) nounwind {
112   ret <vscale x 4 x i1> %arg4
115 ; CHECK-LABEL: name: sve_signature_vec
116 ; CHECK: [[RES:%[0-9]+]]:zpr = COPY $z1
117 ; CHECK: $z0 = COPY [[RES]]
118 ; CHECK: RET_ReallyLR implicit $z0
119 define <vscale x 4 x i32> @sve_signature_vec(<vscale x 4 x i32> %arg1, <vscale x 4 x i32> %arg2) nounwind {
120  ret <vscale x 4 x i32> %arg2
123 ; CHECK-LABEL: name: sve_signature_pred
124 ; CHECK: [[RES:%[0-9]+]]:ppr = COPY $p1
125 ; CHECK: $p0 = COPY [[RES]]
126 ; CHECK: RET_ReallyLR implicit $p0
127 define <vscale x 4 x i1> @sve_signature_pred(<vscale x 4 x i1> %arg1, <vscale x 4 x i1> %arg2) nounwind {
128   ret <vscale x 4 x i1> %arg2
131 ; Test that scalable predicate argument in [1 x <vscale x 4 x i1>] type are properly assigned to P registers.
132 ; CHECK-LABEL: name: sve_signature_pred_1xv4i1
133 ; CHECK: [[RES:%[0-9]+]]:ppr = COPY $p1
134 ; CHECK: $p0 = COPY [[RES]]
135 ; CHECK: RET_ReallyLR implicit $p0
136 define [1 x <vscale x 4 x i1>] @sve_signature_pred_1xv4i1([1 x <vscale x 4 x i1>] %arg1, [1 x <vscale x 4 x i1>] %arg2) nounwind {
137   ret [1 x <vscale x 4 x i1>] %arg2
140 ; Test that upto to two scalable predicate arguments in [2 x <vscale x 4 x i1>] type can be assigned to P registers.
141 ; CHECK-LABEL: name: sve_signature_pred_2xv4i1
142 ; CHECK: [[RES1:%[0-9]+]]:ppr = COPY $p3
143 ; CHECK: [[RES0:%[0-9]+]]:ppr = COPY $p2
144 ; CHECK: $p0 = COPY [[RES0]]
145 ; CHECK: $p1 = COPY [[RES1]]
146 ; CHECK: RET_ReallyLR implicit $p0, implicit $p1
147 define [2 x <vscale x 4 x i1>] @sve_signature_pred_2xv4i1([2 x <vscale x 4 x i1>] %arg1, [2 x <vscale x 4 x i1>] %arg2) nounwind {
148   ret [2 x <vscale x 4 x i1>] %arg2
151 ; Test that a scalable predicate argument in [1 x <vscale x 32 x i1>] type is assigned to two P registers.
152 ; CHECK-LABLE: name: sve_signature_pred_1xv32i1
153 ; CHECK: [[RES1:%[0-9]+]]:ppr = COPY $p3
154 ; CHECK: [[RES0:%[0-9]+]]:ppr = COPY $p2
155 ; CHECK: $p0 = COPY [[RES0]]
156 ; CHECK: $p1 = COPY [[RES1]]
157 ; CHECK: RET_ReallyLR implicit $p0, implicit $p1
158 define [1 x <vscale x 32 x i1>] @sve_signature_pred_1xv32i1([1 x <vscale x 32 x i1>] %arg1, [1 x <vscale x 32 x i1>] %arg2) nounwind {
159   ret [1 x <vscale x 32 x i1>] %arg2
162 ; Test that a scalable predicate argument in [2 x <vscale x 32 x i1>] type is assigned to four P registers.
163 ; CHECK-LABLE: name: sve_signature_pred_2xv32i1
164 ; CHECK: [[RES3:%[0-9]+]]:ppr = COPY $p3
165 ; CHECK: [[RES2:%[0-9]+]]:ppr = COPY $p2
166 ; CHECK: [[RES1:%[0-9]+]]:ppr = COPY $p1
167 ; CHECK: [[RES0:%[0-9]+]]:ppr = COPY $p0
168 ; CHECK: $p0 = COPY [[RES0]]
169 ; CHECK: $p1 = COPY [[RES1]]
170 ; CHECK: $p2 = COPY [[RES2]]
171 ; CHECK: $p3 = COPY [[RES3]]
172 ; CHECK: RET_ReallyLR implicit $p0, implicit $p1, implicit $p2, implicit $p3
173 define [2 x <vscale x 32 x i1>] @sve_signature_pred_2xv32i1([2 x <vscale x 32 x i1>] %arg1) nounwind {
174   ret [2 x <vscale x 32 x i1>] %arg1
177 ; CHECK-LABEL: name: sve_signature_vec_caller
178 ; CHECK-DAG: [[ARG2:%[0-9]+]]:zpr = COPY $z1
179 ; CHECK-DAG: [[ARG1:%[0-9]+]]:zpr = COPY $z0
180 ; CHECK-DAG: $z0 = COPY [[ARG2]]
181 ; CHECK-DAG: $z1 = COPY [[ARG1]]
182 ; CHECK-NEXT: BL @sve_signature_vec, csr_aarch64_sve_aapcs
183 ; CHECK: [[RES:%[0-9]+]]:zpr = COPY $z0
184 ; CHECK: $z0 = COPY [[RES]]
185 ; CHECK: RET_ReallyLR implicit $z0
186 define <vscale x 4 x i32> @sve_signature_vec_caller(<vscale x 4 x i32> %arg1, <vscale x 4 x i32> %arg2) nounwind {
187   %res = call <vscale x 4 x i32> @sve_signature_vec(<vscale x 4 x i32> %arg2, <vscale x 4 x i32> %arg1)
188   ret <vscale x 4 x i32> %res
191 ; CHECK-LABEL: name: sve_signature_pred_caller
192 ; CHECK-DAG: [[ARG2:%[0-9]+]]:ppr = COPY $p1
193 ; CHECK-DAG: [[ARG1:%[0-9]+]]:ppr = COPY $p0
194 ; CHECK-DAG: $p0 = COPY [[ARG2]]
195 ; CHECK-DAG: $p1 = COPY [[ARG1]]
196 ; CHECK-NEXT: BL @sve_signature_pred, csr_aarch64_sve_aapcs
197 ; CHECK: [[RES:%[0-9]+]]:ppr = COPY $p0
198 ; CHECK: $p0 = COPY [[RES]]
199 ; CHECK: RET_ReallyLR implicit $p0
200 define <vscale x 4 x i1> @sve_signature_pred_caller(<vscale x 4 x i1> %arg1, <vscale x 4 x i1> %arg2) nounwind {
201   %res = call <vscale x 4 x i1> @sve_signature_pred(<vscale x 4 x i1> %arg2, <vscale x 4 x i1> %arg1)
202   ret <vscale x 4 x i1> %res
205 ; CHECK-LABEL: name: sve_signature_pred_1xv4i1_caller
206 ; CHECK-DAG: [[ARG2:%[0-9]+]]:ppr = COPY $p1
207 ; CHECK-DAG: [[ARG1:%[0-9]+]]:ppr = COPY $p0
208 ; CHECK-DAG: $p0 = COPY [[ARG2]]
209 ; CHECK-DAG: $p1 = COPY [[ARG1]]
210 ; CHECK-NEXT: BL @sve_signature_pred_1xv4i1, csr_aarch64_sve_aapcs
211 ; CHECK: [[RES:%[0-9]+]]:ppr = COPY $p0
212 ; CHECK: $p0 = COPY [[RES]]
213 ; CHECK: RET_ReallyLR implicit $p0
214 define [1 x <vscale x 4 x i1>] @sve_signature_pred_1xv4i1_caller([1 x <vscale x 4 x i1>] %arg1, [1 x <vscale x 4 x i1>] %arg2) nounwind {
215   %res = call [1 x <vscale x 4 x i1>] @sve_signature_pred_1xv4i1([1 x <vscale x 4 x i1>] %arg2, [1 x <vscale x 4 x i1>] %arg1)
216   ret [1 x <vscale x 4 x i1>] %res
219 ; CHECK-LABEL: name: sve_signature_pred_2xv4i1_caller
220 ; CHECK-DAG: [[ARG2_2:%[0-9]+]]:ppr = COPY $p3
221 ; CHECK-DAG: [[ARG2_1:%[0-9]+]]:ppr = COPY $p2
222 ; CHECK-DAG: [[ARG1_2:%[0-9]+]]:ppr = COPY $p1
223 ; CHECK-DAG: [[ARG1_1:%[0-9]+]]:ppr = COPY $p0
224 ; CHECK-DAG: $p0 = COPY [[ARG2_1]]
225 ; CHECK-DAG: $p1 = COPY [[ARG2_2]]
226 ; CHECK-DAG: $p2 = COPY [[ARG1_1]]
227 ; CHECK-DAG: $p3 = COPY [[ARG1_2]]
228 ; CHECK-NEXT: BL @sve_signature_pred_2xv4i1, csr_aarch64_sve_aapcs
229 ; CHECK: [[RES0:%[0-9]+]]:ppr = COPY $p0
230 ; CHECK: [[RES1:%[0-9]+]]:ppr = COPY $p1
231 ; CHECK: $p0 = COPY [[RES0]]
232 ; CHECK: $p1 = COPY [[RES1]]
233 ; CHECK: RET_ReallyLR implicit $p0, implicit $p1
234 define [2 x <vscale x 4 x i1>] @sve_signature_pred_2xv4i1_caller([2 x <vscale x 4 x i1>] %arg1, [2 x <vscale x 4 x i1>] %arg2) nounwind {
235   %res = call [2 x <vscale x 4 x i1>] @sve_signature_pred_2xv4i1([2 x <vscale x 4 x i1>] %arg2, [2 x <vscale x 4 x i1>] %arg1)
236   ret [2 x <vscale x 4 x i1>] %res
239 ; CHECK-LABEL: name: sve_signature_pred_1xv32i1_caller
240 ; CHECK-DAG: [[ARG2_2:%[0-9]+]]:ppr = COPY $p3
241 ; CHECK-DAG: [[ARG2_1:%[0-9]+]]:ppr = COPY $p2
242 ; CHECK-DAG: [[ARG1_2:%[0-9]+]]:ppr = COPY $p1
243 ; CHECK-DAG: [[ARG1_1:%[0-9]+]]:ppr = COPY $p0
244 ; CHECK-DAG: $p0 = COPY [[ARG2_1]]
245 ; CHECK-DAG: $p1 = COPY [[ARG2_2]]
246 ; CHECK-DAG: $p2 = COPY [[ARG1_1]]
247 ; CHECK-DAG: $p3 = COPY [[ARG1_2]]
248 ; CHECK-NEXT: BL @sve_signature_pred_1xv32i1, csr_aarch64_sve_aapcs
249 ; CHECK: [[RES0:%[0-9]+]]:ppr = COPY $p0
250 ; CHECK: [[RES1:%[0-9]+]]:ppr = COPY $p1
251 ; CHECK: $p0 = COPY [[RES0]]
252 ; CHECK: $p1 = COPY [[RES1]]
253 ; CHECK: RET_ReallyLR implicit $p0, implicit $p1
254 define [1 x <vscale x 32 x i1>] @sve_signature_pred_1xv32i1_caller([1 x <vscale x 32 x i1>] %arg1, [1 x <vscale x 32 x i1>] %arg2) nounwind {
255   %res = call [1 x <vscale x 32 x i1>] @sve_signature_pred_1xv32i1([1 x <vscale x 32 x i1>] %arg2, [1 x <vscale x 32 x i1>] %arg1)
256   ret [1 x <vscale x 32 x i1>] %res
259 ; CHECK-LABEL: name: sve_signature_pred_2xv32i1_caller
260 ; CHECK-DAG: [[ARG3:%[0-9]+]]:ppr = COPY $p3
261 ; CHECK-DAG: [[ARG2:%[0-9]+]]:ppr = COPY $p2
262 ; CHECK-DAG: [[ARG1:%[0-9]+]]:ppr = COPY $p1
263 ; CHECK-DAG: [[ARG0:%[0-9]+]]:ppr = COPY $p0
264 ; CHECK-DAG: $p0 = COPY [[ARG0]]
265 ; CHECK-DAG: $p1 = COPY [[ARG1]]
266 ; CHECK-DAG: $p2 = COPY [[ARG2]]
267 ; CHECK-DAG: $p3 = COPY [[ARG3]]
268 ; CHECK-NEXT: BL @sve_signature_pred_2xv32i1, csr_aarch64_sve_aapcs
269 ; CHECK: [[RES0:%[0-9]+]]:ppr = COPY $p0
270 ; CHECK: [[RES1:%[0-9]+]]:ppr = COPY $p1
271 ; CHECK: [[RES2:%[0-9]+]]:ppr = COPY $p2
272 ; CHECK: [[RES3:%[0-9]+]]:ppr = COPY $p3
273 ; CHECK: $p0 = COPY [[RES0]]
274 ; CHECK: $p1 = COPY [[RES1]]
275 ; CHECK: $p2 = COPY [[RES2]]
276 ; CHECK: $p3 = COPY [[RES3]]
277 ; CHECK: RET_ReallyLR implicit $p0, implicit $p1
278 define [2 x <vscale x 32 x i1>] @sve_signature_pred_2xv32i1_caller([2 x <vscale x 32 x i1>] %arg1) {
279   %res = call [2 x <vscale x 32 x i1>] @sve_signature_pred_2xv32i1([2 x <vscale x 32 x i1>] %arg1)
280   ret [2 x <vscale x 32 x i1>] %res
283 ; Test that functions returning or taking SVE arguments use the correct
284 ; callee-saved set when using the default C calling convention (as opposed
285 ; to aarch64_sve_vector_pcs)
287 ; CHECKCSR-LABEL: name: sve_signature_vec_ret_callee
288 ; CHECKCSR: callee-saved-register: '$z8'
289 ; CHECKCSR: callee-saved-register: '$p4'
290 ; CHECKCSR: RET_ReallyLR
291 define <vscale x 4 x i32> @sve_signature_vec_ret_callee() nounwind {
292   call void asm sideeffect "nop", "~{z8},~{p4}"()
293   ret <vscale x 4 x i32> zeroinitializer
296 ; CHECKCSR-LABEL: name: sve_signature_vec_arg_callee
297 ; CHECKCSR: callee-saved-register: '$z8'
298 ; CHECKCSR: callee-saved-register: '$p4'
299 ; CHECKCSR: RET_ReallyLR
300 define void @sve_signature_vec_arg_callee(<vscale x 4 x i32> %v) nounwind {
301   call void asm sideeffect "nop", "~{z8},~{p4}"()
302   ret void