xref: /llvm-project/llvm/test/CodeGen/AArch64/sve-streaming-mode-fixed-length-subvector.ll (revision 8e0cd7382adacd8bc1741dc26bc0be6bdf8e238a)
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
5
6
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
10;
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.
15
16target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
17target triple = "aarch64-unknown-linux-gnu"
18
19; i8
20define 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]
26; CHECK-NEXT:    ret
27;
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
38  br label %bb1
39
40bb1:
41  store <4 x i8> %a, ptr %out
42  ret void
43}
44
45define 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]
50; CHECK-NEXT:    ret
51;
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
58  br label %bb1
59
60bb1:
61  store <8 x i8> %a, ptr %out
62  ret void
63}
64
65define 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]
70; CHECK-NEXT:    ret
71;
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
78  br label %bb1
79
80bb1:
81  store <16 x i8> %a, ptr %out
82  ret void
83}
84
85define 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]
90; CHECK-NEXT:    ret
91;
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
98  br label %bb1
99
100bb1:
101  store <32 x i8> %a, ptr %out
102  ret void
103}
104
105; i16
106define 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]
112; CHECK-NEXT:    ret
113;
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
120  br label %bb1
121
122bb1:
123  store <2 x i16> %a, ptr %out
124  ret void
125}
126
127define 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]
132; CHECK-NEXT:    ret
133;
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
140  br label %bb1
141
142bb1:
143  store <4 x i16> %a, ptr %out
144  ret void
145}
146
147define 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]
152; CHECK-NEXT:    ret
153;
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
160  br label %bb1
161
162bb1:
163  store <8 x i16> %a, ptr %out
164  ret void
165}
166
167define 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]
172; CHECK-NEXT:    ret
173;
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
180  br label %bb1
181
182bb1:
183  store <16 x i16> %a, ptr %out
184  ret void
185}
186
187; i32
188define 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]
193; CHECK-NEXT:    ret
194;
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
201  br label %bb1
202
203bb1:
204  store <2 x i32> %a, ptr %out
205  ret void
206}
207
208define 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]
213; CHECK-NEXT:    ret
214;
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
221  br label %bb1
222
223bb1:
224  store <4 x i32> %a, ptr %out
225  ret void
226}
227
228define 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]
233; CHECK-NEXT:    ret
234;
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
241  br label %bb1
242
243bb1:
244  store <8 x i32> %a, ptr %out
245  ret void
246}
247
248; i64
249define 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]
254; CHECK-NEXT:    ret
255;
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
262  br label %bb1
263
264bb1:
265  store <2 x i64> %a, ptr %out
266  ret void
267}
268
269define 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]
274; CHECK-NEXT:    ret
275;
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
282  br label %bb1
283
284bb1:
285  store <4 x i64> %a, ptr %out
286  ret void
287}
288
289; f16
290define 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]
295; CHECK-NEXT:    ret
296;
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
303  br label %bb1
304
305bb1:
306  store <2 x half> %a, ptr %out
307  ret void
308}
309
310define 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]
315; CHECK-NEXT:    ret
316;
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
323  br label %bb1
324
325bb1:
326  store <4 x half> %a, ptr %out
327  ret void
328}
329
330define 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]
335; CHECK-NEXT:    ret
336;
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
343  br label %bb1
344
345bb1:
346  store <8 x half> %a, ptr %out
347  ret void
348}
349
350define 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]
355; CHECK-NEXT:    ret
356;
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
363  br label %bb1
364
365bb1:
366  store <16 x half> %a, ptr %out
367  ret void
368}
369
370; f32
371define 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]
376; CHECK-NEXT:    ret
377;
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
384  br label %bb1
385
386bb1:
387  store <2 x float> %a, ptr %out
388  ret void
389}
390
391define 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]
396; CHECK-NEXT:    ret
397;
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
404  br label %bb1
405
406bb1:
407  store <4 x float> %a, ptr %out
408  ret void
409}
410
411define 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]
416; CHECK-NEXT:    ret
417;
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
424  br label %bb1
425
426bb1:
427  store <8 x float> %a, ptr %out
428  ret void
429}
430
431; f64
432define 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]
437; CHECK-NEXT:    ret
438;
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
445  br label %bb1
446
447bb1:
448  store <2 x double> %a, ptr %out
449  ret void
450}
451
452define 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]
457; CHECK-NEXT:    ret
458;
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
465  br label %bb1
466
467bb1:
468  store <4 x double> %a, ptr %out
469  ret void
470}
471