[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / CodeGen / AArch64 / sve-fixed-length-concat.ll
blob522b5a55f9dcffd5698a84b1247362cabbc3c365
1 ; RUN: llc -aarch64-sve-vector-bits-min=128  -asm-verbose=0 < %s | FileCheck %s -check-prefix=NO_SVE
2 ; RUN: llc -aarch64-sve-vector-bits-min=256  -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK
3 ; RUN: llc -aarch64-sve-vector-bits-min=384  -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK
4 ; RUN: llc -aarch64-sve-vector-bits-min=512  -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512
5 ; RUN: llc -aarch64-sve-vector-bits-min=640  -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512
6 ; RUN: llc -aarch64-sve-vector-bits-min=768  -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512
7 ; RUN: llc -aarch64-sve-vector-bits-min=896  -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512
8 ; RUN: llc -aarch64-sve-vector-bits-min=1024 -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
9 ; RUN: llc -aarch64-sve-vector-bits-min=1152 -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
10 ; RUN: llc -aarch64-sve-vector-bits-min=1280 -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
11 ; RUN: llc -aarch64-sve-vector-bits-min=1408 -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
12 ; RUN: llc -aarch64-sve-vector-bits-min=1536 -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
13 ; RUN: llc -aarch64-sve-vector-bits-min=1664 -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
14 ; RUN: llc -aarch64-sve-vector-bits-min=1792 -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
15 ; RUN: llc -aarch64-sve-vector-bits-min=1920 -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
16 ; RUN: llc -aarch64-sve-vector-bits-min=2048 -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024,VBITS_GE_2048
18 target triple = "aarch64-unknown-linux-gnu"
20 ; Don't use SVE when its registers are no bigger than NEON.
21 ; NO_SVE-NOT: ptrue
24 ; i8
27 ; Don't use SVE for 64-bit vectors.
28 define <8 x i8> @concat_v8i8(<4 x i8> %op1, <4 x i8> %op2) #0 {
29 ; CHECK-LABEL: concat_v8i8:
30 ; CHECK: uzp1 v0.8b, v0.8b, v1.8b
31 ; CHECK-NEXT: ret
32   %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>
33   ret <8 x i8> %res
36 ; Don't use SVE for 128-bit vectors.
37 define <16 x i8> @concat_v16i8(<8 x i8> %op1, <8 x i8> %op2) #0 {
38 ; CHECK-LABEL: concat_v16i8:
39 ; CHECK: mov v0.d[1], v1.d[0]
40 ; CHECK-NEXT: ret
41   %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,
42                                                                  i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
43   ret <16 x i8> %res
46 define void @concat_v32i8(<16 x i8>* %a, <16 x i8>* %b, <32 x i8>* %c) #0 {
47 ; CHECK-LABEL: concat_v32i8:
48 ; CHECK: ldr q[[OP1:[0-9]+]], [x0]
49 ; CHECK-NEXT: ldr q[[OP2:[0-9]+]], [x1]
50 ; CHECK-NEXT: ptrue [[PG1:p[0-9]+]].b, vl16
51 ; CHECK-NEXT: splice [[RES:z[0-9]+]].b, [[PG1]], z[[OP1]].b, z[[OP2]].b
52 ; CHECK-NEXT: ptrue [[PG2:p[0-9]+]].b, vl32
53 ; CHECK-NEXT: st1b { [[RES]].b }, [[PG2]], [x2]
54 ; CHECK-NEXT: ret
55   %op1 = load <16 x i8>, <16 x i8>* %a
56   %op2 = load <16 x i8>, <16 x i8>* %b
57   %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,
58                                                                    i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15,
59                                                                    i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23,
60                                                                    i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
61   store <32 x i8> %res, <32 x i8>* %c
62   ret void
65 define void @concat_v64i8(<32 x i8>* %a, <32 x i8>* %b, <64 x i8>* %c) #0 {
66 ; CHECK-LABEL: concat_v64i8:
67 ; VBITS_GE_512: ptrue [[PG1:p[0-9]+]].b, vl32
68 ; VBITS_GE_512-NEXT: ld1b { [[OP1:z[0-9]+]].b }, [[PG1]]/z, [x0]
69 ; VBITS_GE_512-NEXT: ld1b { [[OP2:z[0-9]+]].b }, [[PG1]]/z, [x1]
70 ; VBITS_GE_512-NEXT: splice [[RES:z[0-9]+]].b, [[PG1]], [[OP1]].b, [[OP2]].b
71 ; VBITS_GE_512-NEXT: ptrue [[PG2:p[0-9]+]].b, vl64
72 ; VBITS_GE_512-NEXT: st1b { [[RES]].b }, [[PG2]], [x2]
73 ; VBITS_GE_512-NEXT: ret
74   %op1 = load <32 x i8>, <32 x i8>* %a
75   %op2 = load <32 x i8>, <32 x i8>* %b
76   %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,
77                                                                    i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15,
78                                                                    i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23,
79                                                                    i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31,
80                                                                    i32 32, i32 33, i32 34, i32 35, i32 36, i32 37, i32 38, i32 39,
81                                                                    i32 40, i32 41, i32 42, i32 43, i32 44, i32 45, i32 46, i32 47,
82                                                                    i32 48, i32 49, i32 50, i32 51, i32 52, i32 53, i32 54, i32 55,
83                                                                    i32 56, i32 57, i32 58, i32 59, i32 60, i32 61, i32 62, i32 63>
84   store <64 x i8> %res, <64 x i8>* %c
85   ret void
88 define void @concat_v128i8(<64 x i8>* %a, <64 x i8>* %b, <128 x i8>* %c) #0 {
89 ; CHECK-LABEL: concat_v128i8:
90 ; VBITS_GE_1024: ptrue [[PG1:p[0-9]+]].b, vl64
91 ; VBITS_GE_1024-NEXT: ld1b { [[OP1:z[0-9]+]].b }, [[PG1]]/z, [x0]
92 ; VBITS_GE_1024-NEXT: ld1b { [[OP2:z[0-9]+]].b }, [[PG1]]/z, [x1]
93 ; VBITS_GE_1024-NEXT: splice [[RES:z[0-9]+]].b, [[PG1]], [[OP1]].b, [[OP2]].b
94 ; VBITS_GE_1024-NEXT: ptrue [[PG2:p[0-9]+]].b, vl128
95 ; VBITS_GE_1024-NEXT: st1b { [[RES]].b }, [[PG2]], [x2]
96 ; VBITS_GE_1024-NEXT: ret
97   %op1 = load <64 x i8>, <64 x i8>* %a
98   %op2 = load <64 x i8>, <64 x i8>* %b
99   %res = shufflevector <64 x i8> %op1, <64 x i8> %op2, <128 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
100                                                                     i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15,
101                                                                     i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23,
102                                                                     i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31,
103                                                                     i32 32, i32 33, i32 34, i32 35, i32 36, i32 37, i32 38, i32 39,
104                                                                     i32 40, i32 41, i32 42, i32 43, i32 44, i32 45, i32 46, i32 47,
105                                                                     i32 48, i32 49, i32 50, i32 51, i32 52, i32 53, i32 54, i32 55,
106                                                                     i32 56, i32 57, i32 58, i32 59, i32 60, i32 61, i32 62, i32 63,
107                                                                     i32 64, i32 65, i32 66, i32 67, i32 68, i32 69, i32 70, i32 71,
108                                                                     i32 72, i32 73, i32 74, i32 75, i32 76, i32 77, i32 78, i32 79,
109                                                                     i32 80, i32 81, i32 82, i32 83, i32 84, i32 85, i32 86, i32 87,
110                                                                     i32 88, i32 89, i32 90, i32 91, i32 92, i32 93, i32 94, i32 95,
111                                                                     i32 96, i32 97, i32 98, i32 99, i32 100, i32 101, i32 102, i32 103,
112                                                                     i32 104, i32 105, i32 106, i32 107, i32 108, i32 109, i32 110, i32 111,
113                                                                     i32 112, i32 113, i32 114, i32 115, i32 116, i32 117, i32 118, i32 119,
114                                                                     i32 120, i32 121, i32 122, i32 123, i32 124, i32 125, i32 126, i32 127>
115   store <128 x i8> %res, <128 x i8>* %c
116   ret void
119 define void @concat_v256i8(<128 x i8>* %a, <128 x i8>* %b, <256 x i8>* %c) #0 {
120 ; CHECK-LABEL: concat_v256i8:
121 ; VBITS_GE_2048: ptrue [[PG1:p[0-9]+]].b, vl128
122 ; VBITS_GE_2048-NEXT: ld1b { [[OP1:z[0-9]+]].b }, [[PG1]]/z, [x0]
123 ; VBITS_GE_2048-NEXT: ld1b { [[OP2:z[0-9]+]].b }, [[PG1]]/z, [x1]
124 ; VBITS_GE_2048-NEXT: splice [[RES:z[0-9]+]].b, [[PG1]], [[OP1]].b, [[OP2]].b
125 ; VBITS_GE_2048-NEXT: ptrue [[PG2:p[0-9]+]].b, vl256
126 ; VBITS_GE_2048-NEXT: st1b { [[RES]].b }, [[PG2]], [x2]
127 ; VBITS_GE_2048-NEXT: ret
128   %op1 = load <128 x i8>, <128 x i8>* %a
129   %op2 = load <128 x i8>, <128 x i8>* %b
130   %res = shufflevector <128 x i8> %op1, <128 x i8> %op2, <256 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
131                                                                       i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15,
132                                                                       i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23,
133                                                                       i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31,
134                                                                       i32 32, i32 33, i32 34, i32 35, i32 36, i32 37, i32 38, i32 39,
135                                                                       i32 40, i32 41, i32 42, i32 43, i32 44, i32 45, i32 46, i32 47,
136                                                                       i32 48, i32 49, i32 50, i32 51, i32 52, i32 53, i32 54, i32 55,
137                                                                       i32 56, i32 57, i32 58, i32 59, i32 60, i32 61, i32 62, i32 63,
138                                                                       i32 64, i32 65, i32 66, i32 67, i32 68, i32 69, i32 70, i32 71,
139                                                                       i32 72, i32 73, i32 74, i32 75, i32 76, i32 77, i32 78, i32 79,
140                                                                       i32 80, i32 81, i32 82, i32 83, i32 84, i32 85, i32 86, i32 87,
141                                                                       i32 88, i32 89, i32 90, i32 91, i32 92, i32 93, i32 94, i32 95,
142                                                                       i32 96, i32 97, i32 98, i32 99, i32 100, i32 101, i32 102, i32 103,
143                                                                       i32 104, i32 105, i32 106, i32 107, i32 108, i32 109, i32 110, i32 111,
144                                                                       i32 112, i32 113, i32 114, i32 115, i32 116, i32 117, i32 118, i32 119,
145                                                                       i32 120, i32 121, i32 122, i32 123, i32 124, i32 125, i32 126, i32 127,
146                                                                       i32 128, i32 129, i32 130, i32 131, i32 132, i32 133, i32 134, i32 135,
147                                                                       i32 136, i32 137, i32 138, i32 139, i32 140, i32 141, i32 142, i32 143,
148                                                                       i32 144, i32 145, i32 146, i32 147, i32 148, i32 149, i32 150, i32 151,
149                                                                       i32 152, i32 153, i32 154, i32 155, i32 156, i32 157, i32 158, i32 159,
150                                                                       i32 160, i32 161, i32 162, i32 163, i32 164, i32 165, i32 166, i32 167,
151                                                                       i32 168, i32 169, i32 170, i32 171, i32 172, i32 173, i32 174, i32 175,
152                                                                       i32 176, i32 177, i32 178, i32 179, i32 180, i32 181, i32 182, i32 183,
153                                                                       i32 184, i32 185, i32 186, i32 187, i32 188, i32 189, i32 190, i32 191,
154                                                                       i32 192, i32 193, i32 194, i32 195, i32 196, i32 197, i32 198, i32 199,
155                                                                       i32 200, i32 201, i32 202, i32 203, i32 204, i32 205, i32 206, i32 207,
156                                                                       i32 208, i32 209, i32 210, i32 211, i32 212, i32 213, i32 214, i32 215,
157                                                                       i32 216, i32 217, i32 218, i32 219, i32 220, i32 221, i32 222, i32 223,
158                                                                       i32 224, i32 225, i32 226, i32 227, i32 228, i32 229, i32 230, i32 231,
159                                                                       i32 232, i32 233, i32 234, i32 235, i32 236, i32 237, i32 238, i32 239,
160                                                                       i32 240, i32 241, i32 242, i32 243, i32 244, i32 245, i32 246, i32 247,
161                                                                       i32 248, i32 249, i32 250, i32 251, i32 252, i32 253, i32 254, i32 255>
162   store <256 x i8> %res, <256 x i8>* %c
163   ret void
167 ; i16
170 ; Don't use SVE for 64-bit vectors.
171 define <4 x i16> @concat_v4i16(<2 x i16> %op1, <2 x i16> %op2) #0 {
172 ; CHECK-LABEL: concat_v4i16:
173 ; CHECK: uzp1 v0.4h, v0.4h, v1.4h
174 ; CHECK-NEXT: ret
175   %res = shufflevector <2 x i16> %op1, <2 x i16> %op2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
176   ret <4 x i16> %res
179 ; Don't use SVE for 128-bit vectors.
180 define <8 x i16> @concat_v8i16(<4 x i16> %op1, <4 x i16> %op2) #0 {
181 ; CHECK-LABEL: concat_v8i16:
182 ; CHECK: mov v0.d[1], v1.d[0]
183 ; CHECK-NEXT: ret
184   %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>
185   ret <8 x i16> %res
188 define void @concat_v16i16(<8 x i16>* %a, <8 x i16>* %b, <16 x i16>* %c) #0 {
189 ; CHECK-LABEL: concat_v16i16:
190 ; CHECK: ldr q[[OP1:[0-9]+]], [x0]
191 ; CHECK-NEXT: ldr q[[OP2:[0-9]+]], [x1]
192 ; CHECK-NEXT: ptrue [[PG1:p[0-9]+]].h, vl8
193 ; CHECK-NEXT: splice [[RES:z[0-9]+]].h, [[PG1]], z[[OP1]].h, z[[OP2]].h
194 ; CHECK-NEXT: ptrue [[PG2:p[0-9]+]].h, vl16
195 ; CHECK-NEXT: st1h { [[RES]].h }, [[PG2]], [x2]
196 ; CHECK-NEXT: ret
197   %op1 = load <8 x i16>, <8 x i16>* %a
198   %op2 = load <8 x i16>, <8 x i16>* %b
199   %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,
200                                                                    i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
201   store <16 x i16> %res, <16 x i16>* %c
202   ret void
205 define void @concat_v32i16(<16 x i16>* %a, <16 x i16>* %b, <32 x i16>* %c) #0 {
206 ; CHECK-LABEL: concat_v32i16:
207 ; VBITS_GE_512: ptrue [[PG1:p[0-9]+]].h, vl16
208 ; VBITS_GE_512-NEXT: ld1h { [[OP1:z[0-9]+]].h }, [[PG1]]/z, [x0]
209 ; VBITS_GE_512-NEXT: ld1h { [[OP2:z[0-9]+]].h }, [[PG1]]/z, [x1]
210 ; VBITS_GE_512-NEXT: splice [[RES:z[0-9]+]].h, [[PG1]], [[OP1]].h, [[OP2]].h
211 ; VBITS_GE_512-NEXT: ptrue [[PG2:p[0-9]+]].h, vl32
212 ; VBITS_GE_512-NEXT: st1h { [[RES]].h }, [[PG2]], [x2]
213 ; VBITS_GE_512-NEXT: ret
214   %op1 = load <16 x i16>, <16 x i16>* %a
215   %op2 = load <16 x i16>, <16 x i16>* %b
216   %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,
217                                                                      i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15,
218                                                                      i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23,
219                                                                      i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
220   store <32 x i16> %res, <32 x i16>* %c
221   ret void
224 define void @concat_v64i16(<32 x i16>* %a, <32 x i16>* %b, <64 x i16>* %c) #0 {
225 ; CHECK-LABEL: concat_v64i16:
226 ; VBITS_GE_1024: ptrue [[PG1:p[0-9]+]].h, vl32
227 ; VBITS_GE_1024-NEXT: ld1h { [[OP1:z[0-9]+]].h }, [[PG1]]/z, [x0]
228 ; VBITS_GE_1024-NEXT: ld1h { [[OP2:z[0-9]+]].h }, [[PG1]]/z, [x1]
229 ; VBITS_GE_1024-NEXT: splice [[RES:z[0-9]+]].h, [[PG1]], [[OP1]].h, [[OP2]].h
230 ; VBITS_GE_1024-NEXT: ptrue [[PG2:p[0-9]+]].h, vl64
231 ; VBITS_GE_1024-NEXT: st1h { [[RES]].h }, [[PG2]], [x2]
232 ; VBITS_GE_1024-NEXT: ret
233   %op1 = load <32 x i16>, <32 x i16>* %a
234   %op2 = load <32 x i16>, <32 x i16>* %b
235   %res = shufflevector <32 x i16> %op1, <32 x i16> %op2, <64 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
236                                                                      i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15,
237                                                                      i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23,
238                                                                      i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31,
239                                                                      i32 32, i32 33, i32 34, i32 35, i32 36, i32 37, i32 38, i32 39,
240                                                                      i32 40, i32 41, i32 42, i32 43, i32 44, i32 45, i32 46, i32 47,
241                                                                      i32 48, i32 49, i32 50, i32 51, i32 52, i32 53, i32 54, i32 55,
242                                                                      i32 56, i32 57, i32 58, i32 59, i32 60, i32 61, i32 62, i32 63>
243   store <64 x i16> %res, <64 x i16>* %c
244   ret void
247 define void @concat_v128i16(<64 x i16>* %a, <64 x i16>* %b, <128 x i16>* %c) #0 {
248 ; CHECK-LABEL: concat_v128i16:
249 ; VBITS_GE_2048: ptrue [[PG1:p[0-9]+]].h, vl64
250 ; VBITS_GE_2048-NEXT: ld1h { [[OP1:z[0-9]+]].h }, [[PG1]]/z, [x0]
251 ; VBITS_GE_2048-NEXT: ld1h { [[OP2:z[0-9]+]].h }, [[PG1]]/z, [x1]
252 ; VBITS_GE_2048-NEXT: splice [[RES:z[0-9]+]].h, [[PG1]], [[OP1]].h, [[OP2]].h
253 ; VBITS_GE_2048-NEXT: ptrue [[PG2:p[0-9]+]].h, vl128
254 ; VBITS_GE_2048-NEXT: st1h { [[RES]].h }, [[PG2]], [x2]
255 ; VBITS_GE_2048-NEXT: ret
256   %op1 = load <64 x i16>, <64 x i16>* %a
257   %op2 = load <64 x i16>, <64 x i16>* %b
258   %res = shufflevector <64 x i16> %op1, <64 x i16> %op2, <128 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
259                                                                       i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15,
260                                                                       i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23,
261                                                                       i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31,
262                                                                       i32 32, i32 33, i32 34, i32 35, i32 36, i32 37, i32 38, i32 39,
263                                                                       i32 40, i32 41, i32 42, i32 43, i32 44, i32 45, i32 46, i32 47,
264                                                                       i32 48, i32 49, i32 50, i32 51, i32 52, i32 53, i32 54, i32 55,
265                                                                       i32 56, i32 57, i32 58, i32 59, i32 60, i32 61, i32 62, i32 63,
266                                                                       i32 64, i32 65, i32 66, i32 67, i32 68, i32 69, i32 70, i32 71,
267                                                                       i32 72, i32 73, i32 74, i32 75, i32 76, i32 77, i32 78, i32 79,
268                                                                       i32 80, i32 81, i32 82, i32 83, i32 84, i32 85, i32 86, i32 87,
269                                                                       i32 88, i32 89, i32 90, i32 91, i32 92, i32 93, i32 94, i32 95,
270                                                                       i32 96, i32 97, i32 98, i32 99, i32 100, i32 101, i32 102, i32 103,
271                                                                       i32 104, i32 105, i32 106, i32 107, i32 108, i32 109, i32 110, i32 111,
272                                                                       i32 112, i32 113, i32 114, i32 115, i32 116, i32 117, i32 118, i32 119,
273                                                                       i32 120, i32 121, i32 122, i32 123, i32 124, i32 125, i32 126, i32 127>
274   store <128 x i16> %res, <128 x i16>* %c
275   ret void
279 ; i32
282 ; Don't use SVE for 64-bit vectors.
283 define <2 x i32> @concat_v2i32(<1 x i32> %op1, <1 x i32> %op2) #0 {
284 ; CHECK-LABEL: concat_v2i32:
285 ; CHECK: zip1 v0.2s, v0.2s, v1.2s
286 ; CHECK-NEXT: ret
287   %res = shufflevector <1 x i32> %op1, <1 x i32> %op2, <2 x i32> <i32 0, i32 1>
288   ret <2 x i32> %res
291 ; Don't use SVE for 128-bit vectors.
292 define <4 x i32> @concat_v4i32(<2 x i32> %op1, <2 x i32> %op2) #0 {
293 ; CHECK-LABEL: concat_v4i32:
294 ; CHECK: mov v0.d[1], v1.d[0]
295 ; CHECK-NEXT: ret
296   %res = shufflevector <2 x i32> %op1, <2 x i32> %op2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
297   ret <4 x i32> %res
300 define void @concat_v8i32(<4 x i32>* %a, <4 x i32>* %b, <8 x i32>* %c) #0 {
301 ; CHECK-LABEL: concat_v8i32:
302 ; CHECK: ldr q[[OP1:[0-9]+]], [x0]
303 ; CHECK-NEXT: ldr q[[OP2:[0-9]+]], [x1]
304 ; CHECK-NEXT: ptrue [[PG1:p[0-9]+]].s, vl4
305 ; CHECK-NEXT: splice [[RES:z[0-9]+]].s, [[PG1]], z[[OP1]].s, z[[OP2]].s
306 ; CHECK-NEXT: ptrue [[PG2:p[0-9]+]].s, vl8
307 ; CHECK-NEXT: st1w { [[RES]].s }, [[PG2]], [x2]
308 ; CHECK-NEXT: ret
309   %op1 = load <4 x i32>, <4 x i32>* %a
310   %op2 = load <4 x i32>, <4 x i32>* %b
311   %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>
312   store <8 x i32> %res, <8 x i32>* %c
313   ret void
316 define void @concat_v16i32(<8 x i32>* %a, <8 x i32>* %b, <16 x i32>* %c) #0 {
317 ; CHECK-LABEL: concat_v16i32:
318 ; VBITS_GE_512: ptrue [[PG1:p[0-9]+]].s, vl8
319 ; VBITS_GE_512-NEXT: ld1w { [[OP1:z[0-9]+]].s }, [[PG1]]/z, [x0]
320 ; VBITS_GE_512-NEXT: ld1w { [[OP2:z[0-9]+]].s }, [[PG1]]/z, [x1]
321 ; VBITS_GE_512-NEXT: splice [[RES:z[0-9]+]].s, [[PG1]], [[OP1]].s, [[OP2]].s
322 ; VBITS_GE_512-NEXT: ptrue [[PG2:p[0-9]+]].s, vl16
323 ; VBITS_GE_512-NEXT: st1w { [[RES]].s }, [[PG2]], [x2]
324 ; VBITS_GE_512-NEXT: ret
325   %op1 = load <8 x i32>, <8 x i32>* %a
326   %op2 = load <8 x i32>, <8 x i32>* %b
327   %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,
328                                                                    i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
329   store <16 x i32> %res, <16 x i32>* %c
330   ret void
333 define void @concat_v32i32(<16 x i32>* %a, <16 x i32>* %b, <32 x i32>* %c) #0 {
334 ; CHECK-LABEL: concat_v32i32:
335 ; VBITS_GE_1024: ptrue [[PG1:p[0-9]+]].s, vl16
336 ; VBITS_GE_1024-NEXT: ld1w { [[OP1:z[0-9]+]].s }, [[PG1]]/z, [x0]
337 ; VBITS_GE_1024-NEXT: ld1w { [[OP2:z[0-9]+]].s }, [[PG1]]/z, [x1]
338 ; VBITS_GE_1024-NEXT: splice [[RES:z[0-9]+]].s, [[PG1]], [[OP1]].s, [[OP2]].s
339 ; VBITS_GE_1024-NEXT: ptrue [[PG2:p[0-9]+]].s, vl32
340 ; VBITS_GE_1024-NEXT: st1w { [[RES]].s }, [[PG2]], [x2]
341 ; VBITS_GE_1024-NEXT: ret
342   %op1 = load <16 x i32>, <16 x i32>* %a
343   %op2 = load <16 x i32>, <16 x i32>* %b
344   %res = shufflevector <16 x i32> %op1, <16 x i32> %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 i32> %res, <32 x i32>* %c
349   ret void
352 define void @concat_v64i32(<32 x i32>* %a, <32 x i32>* %b, <64 x i32>* %c) #0 {
353 ; CHECK-LABEL: concat_v64i32:
354 ; VBITS_GE_2048: ptrue [[PG1:p[0-9]+]].s, vl32
355 ; VBITS_GE_2048-NEXT: ld1w { [[OP1:z[0-9]+]].s }, [[PG1]]/z, [x0]
356 ; VBITS_GE_2048-NEXT: ld1w { [[OP2:z[0-9]+]].s }, [[PG1]]/z, [x1]
357 ; VBITS_GE_2048-NEXT: splice [[RES:z[0-9]+]].s, [[PG1]], [[OP1]].s, [[OP2]].s
358 ; VBITS_GE_2048-NEXT: ptrue [[PG2:p[0-9]+]].s, vl64
359 ; VBITS_GE_2048-NEXT: st1w { [[RES]].s }, [[PG2]], [x2]
360 ; VBITS_GE_2048-NEXT: ret
361   %op1 = load <32 x i32>, <32 x i32>* %a
362   %op2 = load <32 x i32>, <32 x i32>* %b
363   %res = shufflevector <32 x i32> %op1, <32 x i32> %op2, <64 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
364                                                                      i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15,
365                                                                      i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23,
366                                                                      i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31,
367                                                                      i32 32, i32 33, i32 34, i32 35, i32 36, i32 37, i32 38, i32 39,
368                                                                      i32 40, i32 41, i32 42, i32 43, i32 44, i32 45, i32 46, i32 47,
369                                                                      i32 48, i32 49, i32 50, i32 51, i32 52, i32 53, i32 54, i32 55,
370                                                                      i32 56, i32 57, i32 58, i32 59, i32 60, i32 61, i32 62, i32 63>
371   store <64 x i32> %res, <64 x i32>* %c
372   ret void
376 ; i64
379 ; Don't use SVE for 128-bit vectors.
380 define <2 x i64> @concat_v2i64(<1 x i64> %op1, <1 x i64> %op2) #0 {
381 ; CHECK-LABEL: concat_v2i64:
382 ; CHECK: mov v0.d[1], v1.d[0]
383 ; CHECK-NEXT: ret
384   %res = shufflevector <1 x i64> %op1, <1 x i64> %op2, <2 x i32> <i32 0, i32 1>
385   ret <2 x i64> %res
388 define void @concat_v4i64(<2 x i64>* %a, <2 x i64>* %b, <4 x i64>* %c) #0 {
389 ; CHECK-LABEL: concat_v4i64:
390 ; CHECK: ldr q[[OP1:[0-9]+]], [x0]
391 ; CHECK-NEXT: ldr q[[OP2:[0-9]+]], [x1]
392 ; CHECK-NEXT: ptrue [[PG1:p[0-9]+]].d, vl2
393 ; CHECK-NEXT: splice [[RES:z[0-9]+]].d, [[PG1]], z[[OP1]].d, z[[OP2]].d
394 ; CHECK-NEXT: ptrue [[PG2:p[0-9]+]].d, vl4
395 ; CHECK-NEXT: st1d { [[RES]].d }, [[PG2]], [x2]
396 ; CHECK-NEXT: ret
397   %op1 = load <2 x i64>, <2 x i64>* %a
398   %op2 = load <2 x i64>, <2 x i64>* %b
399   %res = shufflevector <2 x i64> %op1, <2 x i64> %op2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
400   store <4 x i64> %res, <4 x i64>* %c
401   ret void
404 define void @concat_v8i64(<4 x i64>* %a, <4 x i64>* %b, <8 x i64>* %c) #0 {
405 ; CHECK-LABEL: concat_v8i64:
406 ; VBITS_GE_512: ptrue [[PG1:p[0-9]+]].d, vl4
407 ; VBITS_GE_512-NEXT: ld1d { [[OP1:z[0-9]+]].d }, [[PG1]]/z, [x0]
408 ; VBITS_GE_512-NEXT: ld1d { [[OP2:z[0-9]+]].d }, [[PG1]]/z, [x1]
409 ; VBITS_GE_512-NEXT: splice [[RES:z[0-9]+]].d, [[PG1]], [[OP1]].d, [[OP2]].d
410 ; VBITS_GE_512-NEXT: ptrue [[PG2:p[0-9]+]].d, vl8
411 ; VBITS_GE_512-NEXT: st1d { [[RES]].d }, [[PG2]], [x2]
412 ; VBITS_GE_512-NEXT: ret
413   %op1 = load <4 x i64>, <4 x i64>* %a
414   %op2 = load <4 x i64>, <4 x i64>* %b
415   %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>
416   store <8 x i64> %res, <8 x i64>* %c
417   ret void
420 define void @concat_v16i64(<8 x i64>* %a, <8 x i64>* %b, <16 x i64>* %c) #0 {
421 ; CHECK-LABEL: concat_v16i64:
422 ; VBITS_GE_1024: ptrue [[PG1:p[0-9]+]].d, vl8
423 ; VBITS_GE_1024-NEXT: ld1d { [[OP1:z[0-9]+]].d }, [[PG1]]/z, [x0]
424 ; VBITS_GE_1024-NEXT: ld1d { [[OP2:z[0-9]+]].d }, [[PG1]]/z, [x1]
425 ; VBITS_GE_1024-NEXT: splice [[RES:z[0-9]+]].d, [[PG1]], [[OP1]].d, [[OP2]].d
426 ; VBITS_GE_1024-NEXT: ptrue [[PG2:p[0-9]+]].d, vl16
427 ; VBITS_GE_1024-NEXT: st1d { [[RES]].d }, [[PG2]], [x2]
428 ; VBITS_GE_1024-NEXT: ret
429   %op1 = load <8 x i64>, <8 x i64>* %a
430   %op2 = load <8 x i64>, <8 x i64>* %b
431   %res = shufflevector <8 x i64> %op1, <8 x i64> %op2, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
432                                                                    i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
433   store <16 x i64> %res, <16 x i64>* %c
434   ret void
437 define void @concat_v32i64(<16 x i64>* %a, <16 x i64>* %b, <32 x i64>* %c) #0 {
438 ; CHECK-LABEL: concat_v32i64:
439 ; VBITS_GE_2048: ptrue [[PG1:p[0-9]+]].d, vl16
440 ; VBITS_GE_2048-NEXT: ld1d { [[OP1:z[0-9]+]].d }, [[PG1]]/z, [x0]
441 ; VBITS_GE_2048-NEXT: ld1d { [[OP2:z[0-9]+]].d }, [[PG1]]/z, [x1]
442 ; VBITS_GE_2048-NEXT: splice [[RES:z[0-9]+]].d, [[PG1]], [[OP1]].d, [[OP2]].d
443 ; VBITS_GE_2048-NEXT: ptrue [[PG2:p[0-9]+]].d, vl32
444 ; VBITS_GE_2048-NEXT: st1d { [[RES]].d }, [[PG2]], [x2]
445 ; VBITS_GE_2048-NEXT: ret
446   %op1 = load <16 x i64>, <16 x i64>* %a
447   %op2 = load <16 x i64>, <16 x i64>* %b
448   %res = shufflevector <16 x i64> %op1, <16 x i64> %op2, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
449                                                                      i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15,
450                                                                      i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23,
451                                                                      i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
452   store <32 x i64> %res, <32 x i64>* %c
453   ret void
457 ; f16
460 ; Don't use SVE for 64-bit vectors.
461 define <4 x half> @concat_v4f16(<2 x half> %op1, <2 x half> %op2) #0 {
462 ; CHECK-LABEL: concat_v4f16:
463 ; CHECK: ext v0.8b, v0.8b, v0.8b, #4
464 ; CHECK-NEXT: ext v0.8b, v0.8b, v1.8b, #4
465 ; CHECK-NEXT: ret
466   %res = shufflevector <2 x half> %op1, <2 x half> %op2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
467   ret <4 x half> %res
470 ; Don't use SVE for 128-bit vectors.
471 define <8 x half> @concat_v8f16(<4 x half> %op1, <4 x half> %op2) #0 {
472 ; CHECK-LABEL: concat_v8f16:
473 ; CHECK: mov v0.d[1], v1.d[0]
474 ; CHECK-NEXT: ret
475   %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>
476   ret <8 x half> %res
479 define void @concat_v16f16(<8 x half>* %a, <8 x half>* %b, <16 x half>* %c) #0 {
480 ; CHECK-LABEL: concat_v16f16:
481 ; CHECK: ldr q[[OP1:[0-9]+]], [x0]
482 ; CHECK-NEXT: ldr q[[OP2:[0-9]+]], [x1]
483 ; CHECK-NEXT: ptrue [[PG1:p[0-9]+]].h, vl8
484 ; CHECK-NEXT: splice [[RES:z[0-9]+]].h, [[PG1]], z[[OP1]].h, z[[OP2]].h
485 ; CHECK-NEXT: ptrue [[PG2:p[0-9]+]].h, vl16
486 ; CHECK-NEXT: st1h { [[RES]].h }, [[PG2]], [x2]
487 ; CHECK-NEXT: ret
488   %op1 = load <8 x half>, <8 x half>* %a
489   %op2 = load <8 x half>, <8 x half>* %b
490   %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,
491                                                                      i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
492   store <16 x half> %res, <16 x half>* %c
493   ret void
496 define void @concat_v32f16(<16 x half>* %a, <16 x half>* %b, <32 x half>* %c) #0 {
497 ; CHECK-LABEL: concat_v32f16:
498 ; VBITS_GE_512: ptrue [[PG1:p[0-9]+]].h, vl16
499 ; VBITS_GE_512-NEXT: ld1h { [[OP1:z[0-9]+]].h }, [[PG1]]/z, [x0]
500 ; VBITS_GE_512-NEXT: ld1h { [[OP2:z[0-9]+]].h }, [[PG1]]/z, [x1]
501 ; VBITS_GE_512-NEXT: splice [[RES:z[0-9]+]].h, [[PG1]], [[OP1]].h, [[OP2]].h
502 ; VBITS_GE_512-NEXT: ptrue [[PG2:p[0-9]+]].h, vl32
503 ; VBITS_GE_512-NEXT: st1h { [[RES]].h }, [[PG2]], [x2]
504 ; VBITS_GE_512-NEXT: ret
505   %op1 = load <16 x half>, <16 x half>* %a
506   %op2 = load <16 x half>, <16 x half>* %b
507   %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,
508                                                                        i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15,
509                                                                        i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23,
510                                                                        i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
511   store <32 x half> %res, <32 x half>* %c
512   ret void
515 define void @concat_v64f16(<32 x half>* %a, <32 x half>* %b, <64 x half>* %c) #0 {
516 ; CHECK-LABEL: concat_v64f16:
517 ; VBITS_GE_1024: ptrue [[PG1:p[0-9]+]].h, vl32
518 ; VBITS_GE_1024-NEXT: ld1h { [[OP1:z[0-9]+]].h }, [[PG1]]/z, [x0]
519 ; VBITS_GE_1024-NEXT: ld1h { [[OP2:z[0-9]+]].h }, [[PG1]]/z, [x1]
520 ; VBITS_GE_1024-NEXT: splice [[RES:z[0-9]+]].h, [[PG1]], [[OP1]].h, [[OP2]].h
521 ; VBITS_GE_1024-NEXT: ptrue [[PG2:p[0-9]+]].h, vl64
522 ; VBITS_GE_1024-NEXT: st1h { [[RES]].h }, [[PG2]], [x2]
523 ; VBITS_GE_1024-NEXT: ret
524   %op1 = load <32 x half>, <32 x half>* %a
525   %op2 = load <32 x half>, <32 x half>* %b
526   %res = shufflevector <32 x half> %op1, <32 x half> %op2, <64 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
527                                                                        i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15,
528                                                                        i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23,
529                                                                        i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31,
530                                                                        i32 32, i32 33, i32 34, i32 35, i32 36, i32 37, i32 38, i32 39,
531                                                                        i32 40, i32 41, i32 42, i32 43, i32 44, i32 45, i32 46, i32 47,
532                                                                        i32 48, i32 49, i32 50, i32 51, i32 52, i32 53, i32 54, i32 55,
533                                                                        i32 56, i32 57, i32 58, i32 59, i32 60, i32 61, i32 62, i32 63>
534   store <64 x half> %res, <64 x half>* %c
535   ret void
538 define void @concat_v128f16(<64 x half>* %a, <64 x half>* %b, <128 x half>* %c) #0 {
539 ; CHECK-LABEL: concat_v128f16:
540 ; VBITS_GE_2048: ptrue [[PG1:p[0-9]+]].h, vl64
541 ; VBITS_GE_2048-NEXT: ld1h { [[OP1:z[0-9]+]].h }, [[PG1]]/z, [x0]
542 ; VBITS_GE_2048-NEXT: ld1h { [[OP2:z[0-9]+]].h }, [[PG1]]/z, [x1]
543 ; VBITS_GE_2048-NEXT: splice [[RES:z[0-9]+]].h, [[PG1]], [[OP1]].h, [[OP2]].h
544 ; VBITS_GE_2048-NEXT: ptrue [[PG2:p[0-9]+]].h, vl128
545 ; VBITS_GE_2048-NEXT: st1h { [[RES]].h }, [[PG2]], [x2]
546 ; VBITS_GE_2048-NEXT: ret
547   %op1 = load <64 x half>, <64 x half>* %a
548   %op2 = load <64 x half>, <64 x half>* %b
549   %res = shufflevector <64 x half> %op1, <64 x half> %op2, <128 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
550                                                                         i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15,
551                                                                         i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23,
552                                                                         i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31,
553                                                                         i32 32, i32 33, i32 34, i32 35, i32 36, i32 37, i32 38, i32 39,
554                                                                         i32 40, i32 41, i32 42, i32 43, i32 44, i32 45, i32 46, i32 47,
555                                                                         i32 48, i32 49, i32 50, i32 51, i32 52, i32 53, i32 54, i32 55,
556                                                                         i32 56, i32 57, i32 58, i32 59, i32 60, i32 61, i32 62, i32 63,
557                                                                         i32 64, i32 65, i32 66, i32 67, i32 68, i32 69, i32 70, i32 71,
558                                                                         i32 72, i32 73, i32 74, i32 75, i32 76, i32 77, i32 78, i32 79,
559                                                                         i32 80, i32 81, i32 82, i32 83, i32 84, i32 85, i32 86, i32 87,
560                                                                         i32 88, i32 89, i32 90, i32 91, i32 92, i32 93, i32 94, i32 95,
561                                                                         i32 96, i32 97, i32 98, i32 99, i32 100, i32 101, i32 102, i32 103,
562                                                                         i32 104, i32 105, i32 106, i32 107, i32 108, i32 109, i32 110, i32 111,
563                                                                         i32 112, i32 113, i32 114, i32 115, i32 116, i32 117, i32 118, i32 119,
564                                                                         i32 120, i32 121, i32 122, i32 123, i32 124, i32 125, i32 126, i32 127>
565   store <128 x half> %res, <128 x half>* %c
566   ret void
570 ; i32
573 ; Don't use SVE for 64-bit vectors.
574 define <2 x float> @concat_v2f32(<1 x float> %op1, <1 x float> %op2) #0 {
575 ; CHECK-LABEL: concat_v2f32:
576 ; CHECK: zip1 v0.2s, v0.2s, v1.2s
577 ; CHECK-NEXT: ret
578   %res = shufflevector <1 x float> %op1, <1 x float> %op2, <2 x i32> <i32 0, i32 1>
579   ret <2 x float> %res
582 ; Don't use SVE for 128-bit vectors.
583 define <4 x float> @concat_v4f32(<2 x float> %op1, <2 x float> %op2) #0 {
584 ; CHECK-LABEL: concat_v4f32:
585 ; CHECK: mov v0.d[1], v1.d[0]
586 ; CHECK-NEXT: ret
587   %res = shufflevector <2 x float> %op1, <2 x float> %op2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
588   ret <4 x float> %res
591 define void @concat_v8f32(<4 x float>* %a, <4 x float>* %b, <8 x float>* %c) #0 {
592 ; CHECK-LABEL: concat_v8f32:
593 ; CHECK: ldr q[[OP1:[0-9]+]], [x0]
594 ; CHECK-NEXT: ldr q[[OP2:[0-9]+]], [x1]
595 ; CHECK-NEXT: ptrue [[PG1:p[0-9]+]].s, vl4
596 ; CHECK-NEXT: splice [[RES:z[0-9]+]].s, [[PG1]], z[[OP1]].s, z[[OP2]].s
597 ; CHECK-NEXT: ptrue [[PG2:p[0-9]+]].s, vl8
598 ; CHECK-NEXT: st1w { [[RES]].s }, [[PG2]], [x2]
599 ; CHECK-NEXT: ret
600   %op1 = load <4 x float>, <4 x float>* %a
601   %op2 = load <4 x float>, <4 x float>* %b
602   %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>
603   store <8 x float> %res, <8 x float>* %c
604   ret void
607 define void @concat_v16f32(<8 x float>* %a, <8 x float>* %b, <16 x float>* %c) #0 {
608 ; CHECK-LABEL: concat_v16f32:
609 ; VBITS_GE_512: ptrue [[PG1:p[0-9]+]].s, vl8
610 ; VBITS_GE_512-NEXT: ld1w { [[OP1:z[0-9]+]].s }, [[PG1]]/z, [x0]
611 ; VBITS_GE_512-NEXT: ld1w { [[OP2:z[0-9]+]].s }, [[PG1]]/z, [x1]
612 ; VBITS_GE_512-NEXT: splice [[RES:z[0-9]+]].s, [[PG1]], [[OP1]].s, [[OP2]].s
613 ; VBITS_GE_512-NEXT: ptrue [[PG2:p[0-9]+]].s, vl16
614 ; VBITS_GE_512-NEXT: st1w { [[RES]].s }, [[PG2]], [x2]
615 ; VBITS_GE_512-NEXT: ret
616   %op1 = load <8 x float>, <8 x float>* %a
617   %op2 = load <8 x float>, <8 x float>* %b
618   %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,
619                                                                        i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
620   store <16 x float> %res, <16 x float>* %c
621   ret void
624 define void @concat_v32f32(<16 x float>* %a, <16 x float>* %b, <32 x float>* %c) #0 {
625 ; CHECK-LABEL: concat_v32f32:
626 ; VBITS_GE_1024: ptrue [[PG1:p[0-9]+]].s, vl16
627 ; VBITS_GE_1024-NEXT: ld1w { [[OP1:z[0-9]+]].s }, [[PG1]]/z, [x0]
628 ; VBITS_GE_1024-NEXT: ld1w { [[OP2:z[0-9]+]].s }, [[PG1]]/z, [x1]
629 ; VBITS_GE_1024-NEXT: splice [[RES:z[0-9]+]].s, [[PG1]], [[OP1]].s, [[OP2]].s
630 ; VBITS_GE_1024-NEXT: ptrue [[PG2:p[0-9]+]].s, vl32
631 ; VBITS_GE_1024-NEXT: st1w { [[RES]].s }, [[PG2]], [x2]
632 ; VBITS_GE_1024-NEXT: ret
633   %op1 = load <16 x float>, <16 x float>* %a
634   %op2 = load <16 x float>, <16 x float>* %b
635   %res = shufflevector <16 x float> %op1, <16 x float> %op2, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
636                                                                          i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15,
637                                                                          i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23,
638                                                                          i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
639   store <32 x float> %res, <32 x float>* %c
640   ret void
643 define void @concat_v64f32(<32 x float>* %a, <32 x float>* %b, <64 x float>* %c) #0 {
644 ; CHECK-LABEL: concat_v64f32:
645 ; VBITS_GE_2048: ptrue [[PG1:p[0-9]+]].s, vl32
646 ; VBITS_GE_2048-NEXT: ld1w { [[OP1:z[0-9]+]].s }, [[PG1]]/z, [x0]
647 ; VBITS_GE_2048-NEXT: ld1w { [[OP2:z[0-9]+]].s }, [[PG1]]/z, [x1]
648 ; VBITS_GE_2048-NEXT: splice [[RES:z[0-9]+]].s, [[PG1]], [[OP1]].s, [[OP2]].s
649 ; VBITS_GE_2048-NEXT: ptrue [[PG2:p[0-9]+]].s, vl64
650 ; VBITS_GE_2048-NEXT: st1w { [[RES]].s }, [[PG2]], [x2]
651 ; VBITS_GE_2048-NEXT: ret
652   %op1 = load <32 x float>, <32 x float>* %a
653   %op2 = load <32 x float>, <32 x float>* %b
654   %res = shufflevector <32 x float> %op1, <32 x float> %op2, <64 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
655                                                                          i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15,
656                                                                          i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23,
657                                                                          i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31,
658                                                                          i32 32, i32 33, i32 34, i32 35, i32 36, i32 37, i32 38, i32 39,
659                                                                          i32 40, i32 41, i32 42, i32 43, i32 44, i32 45, i32 46, i32 47,
660                                                                          i32 48, i32 49, i32 50, i32 51, i32 52, i32 53, i32 54, i32 55,
661                                                                          i32 56, i32 57, i32 58, i32 59, i32 60, i32 61, i32 62, i32 63>
662   store <64 x float> %res, <64 x float>* %c
663   ret void
667 ; f64
670 ; Don't use SVE for 128-bit vectors.
671 define <2 x double> @concat_v2f64(<1 x double> %op1, <1 x double> %op2) #0 {
672 ; CHECK-LABEL: concat_v2f64:
673 ; CHECK: mov v0.d[1], v1.d[0]
674 ; CHECK-NEXT: ret
675   %res = shufflevector <1 x double> %op1, <1 x double> %op2, <2 x i32> <i32 0, i32 1>
676   ret <2 x double> %res
679 define void @concat_v4f64(<2 x double>* %a, <2 x double>* %b, <4 x double>* %c) #0 {
680 ; CHECK-LABEL: concat_v4f64:
681 ; CHECK: ldr q[[OP1:[0-9]+]], [x0]
682 ; CHECK-NEXT: ldr q[[OP2:[0-9]+]], [x1]
683 ; CHECK-NEXT: ptrue [[PG1:p[0-9]+]].d, vl2
684 ; CHECK-NEXT: splice [[RES:z[0-9]+]].d, [[PG1]], z[[OP1]].d, z[[OP2]].d
685 ; CHECK-NEXT: ptrue [[PG2:p[0-9]+]].d, vl4
686 ; CHECK-NEXT: st1d { [[RES]].d }, [[PG2]], [x2]
687 ; CHECK-NEXT: ret
688   %op1 = load <2 x double>, <2 x double>* %a
689   %op2 = load <2 x double>, <2 x double>* %b
690   %res = shufflevector <2 x double> %op1, <2 x double> %op2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
691   store <4 x double> %res, <4 x double>* %c
692   ret void
695 define void @concat_v8f64(<4 x double>* %a, <4 x double>* %b, <8 x double>* %c) #0 {
696 ; CHECK-LABEL: concat_v8f64:
697 ; VBITS_GE_512: ptrue [[PG1:p[0-9]+]].d, vl4
698 ; VBITS_GE_512-NEXT: ld1d { [[OP1:z[0-9]+]].d }, [[PG1]]/z, [x0]
699 ; VBITS_GE_512-NEXT: ld1d { [[OP2:z[0-9]+]].d }, [[PG1]]/z, [x1]
700 ; VBITS_GE_512-NEXT: splice [[RES:z[0-9]+]].d, [[PG1]], [[OP1]].d, [[OP2]].d
701 ; VBITS_GE_512-NEXT: ptrue [[PG2:p[0-9]+]].d, vl8
702 ; VBITS_GE_512-NEXT: st1d { [[RES]].d }, [[PG2]], [x2]
703 ; VBITS_GE_512-NEXT: ret
704   %op1 = load <4 x double>, <4 x double>* %a
705   %op2 = load <4 x double>, <4 x double>* %b
706   %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>
707   store <8 x double> %res, <8 x double>* %c
708   ret void
711 define void @concat_v16f64(<8 x double>* %a, <8 x double>* %b, <16 x double>* %c) #0 {
712 ; CHECK-LABEL: concat_v16f64:
713 ; VBITS_GE_1024: ptrue [[PG1:p[0-9]+]].d, vl8
714 ; VBITS_GE_1024-NEXT: ld1d { [[OP1:z[0-9]+]].d }, [[PG1]]/z, [x0]
715 ; VBITS_GE_1024-NEXT: ld1d { [[OP2:z[0-9]+]].d }, [[PG1]]/z, [x1]
716 ; VBITS_GE_1024-NEXT: splice [[RES:z[0-9]+]].d, [[PG1]], [[OP1]].d, [[OP2]].d
717 ; VBITS_GE_1024-NEXT: ptrue [[PG2:p[0-9]+]].d, vl16
718 ; VBITS_GE_1024-NEXT: st1d { [[RES]].d }, [[PG2]], [x2]
719 ; VBITS_GE_1024-NEXT: ret
720   %op1 = load <8 x double>, <8 x double>* %a
721   %op2 = load <8 x double>, <8 x double>* %b
722   %res = shufflevector <8 x double> %op1, <8 x double> %op2, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
723                                                                          i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
724   store <16 x double> %res, <16 x double>* %c
725   ret void
728 define void @concat_v32f64(<16 x double>* %a, <16 x double>* %b, <32 x double>* %c) #0 {
729 ; CHECK-LABEL: concat_v32f64:
730 ; VBITS_GE_2048: ptrue [[PG1:p[0-9]+]].d, vl16
731 ; VBITS_GE_2048-NEXT: ld1d { [[OP1:z[0-9]+]].d }, [[PG1]]/z, [x0]
732 ; VBITS_GE_2048-NEXT: ld1d { [[OP2:z[0-9]+]].d }, [[PG1]]/z, [x1]
733 ; VBITS_GE_2048-NEXT: splice [[RES:z[0-9]+]].d, [[PG1]], [[OP1]].d, [[OP2]].d
734 ; VBITS_GE_2048-NEXT: ptrue [[PG2:p[0-9]+]].d, vl32
735 ; VBITS_GE_2048-NEXT: st1d { [[RES]].d }, [[PG2]], [x2]
736 ; VBITS_GE_2048-NEXT: ret
737   %op1 = load <16 x double>, <16 x double>* %a
738   %op2 = load <16 x double>, <16 x double>* %b
739   %res = shufflevector <16 x double> %op1, <16 x double> %op2, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
740                                                                            i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15,
741                                                                            i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23,
742                                                                            i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
743   store <32 x double> %res, <32 x double>* %c
744   ret void
748 ; undef
751 define void @concat_v32i8_undef(<16 x i8>* %a, <32 x i8>* %b) #0 {
752 ; CHECK-LABEL: concat_v32i8_undef:
753 ; CHECK: ldr q[[OP1:[0-9]+]], [x0]
754 ; CHECK-NEXT: ptrue [[PG:p[0-9]+]].b, vl32
755 ; CHECK-NEXT: st1b { z[[OP1]].b }, [[PG]], [x1]
756 ; CHECK-NEXT: ret
757   %op1 = load <16 x i8>, <16 x i8>* %a
758   %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,
759                                                                     i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15,
760                                                                     i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23,
761                                                                     i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
762   store <32 x i8> %res, <32 x i8>* %b
763   ret void
766 define void @concat_v16i16_undef(<8 x i16>* %a, <16 x i16>* %b) #0 {
767 ; CHECK-LABEL: concat_v16i16_undef:
768 ; CHECK: ldr q[[OP1:[0-9]+]], [x0]
769 ; CHECK-NEXT: ptrue [[PG:p[0-9]+]].h, vl16
770 ; CHECK-NEXT: st1h { z[[OP1]].h }, [[PG]], [x1]
771 ; CHECK-NEXT: ret
772   %op1 = load <8 x i16>, <8 x i16>* %a
773   %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,
774                                                                     i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
775   store <16 x i16> %res, <16 x i16>* %b
776   ret void
779 define void @concat_v8i32_undef(<4 x i32>* %a, <8 x i32>* %b) #0 {
780 ; CHECK-LABEL: concat_v8i32_undef:
781 ; CHECK: ldr q[[OP1:[0-9]+]], [x0]
782 ; CHECK-NEXT: ptrue [[PG:p[0-9]+]].s, vl8
783 ; CHECK-NEXT: st1w { z[[OP1]].s }, [[PG]], [x1]
784 ; CHECK-NEXT: ret
785   %op1 = load <4 x i32>, <4 x i32>* %a
786   %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>
787   store <8 x i32> %res, <8 x i32>* %b
788   ret void
791 define void @concat_v4i64_undef(<2 x i64>* %a, <4 x i64>* %b) #0 {
792 ; CHECK-LABEL: concat_v4i64_undef:
793 ; CHECK: ldr q[[OP1:[0-9]+]], [x0]
794 ; CHECK-NEXT: ptrue [[PG:p[0-9]+]].d, vl4
795 ; CHECK-NEXT: st1d { z[[OP1]].d }, [[PG]], [x1]
796 ; CHECK-NEXT: ret
797   %op1 = load <2 x i64>, <2 x i64>* %a
798   %res = shufflevector <2 x i64> %op1, <2 x i64> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
799   store <4 x i64> %res, <4 x i64>* %b
800   ret void
804 ; > 2 operands
807 define void @concat_v32i8_4op(<8 x i8>* %a, <32 x i8>* %b) #0 {
808 ; CHECK-LABEL: concat_v32i8_4op:
809 ; CHECK: ldr d[[OP1:[0-9]+]], [x0]
810 ; CHECK-NEXT: ptrue [[PG:p[0-9]+]].b, vl32
811 ; CHECK-NEXT: st1b { z[[OP1]].b }, [[PG]], [x1]
812 ; CHECK-NEXT: ret
813   %op1 = load <8 x i8>, <8 x i8>* %a
814   %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,
815                                                                       i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
816   %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,
817                                                                         i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15,
818                                                                         i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23,
819                                                                         i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
820   store <32 x i8> %res, <32 x i8>* %b
821   ret void
824 define void @concat_v16i16_4op(<4 x i16>* %a, <16 x i16>* %b) #0 {
825 ; CHECK-LABEL: concat_v16i16_4op:
826 ; CHECK: ldr d[[OP1:[0-9]+]], [x0]
827 ; CHECK-NEXT: ptrue [[PG:p[0-9]+]].h, vl16
828 ; CHECK-NEXT: st1h { z[[OP1]].h }, [[PG]], [x1]
829 ; CHECK-NEXT: ret
830   %op1 = load <4 x i16>, <4 x i16>* %a
831   %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>
832   %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,
833                                                                         i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
834   store <16 x i16> %res, <16 x i16>* %b
835   ret void
838 define void @concat_v8i32_4op(<2 x i32>* %a, <8 x i32>* %b) #0 {
839 ; CHECK-LABEL: concat_v8i32_4op:
840 ; CHECK: ldr d[[OP1:[0-9]+]], [x0]
841 ; CHECK-NEXT: ptrue [[PG:p[0-9]+]].s, vl8
842 ; CHECK-NEXT: st1w { z[[OP1]].s }, [[PG]], [x1]
843 ; CHECK-NEXT: ret
844   %op1 = load <2 x i32>, <2 x i32>* %a
845   %shuffle = shufflevector <2 x i32> %op1, <2 x i32> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
846   %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>
847   store <8 x i32> %res, <8 x i32>* %b
848   ret void
851 define void @concat_v4i64_4op(<1 x i64>* %a, <4 x i64>* %b) #0 {
852 ; CHECK-LABEL: concat_v4i64_4op:
853 ; CHECK: ldr d[[OP1:[0-9]+]], [x0]
854 ; CHECK-NEXT: ptrue [[PG:p[0-9]+]].d, vl4
855 ; CHECK-NEXT: st1d { z[[OP1]].d }, [[PG]], [x1]
856 ; CHECK-NEXT: ret
857   %op1 = load <1 x i64>, <1 x i64>* %a
858   %shuffle = shufflevector <1 x i64> %op1, <1 x i64> undef, <2 x i32> <i32 0, i32 1>
859   %res = shufflevector <2 x i64> %shuffle, <2 x i64> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
860   store <4 x i64> %res, <4 x i64>* %b
861   ret void
864 attributes #0 = { "target-features"="+sve" }