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