Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / CodeGen / AArch64 / shufflevector.ll
blobb1131f287fe9a9ff1ee61524abe02106fef2f997
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
2 ; RUN: llc -mtriple=aarch64-none-linux-gnu %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SD
3 ; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel -global-isel-abort=2 %s -o - 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-GI
5 ; CHECK-GI:         warning: Instruction selection used fallback path for shufflevector_v2i1
6 ; CHECK-GI-NEXT:    warning: Instruction selection used fallback path for shufflevector_v2i1_zeroes
8 ; ===== Legal Vector Types =====
10 define <8 x i8> @shufflevector_v8i8(<8 x i8> %a, <8 x i8> %b) {
11 ; CHECK-SD-LABEL: shufflevector_v8i8:
12 ; CHECK-SD:       // %bb.0:
13 ; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 def $q0
14 ; CHECK-SD-NEXT:    // kill: def $d1 killed $d1 def $q1
15 ; CHECK-SD-NEXT:    adrp x8, .LCPI0_0
16 ; CHECK-SD-NEXT:    mov v0.d[1], v1.d[0]
17 ; CHECK-SD-NEXT:    ldr d1, [x8, :lo12:.LCPI0_0]
18 ; CHECK-SD-NEXT:    tbl v0.8b, { v0.16b }, v1.8b
19 ; CHECK-SD-NEXT:    ret
21 ; CHECK-GI-LABEL: shufflevector_v8i8:
22 ; CHECK-GI:       // %bb.0:
23 ; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 def $q0
24 ; CHECK-GI-NEXT:    // kill: def $d1 killed $d1 def $q1
25 ; CHECK-GI-NEXT:    adrp x8, .LCPI0_0
26 ; CHECK-GI-NEXT:    mov v0.d[1], v1.d[0]
27 ; CHECK-GI-NEXT:    ldr d1, [x8, :lo12:.LCPI0_0]
28 ; CHECK-GI-NEXT:    tbl v0.16b, { v0.16b }, v1.16b
29 ; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0
30 ; CHECK-GI-NEXT:    ret
31     %c = shufflevector <8 x i8> %a, <8 x i8> %b, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 8, i32 10, i32 12, i32 15>
32     ret <8 x i8> %c
35 define <16 x i8> @shufflevector_v16i8(<16 x i8> %a, <16 x i8> %b) {
36 ; CHECK-SD-LABEL: shufflevector_v16i8:
37 ; CHECK-SD:       // %bb.0:
38 ; CHECK-SD-NEXT:    adrp x8, .LCPI1_0
39 ; CHECK-SD-NEXT:    // kill: def $q1 killed $q1 killed $q0_q1 def $q0_q1
40 ; CHECK-SD-NEXT:    ldr q2, [x8, :lo12:.LCPI1_0]
41 ; CHECK-SD-NEXT:    // kill: def $q0 killed $q0 killed $q0_q1 def $q0_q1
42 ; CHECK-SD-NEXT:    tbl v0.16b, { v0.16b, v1.16b }, v2.16b
43 ; CHECK-SD-NEXT:    ret
45 ; CHECK-GI-LABEL: shufflevector_v16i8:
46 ; CHECK-GI:       // %bb.0:
47 ; CHECK-GI-NEXT:    adrp x8, .LCPI1_0
48 ; CHECK-GI-NEXT:    // kill: def $q0 killed $q0 killed $q0_q1 def $q0_q1
49 ; CHECK-GI-NEXT:    ldr q2, [x8, :lo12:.LCPI1_0]
50 ; CHECK-GI-NEXT:    // kill: def $q1 killed $q1 killed $q0_q1 def $q0_q1
51 ; CHECK-GI-NEXT:    tbl v0.16b, { v0.16b, v1.16b }, v2.16b
52 ; CHECK-GI-NEXT:    ret
53     %c = shufflevector <16 x i8> %a, <16 x i8> %b, <16 x i32> <i32 1, i32 3, i32 5, i32 7, i32 8, i32 10, i32 12, i32 15, i32 2, i32 4, i32 6, i32 8, i32 25, i32 30, i32 31, i32 31>
54     ret <16 x i8> %c
57 define <4 x i16> @shufflevector_v4i16(<4 x i16> %a, <4 x i16> %b) {
58 ; CHECK-LABEL: shufflevector_v4i16:
59 ; CHECK:       // %bb.0:
60 ; CHECK-NEXT:    uzp2 v0.4h, v0.4h, v1.4h
61 ; CHECK-NEXT:    ret
62     %c = shufflevector <4 x i16> %a, <4 x i16> %b, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
63     ret <4 x i16> %c
66 define <8 x i16> @shufflevector_v8i16(<8 x i16> %a, <8 x i16> %b) {
67 ; CHECK-SD-LABEL: shufflevector_v8i16:
68 ; CHECK-SD:       // %bb.0:
69 ; CHECK-SD-NEXT:    adrp x8, .LCPI3_0
70 ; CHECK-SD-NEXT:    // kill: def $q1 killed $q1 killed $q0_q1 def $q0_q1
71 ; CHECK-SD-NEXT:    ldr q2, [x8, :lo12:.LCPI3_0]
72 ; CHECK-SD-NEXT:    // kill: def $q0 killed $q0 killed $q0_q1 def $q0_q1
73 ; CHECK-SD-NEXT:    tbl v0.16b, { v0.16b, v1.16b }, v2.16b
74 ; CHECK-SD-NEXT:    ret
76 ; CHECK-GI-LABEL: shufflevector_v8i16:
77 ; CHECK-GI:       // %bb.0:
78 ; CHECK-GI-NEXT:    adrp x8, .LCPI3_0
79 ; CHECK-GI-NEXT:    // kill: def $q0 killed $q0 killed $q0_q1 def $q0_q1
80 ; CHECK-GI-NEXT:    ldr q2, [x8, :lo12:.LCPI3_0]
81 ; CHECK-GI-NEXT:    // kill: def $q1 killed $q1 killed $q0_q1 def $q0_q1
82 ; CHECK-GI-NEXT:    tbl v0.16b, { v0.16b, v1.16b }, v2.16b
83 ; CHECK-GI-NEXT:    ret
84     %c = shufflevector <8 x i16> %a, <8 x i16> %b, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 8, i32 10, i32 12, i32 15>
85     ret <8 x i16> %c
88 define <2 x i32> @shufflevector_v2i32(<2 x i32> %a, <2 x i32> %b) {
89 ; CHECK-LABEL: shufflevector_v2i32:
90 ; CHECK:       // %bb.0:
91 ; CHECK-NEXT:    zip2 v0.2s, v0.2s, v1.2s
92 ; CHECK-NEXT:    ret
93     %c = shufflevector <2 x i32> %a, <2 x i32> %b, <2 x i32> <i32 1, i32 3>
94     ret <2 x i32> %c
97 define <4 x i32> @shufflevector_v4i32(<4 x i32> %a, <4 x i32> %b) {
98 ; CHECK-LABEL: shufflevector_v4i32:
99 ; CHECK:       // %bb.0:
100 ; CHECK-NEXT:    uzp2 v0.4s, v0.4s, v1.4s
101 ; CHECK-NEXT:    ret
102     %c = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
103     ret <4 x i32> %c
106 define <2 x i64> @shufflevector_v2i64(<2 x i64> %a, <2 x i64> %b) {
107 ; CHECK-LABEL: shufflevector_v2i64:
108 ; CHECK:       // %bb.0:
109 ; CHECK-NEXT:    zip2 v0.2d, v0.2d, v1.2d
110 ; CHECK-NEXT:    ret
111     %c = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 1, i32 3>
112     ret <2 x i64> %c
115 ; ===== Legal Vector Types with Zero Masks =====
117 define <8 x i8> @shufflevector_v8i8_zeroes(<8 x i8> %a, <8 x i8> %b) {
118 ; CHECK-LABEL: shufflevector_v8i8_zeroes:
119 ; CHECK:       // %bb.0:
120 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
121 ; CHECK-NEXT:    dup v0.8b, v0.b[0]
122 ; CHECK-NEXT:    ret
123     %c = shufflevector <8 x i8> %a, <8 x i8> %b, <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
124     ret <8 x i8> %c
127 define <16 x i8> @shufflevector_v16i8_zeroes(<16 x i8> %a, <16 x i8> %b) {
128 ; CHECK-LABEL: shufflevector_v16i8_zeroes:
129 ; CHECK:       // %bb.0:
130 ; CHECK-NEXT:    dup v0.16b, v0.b[0]
131 ; CHECK-NEXT:    ret
132     %c = shufflevector <16 x i8> %a, <16 x i8> %b, <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
133     ret <16 x i8> %c
136 define <4 x i16> @shufflevector_v4i16_zeroes(<4 x i16> %a, <4 x i16> %b) {
137 ; CHECK-LABEL: shufflevector_v4i16_zeroes:
138 ; CHECK:       // %bb.0:
139 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
140 ; CHECK-NEXT:    dup v0.4h, v0.h[0]
141 ; CHECK-NEXT:    ret
142     %c = shufflevector <4 x i16> %a, <4 x i16> %b, <4 x i32> <i32 0, i32 0, i32 0, i32 0>
143     ret <4 x i16> %c
146 define <8 x i16> @shufflevector_v8i16_zeroes(<8 x i16> %a, <8 x i16> %b) {
147 ; CHECK-LABEL: shufflevector_v8i16_zeroes:
148 ; CHECK:       // %bb.0:
149 ; CHECK-NEXT:    dup v0.8h, v0.h[0]
150 ; CHECK-NEXT:    ret
151     %c = shufflevector <8 x i16> %a, <8 x i16> %b, <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
152     ret <8 x i16> %c
155 define <2 x i32> @shufflevector_v2i32_zeroes(<2 x i32> %a, <2 x i32> %b) {
156 ; CHECK-LABEL: shufflevector_v2i32_zeroes:
157 ; CHECK:       // %bb.0:
158 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
159 ; CHECK-NEXT:    dup v0.2s, v0.s[0]
160 ; CHECK-NEXT:    ret
161     %c = shufflevector <2 x i32> %a, <2 x i32> %b, <2 x i32> <i32 0, i32 0>
162     ret <2 x i32> %c
165 define <4 x i32> @shufflevector_v4i32_zeroes(<4 x i32> %a, <4 x i32> %b) {
166 ; CHECK-LABEL: shufflevector_v4i32_zeroes:
167 ; CHECK:       // %bb.0:
168 ; CHECK-NEXT:    dup v0.4s, v0.s[0]
169 ; CHECK-NEXT:    ret
170     %c = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 0, i32 0, i32 0>
171     ret <4 x i32> %c
174 define <2 x i64> @shufflevector_v2i64_zeroes(<2 x i64> %a, <2 x i64> %b) {
175 ; CHECK-LABEL: shufflevector_v2i64_zeroes:
176 ; CHECK:       // %bb.0:
177 ; CHECK-NEXT:    dup v0.2d, v0.d[0]
178 ; CHECK-NEXT:    ret
179     %c = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 0, i32 0>
180     ret <2 x i64> %c
183 ; ===== Smaller/Larger Width Vectors with Legal Element Sizes =====
185 define <2 x i1> @shufflevector_v2i1(<2 x i1> %a, <2 x i1> %b){
186 ; CHECK-LABEL: shufflevector_v2i1:
187 ; CHECK:       // %bb.0:
188 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
189 ; CHECK-NEXT:    // kill: def $d1 killed $d1 def $q1
190 ; CHECK-NEXT:    mov v0.s[1], v1.s[1]
191 ; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $q0
192 ; CHECK-NEXT:    ret
193     %c = shufflevector <2 x i1> %a, <2 x i1> %b, <2 x i32> <i32 0, i32 3>
194     ret <2 x i1> %c
197 define i32 @shufflevector_v4i8(<4 x i8> %a, <4 x i8> %b){
198 ; CHECK-SD-LABEL: shufflevector_v4i8:
199 ; CHECK-SD:       // %bb.0:
200 ; CHECK-SD-NEXT:    sub sp, sp, #16
201 ; CHECK-SD-NEXT:    .cfi_def_cfa_offset 16
202 ; CHECK-SD-NEXT:    ext v0.8b, v1.8b, v0.8b, #6
203 ; CHECK-SD-NEXT:    zip1 v1.4h, v1.4h, v0.4h
204 ; CHECK-SD-NEXT:    ext v0.8b, v0.8b, v1.8b, #4
205 ; CHECK-SD-NEXT:    uzp1 v0.8b, v0.8b, v0.8b
206 ; CHECK-SD-NEXT:    fmov w0, s0
207 ; CHECK-SD-NEXT:    add sp, sp, #16
208 ; CHECK-SD-NEXT:    ret
210 ; CHECK-GI-LABEL: shufflevector_v4i8:
211 ; CHECK-GI:       // %bb.0:
212 ; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 def $q0
213 ; CHECK-GI-NEXT:    // kill: def $d1 killed $d1 def $q1
214 ; CHECK-GI-NEXT:    mov h2, v0.h[1]
215 ; CHECK-GI-NEXT:    mov h3, v1.h[1]
216 ; CHECK-GI-NEXT:    adrp x8, .LCPI15_0
217 ; CHECK-GI-NEXT:    mov h4, v0.h[2]
218 ; CHECK-GI-NEXT:    mov h5, v0.h[3]
219 ; CHECK-GI-NEXT:    mov h6, v1.h[3]
220 ; CHECK-GI-NEXT:    mov v0.b[1], v2.b[0]
221 ; CHECK-GI-NEXT:    mov h2, v1.h[2]
222 ; CHECK-GI-NEXT:    mov v1.b[1], v3.b[0]
223 ; CHECK-GI-NEXT:    mov v0.b[2], v4.b[0]
224 ; CHECK-GI-NEXT:    mov v1.b[2], v2.b[0]
225 ; CHECK-GI-NEXT:    mov v0.b[3], v5.b[0]
226 ; CHECK-GI-NEXT:    mov v1.b[3], v6.b[0]
227 ; CHECK-GI-NEXT:    mov v0.d[1], v1.d[0]
228 ; CHECK-GI-NEXT:    ldr d1, [x8, :lo12:.LCPI15_0]
229 ; CHECK-GI-NEXT:    tbl v0.16b, { v0.16b }, v1.16b
230 ; CHECK-GI-NEXT:    fmov w0, s0
231 ; CHECK-GI-NEXT:    ret
232     %c = shufflevector <4 x i8> %a, <4 x i8> %b, <4 x i32> <i32 1, i32 2, i32 4, i32 7>
233     %d = bitcast <4 x i8> %c to i32
234     ret i32 %d
237 define <32 x i8> @shufflevector_v32i8(<32 x i8> %a, <32 x i8> %b){
238 ; CHECK-SD-LABEL: shufflevector_v32i8:
239 ; CHECK-SD:       // %bb.0:
240 ; CHECK-SD-NEXT:    // kill: def $q2 killed $q2 def $q1_q2
241 ; CHECK-SD-NEXT:    adrp x8, .LCPI16_0
242 ; CHECK-SD-NEXT:    adrp x9, .LCPI16_1
243 ; CHECK-SD-NEXT:    mov v1.16b, v0.16b
244 ; CHECK-SD-NEXT:    ldr q3, [x8, :lo12:.LCPI16_0]
245 ; CHECK-SD-NEXT:    ldr q4, [x9, :lo12:.LCPI16_1]
246 ; CHECK-SD-NEXT:    tbl v0.16b, { v1.16b, v2.16b }, v3.16b
247 ; CHECK-SD-NEXT:    tbl v1.16b, { v1.16b, v2.16b }, v4.16b
248 ; CHECK-SD-NEXT:    ret
250 ; CHECK-GI-LABEL: shufflevector_v32i8:
251 ; CHECK-GI:       // %bb.0:
252 ; CHECK-GI-NEXT:    mov v3.16b, v0.16b
253 ; CHECK-GI-NEXT:    adrp x8, .LCPI16_1
254 ; CHECK-GI-NEXT:    adrp x9, .LCPI16_0
255 ; CHECK-GI-NEXT:    mov v4.16b, v2.16b
256 ; CHECK-GI-NEXT:    ldr q0, [x8, :lo12:.LCPI16_1]
257 ; CHECK-GI-NEXT:    ldr q1, [x9, :lo12:.LCPI16_0]
258 ; CHECK-GI-NEXT:    tbl v0.16b, { v3.16b, v4.16b }, v0.16b
259 ; CHECK-GI-NEXT:    tbl v1.16b, { v3.16b, v4.16b }, v1.16b
260 ; CHECK-GI-NEXT:    ret
261     %c = shufflevector <32 x i8> %a, <32 x i8> %b, <32 x i32> <i32 0, i32 32, i32 32, i32 32, i32 1, i32 32, i32 32, i32 32, i32 2, i32 32, i32 32, i32 32, i32 3, i32 32, i32 32, i32 32, i32 4, i32 32, i32 32, i32 32, i32 5, i32 32, i32 32, i32 32, i32 6, i32 32, i32 32, i32 32, i32 7, i32 32, i32 32, i32 32>
262     ret <32 x i8> %c
265 define i32 @shufflevector_v2i16(<2 x i16> %a, <2 x i16> %b){
266 ; CHECK-SD-LABEL: shufflevector_v2i16:
267 ; CHECK-SD:       // %bb.0:
268 ; CHECK-SD-NEXT:    sub sp, sp, #16
269 ; CHECK-SD-NEXT:    .cfi_def_cfa_offset 16
270 ; CHECK-SD-NEXT:    ext v0.8b, v0.8b, v1.8b, #4
271 ; CHECK-SD-NEXT:    mov w8, v0.s[1]
272 ; CHECK-SD-NEXT:    fmov w9, s0
273 ; CHECK-SD-NEXT:    strh w9, [sp, #12]
274 ; CHECK-SD-NEXT:    strh w8, [sp, #14]
275 ; CHECK-SD-NEXT:    ldr w0, [sp, #12]
276 ; CHECK-SD-NEXT:    add sp, sp, #16
277 ; CHECK-SD-NEXT:    ret
279 ; CHECK-GI-LABEL: shufflevector_v2i16:
280 ; CHECK-GI:       // %bb.0:
281 ; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 def $q0
282 ; CHECK-GI-NEXT:    // kill: def $d1 killed $d1 def $q1
283 ; CHECK-GI-NEXT:    mov s2, v0.s[1]
284 ; CHECK-GI-NEXT:    mov s3, v1.s[1]
285 ; CHECK-GI-NEXT:    adrp x8, .LCPI17_0
286 ; CHECK-GI-NEXT:    mov v0.h[1], v2.h[0]
287 ; CHECK-GI-NEXT:    mov v1.h[1], v3.h[0]
288 ; CHECK-GI-NEXT:    mov v0.d[1], v1.d[0]
289 ; CHECK-GI-NEXT:    ldr d1, [x8, :lo12:.LCPI17_0]
290 ; CHECK-GI-NEXT:    tbl v0.16b, { v0.16b }, v1.16b
291 ; CHECK-GI-NEXT:    fmov w0, s0
292 ; CHECK-GI-NEXT:    ret
293     %c = shufflevector <2 x i16> %a, <2 x i16> %b, <2 x i32> <i32 1, i32 2>
294     %d = bitcast <2 x i16> %c to i32
295     ret i32 %d
298 define <16 x i16> @shufflevector_v16i16(<16 x i16> %a, <16 x i16> %b){
299 ; CHECK-SD-LABEL: shufflevector_v16i16:
300 ; CHECK-SD:       // %bb.0:
301 ; CHECK-SD-NEXT:    // kill: def $q2 killed $q2 def $q1_q2
302 ; CHECK-SD-NEXT:    adrp x8, .LCPI18_0
303 ; CHECK-SD-NEXT:    adrp x9, .LCPI18_1
304 ; CHECK-SD-NEXT:    mov v1.16b, v0.16b
305 ; CHECK-SD-NEXT:    ldr q3, [x8, :lo12:.LCPI18_0]
306 ; CHECK-SD-NEXT:    ldr q4, [x9, :lo12:.LCPI18_1]
307 ; CHECK-SD-NEXT:    tbl v0.16b, { v1.16b, v2.16b }, v3.16b
308 ; CHECK-SD-NEXT:    tbl v1.16b, { v1.16b, v2.16b }, v4.16b
309 ; CHECK-SD-NEXT:    ret
311 ; CHECK-GI-LABEL: shufflevector_v16i16:
312 ; CHECK-GI:       // %bb.0:
313 ; CHECK-GI-NEXT:    mov v3.16b, v0.16b
314 ; CHECK-GI-NEXT:    adrp x8, .LCPI18_1
315 ; CHECK-GI-NEXT:    adrp x9, .LCPI18_0
316 ; CHECK-GI-NEXT:    mov v4.16b, v2.16b
317 ; CHECK-GI-NEXT:    ldr q0, [x8, :lo12:.LCPI18_1]
318 ; CHECK-GI-NEXT:    ldr q1, [x9, :lo12:.LCPI18_0]
319 ; CHECK-GI-NEXT:    tbl v0.16b, { v3.16b, v4.16b }, v0.16b
320 ; CHECK-GI-NEXT:    tbl v1.16b, { v3.16b, v4.16b }, v1.16b
321 ; CHECK-GI-NEXT:    ret
322     %c = shufflevector <16 x i16> %a, <16 x i16> %b, <16 x i32> <i32 0, i32 16, i32 16, i32 16, i32 1, i32 16, i32 16, i32 16, i32 1, i32 16, i32 16, i32 16, i32 3, i32 16, i32 16, i32 16>
323     ret <16 x i16> %c
326 define <1 x i32> @shufflevector_v1i32(<1 x i32> %a, <1 x i32> %b) {
327 ; CHECK-LABEL: shufflevector_v1i32:
328 ; CHECK:       // %bb.0:
329 ; CHECK-NEXT:    fmov d0, d1
330 ; CHECK-NEXT:    ret
331     %c = shufflevector <1 x i32> %a, <1 x i32> %b, <1 x i32> <i32 1>
332     ret <1 x i32> %c
335 define <8 x i32> @shufflevector_v8i32(<8 x i32> %a, <8 x i32> %b) {
336 ; CHECK-SD-LABEL: shufflevector_v8i32:
337 ; CHECK-SD:       // %bb.0:
338 ; CHECK-SD-NEXT:    uzp1 v2.4s, v2.4s, v3.4s
339 ; CHECK-SD-NEXT:    uzp2 v0.4s, v0.4s, v1.4s
340 ; CHECK-SD-NEXT:    mov v2.s[3], v3.s[3]
341 ; CHECK-SD-NEXT:    mov v1.16b, v2.16b
342 ; CHECK-SD-NEXT:    ret
344 ; CHECK-GI-LABEL: shufflevector_v8i32:
345 ; CHECK-GI:       // %bb.0:
346 ; CHECK-GI-NEXT:    adrp x8, .LCPI20_0
347 ; CHECK-GI-NEXT:    // kill: def $q2 killed $q2 killed $q2_q3 def $q2_q3
348 ; CHECK-GI-NEXT:    uzp2 v0.4s, v0.4s, v1.4s
349 ; CHECK-GI-NEXT:    ldr q4, [x8, :lo12:.LCPI20_0]
350 ; CHECK-GI-NEXT:    // kill: def $q3 killed $q3 killed $q2_q3 def $q2_q3
351 ; CHECK-GI-NEXT:    tbl v1.16b, { v2.16b, v3.16b }, v4.16b
352 ; CHECK-GI-NEXT:    ret
353     %c = shufflevector <8 x i32> %a, <8 x i32> %b, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 8, i32 10, i32 12, i32 15>
354     ret <8 x i32> %c
357 define <4 x i64> @shufflevector_v4i64(<4 x i64> %a, <4 x i64> %b) {
358 ; CHECK-SD-LABEL: shufflevector_v4i64:
359 ; CHECK-SD:       // %bb.0:
360 ; CHECK-SD-NEXT:    zip2 v2.2d, v2.2d, v3.2d
361 ; CHECK-SD-NEXT:    zip2 v0.2d, v0.2d, v1.2d
362 ; CHECK-SD-NEXT:    mov v1.16b, v2.16b
363 ; CHECK-SD-NEXT:    ret
365 ; CHECK-GI-LABEL: shufflevector_v4i64:
366 ; CHECK-GI:       // %bb.0:
367 ; CHECK-GI-NEXT:    zip2 v0.2d, v0.2d, v1.2d
368 ; CHECK-GI-NEXT:    zip2 v1.2d, v2.2d, v3.2d
369 ; CHECK-GI-NEXT:    ret
370     %c = shufflevector <4 x i64> %a, <4 x i64> %b, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
371     ret <4 x i64> %c
374 ; ===== Smaller/Larger Width Vectors with Zero Masks =====
376 define <2 x i1> @shufflevector_v2i1_zeroes(<2 x i1> %a, <2 x i1> %b){
377 ; CHECK-LABEL: shufflevector_v2i1_zeroes:
378 ; CHECK:       // %bb.0:
379 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
380 ; CHECK-NEXT:    dup v0.2s, v0.s[0]
381 ; CHECK-NEXT:    ret
382     %c = shufflevector <2 x i1> %a, <2 x i1> %b, <2 x i32> <i32 0, i32 0>
383     ret <2 x i1> %c
386 define i32 @shufflevector_v4i8_zeroes(<4 x i8> %a, <4 x i8> %b){
387 ; CHECK-SD-LABEL: shufflevector_v4i8_zeroes:
388 ; CHECK-SD:       // %bb.0:
389 ; CHECK-SD-NEXT:    sub sp, sp, #16
390 ; CHECK-SD-NEXT:    .cfi_def_cfa_offset 16
391 ; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 def $q0
392 ; CHECK-SD-NEXT:    dup v0.4h, v0.h[0]
393 ; CHECK-SD-NEXT:    uzp1 v0.8b, v0.8b, v0.8b
394 ; CHECK-SD-NEXT:    fmov w0, s0
395 ; CHECK-SD-NEXT:    add sp, sp, #16
396 ; CHECK-SD-NEXT:    ret
398 ; CHECK-GI-LABEL: shufflevector_v4i8_zeroes:
399 ; CHECK-GI:       // %bb.0:
400 ; CHECK-GI-NEXT:    fmov w8, s0
401 ; CHECK-GI-NEXT:    dup v0.8b, w8
402 ; CHECK-GI-NEXT:    fmov w0, s0
403 ; CHECK-GI-NEXT:    ret
404     %c = shufflevector <4 x i8> %a, <4 x i8> %b, <4 x i32> <i32 0, i32 0, i32 0, i32 0>
405     %d = bitcast <4 x i8> %c to i32
406     ret i32 %d
409 define <32 x i8> @shufflevector_v32i8_zeroes(<32 x i8> %a, <32 x i8> %b){
410 ; CHECK-LABEL: shufflevector_v32i8_zeroes:
411 ; CHECK:       // %bb.0:
412 ; CHECK-NEXT:    dup v0.16b, v0.b[0]
413 ; CHECK-NEXT:    mov v1.16b, v0.16b
414 ; CHECK-NEXT:    ret
415     %c = shufflevector <32 x i8> %a, <32 x i8> %b, <32 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
416     ret <32 x i8> %c
419 define i32 @shufflevector_v2i16_zeroes(<2 x i16> %a, <2 x i16> %b){
420 ; CHECK-SD-LABEL: shufflevector_v2i16_zeroes:
421 ; CHECK-SD:       // %bb.0:
422 ; CHECK-SD-NEXT:    sub sp, sp, #16
423 ; CHECK-SD-NEXT:    .cfi_def_cfa_offset 16
424 ; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 def $q0
425 ; CHECK-SD-NEXT:    dup v1.2s, v0.s[0]
426 ; CHECK-SD-NEXT:    fmov w9, s0
427 ; CHECK-SD-NEXT:    strh w9, [sp, #12]
428 ; CHECK-SD-NEXT:    mov w8, v1.s[1]
429 ; CHECK-SD-NEXT:    strh w8, [sp, #14]
430 ; CHECK-SD-NEXT:    ldr w0, [sp, #12]
431 ; CHECK-SD-NEXT:    add sp, sp, #16
432 ; CHECK-SD-NEXT:    ret
434 ; CHECK-GI-LABEL: shufflevector_v2i16_zeroes:
435 ; CHECK-GI:       // %bb.0:
436 ; CHECK-GI-NEXT:    fmov w8, s0
437 ; CHECK-GI-NEXT:    dup v0.4h, w8
438 ; CHECK-GI-NEXT:    fmov w0, s0
439 ; CHECK-GI-NEXT:    ret
440     %c = shufflevector <2 x i16> %a, <2 x i16> %b, <2 x i32> <i32 0, i32 0>
441     %d = bitcast <2 x i16> %c to i32
442     ret i32 %d
445 define <16 x i16> @shufflevector_v16i16_zeroes(<16 x i16> %a, <16 x i16> %b){
446 ; CHECK-LABEL: shufflevector_v16i16_zeroes:
447 ; CHECK:       // %bb.0:
448 ; CHECK-NEXT:    dup v0.8h, v0.h[0]
449 ; CHECK-NEXT:    mov v1.16b, v0.16b
450 ; CHECK-NEXT:    ret
451     %c = shufflevector <16 x i16> %a, <16 x i16> %b, <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
452     ret <16 x i16> %c
455 define <1 x i32> @shufflevector_v1i32_zeroes(<1 x i32> %a, <1 x i32> %b) {
456 ; CHECK-LABEL: shufflevector_v1i32_zeroes:
457 ; CHECK:       // %bb.0:
458 ; CHECK-NEXT:    ret
459     %c = shufflevector <1 x i32> %a, <1 x i32> %b, <1 x i32> <i32 0>
460     ret <1 x i32> %c
463 define <8 x i32> @shufflevector_v8i32_zeroes(<8 x i32> %a, <8 x i32> %b) {
464 ; CHECK-LABEL: shufflevector_v8i32_zeroes:
465 ; CHECK:       // %bb.0:
466 ; CHECK-NEXT:    dup v0.4s, v0.s[0]
467 ; CHECK-NEXT:    mov v1.16b, v0.16b
468 ; CHECK-NEXT:    ret
469     %c = shufflevector <8 x i32> %a, <8 x i32> %b, <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
470     ret <8 x i32> %c
473 define <4 x i64> @shufflevector_v4i64_zeroes(<4 x i64> %a, <4 x i64> %b) {
474 ; CHECK-LABEL: shufflevector_v4i64_zeroes:
475 ; CHECK:       // %bb.0:
476 ; CHECK-NEXT:    dup v0.2d, v0.d[0]
477 ; CHECK-NEXT:    mov v1.16b, v0.16b
478 ; CHECK-NEXT:    ret
479     %c = shufflevector <4 x i64> %a, <4 x i64> %b, <4 x i32> <i32 0, i32 0, i32 0, i32 0>
480     ret <4 x i64> %c
483 ; ===== Vectors with Non-Pow 2 Widths =====
485 define <3 x i8> @shufflevector_v3i8(<3 x i8> %a, <3 x i8> %b) {
486 ; CHECK-SD-LABEL: shufflevector_v3i8:
487 ; CHECK-SD:       // %bb.0:
488 ; CHECK-SD-NEXT:    mov w0, w1
489 ; CHECK-SD-NEXT:    mov w1, w2
490 ; CHECK-SD-NEXT:    mov w2, w4
491 ; CHECK-SD-NEXT:    ret
493 ; CHECK-GI-LABEL: shufflevector_v3i8:
494 ; CHECK-GI:       // %bb.0:
495 ; CHECK-GI-NEXT:    fmov s0, w0
496 ; CHECK-GI-NEXT:    fmov s1, w1
497 ; CHECK-GI-NEXT:    adrp x8, .LCPI30_0
498 ; CHECK-GI-NEXT:    fmov s2, w3
499 ; CHECK-GI-NEXT:    fmov s3, w4
500 ; CHECK-GI-NEXT:    mov v0.b[1], v1.b[0]
501 ; CHECK-GI-NEXT:    fmov s1, w2
502 ; CHECK-GI-NEXT:    mov v2.b[1], v3.b[0]
503 ; CHECK-GI-NEXT:    fmov s3, w5
504 ; CHECK-GI-NEXT:    mov v0.b[2], v1.b[0]
505 ; CHECK-GI-NEXT:    ldr d1, [x8, :lo12:.LCPI30_0]
506 ; CHECK-GI-NEXT:    mov v2.b[2], v3.b[0]
507 ; CHECK-GI-NEXT:    mov v0.d[1], v2.d[0]
508 ; CHECK-GI-NEXT:    tbl v0.16b, { v0.16b }, v1.16b
509 ; CHECK-GI-NEXT:    mov b1, v0.b[1]
510 ; CHECK-GI-NEXT:    mov b2, v0.b[2]
511 ; CHECK-GI-NEXT:    fmov w0, s0
512 ; CHECK-GI-NEXT:    fmov w1, s1
513 ; CHECK-GI-NEXT:    fmov w2, s2
514 ; CHECK-GI-NEXT:    ret
515     %c = shufflevector <3 x i8> %a, <3 x i8> %b, <3 x i32> <i32 1, i32 2, i32 4>
516     ret <3 x i8> %c
519 define <7 x i8> @shufflevector_v7i8(<7 x i8> %a, <7 x i8> %b) {
520 ; CHECK-SD-LABEL: shufflevector_v7i8:
521 ; CHECK-SD:       // %bb.0:
522 ; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 def $q0
523 ; CHECK-SD-NEXT:    // kill: def $d1 killed $d1 def $q1
524 ; CHECK-SD-NEXT:    adrp x8, .LCPI31_0
525 ; CHECK-SD-NEXT:    mov v0.d[1], v1.d[0]
526 ; CHECK-SD-NEXT:    ldr d1, [x8, :lo12:.LCPI31_0]
527 ; CHECK-SD-NEXT:    tbl v0.8b, { v0.16b }, v1.8b
528 ; CHECK-SD-NEXT:    ret
530 ; CHECK-GI-LABEL: shufflevector_v7i8:
531 ; CHECK-GI:       // %bb.0:
532 ; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 def $q0
533 ; CHECK-GI-NEXT:    // kill: def $d1 killed $d1 def $q1
534 ; CHECK-GI-NEXT:    adrp x8, .LCPI31_0
535 ; CHECK-GI-NEXT:    mov v0.d[1], v1.d[0]
536 ; CHECK-GI-NEXT:    ldr d1, [x8, :lo12:.LCPI31_0]
537 ; CHECK-GI-NEXT:    tbl v0.16b, { v0.16b }, v1.16b
538 ; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0
539 ; CHECK-GI-NEXT:    ret
540     %c = shufflevector <7 x i8> %a, <7 x i8> %b, <7 x i32> <i32 1, i32 3, i32 5, i32 7, i32 8, i32 10, i32 12>
541     ret <7 x i8> %c
544 define <3 x i16> @shufflevector_v3i16(<3 x i16> %a, <3 x i16> %b) {
545 ; CHECK-SD-LABEL: shufflevector_v3i16:
546 ; CHECK-SD:       // %bb.0:
547 ; CHECK-SD-NEXT:    zip1 v1.4h, v0.4h, v1.4h
548 ; CHECK-SD-NEXT:    zip2 v0.4h, v1.4h, v0.4h
549 ; CHECK-SD-NEXT:    ret
551 ; CHECK-GI-LABEL: shufflevector_v3i16:
552 ; CHECK-GI:       // %bb.0:
553 ; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 def $q0
554 ; CHECK-GI-NEXT:    // kill: def $d1 killed $d1 def $q1
555 ; CHECK-GI-NEXT:    adrp x8, .LCPI32_0
556 ; CHECK-GI-NEXT:    mov v0.d[1], v1.d[0]
557 ; CHECK-GI-NEXT:    ldr d1, [x8, :lo12:.LCPI32_0]
558 ; CHECK-GI-NEXT:    tbl v0.16b, { v0.16b }, v1.16b
559 ; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0
560 ; CHECK-GI-NEXT:    ret
561     %c = shufflevector <3 x i16> %a, <3 x i16> %b, <3 x i32> <i32 1, i32 2, i32 4>
562     ret <3 x i16> %c
565 define <7 x i16> @shufflevector_v7i16(<7 x i16> %a, <7 x i16> %b) {
566 ; CHECK-SD-LABEL: shufflevector_v7i16:
567 ; CHECK-SD:       // %bb.0:
568 ; CHECK-SD-NEXT:    adrp x8, .LCPI33_0
569 ; CHECK-SD-NEXT:    // kill: def $q1 killed $q1 killed $q0_q1 def $q0_q1
570 ; CHECK-SD-NEXT:    ldr q2, [x8, :lo12:.LCPI33_0]
571 ; CHECK-SD-NEXT:    // kill: def $q0 killed $q0 killed $q0_q1 def $q0_q1
572 ; CHECK-SD-NEXT:    tbl v0.16b, { v0.16b, v1.16b }, v2.16b
573 ; CHECK-SD-NEXT:    ret
575 ; CHECK-GI-LABEL: shufflevector_v7i16:
576 ; CHECK-GI:       // %bb.0:
577 ; CHECK-GI-NEXT:    adrp x8, .LCPI33_0
578 ; CHECK-GI-NEXT:    // kill: def $q0 killed $q0 killed $q0_q1 def $q0_q1
579 ; CHECK-GI-NEXT:    ldr q2, [x8, :lo12:.LCPI33_0]
580 ; CHECK-GI-NEXT:    // kill: def $q1 killed $q1 killed $q0_q1 def $q0_q1
581 ; CHECK-GI-NEXT:    tbl v0.16b, { v0.16b, v1.16b }, v2.16b
582 ; CHECK-GI-NEXT:    ret
583     %c = shufflevector <7 x i16> %a, <7 x i16> %b, <7 x i32> <i32 1, i32 3, i32 5, i32 7, i32 8, i32 10, i32 12>
584     ret <7 x i16> %c
587 define <3 x i32> @shufflevector_v3i32(<3 x i32> %a, <3 x i32> %b) {
588 ; CHECK-SD-LABEL: shufflevector_v3i32:
589 ; CHECK-SD:       // %bb.0:
590 ; CHECK-SD-NEXT:    zip1 v1.4s, v0.4s, v1.4s
591 ; CHECK-SD-NEXT:    zip2 v0.4s, v1.4s, v0.4s
592 ; CHECK-SD-NEXT:    ret
594 ; CHECK-GI-LABEL: shufflevector_v3i32:
595 ; CHECK-GI:       // %bb.0:
596 ; CHECK-GI-NEXT:    adrp x8, .LCPI34_0
597 ; CHECK-GI-NEXT:    // kill: def $q0 killed $q0 killed $q0_q1 def $q0_q1
598 ; CHECK-GI-NEXT:    ldr q2, [x8, :lo12:.LCPI34_0]
599 ; CHECK-GI-NEXT:    // kill: def $q1 killed $q1 killed $q0_q1 def $q0_q1
600 ; CHECK-GI-NEXT:    tbl v0.16b, { v0.16b, v1.16b }, v2.16b
601 ; CHECK-GI-NEXT:    ret
602     %c = shufflevector <3 x i32> %a, <3 x i32> %b, <3 x i32> <i32 1, i32 2, i32 4>
603     ret <3 x i32> %c
606 ; ===== Vectors with Non-Pow 2 Widths with Zero Masks =====
608 define <3 x i8> @shufflevector_v3i8_zeroes(<3 x i8> %a, <3 x i8> %b) {
609 ; CHECK-SD-LABEL: shufflevector_v3i8_zeroes:
610 ; CHECK-SD:       // %bb.0:
611 ; CHECK-SD-NEXT:    mov w1, w0
612 ; CHECK-SD-NEXT:    mov w2, w0
613 ; CHECK-SD-NEXT:    ret
615 ; CHECK-GI-LABEL: shufflevector_v3i8_zeroes:
616 ; CHECK-GI:       // %bb.0:
617 ; CHECK-GI-NEXT:    dup v0.8b, w0
618 ; CHECK-GI-NEXT:    mov b1, v0.b[1]
619 ; CHECK-GI-NEXT:    mov b2, v0.b[2]
620 ; CHECK-GI-NEXT:    fmov w0, s0
621 ; CHECK-GI-NEXT:    fmov w1, s1
622 ; CHECK-GI-NEXT:    fmov w2, s2
623 ; CHECK-GI-NEXT:    ret
624     %c = shufflevector <3 x i8> %a, <3 x i8> %b, <3 x i32> <i32 0, i32 0, i32 0>
625     ret <3 x i8> %c
628 define <7 x i8> @shufflevector_v7i8_zeroes(<7 x i8> %a, <7 x i8> %b) {
629 ; CHECK-LABEL: shufflevector_v7i8_zeroes:
630 ; CHECK:       // %bb.0:
631 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
632 ; CHECK-NEXT:    dup v0.8b, v0.b[0]
633 ; CHECK-NEXT:    ret
634     %c = shufflevector <7 x i8> %a, <7 x i8> %b, <7 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
635     ret <7 x i8> %c
638 define <3 x i16> @shufflevector_v3i16_zeroes(<3 x i16> %a, <3 x i16> %b) {
639 ; CHECK-LABEL: shufflevector_v3i16_zeroes:
640 ; CHECK:       // %bb.0:
641 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
642 ; CHECK-NEXT:    dup v0.4h, v0.h[0]
643 ; CHECK-NEXT:    ret
644     %c = shufflevector <3 x i16> %a, <3 x i16> %b, <3 x i32> <i32 0, i32 0, i32 0>
645     ret <3 x i16> %c
648 define <7 x i16> @shufflevector_v7i16_zeroes(<7 x i16> %a, <7 x i16> %b) {
649 ; CHECK-LABEL: shufflevector_v7i16_zeroes:
650 ; CHECK:       // %bb.0:
651 ; CHECK-NEXT:    dup v0.8h, v0.h[0]
652 ; CHECK-NEXT:    ret
653     %c = shufflevector <7 x i16> %a, <7 x i16> %b, <7 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
654     ret <7 x i16> %c
657 define <3 x i32> @shufflevector_v3i32_zeroes(<3 x i32> %a, <3 x i32> %b) {
658 ; CHECK-LABEL: shufflevector_v3i32_zeroes:
659 ; CHECK:       // %bb.0:
660 ; CHECK-NEXT:    dup v0.4s, v0.s[0]
661 ; CHECK-NEXT:    ret
662     %c = shufflevector <3 x i32> %a, <3 x i32> %b, <3 x i32> <i32 0, i32 0, i32 0>
663     ret <3 x i32> %c