1 ; RUN: llc < %s -mtriple=arm64-eabi -aarch64-neon-syntax=apple | FileCheck %s
3 ; This is the IR generated by Clang's __builtin_shufflevector for two 16x uint8_t vectors.
4 define <16 x i8> @shuffle16_with_and_mask(<16 x i8> %src, <16 x i8> %mask) {
5 ; CHECK-LABEL: shuffle16_with_and_mask:
7 ; CHECK-NEXT: movi.16b v2, #15
8 ; CHECK-NEXT: and.16b v1, v1, v2
9 ; CHECK-NEXT: tbl.16b v0, { v0 }, v1
12 %masked_mask = and <16 x i8> %mask, <i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15>
13 %1 = extractelement <16 x i8> %masked_mask, i64 0
14 %2 = extractelement <16 x i8> %src, i8 %1
15 %3 = insertelement <16 x i8> undef, i8 %2, i64 0
16 %4 = extractelement <16 x i8> %masked_mask, i64 1
17 %5 = extractelement <16 x i8> %src, i8 %4
18 %6 = insertelement <16 x i8> %3, i8 %5, i64 1
19 %7 = extractelement <16 x i8> %masked_mask, i64 2
20 %8 = extractelement <16 x i8> %src, i8 %7
21 %9 = insertelement <16 x i8> %6, i8 %8, i64 2
22 %10 = extractelement <16 x i8> %masked_mask, i64 3
23 %11 = extractelement <16 x i8> %src, i8 %10
24 %12 = insertelement <16 x i8> %9, i8 %11, i64 3
25 %13 = extractelement <16 x i8> %masked_mask, i64 4
26 %14 = extractelement <16 x i8> %src, i8 %13
27 %15 = insertelement <16 x i8> %12, i8 %14, i64 4
28 %16 = extractelement <16 x i8> %masked_mask, i64 5
29 %17 = extractelement <16 x i8> %src, i8 %16
30 %18 = insertelement <16 x i8> %15, i8 %17, i64 5
31 %19 = extractelement <16 x i8> %masked_mask, i64 6
32 %20 = extractelement <16 x i8> %src, i8 %19
33 %21 = insertelement <16 x i8> %18, i8 %20, i64 6
34 %22 = extractelement <16 x i8> %masked_mask, i64 7
35 %23 = extractelement <16 x i8> %src, i8 %22
36 %24 = insertelement <16 x i8> %21, i8 %23, i64 7
37 %25 = extractelement <16 x i8> %masked_mask, i64 8
38 %26 = extractelement <16 x i8> %src, i8 %25
39 %27 = insertelement <16 x i8> %24, i8 %26, i64 8
40 %28 = extractelement <16 x i8> %masked_mask, i64 9
41 %29 = extractelement <16 x i8> %src, i8 %28
42 %30 = insertelement <16 x i8> %27, i8 %29, i64 9
43 %31 = extractelement <16 x i8> %masked_mask, i64 10
44 %32 = extractelement <16 x i8> %src, i8 %31
45 %33 = insertelement <16 x i8> %30, i8 %32, i64 10
46 %34 = extractelement <16 x i8> %masked_mask, i64 11
47 %35 = extractelement <16 x i8> %src, i8 %34
48 %36 = insertelement <16 x i8> %33, i8 %35, i64 11
49 %37 = extractelement <16 x i8> %masked_mask, i64 12
50 %38 = extractelement <16 x i8> %src, i8 %37
51 %39 = insertelement <16 x i8> %36, i8 %38, i64 12
52 %40 = extractelement <16 x i8> %masked_mask, i64 13
53 %41 = extractelement <16 x i8> %src, i8 %40
54 %42 = insertelement <16 x i8> %39, i8 %41, i64 13
55 %43 = extractelement <16 x i8> %masked_mask, i64 14
56 %44 = extractelement <16 x i8> %src, i8 %43
57 %45 = insertelement <16 x i8> %42, i8 %44, i64 14
58 %46 = extractelement <16 x i8> %masked_mask, i64 15
59 ; Make sure that ANY_EXTEND is ignored
60 %47 = zext i8 %46 to i32
61 %48 = extractelement <16 x i8> %src, i32 %47
62 %49 = insertelement <16 x i8> %45, i8 %48, i64 15
66 define <8 x i8> @shuffle8_with_and_mask(<8 x i8> %src, <8 x i8> %mask) {
67 ; CHECK-LABEL: shuffle8_with_and_mask:
69 ; CHECK-NEXT: movi.8b v2, #7
70 ; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
71 ; CHECK-NEXT: and.8b v1, v1, v2
72 ; CHECK-NEXT: tbl.8b v0, { v0 }, v1
75 %masked_mask = and <8 x i8> %mask, <i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7>
76 %1 = extractelement <8 x i8> %masked_mask, i64 0
77 %2 = extractelement <8 x i8> %src, i8 %1
78 %3 = insertelement <8 x i8> undef, i8 %2, i64 0
79 %4 = extractelement <8 x i8> %masked_mask, i64 1
80 %5 = extractelement <8 x i8> %src, i8 %4
81 %6 = insertelement <8 x i8> %3, i8 %5, i64 1
82 %7 = extractelement <8 x i8> %masked_mask, i64 2
83 %8 = extractelement <8 x i8> %src, i8 %7
84 %9 = insertelement <8 x i8> %6, i8 %8, i64 2
85 %10 = extractelement <8 x i8> %masked_mask, i64 3
86 %11 = extractelement <8 x i8> %src, i8 %10
87 %12 = insertelement <8 x i8> %9, i8 %11, i64 3
88 %13 = extractelement <8 x i8> %masked_mask, i64 4
89 %14 = extractelement <8 x i8> %src, i8 %13
90 %15 = insertelement <8 x i8> %12, i8 %14, i64 4
91 %16 = extractelement <8 x i8> %masked_mask, i64 5
92 %17 = extractelement <8 x i8> %src, i8 %16
93 %18 = insertelement <8 x i8> %15, i8 %17, i64 5
94 %19 = extractelement <8 x i8> %masked_mask, i64 6
95 %20 = extractelement <8 x i8> %src, i8 %19
96 %21 = insertelement <8 x i8> %18, i8 %20, i64 6
97 %22 = extractelement <8 x i8> %masked_mask, i64 7
98 %23 = extractelement <8 x i8> %src, i8 %22
99 %24 = insertelement <8 x i8> %21, i8 %23, i64 7
103 define <8 x i8> @shuffle8_with_and_mask_different_constants(<8 x i8> %src, <8 x i8> %mask) {
104 ; CHECK-LABEL: LCPI2_0:
105 ; CHECK-NEXT: .byte 3
106 ; CHECK-NEXT: .byte 1
107 ; CHECK-NEXT: .byte 7
108 ; CHECK-NEXT: .byte 1
109 ; CHECK-NEXT: .byte 7
110 ; CHECK-NEXT: .byte 3
111 ; CHECK-NEXT: .byte 7
112 ; CHECK-NEXT: .byte 7
114 ; CHECK-LABEL: shuffle8_with_and_mask_different_constants:
116 ; CHECK-NEXT: adrp x8, .LCPI2_0
117 ; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
118 ; CHECK-NEXT: ldr d2, [x8, :lo12:.LCPI2_0]
119 ; CHECK-NEXT: and.8b v1, v1, v2
120 ; CHECK-NEXT: tbl.8b v0, { v0 }, v1
123 %masked_mask = and <8 x i8> %mask, <i8 3, i8 1, i8 7, i8 1, i8 7, i8 3, i8 7, i8 7>
124 %1 = extractelement <8 x i8> %masked_mask, i64 0
125 %2 = extractelement <8 x i8> %src, i8 %1
126 %3 = insertelement <8 x i8> undef, i8 %2, i64 0
127 %4 = extractelement <8 x i8> %masked_mask, i64 1
128 %5 = extractelement <8 x i8> %src, i8 %4
129 %6 = insertelement <8 x i8> %3, i8 %5, i64 1
130 %7 = extractelement <8 x i8> %masked_mask, i64 2
131 %8 = extractelement <8 x i8> %src, i8 %7
132 %9 = insertelement <8 x i8> %6, i8 %8, i64 2
133 %10 = extractelement <8 x i8> %masked_mask, i64 3
134 %11 = extractelement <8 x i8> %src, i8 %10
135 %12 = insertelement <8 x i8> %9, i8 %11, i64 3
136 %13 = extractelement <8 x i8> %masked_mask, i64 4
137 %14 = extractelement <8 x i8> %src, i8 %13
138 %15 = insertelement <8 x i8> %12, i8 %14, i64 4
139 %16 = extractelement <8 x i8> %masked_mask, i64 5
140 %17 = extractelement <8 x i8> %src, i8 %16
141 %18 = insertelement <8 x i8> %15, i8 %17, i64 5
142 %19 = extractelement <8 x i8> %masked_mask, i64 6
143 %20 = extractelement <8 x i8> %src, i8 %19
144 %21 = insertelement <8 x i8> %18, i8 %20, i64 6
145 %22 = extractelement <8 x i8> %masked_mask, i64 7
146 %23 = extractelement <8 x i8> %src, i8 %22
147 %24 = insertelement <8 x i8> %21, i8 %23, i64 7
151 define <8 x i8> @shuffle8_with_mask(<8 x i8> %src, <8 x i8> %mask) {
152 ; CHECK-LABEL: shuffle8_with_mask:
154 ; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
155 ; CHECK-NEXT: tbl.8b v0, { v0 }, v1
158 %1 = extractelement <8 x i8> %mask, i64 0
159 %2 = extractelement <8 x i8> %src, i8 %1
160 %3 = insertelement <8 x i8> undef, i8 %2, i64 0
161 %4 = extractelement <8 x i8> %mask, i64 1
162 %5 = extractelement <8 x i8> %src, i8 %4
163 %6 = insertelement <8 x i8> %3, i8 %5, i64 1
164 %7 = extractelement <8 x i8> %mask, i64 2
165 %8 = extractelement <8 x i8> %src, i8 %7
166 %9 = insertelement <8 x i8> %6, i8 %8, i64 2
167 %10 = extractelement <8 x i8> %mask, i64 3
168 %11 = extractelement <8 x i8> %src, i8 %10
169 %12 = insertelement <8 x i8> %9, i8 %11, i64 3
170 %13 = extractelement <8 x i8> %mask, i64 4
171 %14 = extractelement <8 x i8> %src, i8 %13
172 %15 = insertelement <8 x i8> %12, i8 %14, i64 4
173 %16 = extractelement <8 x i8> %mask, i64 5
174 %17 = extractelement <8 x i8> %src, i8 %16
175 %18 = insertelement <8 x i8> %15, i8 %17, i64 5
176 %19 = extractelement <8 x i8> %mask, i64 6
177 %20 = extractelement <8 x i8> %src, i8 %19
178 %21 = insertelement <8 x i8> %18, i8 %20, i64 6
179 %22 = extractelement <8 x i8> %mask, i64 7
180 %23 = extractelement <8 x i8> %src, i8 %22
181 %24 = insertelement <8 x i8> %21, i8 %23, i64 7
185 define <8 x i8> @no_shuffle_only_some_and_constants(<8 x i8> %src, <8 x i8> %mask) {
186 ; CHECK-LABEL: no_shuffle_only_some_and_constants:
190 ; Element at 0 has a AND mask, element at 1 does not.
191 %1 = extractelement <8 x i8> %mask, i64 0
192 %masked_elt1 = and i8 %1, 7
193 %2 = extractelement <8 x i8> %src, i8 %masked_elt1
194 %3 = insertelement <8 x i8> undef, i8 %2, i64 0
195 %4 = extractelement <8 x i8> %mask, i64 1
196 %5 = extractelement <8 x i8> %src, i8 %4
197 %6 = insertelement <8 x i8> %3, i8 %5, i64 1
199 %7 = extractelement <8 x i8> %mask, i64 2
200 %8 = extractelement <8 x i8> %src, i8 %7
201 %9 = insertelement <8 x i8> %6, i8 %8, i64 2
202 %10 = extractelement <8 x i8> %mask, i64 3
203 %11 = extractelement <8 x i8> %src, i8 %10
204 %12 = insertelement <8 x i8> %9, i8 %11, i64 3
205 %13 = extractelement <8 x i8> %mask, i64 4
206 %14 = extractelement <8 x i8> %src, i8 %13
207 %15 = insertelement <8 x i8> %12, i8 %14, i64 4
208 %16 = extractelement <8 x i8> %mask, i64 5
209 %17 = extractelement <8 x i8> %src, i8 %16
210 %18 = insertelement <8 x i8> %15, i8 %17, i64 5
211 %19 = extractelement <8 x i8> %mask, i64 6
212 %20 = extractelement <8 x i8> %src, i8 %19
213 %21 = insertelement <8 x i8> %18, i8 %20, i64 6
214 %22 = extractelement <8 x i8> %mask, i64 7
215 %23 = extractelement <8 x i8> %src, i8 %22
216 %24 = insertelement <8 x i8> %21, i8 %23, i64 7
220 ; Takes alternating entries from two mask source vectors. Currently not supported.
221 define <16 x i8> @no_shuffle_with_two_mask_sources(<16 x i8> %src, <16 x i8> %mask1, <16 x i8> %mask2) {
222 ; CHECK-LABEL: shuffle_with_two_mask_sources:
226 %masked_mask1 = and <16 x i8> %mask1, <i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15>
227 %masked_mask2 = and <16 x i8> %mask2, <i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15>
228 %1 = extractelement <16 x i8> %masked_mask1, i64 0
229 %2 = extractelement <16 x i8> %src, i8 %1
230 %3 = insertelement <16 x i8> undef, i8 %2, i64 0
231 %4 = extractelement <16 x i8> %masked_mask2, i64 1
232 %5 = extractelement <16 x i8> %src, i8 %4
233 %6 = insertelement <16 x i8> %3, i8 %5, i64 1
234 %7 = extractelement <16 x i8> %masked_mask1, i64 2
235 %8 = extractelement <16 x i8> %src, i8 %7
236 %9 = insertelement <16 x i8> %6, i8 %8, i64 2
237 %10 = extractelement <16 x i8> %masked_mask2, i64 3
238 %11 = extractelement <16 x i8> %src, i8 %10
239 %12 = insertelement <16 x i8> %9, i8 %11, i64 3
240 %13 = extractelement <16 x i8> %masked_mask1, i64 4
241 %14 = extractelement <16 x i8> %src, i8 %13
242 %15 = insertelement <16 x i8> %12, i8 %14, i64 4
243 %16 = extractelement <16 x i8> %masked_mask2, i64 5
244 %17 = extractelement <16 x i8> %src, i8 %16
245 %18 = insertelement <16 x i8> %15, i8 %17, i64 5
246 %19 = extractelement <16 x i8> %masked_mask1, i64 6
247 %20 = extractelement <16 x i8> %src, i8 %19
248 %21 = insertelement <16 x i8> %18, i8 %20, i64 6
249 %22 = extractelement <16 x i8> %masked_mask2, i64 7
250 %23 = extractelement <16 x i8> %src, i8 %22
251 %24 = insertelement <16 x i8> %21, i8 %23, i64 7
252 %25 = extractelement <16 x i8> %masked_mask1, i64 8
253 %26 = extractelement <16 x i8> %src, i8 %25
254 %27 = insertelement <16 x i8> %24, i8 %26, i64 8
255 %28 = extractelement <16 x i8> %masked_mask2, i64 9
256 %29 = extractelement <16 x i8> %src, i8 %28
257 %30 = insertelement <16 x i8> %27, i8 %29, i64 9
258 %31 = extractelement <16 x i8> %masked_mask1, i64 10
259 %32 = extractelement <16 x i8> %src, i8 %31
260 %33 = insertelement <16 x i8> %30, i8 %32, i64 10
261 %34 = extractelement <16 x i8> %masked_mask2, i64 11
262 %35 = extractelement <16 x i8> %src, i8 %34
263 %36 = insertelement <16 x i8> %33, i8 %35, i64 11
264 %37 = extractelement <16 x i8> %masked_mask1, i64 12
265 %38 = extractelement <16 x i8> %src, i8 %37
266 %39 = insertelement <16 x i8> %36, i8 %38, i64 12
267 %40 = extractelement <16 x i8> %masked_mask2, i64 13
268 %41 = extractelement <16 x i8> %src, i8 %40
269 %42 = insertelement <16 x i8> %39, i8 %41, i64 13
270 %43 = extractelement <16 x i8> %masked_mask1, i64 14
271 %44 = extractelement <16 x i8> %src, i8 %43
272 %45 = insertelement <16 x i8> %42, i8 %44, i64 14
273 %46 = extractelement <16 x i8> %masked_mask2, i64 15
274 %47 = extractelement <16 x i8> %src, i8 %46
275 %48 = insertelement <16 x i8> %45, i8 %47, i64 15
279 ; Non-supported vector type.
280 define <4 x i32> @no_for_shuffle_int_vector(<4 x i32> %src, <4 x i32> %mask) {
281 ; CHECK-LABEL: no_for_shuffle_int_vector:
285 %masked_mask = and <4 x i32> %mask, <i32 3, i32 3, i32 3, i32 3>
286 %1 = extractelement <4 x i32> %masked_mask, i64 0
287 %2 = extractelement <4 x i32> %src, i32 %1
288 %3 = insertelement <4 x i32> undef, i32 %2, i64 0
289 %4 = extractelement <4 x i32> %masked_mask, i64 1
290 %5 = extractelement <4 x i32> %src, i32 %4
291 %6 = insertelement <4 x i32> %3, i32 %5, i64 1
292 %7 = extractelement <4 x i32> %masked_mask, i64 2
293 %8 = extractelement <4 x i32> %src, i32 %7
294 %9 = insertelement <4 x i32> %6, i32 %8, i64 2
295 %10 = extractelement <4 x i32> %masked_mask, i64 3
296 %11 = extractelement <4 x i32> %src, i32 %10
297 %12 = insertelement <4 x i32> %9, i32 %11, i64 3
301 define <8 x i8> @no_shuffle_not_enough_elements(<8 x i8> %src, <8 x i8> %mask) {
302 ; CHECK-LABEL: no_shuffle_not_enough_elements:
306 %masked_mask = and <8 x i8> %mask, <i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7>
307 %1 = extractelement <8 x i8> %masked_mask, i64 0
308 %2 = extractelement <8 x i8> %src, i8 %1
309 %3 = insertelement <8 x i8> undef, i8 %2, i64 0
310 %4 = extractelement <8 x i8> %masked_mask, i64 1
311 %5 = extractelement <8 x i8> %src, i8 %4
312 %6 = insertelement <8 x i8> %3, i8 %5, i64 1
313 %7 = extractelement <8 x i8> %masked_mask, i64 2
314 %8 = extractelement <8 x i8> %src, i8 %7
315 %9 = insertelement <8 x i8> %6, i8 %8, i64 2
316 %10 = extractelement <8 x i8> %masked_mask, i64 3
317 %11 = extractelement <8 x i8> %src, i8 %10
318 %12 = insertelement <8 x i8> %9, i8 %11, i64 3
322 define <8 x i8> @no_shuffle_different_vector_types(<8 x i8> %src, <16 x i8> %mask) {
323 ; CHECK-LABEL: no_shuffle_different_vector_types:
327 %masked_mask = and <16 x i8> %mask, <i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7>
328 %1 = extractelement <16 x i8> %masked_mask, i64 0
329 %2 = extractelement <8 x i8> %src, i8 %1
330 %3 = insertelement <8 x i8> undef, i8 %2, i64 0
331 %4 = extractelement <16 x i8> %masked_mask, i64 1
332 %5 = extractelement <8 x i8> %src, i8 %4
333 %6 = insertelement <8 x i8> %3, i8 %5, i64 1
334 %7 = extractelement <16 x i8> %masked_mask, i64 2
335 %8 = extractelement <8 x i8> %src, i8 %7
336 %9 = insertelement <8 x i8> %6, i8 %8, i64 2
337 %10 = extractelement <16 x i8> %masked_mask, i64 3
338 %11 = extractelement <8 x i8> %src, i8 %10
339 %12 = insertelement <8 x i8> %9, i8 %11, i64 3
340 %13 = extractelement <16 x i8> %masked_mask, i64 4
341 %14 = extractelement <8 x i8> %src, i8 %13
342 %15 = insertelement <8 x i8> %12, i8 %14, i64 4
343 %16 = extractelement <16 x i8> %masked_mask, i64 5
344 %17 = extractelement <8 x i8> %src, i8 %16
345 %18 = insertelement <8 x i8> %15, i8 %17, i64 5
346 %19 = extractelement <16 x i8> %masked_mask, i64 6
347 %20 = extractelement <8 x i8> %src, i8 %19
348 %21 = insertelement <8 x i8> %18, i8 %20, i64 6
349 %22 = extractelement <16 x i8> %masked_mask, i64 7
350 %23 = extractelement <8 x i8> %src, i8 %22
351 %24 = insertelement <8 x i8> %21, i8 %23, i64 7
355 define <8 x i8> @no_shuffle_bad_mask_index(<8 x i8> %src, <8 x i8> %mask) {
356 ; CHECK-LABEL: no_shuffle_bad_mask_index:
360 %masked_mask = and <8 x i8> %mask, <i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7>
362 ; This should extract at 0, but because it extracts at 1, the pattern does not match.
363 %1 = extractelement <8 x i8> %masked_mask, i64 1
365 %2 = extractelement <8 x i8> %src, i8 %1
366 %3 = insertelement <8 x i8> undef, i8 %2, i64 0
367 %4 = extractelement <8 x i8> %masked_mask, i64 1
368 %5 = extractelement <8 x i8> %src, i8 %4
369 %6 = insertelement <8 x i8> %3, i8 %5, i64 1
370 %7 = extractelement <8 x i8> %masked_mask, i64 2
371 %8 = extractelement <8 x i8> %src, i8 %7
372 %9 = insertelement <8 x i8> %6, i8 %8, i64 2
373 %10 = extractelement <8 x i8> %masked_mask, i64 3
374 %11 = extractelement <8 x i8> %src, i8 %10
375 %12 = insertelement <8 x i8> %9, i8 %11, i64 3
376 %13 = extractelement <8 x i8> %masked_mask, i64 4
377 %14 = extractelement <8 x i8> %src, i8 %13
378 %15 = insertelement <8 x i8> %12, i8 %14, i64 4
379 %16 = extractelement <8 x i8> %masked_mask, i64 5
380 %17 = extractelement <8 x i8> %src, i8 %16
381 %18 = insertelement <8 x i8> %15, i8 %17, i64 5
382 %19 = extractelement <8 x i8> %masked_mask, i64 6
383 %20 = extractelement <8 x i8> %src, i8 %19
384 %21 = insertelement <8 x i8> %18, i8 %20, i64 6
385 %22 = extractelement <8 x i8> %masked_mask, i64 7
386 %23 = extractelement <8 x i8> %src, i8 %22
387 %24 = insertelement <8 x i8> %21, i8 %23, i64 7