[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / llvm / test / CodeGen / AArch64 / sve-streaming-mode-fixed-length-concat.ll
blob86494c4be501230e5f41eb3d7f797fc747b9b0b2
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mattr=+sve -force-streaming-compatible-sve  < %s | FileCheck %s
3 ; RUN: llc -mattr=+sme -force-streaming-compatible-sve  < %s | FileCheck %s
5 target triple = "aarch64-unknown-linux-gnu"
8 ; i8
11 define <8 x i8> @concat_v8i8(<4 x i8> %op1, <4 x i8> %op2)  {
12 ; CHECK-LABEL: concat_v8i8:
13 ; CHECK:       // %bb.0:
14 ; CHECK-NEXT:    sub sp, sp, #16
15 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
16 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
17 ; CHECK-NEXT:    mov z2.h, z1.h[3]
18 ; CHECK-NEXT:    fmov w8, s1
19 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
20 ; CHECK-NEXT:    mov z3.h, z1.h[2]
21 ; CHECK-NEXT:    mov z1.h, z1.h[1]
22 ; CHECK-NEXT:    mov z4.h, z0.h[3]
23 ; CHECK-NEXT:    fmov w9, s0
24 ; CHECK-NEXT:    strb w8, [sp, #12]
25 ; CHECK-NEXT:    fmov w8, s2
26 ; CHECK-NEXT:    mov z2.h, z0.h[2]
27 ; CHECK-NEXT:    mov z0.h, z0.h[1]
28 ; CHECK-NEXT:    strb w9, [sp, #8]
29 ; CHECK-NEXT:    fmov w9, s3
30 ; CHECK-NEXT:    strb w8, [sp, #15]
31 ; CHECK-NEXT:    fmov w8, s1
32 ; CHECK-NEXT:    strb w9, [sp, #14]
33 ; CHECK-NEXT:    strb w8, [sp, #13]
34 ; CHECK-NEXT:    fmov w8, s4
35 ; CHECK-NEXT:    strb w8, [sp, #11]
36 ; CHECK-NEXT:    fmov w8, s2
37 ; CHECK-NEXT:    strb w8, [sp, #10]
38 ; CHECK-NEXT:    fmov w8, s0
39 ; CHECK-NEXT:    strb w8, [sp, #9]
40 ; CHECK-NEXT:    ldr d0, [sp, #8]
41 ; CHECK-NEXT:    add sp, sp, #16
42 ; CHECK-NEXT:    ret
43   %res = shufflevector <4 x i8> %op1, <4 x i8> %op2, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
44   ret <8 x i8> %res
47 define <16 x i8> @concat_v16i8(<8 x i8> %op1, <8 x i8> %op2)  {
48 ; CHECK-LABEL: concat_v16i8:
49 ; CHECK:       // %bb.0:
50 ; CHECK-NEXT:    ptrue p0.b, vl8
51 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
52 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
53 ; CHECK-NEXT:    splice z0.b, p0, z0.b, z1.b
54 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
55 ; CHECK-NEXT:    ret
56   %res = shufflevector <8 x i8> %op1, <8 x i8> %op2, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
57                                                                  i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
58   ret <16 x i8> %res
61 define void @concat_v32i8(ptr %a, ptr %b, ptr %c)  {
62 ; CHECK-LABEL: concat_v32i8:
63 ; CHECK:       // %bb.0:
64 ; CHECK-NEXT:    ldr q0, [x1]
65 ; CHECK-NEXT:    ldr q1, [x0]
66 ; CHECK-NEXT:    stp q1, q0, [x2]
67 ; CHECK-NEXT:    ret
68   %op1 = load <16 x i8>, ptr %a
69   %op2 = load <16 x i8>, ptr %b
70   %res = shufflevector <16 x i8> %op1, <16 x i8> %op2, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
71                                                                    i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15,
72                                                                    i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23,
73                                                                    i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
74   store <32 x i8> %res, ptr %c
75   ret void
78 define void @concat_v64i8(ptr %a, ptr %b, ptr %c) {
79 ; CHECK-LABEL: concat_v64i8:
80 ; CHECK:       // %bb.0:
81 ; CHECK-NEXT:    ldp q0, q1, [x1]
82 ; CHECK-NEXT:    ldp q3, q2, [x0]
83 ; CHECK-NEXT:    stp q0, q1, [x2, #32]
84 ; CHECK-NEXT:    stp q3, q2, [x2]
85 ; CHECK-NEXT:    ret
86   %op1 = load <32 x i8>, ptr %a
87   %op2 = load <32 x i8>, ptr %b
88   %res = shufflevector <32 x i8> %op1, <32 x i8> %op2, <64 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
89                                                                    i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15,
90                                                                    i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23,
91                                                                    i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31,
92                                                                    i32 32, i32 33, i32 34, i32 35, i32 36, i32 37, i32 38, i32 39,
93                                                                    i32 40, i32 41, i32 42, i32 43, i32 44, i32 45, i32 46, i32 47,
94                                                                    i32 48, i32 49, i32 50, i32 51, i32 52, i32 53, i32 54, i32 55,
95                                                                    i32 56, i32 57, i32 58, i32 59, i32 60, i32 61, i32 62, i32 63>
96   store <64 x i8> %res, ptr %c
97   ret void
101 ; i16
104 define <4 x i16> @concat_v4i16(<2 x i16> %op1, <2 x i16> %op2)  {
105 ; CHECK-LABEL: concat_v4i16:
106 ; CHECK:       // %bb.0:
107 ; CHECK-NEXT:    sub sp, sp, #16
108 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
109 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
110 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
111 ; CHECK-NEXT:    mov z2.s, z1.s[1]
112 ; CHECK-NEXT:    fmov w8, s1
113 ; CHECK-NEXT:    fmov w9, s0
114 ; CHECK-NEXT:    mov z1.s, z0.s[1]
115 ; CHECK-NEXT:    strh w8, [sp, #12]
116 ; CHECK-NEXT:    fmov w8, s2
117 ; CHECK-NEXT:    strh w9, [sp, #8]
118 ; CHECK-NEXT:    fmov w9, s1
119 ; CHECK-NEXT:    strh w8, [sp, #14]
120 ; CHECK-NEXT:    strh w9, [sp, #10]
121 ; CHECK-NEXT:    ldr d0, [sp, #8]
122 ; CHECK-NEXT:    add sp, sp, #16
123 ; CHECK-NEXT:    ret
124   %res = shufflevector <2 x i16> %op1, <2 x i16> %op2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
125   ret <4 x i16> %res
128 ; Don't use SVE for 128-bit vectors.
129 define <8 x i16> @concat_v8i16(<4 x i16> %op1, <4 x i16> %op2)  {
130 ; CHECK-LABEL: concat_v8i16:
131 ; CHECK:       // %bb.0:
132 ; CHECK-NEXT:    ptrue p0.h, vl4
133 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
134 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
135 ; CHECK-NEXT:    splice z0.h, p0, z0.h, z1.h
136 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
137 ; CHECK-NEXT:    ret
138   %res = shufflevector <4 x i16> %op1, <4 x i16> %op2, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
139   ret <8 x i16> %res
142 define void @concat_v16i16(ptr %a, ptr %b, ptr %c)  {
143 ; CHECK-LABEL: concat_v16i16:
144 ; CHECK:       // %bb.0:
145 ; CHECK-NEXT:    ldr q0, [x1]
146 ; CHECK-NEXT:    ldr q1, [x0]
147 ; CHECK-NEXT:    stp q1, q0, [x2]
148 ; CHECK-NEXT:    ret
149   %op1 = load <8 x i16>, ptr %a
150   %op2 = load <8 x i16>, ptr %b
151   %res = shufflevector <8 x i16> %op1, <8 x i16> %op2, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
152                                                                    i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
153   store <16 x i16> %res, ptr %c
154   ret void
157 define void @concat_v32i16(ptr %a, ptr %b, ptr %c) {
158 ; CHECK-LABEL: concat_v32i16:
159 ; CHECK:       // %bb.0:
160 ; CHECK-NEXT:    ldp q0, q1, [x1]
161 ; CHECK-NEXT:    ldp q3, q2, [x0]
162 ; CHECK-NEXT:    stp q0, q1, [x2, #32]
163 ; CHECK-NEXT:    stp q3, q2, [x2]
164 ; CHECK-NEXT:    ret
165   %op1 = load <16 x i16>, ptr %a
166   %op2 = load <16 x i16>, ptr %b
167   %res = shufflevector <16 x i16> %op1, <16 x i16> %op2, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
168                                                                      i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15,
169                                                                      i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23,
170                                                                      i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
171   store <32 x i16> %res, ptr %c
172   ret void
176 ; i32
179 ; Don't use SVE for 64-bit vectors.
180 define <2 x i32> @concat_v2i32(<1 x i32> %op1, <1 x i32> %op2)  {
181 ; CHECK-LABEL: concat_v2i32:
182 ; CHECK:       // %bb.0:
183 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
184 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
185 ; CHECK-NEXT:    zip1 z0.s, z0.s, z1.s
186 ; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
187 ; CHECK-NEXT:    ret
188   %res = shufflevector <1 x i32> %op1, <1 x i32> %op2, <2 x i32> <i32 0, i32 1>
189   ret <2 x i32> %res
192 ; Don't use SVE for 128-bit vectors.
193 define <4 x i32> @concat_v4i32(<2 x i32> %op1, <2 x i32> %op2)  {
194 ; CHECK-LABEL: concat_v4i32:
195 ; CHECK:       // %bb.0:
196 ; CHECK-NEXT:    ptrue p0.s, vl2
197 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
198 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
199 ; CHECK-NEXT:    splice z0.s, p0, z0.s, z1.s
200 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
201 ; CHECK-NEXT:    ret
202   %res = shufflevector <2 x i32> %op1, <2 x i32> %op2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
203   ret <4 x i32> %res
206 define void @concat_v8i32(ptr %a, ptr %b, ptr %c)  {
207 ; CHECK-LABEL: concat_v8i32:
208 ; CHECK:       // %bb.0:
209 ; CHECK-NEXT:    ldr q0, [x1]
210 ; CHECK-NEXT:    ldr q1, [x0]
211 ; CHECK-NEXT:    stp q1, q0, [x2]
212 ; CHECK-NEXT:    ret
213   %op1 = load <4 x i32>, ptr %a
214   %op2 = load <4 x i32>, ptr %b
215   %res = shufflevector <4 x i32> %op1, <4 x i32> %op2, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
216   store <8 x i32> %res, ptr %c
217   ret void
220 define void @concat_v16i32(ptr %a, ptr %b, ptr %c) {
221 ; CHECK-LABEL: concat_v16i32:
222 ; CHECK:       // %bb.0:
223 ; CHECK-NEXT:    ldp q0, q1, [x1]
224 ; CHECK-NEXT:    ldp q3, q2, [x0]
225 ; CHECK-NEXT:    stp q0, q1, [x2, #32]
226 ; CHECK-NEXT:    stp q3, q2, [x2]
227 ; CHECK-NEXT:    ret
228   %op1 = load <8 x i32>, ptr %a
229   %op2 = load <8 x i32>, ptr %b
230   %res = shufflevector <8 x i32> %op1, <8 x i32> %op2, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
231                                                                    i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
232   store <16 x i32> %res, ptr %c
233   ret void
237 ; i64
240 ; Don't use SVE for 128-bit vectors.
241 define <2 x i64> @concat_v2i64(<1 x i64> %op1, <1 x i64> %op2)  {
242 ; CHECK-LABEL: concat_v2i64:
243 ; CHECK:       // %bb.0:
244 ; CHECK-NEXT:    ptrue p0.d, vl1
245 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
246 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
247 ; CHECK-NEXT:    splice z0.d, p0, z0.d, z1.d
248 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
249 ; CHECK-NEXT:    ret
250   %res = shufflevector <1 x i64> %op1, <1 x i64> %op2, <2 x i32> <i32 0, i32 1>
251   ret <2 x i64> %res
254 define void @concat_v4i64(ptr %a, ptr %b, ptr %c)  {
255 ; CHECK-LABEL: concat_v4i64:
256 ; CHECK:       // %bb.0:
257 ; CHECK-NEXT:    ldr q0, [x1]
258 ; CHECK-NEXT:    ldr q1, [x0]
259 ; CHECK-NEXT:    stp q1, q0, [x2]
260 ; CHECK-NEXT:    ret
261   %op1 = load <2 x i64>, ptr %a
262   %op2 = load <2 x i64>, ptr %b
263   %res = shufflevector <2 x i64> %op1, <2 x i64> %op2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
264   store <4 x i64> %res, ptr %c
265   ret void
268 define void @concat_v8i64(ptr %a, ptr %b, ptr %c) {
269 ; CHECK-LABEL: concat_v8i64:
270 ; CHECK:       // %bb.0:
271 ; CHECK-NEXT:    ldp q0, q1, [x1]
272 ; CHECK-NEXT:    ldp q3, q2, [x0]
273 ; CHECK-NEXT:    stp q0, q1, [x2, #32]
274 ; CHECK-NEXT:    stp q3, q2, [x2]
275 ; CHECK-NEXT:    ret
276   %op1 = load <4 x i64>, ptr %a
277   %op2 = load <4 x i64>, ptr %b
278   %res = shufflevector <4 x i64> %op1, <4 x i64> %op2, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
279   store <8 x i64> %res, ptr %c
280   ret void
284 ; f16
287 define <4 x half> @concat_v4f16(<2 x half> %op1, <2 x half> %op2)  {
288 ; CHECK-LABEL: concat_v4f16:
289 ; CHECK:       // %bb.0:
290 ; CHECK-NEXT:    sub sp, sp, #16
291 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
292 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
293 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
294 ; CHECK-NEXT:    mov z2.h, z1.h[1]
295 ; CHECK-NEXT:    str h1, [sp, #12]
296 ; CHECK-NEXT:    mov z1.h, z0.h[1]
297 ; CHECK-NEXT:    str h0, [sp, #8]
298 ; CHECK-NEXT:    str h2, [sp, #14]
299 ; CHECK-NEXT:    str h1, [sp, #10]
300 ; CHECK-NEXT:    ldr d0, [sp, #8]
301 ; CHECK-NEXT:    add sp, sp, #16
302 ; CHECK-NEXT:    ret
303   %res = shufflevector <2 x half> %op1, <2 x half> %op2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
304   ret <4 x half> %res
307 define <8 x half> @concat_v8f16(<4 x half> %op1, <4 x half> %op2)  {
308 ; CHECK-LABEL: concat_v8f16:
309 ; CHECK:       // %bb.0:
310 ; CHECK-NEXT:    ptrue p0.h, vl4
311 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
312 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
313 ; CHECK-NEXT:    splice z0.h, p0, z0.h, z1.h
314 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
315 ; CHECK-NEXT:    ret
316   %res = shufflevector <4 x half> %op1, <4 x half> %op2, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
317   ret <8 x half> %res
320 define void @concat_v16f16(ptr %a, ptr %b, ptr %c)  {
321 ; CHECK-LABEL: concat_v16f16:
322 ; CHECK:       // %bb.0:
323 ; CHECK-NEXT:    ldr q0, [x1]
324 ; CHECK-NEXT:    ldr q1, [x0]
325 ; CHECK-NEXT:    stp q1, q0, [x2]
326 ; CHECK-NEXT:    ret
327   %op1 = load <8 x half>, ptr %a
328   %op2 = load <8 x half>, ptr %b
329   %res = shufflevector <8 x half> %op1, <8 x half> %op2, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
330                                                                      i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
331   store <16 x half> %res, ptr %c
332   ret void
335 define void @concat_v32f16(ptr %a, ptr %b, ptr %c) {
336 ; CHECK-LABEL: concat_v32f16:
337 ; CHECK:       // %bb.0:
338 ; CHECK-NEXT:    ldp q0, q1, [x1]
339 ; CHECK-NEXT:    ldp q3, q2, [x0]
340 ; CHECK-NEXT:    stp q0, q1, [x2, #32]
341 ; CHECK-NEXT:    stp q3, q2, [x2]
342 ; CHECK-NEXT:    ret
343   %op1 = load <16 x half>, ptr %a
344   %op2 = load <16 x half>, ptr %b
345   %res = shufflevector <16 x half> %op1, <16 x half> %op2, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
346                                                                        i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15,
347                                                                        i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23,
348                                                                        i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
349   store <32 x half> %res, ptr %c
350   ret void
354 ; i32
357 ; Don't use SVE for 64-bit vectors.
358 define <2 x float> @concat_v2f32(<1 x float> %op1, <1 x float> %op2)  {
359 ; CHECK-LABEL: concat_v2f32:
360 ; CHECK:       // %bb.0:
361 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
362 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
363 ; CHECK-NEXT:    zip1 z0.s, z0.s, z1.s
364 ; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
365 ; CHECK-NEXT:    ret
366   %res = shufflevector <1 x float> %op1, <1 x float> %op2, <2 x i32> <i32 0, i32 1>
367   ret <2 x float> %res
370 ; Don't use SVE for 128-bit vectors.
371 define <4 x float> @concat_v4f32(<2 x float> %op1, <2 x float> %op2)  {
372 ; CHECK-LABEL: concat_v4f32:
373 ; CHECK:       // %bb.0:
374 ; CHECK-NEXT:    ptrue p0.s, vl2
375 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
376 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
377 ; CHECK-NEXT:    splice z0.s, p0, z0.s, z1.s
378 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
379 ; CHECK-NEXT:    ret
380   %res = shufflevector <2 x float> %op1, <2 x float> %op2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
381   ret <4 x float> %res
384 define void @concat_v8f32(ptr %a, ptr %b, ptr %c)  {
385 ; CHECK-LABEL: concat_v8f32:
386 ; CHECK:       // %bb.0:
387 ; CHECK-NEXT:    ldr q0, [x1]
388 ; CHECK-NEXT:    ldr q1, [x0]
389 ; CHECK-NEXT:    stp q1, q0, [x2]
390 ; CHECK-NEXT:    ret
391   %op1 = load <4 x float>, ptr %a
392   %op2 = load <4 x float>, ptr %b
393   %res = shufflevector <4 x float> %op1, <4 x float> %op2, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
394   store <8 x float> %res, ptr %c
395   ret void
398 define void @concat_v16f32(ptr %a, ptr %b, ptr %c) {
399 ; CHECK-LABEL: concat_v16f32:
400 ; CHECK:       // %bb.0:
401 ; CHECK-NEXT:    ldp q0, q1, [x1]
402 ; CHECK-NEXT:    ldp q3, q2, [x0]
403 ; CHECK-NEXT:    stp q0, q1, [x2, #32]
404 ; CHECK-NEXT:    stp q3, q2, [x2]
405 ; CHECK-NEXT:    ret
406   %op1 = load <8 x float>, ptr %a
407   %op2 = load <8 x float>, ptr %b
408   %res = shufflevector <8 x float> %op1, <8 x float> %op2, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
409                                                                        i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
410   store <16 x float> %res, ptr %c
411   ret void
415 ; f64
418 ; Don't use SVE for 128-bit vectors.
419 define <2 x double> @concat_v2f64(<1 x double> %op1, <1 x double> %op2)  {
420 ; CHECK-LABEL: concat_v2f64:
421 ; CHECK:       // %bb.0:
422 ; CHECK-NEXT:    ptrue p0.d, vl1
423 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
424 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $z1
425 ; CHECK-NEXT:    splice z0.d, p0, z0.d, z1.d
426 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
427 ; CHECK-NEXT:    ret
428   %res = shufflevector <1 x double> %op1, <1 x double> %op2, <2 x i32> <i32 0, i32 1>
429   ret <2 x double> %res
432 define void @concat_v4f64(ptr %a, ptr %b, ptr %c)  {
433 ; CHECK-LABEL: concat_v4f64:
434 ; CHECK:       // %bb.0:
435 ; CHECK-NEXT:    ldr q0, [x1]
436 ; CHECK-NEXT:    ldr q1, [x0]
437 ; CHECK-NEXT:    stp q1, q0, [x2]
438 ; CHECK-NEXT:    ret
439   %op1 = load <2 x double>, ptr %a
440   %op2 = load <2 x double>, ptr %b
441   %res = shufflevector <2 x double> %op1, <2 x double> %op2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
442   store <4 x double> %res, ptr %c
443   ret void
446 define void @concat_v8f64(ptr %a, ptr %b, ptr %c) {
447 ; CHECK-LABEL: concat_v8f64:
448 ; CHECK:       // %bb.0:
449 ; CHECK-NEXT:    ldp q0, q1, [x1]
450 ; CHECK-NEXT:    ldp q3, q2, [x0]
451 ; CHECK-NEXT:    stp q0, q1, [x2, #32]
452 ; CHECK-NEXT:    stp q3, q2, [x2]
453 ; CHECK-NEXT:    ret
454   %op1 = load <4 x double>, ptr %a
455   %op2 = load <4 x double>, ptr %b
456   %res = shufflevector <4 x double> %op1, <4 x double> %op2, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
457   store <8 x double> %res, ptr %c
458   ret void
462 ; undef
465 define void @concat_v32i8_undef(ptr %a, ptr %b)  {
466 ; CHECK-LABEL: concat_v32i8_undef:
467 ; CHECK:       // %bb.0:
468 ; CHECK-NEXT:    ldr q0, [x0]
469 ; CHECK-NEXT:    str q0, [x1]
470 ; CHECK-NEXT:    ret
471   %op1 = load <16 x i8>, ptr %a
472   %res = shufflevector <16 x i8> %op1, <16 x i8> undef, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
473                                                                     i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15,
474                                                                     i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23,
475                                                                     i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
476   store <32 x i8> %res, ptr %b
477   ret void
480 define void @concat_v16i16_undef(ptr %a, ptr %b)  {
481 ; CHECK-LABEL: concat_v16i16_undef:
482 ; CHECK:       // %bb.0:
483 ; CHECK-NEXT:    ldr q0, [x0]
484 ; CHECK-NEXT:    str q0, [x1]
485 ; CHECK-NEXT:    ret
486   %op1 = load <8 x i16>, ptr %a
487   %res = shufflevector <8 x i16> %op1, <8 x i16> undef, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
488                                                                     i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
489   store <16 x i16> %res, ptr %b
490   ret void
493 define void @concat_v8i32_undef(ptr %a, ptr %b)  {
494 ; CHECK-LABEL: concat_v8i32_undef:
495 ; CHECK:       // %bb.0:
496 ; CHECK-NEXT:    ldr q0, [x0]
497 ; CHECK-NEXT:    str q0, [x1]
498 ; CHECK-NEXT:    ret
499   %op1 = load <4 x i32>, ptr %a
500   %res = shufflevector <4 x i32> %op1, <4 x i32> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
501   store <8 x i32> %res, ptr %b
502   ret void
505 define void @concat_v4i64_undef(ptr %a, ptr %b)  {
506 ; CHECK-LABEL: concat_v4i64_undef:
507 ; CHECK:       // %bb.0:
508 ; CHECK-NEXT:    ldr q0, [x0]
509 ; CHECK-NEXT:    str q0, [x1]
510 ; CHECK-NEXT:    ret
511   %op1 = load <2 x i64>, ptr %a
512   %res = shufflevector <2 x i64> %op1, <2 x i64> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
513   store <4 x i64> %res, ptr %b
514   ret void
518 ; > 2 operands
521 define void @concat_v32i8_4op(ptr %a, ptr %b)  {
522 ; CHECK-LABEL: concat_v32i8_4op:
523 ; CHECK:       // %bb.0:
524 ; CHECK-NEXT:    ldr d0, [x0]
525 ; CHECK-NEXT:    str q0, [x1]
526 ; CHECK-NEXT:    ret
527   %op1 = load <8 x i8>, ptr %a
528   %shuffle = shufflevector <8 x i8> %op1, <8 x i8> undef, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
529                                                                       i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
530   %res = shufflevector <16 x i8> %shuffle, <16 x i8> undef, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
531                                                                         i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15,
532                                                                         i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23,
533                                                                         i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
534   store <32 x i8> %res, ptr %b
535   ret void
538 define void @concat_v16i16_4op(ptr %a, ptr %b)  {
539 ; CHECK-LABEL: concat_v16i16_4op:
540 ; CHECK:       // %bb.0:
541 ; CHECK-NEXT:    ldr d0, [x0]
542 ; CHECK-NEXT:    str q0, [x1]
543 ; CHECK-NEXT:    ret
544   %op1 = load <4 x i16>, ptr %a
545   %shuffle = shufflevector <4 x i16> %op1, <4 x i16> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
546   %res = shufflevector <8 x i16> %shuffle, <8 x i16> undef, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
547                                                                         i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
548   store <16 x i16> %res, ptr %b
549   ret void
552 define void @concat_v8i32_4op(ptr %a, ptr %b)  {
553 ; CHECK-LABEL: concat_v8i32_4op:
554 ; CHECK:       // %bb.0:
555 ; CHECK-NEXT:    ldr d0, [x0]
556 ; CHECK-NEXT:    str q0, [x1]
557 ; CHECK-NEXT:    ret
558   %op1 = load <2 x i32>, ptr %a
559   %shuffle = shufflevector <2 x i32> %op1, <2 x i32> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
560   %res = shufflevector <4 x i32> %shuffle, <4 x i32> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
561   store <8 x i32> %res, ptr %b
562   ret void
565 define void @concat_v4i64_4op(ptr %a, ptr %b)  {
566 ; CHECK-LABEL: concat_v4i64_4op:
567 ; CHECK:       // %bb.0:
568 ; CHECK-NEXT:    ldr d0, [x0]
569 ; CHECK-NEXT:    str q0, [x1]
570 ; CHECK-NEXT:    ret
571   %op1 = load <1 x i64>, ptr %a
572   %shuffle = shufflevector <1 x i64> %op1, <1 x i64> undef, <2 x i32> <i32 0, i32 1>
573   %res = shufflevector <2 x i64> %shuffle, <2 x i64> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
574   store <4 x i64> %res, ptr %b
575   ret void