1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mattr=+sve -force-streaming-compatible < %s | FileCheck %s
3 ; RUN: llc -mattr=+sme -force-streaming < %s | FileCheck %s
4 ; RUN: llc -force-streaming-compatible < %s | FileCheck %s --check-prefix=NONEON-NOSVE
7 ; Test we can code generater patterns of the form:
8 ; fixed_length_vector = ISD::EXTRACT_SUBVECTOR scalable_vector, 0
9 ; scalable_vector = ISD::INSERT_SUBVECTOR scalable_vector, fixed_length_vector, 0
11 ; NOTE: Currently shufflevector does not support scalable vectors so it cannot
12 ; be used to model the above operations. Instead these tests rely on knowing
13 ; how fixed length operation are lowered to scalable ones, with multiple blocks
14 ; ensuring insert/extract sequences are not folded away.
16 target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
17 target triple = "aarch64-unknown-linux-gnu"
20 define void @subvector_v4i8(ptr %in, ptr %out) {
21 ; CHECK-LABEL: subvector_v4i8:
22 ; CHECK: // %bb.0: // %bb1
23 ; CHECK-NEXT: ptrue p0.h, vl4
24 ; CHECK-NEXT: ld1b { z0.h }, p0/z, [x0]
25 ; CHECK-NEXT: st1b { z0.h }, p0, [x1]
28 ; NONEON-NOSVE-LABEL: subvector_v4i8:
29 ; NONEON-NOSVE: // %bb.0: // %bb1
30 ; NONEON-NOSVE-NEXT: ldrh w8, [x0, #2]
31 ; NONEON-NOSVE-NEXT: ldrb w9, [x0, #1]
32 ; NONEON-NOSVE-NEXT: ldrb w10, [x0]
33 ; NONEON-NOSVE-NEXT: strh w8, [x1, #2]
34 ; NONEON-NOSVE-NEXT: strb w9, [x1, #1]
35 ; NONEON-NOSVE-NEXT: strb w10, [x1]
36 ; NONEON-NOSVE-NEXT: ret
37 %a = load <4 x i8>, ptr %in
41 store <4 x i8> %a, ptr %out
45 define void @subvector_v8i8(ptr %in, ptr %out) {
46 ; CHECK-LABEL: subvector_v8i8:
47 ; CHECK: // %bb.0: // %bb1
48 ; CHECK-NEXT: ldr d0, [x0]
49 ; CHECK-NEXT: str d0, [x1]
52 ; NONEON-NOSVE-LABEL: subvector_v8i8:
53 ; NONEON-NOSVE: // %bb.0: // %bb1
54 ; NONEON-NOSVE-NEXT: ldr d0, [x0]
55 ; NONEON-NOSVE-NEXT: str d0, [x1]
56 ; NONEON-NOSVE-NEXT: ret
57 %a = load <8 x i8>, ptr %in
61 store <8 x i8> %a, ptr %out
65 define void @subvector_v16i8(ptr %in, ptr %out) {
66 ; CHECK-LABEL: subvector_v16i8:
67 ; CHECK: // %bb.0: // %bb1
68 ; CHECK-NEXT: ldr q0, [x0]
69 ; CHECK-NEXT: str q0, [x1]
72 ; NONEON-NOSVE-LABEL: subvector_v16i8:
73 ; NONEON-NOSVE: // %bb.0: // %bb1
74 ; NONEON-NOSVE-NEXT: ldr q0, [x0]
75 ; NONEON-NOSVE-NEXT: str q0, [x1]
76 ; NONEON-NOSVE-NEXT: ret
77 %a = load <16 x i8>, ptr %in
81 store <16 x i8> %a, ptr %out
85 define void @subvector_v32i8(ptr %in, ptr %out) {
86 ; CHECK-LABEL: subvector_v32i8:
87 ; CHECK: // %bb.0: // %bb1
88 ; CHECK-NEXT: ldp q0, q1, [x0]
89 ; CHECK-NEXT: stp q0, q1, [x1]
92 ; NONEON-NOSVE-LABEL: subvector_v32i8:
93 ; NONEON-NOSVE: // %bb.0: // %bb1
94 ; NONEON-NOSVE-NEXT: ldp q0, q1, [x0]
95 ; NONEON-NOSVE-NEXT: stp q0, q1, [x1]
96 ; NONEON-NOSVE-NEXT: ret
97 %a = load <32 x i8>, ptr %in
101 store <32 x i8> %a, ptr %out
106 define void @subvector_v2i16(ptr %in, ptr %out) {
107 ; CHECK-LABEL: subvector_v2i16:
108 ; CHECK: // %bb.0: // %bb1
109 ; CHECK-NEXT: ptrue p0.s, vl2
110 ; CHECK-NEXT: ld1h { z0.s }, p0/z, [x0]
111 ; CHECK-NEXT: st1h { z0.s }, p0, [x1]
114 ; NONEON-NOSVE-LABEL: subvector_v2i16:
115 ; NONEON-NOSVE: // %bb.0: // %bb1
116 ; NONEON-NOSVE-NEXT: ldr w8, [x0]
117 ; NONEON-NOSVE-NEXT: str w8, [x1]
118 ; NONEON-NOSVE-NEXT: ret
119 %a = load <2 x i16>, ptr %in
123 store <2 x i16> %a, ptr %out
127 define void @subvector_v4i16(ptr %in, ptr %out) {
128 ; CHECK-LABEL: subvector_v4i16:
129 ; CHECK: // %bb.0: // %bb1
130 ; CHECK-NEXT: ldr d0, [x0]
131 ; CHECK-NEXT: str d0, [x1]
134 ; NONEON-NOSVE-LABEL: subvector_v4i16:
135 ; NONEON-NOSVE: // %bb.0: // %bb1
136 ; NONEON-NOSVE-NEXT: ldr d0, [x0]
137 ; NONEON-NOSVE-NEXT: str d0, [x1]
138 ; NONEON-NOSVE-NEXT: ret
139 %a = load <4 x i16>, ptr %in
143 store <4 x i16> %a, ptr %out
147 define void @subvector_v8i16(ptr %in, ptr %out) {
148 ; CHECK-LABEL: subvector_v8i16:
149 ; CHECK: // %bb.0: // %bb1
150 ; CHECK-NEXT: ldr q0, [x0]
151 ; CHECK-NEXT: str q0, [x1]
154 ; NONEON-NOSVE-LABEL: subvector_v8i16:
155 ; NONEON-NOSVE: // %bb.0: // %bb1
156 ; NONEON-NOSVE-NEXT: ldr q0, [x0]
157 ; NONEON-NOSVE-NEXT: str q0, [x1]
158 ; NONEON-NOSVE-NEXT: ret
159 %a = load <8 x i16>, ptr %in
163 store <8 x i16> %a, ptr %out
167 define void @subvector_v16i16(ptr %in, ptr %out) {
168 ; CHECK-LABEL: subvector_v16i16:
169 ; CHECK: // %bb.0: // %bb1
170 ; CHECK-NEXT: ldp q0, q1, [x0]
171 ; CHECK-NEXT: stp q0, q1, [x1]
174 ; NONEON-NOSVE-LABEL: subvector_v16i16:
175 ; NONEON-NOSVE: // %bb.0: // %bb1
176 ; NONEON-NOSVE-NEXT: ldp q0, q1, [x0]
177 ; NONEON-NOSVE-NEXT: stp q0, q1, [x1]
178 ; NONEON-NOSVE-NEXT: ret
179 %a = load <16 x i16>, ptr %in
183 store <16 x i16> %a, ptr %out
188 define void @subvector_v2i32(ptr %in, ptr %out) {
189 ; CHECK-LABEL: subvector_v2i32:
190 ; CHECK: // %bb.0: // %bb1
191 ; CHECK-NEXT: ldr d0, [x0]
192 ; CHECK-NEXT: str d0, [x1]
195 ; NONEON-NOSVE-LABEL: subvector_v2i32:
196 ; NONEON-NOSVE: // %bb.0: // %bb1
197 ; NONEON-NOSVE-NEXT: ldr d0, [x0]
198 ; NONEON-NOSVE-NEXT: str d0, [x1]
199 ; NONEON-NOSVE-NEXT: ret
200 %a = load <2 x i32>, ptr %in
204 store <2 x i32> %a, ptr %out
208 define void @subvector_v4i32(ptr %in, ptr %out) {
209 ; CHECK-LABEL: subvector_v4i32:
210 ; CHECK: // %bb.0: // %bb1
211 ; CHECK-NEXT: ldr q0, [x0]
212 ; CHECK-NEXT: str q0, [x1]
215 ; NONEON-NOSVE-LABEL: subvector_v4i32:
216 ; NONEON-NOSVE: // %bb.0: // %bb1
217 ; NONEON-NOSVE-NEXT: ldr q0, [x0]
218 ; NONEON-NOSVE-NEXT: str q0, [x1]
219 ; NONEON-NOSVE-NEXT: ret
220 %a = load <4 x i32>, ptr %in
224 store <4 x i32> %a, ptr %out
228 define void @subvector_v8i32(ptr %in, ptr %out) {
229 ; CHECK-LABEL: subvector_v8i32:
230 ; CHECK: // %bb.0: // %bb1
231 ; CHECK-NEXT: ldp q0, q1, [x0]
232 ; CHECK-NEXT: stp q0, q1, [x1]
235 ; NONEON-NOSVE-LABEL: subvector_v8i32:
236 ; NONEON-NOSVE: // %bb.0: // %bb1
237 ; NONEON-NOSVE-NEXT: ldp q0, q1, [x0]
238 ; NONEON-NOSVE-NEXT: stp q0, q1, [x1]
239 ; NONEON-NOSVE-NEXT: ret
240 %a = load <8 x i32>, ptr %in
244 store <8 x i32> %a, ptr %out
249 define void @subvector_v2i64(ptr %in, ptr %out) {
250 ; CHECK-LABEL: subvector_v2i64:
251 ; CHECK: // %bb.0: // %bb1
252 ; CHECK-NEXT: ldr q0, [x0]
253 ; CHECK-NEXT: str q0, [x1]
256 ; NONEON-NOSVE-LABEL: subvector_v2i64:
257 ; NONEON-NOSVE: // %bb.0: // %bb1
258 ; NONEON-NOSVE-NEXT: ldr q0, [x0]
259 ; NONEON-NOSVE-NEXT: str q0, [x1]
260 ; NONEON-NOSVE-NEXT: ret
261 %a = load <2 x i64>, ptr %in
265 store <2 x i64> %a, ptr %out
269 define void @subvector_v4i64(ptr %in, ptr %out) {
270 ; CHECK-LABEL: subvector_v4i64:
271 ; CHECK: // %bb.0: // %bb1
272 ; CHECK-NEXT: ldp q0, q1, [x0]
273 ; CHECK-NEXT: stp q0, q1, [x1]
276 ; NONEON-NOSVE-LABEL: subvector_v4i64:
277 ; NONEON-NOSVE: // %bb.0: // %bb1
278 ; NONEON-NOSVE-NEXT: ldp q0, q1, [x0]
279 ; NONEON-NOSVE-NEXT: stp q0, q1, [x1]
280 ; NONEON-NOSVE-NEXT: ret
281 %a = load <4 x i64>, ptr %in
285 store <4 x i64> %a, ptr %out
290 define void @subvector_v2f16(ptr %in, ptr %out) {
291 ; CHECK-LABEL: subvector_v2f16:
292 ; CHECK: // %bb.0: // %bb1
293 ; CHECK-NEXT: ldr w8, [x0]
294 ; CHECK-NEXT: str w8, [x1]
297 ; NONEON-NOSVE-LABEL: subvector_v2f16:
298 ; NONEON-NOSVE: // %bb.0: // %bb1
299 ; NONEON-NOSVE-NEXT: ldr w8, [x0]
300 ; NONEON-NOSVE-NEXT: str w8, [x1]
301 ; NONEON-NOSVE-NEXT: ret
302 %a = load <2 x half>, ptr %in
306 store <2 x half> %a, ptr %out
310 define void @subvector_v4f16(ptr %in, ptr %out) {
311 ; CHECK-LABEL: subvector_v4f16:
312 ; CHECK: // %bb.0: // %bb1
313 ; CHECK-NEXT: ldr d0, [x0]
314 ; CHECK-NEXT: str d0, [x1]
317 ; NONEON-NOSVE-LABEL: subvector_v4f16:
318 ; NONEON-NOSVE: // %bb.0: // %bb1
319 ; NONEON-NOSVE-NEXT: ldr d0, [x0]
320 ; NONEON-NOSVE-NEXT: str d0, [x1]
321 ; NONEON-NOSVE-NEXT: ret
322 %a = load <4 x half>, ptr %in
326 store <4 x half> %a, ptr %out
330 define void @subvector_v8f16(ptr %in, ptr %out) {
331 ; CHECK-LABEL: subvector_v8f16:
332 ; CHECK: // %bb.0: // %bb1
333 ; CHECK-NEXT: ldr q0, [x0]
334 ; CHECK-NEXT: str q0, [x1]
337 ; NONEON-NOSVE-LABEL: subvector_v8f16:
338 ; NONEON-NOSVE: // %bb.0: // %bb1
339 ; NONEON-NOSVE-NEXT: ldr q0, [x0]
340 ; NONEON-NOSVE-NEXT: str q0, [x1]
341 ; NONEON-NOSVE-NEXT: ret
342 %a = load <8 x half>, ptr %in
346 store <8 x half> %a, ptr %out
350 define void @subvector_v16f16(ptr %in, ptr %out) {
351 ; CHECK-LABEL: subvector_v16f16:
352 ; CHECK: // %bb.0: // %bb1
353 ; CHECK-NEXT: ldp q0, q1, [x0]
354 ; CHECK-NEXT: stp q0, q1, [x1]
357 ; NONEON-NOSVE-LABEL: subvector_v16f16:
358 ; NONEON-NOSVE: // %bb.0: // %bb1
359 ; NONEON-NOSVE-NEXT: ldp q0, q1, [x0]
360 ; NONEON-NOSVE-NEXT: stp q0, q1, [x1]
361 ; NONEON-NOSVE-NEXT: ret
362 %a = load <16 x half>, ptr %in
366 store <16 x half> %a, ptr %out
371 define void @subvector_v2f32(ptr %in, ptr %out) {
372 ; CHECK-LABEL: subvector_v2f32:
373 ; CHECK: // %bb.0: // %bb1
374 ; CHECK-NEXT: ldr d0, [x0]
375 ; CHECK-NEXT: str d0, [x1]
378 ; NONEON-NOSVE-LABEL: subvector_v2f32:
379 ; NONEON-NOSVE: // %bb.0: // %bb1
380 ; NONEON-NOSVE-NEXT: ldr d0, [x0]
381 ; NONEON-NOSVE-NEXT: str d0, [x1]
382 ; NONEON-NOSVE-NEXT: ret
383 %a = load <2 x float>, ptr %in
387 store <2 x float> %a, ptr %out
391 define void @subvector_v4f32(ptr %in, ptr %out) {
392 ; CHECK-LABEL: subvector_v4f32:
393 ; CHECK: // %bb.0: // %bb1
394 ; CHECK-NEXT: ldr q0, [x0]
395 ; CHECK-NEXT: str q0, [x1]
398 ; NONEON-NOSVE-LABEL: subvector_v4f32:
399 ; NONEON-NOSVE: // %bb.0: // %bb1
400 ; NONEON-NOSVE-NEXT: ldr q0, [x0]
401 ; NONEON-NOSVE-NEXT: str q0, [x1]
402 ; NONEON-NOSVE-NEXT: ret
403 %a = load <4 x float>, ptr %in
407 store <4 x float> %a, ptr %out
411 define void @subvector_v8f32(ptr %in, ptr %out) {
412 ; CHECK-LABEL: subvector_v8f32:
413 ; CHECK: // %bb.0: // %bb1
414 ; CHECK-NEXT: ldp q0, q1, [x0]
415 ; CHECK-NEXT: stp q0, q1, [x1]
418 ; NONEON-NOSVE-LABEL: subvector_v8f32:
419 ; NONEON-NOSVE: // %bb.0: // %bb1
420 ; NONEON-NOSVE-NEXT: ldp q0, q1, [x0]
421 ; NONEON-NOSVE-NEXT: stp q0, q1, [x1]
422 ; NONEON-NOSVE-NEXT: ret
423 %a = load <8 x float>,ptr %in
427 store <8 x float> %a, ptr %out
432 define void @subvector_v2f64(ptr %in, ptr %out) {
433 ; CHECK-LABEL: subvector_v2f64:
434 ; CHECK: // %bb.0: // %bb1
435 ; CHECK-NEXT: ldr q0, [x0]
436 ; CHECK-NEXT: str q0, [x1]
439 ; NONEON-NOSVE-LABEL: subvector_v2f64:
440 ; NONEON-NOSVE: // %bb.0: // %bb1
441 ; NONEON-NOSVE-NEXT: ldr q0, [x0]
442 ; NONEON-NOSVE-NEXT: str q0, [x1]
443 ; NONEON-NOSVE-NEXT: ret
444 %a = load <2 x double>, ptr %in
448 store <2 x double> %a, ptr %out
452 define void @subvector_v4f64(ptr %in, ptr %out) {
453 ; CHECK-LABEL: subvector_v4f64:
454 ; CHECK: // %bb.0: // %bb1
455 ; CHECK-NEXT: ldp q0, q1, [x0]
456 ; CHECK-NEXT: stp q0, q1, [x1]
459 ; NONEON-NOSVE-LABEL: subvector_v4f64:
460 ; NONEON-NOSVE: // %bb.0: // %bb1
461 ; NONEON-NOSVE-NEXT: ldp q0, q1, [x0]
462 ; NONEON-NOSVE-NEXT: stp q0, q1, [x1]
463 ; NONEON-NOSVE-NEXT: ret
464 %a = load <4 x double>, ptr %in
468 store <4 x double> %a, ptr %out