1 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 | FileCheck %s --check-prefix=ALL --check-prefix=SSE --check-prefix=SSE2
2 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+sse4.1 | FileCheck %s --check-prefix=ALL --check-prefix=SSE --check-prefix=SSE41
3 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+avx | FileCheck %s --check-prefix=ALL --check-prefix=AVX --check-prefix=AVX1
4 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+avx2 | FileCheck %s --check-prefix=ALL --check-prefix=AVX --check-prefix=AVX2
10 define <2 x i64> @var_shift_v2i64(<2 x i64> %a, <2 x i64> %b) {
11 ; SSE2-LABEL: var_shift_v2i64:
13 ; SSE2-NEXT: pshufd {{.*#+}} xmm3 = xmm1[2,3,0,1]
14 ; SSE2-NEXT: movdqa %xmm0, %xmm2
15 ; SSE2-NEXT: psrlq %xmm3, %xmm2
16 ; SSE2-NEXT: psrlq %xmm1, %xmm0
17 ; SSE2-NEXT: movsd {{.*#+}} xmm2 = xmm0[0],xmm2[1]
18 ; SSE2-NEXT: movapd %xmm2, %xmm0
21 ; SSE41-LABEL: var_shift_v2i64:
23 ; SSE41-NEXT: movdqa %xmm0, %xmm2
24 ; SSE41-NEXT: psrlq %xmm1, %xmm2
25 ; SSE41-NEXT: pshufd {{.*#+}} xmm1 = xmm1[2,3,0,1]
26 ; SSE41-NEXT: psrlq %xmm1, %xmm0
27 ; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm2[0,1,2,3],xmm0[4,5,6,7]
30 ; AVX1-LABEL: var_shift_v2i64:
32 ; AVX1-NEXT: vpsrlq %xmm1, %xmm0, %xmm2
33 ; AVX1-NEXT: vpshufd {{.*#+}} xmm1 = xmm1[2,3,0,1]
34 ; AVX1-NEXT: vpsrlq %xmm1, %xmm0, %xmm0
35 ; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm2[0,1,2,3],xmm0[4,5,6,7]
38 ; AVX2-LABEL: var_shift_v2i64:
40 ; AVX2-NEXT: vpsrlvq %xmm1, %xmm0, %xmm0
42 %shift = lshr <2 x i64> %a, %b
46 define <4 x i32> @var_shift_v4i32(<4 x i32> %a, <4 x i32> %b) {
47 ; SSE2-LABEL: var_shift_v4i32:
49 ; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm0[3,1,2,3]
50 ; SSE2-NEXT: movd %xmm2, %eax
51 ; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm1[3,1,2,3]
52 ; SSE2-NEXT: movd %xmm2, %ecx
53 ; SSE2-NEXT: shrl %cl, %eax
54 ; SSE2-NEXT: movd %eax, %xmm2
55 ; SSE2-NEXT: pshufd {{.*#+}} xmm3 = xmm0[1,1,2,3]
56 ; SSE2-NEXT: movd %xmm3, %eax
57 ; SSE2-NEXT: pshufd {{.*#+}} xmm3 = xmm1[1,1,2,3]
58 ; SSE2-NEXT: movd %xmm3, %ecx
59 ; SSE2-NEXT: shrl %cl, %eax
60 ; SSE2-NEXT: movd %eax, %xmm3
61 ; SSE2-NEXT: punpckldq {{.*#+}} xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1]
62 ; SSE2-NEXT: movd %xmm0, %eax
63 ; SSE2-NEXT: movd %xmm1, %ecx
64 ; SSE2-NEXT: shrl %cl, %eax
65 ; SSE2-NEXT: movd %eax, %xmm2
66 ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
67 ; SSE2-NEXT: movd %xmm0, %eax
68 ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,0,1]
69 ; SSE2-NEXT: movd %xmm0, %ecx
70 ; SSE2-NEXT: shrl %cl, %eax
71 ; SSE2-NEXT: movd %eax, %xmm0
72 ; SSE2-NEXT: punpckldq {{.*#+}} xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1]
73 ; SSE2-NEXT: punpckldq {{.*#+}} xmm2 = xmm2[0],xmm3[0],xmm2[1],xmm3[1]
74 ; SSE2-NEXT: movdqa %xmm2, %xmm0
77 ; SSE41-LABEL: var_shift_v4i32:
79 ; SSE41-NEXT: pextrd $1, %xmm0, %eax
80 ; SSE41-NEXT: pextrd $1, %xmm1, %ecx
81 ; SSE41-NEXT: shrl %cl, %eax
82 ; SSE41-NEXT: movd %xmm0, %edx
83 ; SSE41-NEXT: movd %xmm1, %ecx
84 ; SSE41-NEXT: shrl %cl, %edx
85 ; SSE41-NEXT: movd %edx, %xmm2
86 ; SSE41-NEXT: pinsrd $1, %eax, %xmm2
87 ; SSE41-NEXT: pextrd $2, %xmm0, %eax
88 ; SSE41-NEXT: pextrd $2, %xmm1, %ecx
89 ; SSE41-NEXT: shrl %cl, %eax
90 ; SSE41-NEXT: pinsrd $2, %eax, %xmm2
91 ; SSE41-NEXT: pextrd $3, %xmm0, %eax
92 ; SSE41-NEXT: pextrd $3, %xmm1, %ecx
93 ; SSE41-NEXT: shrl %cl, %eax
94 ; SSE41-NEXT: pinsrd $3, %eax, %xmm2
95 ; SSE41-NEXT: movdqa %xmm2, %xmm0
98 ; AVX1-LABEL: var_shift_v4i32:
100 ; AVX1-NEXT: vpextrd $1, %xmm0, %eax
101 ; AVX1-NEXT: vpextrd $1, %xmm1, %ecx
102 ; AVX1-NEXT: shrl %cl, %eax
103 ; AVX1-NEXT: vmovd %xmm0, %edx
104 ; AVX1-NEXT: vmovd %xmm1, %ecx
105 ; AVX1-NEXT: shrl %cl, %edx
106 ; AVX1-NEXT: vmovd %edx, %xmm2
107 ; AVX1-NEXT: vpinsrd $1, %eax, %xmm2, %xmm2
108 ; AVX1-NEXT: vpextrd $2, %xmm0, %eax
109 ; AVX1-NEXT: vpextrd $2, %xmm1, %ecx
110 ; AVX1-NEXT: shrl %cl, %eax
111 ; AVX1-NEXT: vpinsrd $2, %eax, %xmm2, %xmm2
112 ; AVX1-NEXT: vpextrd $3, %xmm0, %eax
113 ; AVX1-NEXT: vpextrd $3, %xmm1, %ecx
114 ; AVX1-NEXT: shrl %cl, %eax
115 ; AVX1-NEXT: vpinsrd $3, %eax, %xmm2, %xmm0
118 ; AVX2-LABEL: var_shift_v4i32:
120 ; AVX2-NEXT: vpsrlvd %xmm1, %xmm0, %xmm0
122 %shift = lshr <4 x i32> %a, %b
126 define <8 x i16> @var_shift_v8i16(<8 x i16> %a, <8 x i16> %b) {
127 ; SSE2-LABEL: var_shift_v8i16:
129 ; SSE2-NEXT: psllw $12, %xmm1
130 ; SSE2-NEXT: movdqa %xmm1, %xmm2
131 ; SSE2-NEXT: psraw $15, %xmm2
132 ; SSE2-NEXT: movdqa %xmm2, %xmm3
133 ; SSE2-NEXT: pandn %xmm0, %xmm3
134 ; SSE2-NEXT: psrlw $8, %xmm0
135 ; SSE2-NEXT: pand %xmm2, %xmm0
136 ; SSE2-NEXT: por %xmm3, %xmm0
137 ; SSE2-NEXT: paddw %xmm1, %xmm1
138 ; SSE2-NEXT: movdqa %xmm1, %xmm2
139 ; SSE2-NEXT: psraw $15, %xmm2
140 ; SSE2-NEXT: movdqa %xmm2, %xmm3
141 ; SSE2-NEXT: pandn %xmm0, %xmm3
142 ; SSE2-NEXT: psrlw $4, %xmm0
143 ; SSE2-NEXT: pand %xmm2, %xmm0
144 ; SSE2-NEXT: por %xmm3, %xmm0
145 ; SSE2-NEXT: paddw %xmm1, %xmm1
146 ; SSE2-NEXT: movdqa %xmm1, %xmm2
147 ; SSE2-NEXT: psraw $15, %xmm2
148 ; SSE2-NEXT: movdqa %xmm2, %xmm3
149 ; SSE2-NEXT: pandn %xmm0, %xmm3
150 ; SSE2-NEXT: psrlw $2, %xmm0
151 ; SSE2-NEXT: pand %xmm2, %xmm0
152 ; SSE2-NEXT: por %xmm3, %xmm0
153 ; SSE2-NEXT: paddw %xmm1, %xmm1
154 ; SSE2-NEXT: psraw $15, %xmm1
155 ; SSE2-NEXT: movdqa %xmm1, %xmm2
156 ; SSE2-NEXT: pandn %xmm0, %xmm2
157 ; SSE2-NEXT: psrlw $1, %xmm0
158 ; SSE2-NEXT: pand %xmm1, %xmm0
159 ; SSE2-NEXT: por %xmm2, %xmm0
162 ; SSE41-LABEL: var_shift_v8i16:
164 ; SSE41-NEXT: movdqa %xmm0, %xmm2
165 ; SSE41-NEXT: movdqa %xmm1, %xmm0
166 ; SSE41-NEXT: psllw $12, %xmm0
167 ; SSE41-NEXT: psllw $4, %xmm1
168 ; SSE41-NEXT: por %xmm0, %xmm1
169 ; SSE41-NEXT: movdqa %xmm1, %xmm3
170 ; SSE41-NEXT: paddw %xmm3, %xmm3
171 ; SSE41-NEXT: movdqa %xmm2, %xmm4
172 ; SSE41-NEXT: psrlw $8, %xmm4
173 ; SSE41-NEXT: movdqa %xmm1, %xmm0
174 ; SSE41-NEXT: pblendvb %xmm4, %xmm2
175 ; SSE41-NEXT: movdqa %xmm2, %xmm1
176 ; SSE41-NEXT: psrlw $4, %xmm1
177 ; SSE41-NEXT: movdqa %xmm3, %xmm0
178 ; SSE41-NEXT: pblendvb %xmm1, %xmm2
179 ; SSE41-NEXT: movdqa %xmm2, %xmm1
180 ; SSE41-NEXT: psrlw $2, %xmm1
181 ; SSE41-NEXT: paddw %xmm3, %xmm3
182 ; SSE41-NEXT: movdqa %xmm3, %xmm0
183 ; SSE41-NEXT: pblendvb %xmm1, %xmm2
184 ; SSE41-NEXT: movdqa %xmm2, %xmm1
185 ; SSE41-NEXT: psrlw $1, %xmm1
186 ; SSE41-NEXT: paddw %xmm3, %xmm3
187 ; SSE41-NEXT: movdqa %xmm3, %xmm0
188 ; SSE41-NEXT: pblendvb %xmm1, %xmm2
189 ; SSE41-NEXT: movdqa %xmm2, %xmm0
192 ; AVX1-LABEL: var_shift_v8i16:
194 ; AVX1-NEXT: vpsllw $12, %xmm1, %xmm2
195 ; AVX1-NEXT: vpsllw $4, %xmm1, %xmm1
196 ; AVX1-NEXT: vpor %xmm2, %xmm1, %xmm1
197 ; AVX1-NEXT: vpaddw %xmm1, %xmm1, %xmm2
198 ; AVX1-NEXT: vpsrlw $8, %xmm0, %xmm3
199 ; AVX1-NEXT: vpblendvb %xmm1, %xmm3, %xmm0, %xmm0
200 ; AVX1-NEXT: vpsrlw $4, %xmm0, %xmm1
201 ; AVX1-NEXT: vpblendvb %xmm2, %xmm1, %xmm0, %xmm0
202 ; AVX1-NEXT: vpsrlw $2, %xmm0, %xmm1
203 ; AVX1-NEXT: vpaddw %xmm2, %xmm2, %xmm2
204 ; AVX1-NEXT: vpblendvb %xmm2, %xmm1, %xmm0, %xmm0
205 ; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm1
206 ; AVX1-NEXT: vpaddw %xmm2, %xmm2, %xmm2
207 ; AVX1-NEXT: vpblendvb %xmm2, %xmm1, %xmm0, %xmm0
210 ; AVX2-LABEL: var_shift_v8i16:
212 ; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero
213 ; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero
214 ; AVX2-NEXT: vpsrlvd %ymm1, %ymm0, %ymm0
215 ; AVX2-NEXT: vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13],zero,zero,zero,zero,zero,zero,zero,zero,ymm0[16,17,20,21,24,25,28,29],zero,zero,zero,zero,zero,zero,zero,zero
216 ; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
217 ; AVX2-NEXT: vzeroupper
219 %shift = lshr <8 x i16> %a, %b
223 define <16 x i8> @var_shift_v16i8(<16 x i8> %a, <16 x i8> %b) {
224 ; SSE2-LABEL: var_shift_v16i8:
226 ; SSE2-NEXT: psllw $5, %xmm1
227 ; SSE2-NEXT: pxor %xmm2, %xmm2
228 ; SSE2-NEXT: pxor %xmm3, %xmm3
229 ; SSE2-NEXT: pcmpgtb %xmm1, %xmm3
230 ; SSE2-NEXT: movdqa %xmm3, %xmm4
231 ; SSE2-NEXT: pandn %xmm0, %xmm4
232 ; SSE2-NEXT: psrlw $4, %xmm0
233 ; SSE2-NEXT: pand {{.*}}(%rip), %xmm0
234 ; SSE2-NEXT: pand %xmm3, %xmm0
235 ; SSE2-NEXT: por %xmm4, %xmm0
236 ; SSE2-NEXT: paddb %xmm1, %xmm1
237 ; SSE2-NEXT: pxor %xmm3, %xmm3
238 ; SSE2-NEXT: pcmpgtb %xmm1, %xmm3
239 ; SSE2-NEXT: movdqa %xmm3, %xmm4
240 ; SSE2-NEXT: pandn %xmm0, %xmm4
241 ; SSE2-NEXT: psrlw $2, %xmm0
242 ; SSE2-NEXT: pand {{.*}}(%rip), %xmm0
243 ; SSE2-NEXT: pand %xmm3, %xmm0
244 ; SSE2-NEXT: por %xmm4, %xmm0
245 ; SSE2-NEXT: paddb %xmm1, %xmm1
246 ; SSE2-NEXT: pcmpgtb %xmm1, %xmm2
247 ; SSE2-NEXT: movdqa %xmm2, %xmm1
248 ; SSE2-NEXT: pandn %xmm0, %xmm1
249 ; SSE2-NEXT: psrlw $1, %xmm0
250 ; SSE2-NEXT: pand {{.*}}(%rip), %xmm0
251 ; SSE2-NEXT: pand %xmm2, %xmm0
252 ; SSE2-NEXT: por %xmm1, %xmm0
255 ; SSE41-LABEL: var_shift_v16i8:
257 ; SSE41-NEXT: movdqa %xmm0, %xmm2
258 ; SSE41-NEXT: psllw $5, %xmm1
259 ; SSE41-NEXT: movdqa %xmm2, %xmm3
260 ; SSE41-NEXT: psrlw $4, %xmm3
261 ; SSE41-NEXT: pand {{.*}}(%rip), %xmm3
262 ; SSE41-NEXT: movdqa %xmm1, %xmm0
263 ; SSE41-NEXT: pblendvb %xmm3, %xmm2
264 ; SSE41-NEXT: movdqa %xmm2, %xmm3
265 ; SSE41-NEXT: psrlw $2, %xmm3
266 ; SSE41-NEXT: pand {{.*}}(%rip), %xmm3
267 ; SSE41-NEXT: paddb %xmm1, %xmm1
268 ; SSE41-NEXT: movdqa %xmm1, %xmm0
269 ; SSE41-NEXT: pblendvb %xmm3, %xmm2
270 ; SSE41-NEXT: movdqa %xmm2, %xmm3
271 ; SSE41-NEXT: psrlw $1, %xmm3
272 ; SSE41-NEXT: pand {{.*}}(%rip), %xmm3
273 ; SSE41-NEXT: paddb %xmm1, %xmm1
274 ; SSE41-NEXT: movdqa %xmm1, %xmm0
275 ; SSE41-NEXT: pblendvb %xmm3, %xmm2
276 ; SSE41-NEXT: movdqa %xmm2, %xmm0
279 ; AVX-LABEL: var_shift_v16i8:
281 ; AVX-NEXT: vpsllw $5, %xmm1, %xmm1
282 ; AVX-NEXT: vpsrlw $4, %xmm0, %xmm2
283 ; AVX-NEXT: vpand {{.*}}(%rip), %xmm2, %xmm2
284 ; AVX-NEXT: vpblendvb %xmm1, %xmm2, %xmm0, %xmm0
285 ; AVX-NEXT: vpsrlw $2, %xmm0, %xmm2
286 ; AVX-NEXT: vpand {{.*}}(%rip), %xmm2, %xmm2
287 ; AVX-NEXT: vpaddb %xmm1, %xmm1, %xmm1
288 ; AVX-NEXT: vpblendvb %xmm1, %xmm2, %xmm0, %xmm0
289 ; AVX-NEXT: vpsrlw $1, %xmm0, %xmm2
290 ; AVX-NEXT: vpand {{.*}}(%rip), %xmm2, %xmm2
291 ; AVX-NEXT: vpaddb %xmm1, %xmm1, %xmm1
292 ; AVX-NEXT: vpblendvb %xmm1, %xmm2, %xmm0, %xmm0
294 %shift = lshr <16 x i8> %a, %b
299 ; Uniform Variable Shifts
302 define <2 x i64> @splatvar_shift_v2i64(<2 x i64> %a, <2 x i64> %b) {
303 ; SSE-LABEL: splatvar_shift_v2i64:
305 ; SSE-NEXT: psrlq %xmm1, %xmm0
308 ; AVX-LABEL: splatvar_shift_v2i64:
310 ; AVX-NEXT: vpsrlq %xmm1, %xmm0, %xmm0
312 %splat = shufflevector <2 x i64> %b, <2 x i64> undef, <2 x i32> zeroinitializer
313 %shift = lshr <2 x i64> %a, %splat
317 define <4 x i32> @splatvar_shift_v4i32(<4 x i32> %a, <4 x i32> %b) {
318 ; SSE2-LABEL: splatvar_shift_v4i32:
320 ; SSE2-NEXT: xorps %xmm2, %xmm2
321 ; SSE2-NEXT: movss {{.*#+}} xmm2 = xmm1[0],xmm2[1,2,3]
322 ; SSE2-NEXT: psrld %xmm2, %xmm0
325 ; SSE41-LABEL: splatvar_shift_v4i32:
327 ; SSE41-NEXT: pxor %xmm2, %xmm2
328 ; SSE41-NEXT: pblendw {{.*#+}} xmm2 = xmm1[0,1],xmm2[2,3,4,5,6,7]
329 ; SSE41-NEXT: psrld %xmm2, %xmm0
332 ; AVX-LABEL: splatvar_shift_v4i32:
334 ; AVX-NEXT: vpxor %xmm2, %xmm2, %xmm2
335 ; AVX-NEXT: vpblendw {{.*#+}} xmm1 = xmm1[0,1],xmm2[2,3,4,5,6,7]
336 ; AVX-NEXT: vpsrld %xmm1, %xmm0, %xmm0
338 %splat = shufflevector <4 x i32> %b, <4 x i32> undef, <4 x i32> zeroinitializer
339 %shift = lshr <4 x i32> %a, %splat
343 define <8 x i16> @splatvar_shift_v8i16(<8 x i16> %a, <8 x i16> %b) {
344 ; SSE2-LABEL: splatvar_shift_v8i16:
346 ; SSE2-NEXT: movd %xmm1, %eax
347 ; SSE2-NEXT: movzwl %ax, %eax
348 ; SSE2-NEXT: movd %eax, %xmm1
349 ; SSE2-NEXT: psrlw %xmm1, %xmm0
352 ; SSE41-LABEL: splatvar_shift_v8i16:
354 ; SSE41-NEXT: pxor %xmm2, %xmm2
355 ; SSE41-NEXT: pblendw {{.*#+}} xmm2 = xmm1[0],xmm2[1,2,3,4,5,6,7]
356 ; SSE41-NEXT: psrlw %xmm2, %xmm0
359 ; AVX-LABEL: splatvar_shift_v8i16:
361 ; AVX-NEXT: vpxor %xmm2, %xmm2, %xmm2
362 ; AVX-NEXT: vpblendw {{.*#+}} xmm1 = xmm1[0],xmm2[1,2,3,4,5,6,7]
363 ; AVX-NEXT: vpsrlw %xmm1, %xmm0, %xmm0
365 %splat = shufflevector <8 x i16> %b, <8 x i16> undef, <8 x i32> zeroinitializer
366 %shift = lshr <8 x i16> %a, %splat
370 define <16 x i8> @splatvar_shift_v16i8(<16 x i8> %a, <16 x i8> %b) {
371 ; SSE2-LABEL: splatvar_shift_v16i8:
373 ; SSE2-NEXT: punpcklbw {{.*#+}} xmm1 = xmm1[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
374 ; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[0,1,0,3]
375 ; SSE2-NEXT: pshuflw {{.*#+}} xmm1 = xmm1[0,0,0,0,4,5,6,7]
376 ; SSE2-NEXT: pshufhw {{.*#+}} xmm2 = xmm1[0,1,2,3,4,4,4,4]
377 ; SSE2-NEXT: psllw $5, %xmm2
378 ; SSE2-NEXT: pxor %xmm1, %xmm1
379 ; SSE2-NEXT: pxor %xmm3, %xmm3
380 ; SSE2-NEXT: pcmpgtb %xmm2, %xmm3
381 ; SSE2-NEXT: movdqa %xmm3, %xmm4
382 ; SSE2-NEXT: pandn %xmm0, %xmm4
383 ; SSE2-NEXT: psrlw $4, %xmm0
384 ; SSE2-NEXT: pand {{.*}}(%rip), %xmm0
385 ; SSE2-NEXT: pand %xmm3, %xmm0
386 ; SSE2-NEXT: por %xmm4, %xmm0
387 ; SSE2-NEXT: paddb %xmm2, %xmm2
388 ; SSE2-NEXT: pxor %xmm3, %xmm3
389 ; SSE2-NEXT: pcmpgtb %xmm2, %xmm3
390 ; SSE2-NEXT: movdqa %xmm3, %xmm4
391 ; SSE2-NEXT: pandn %xmm0, %xmm4
392 ; SSE2-NEXT: psrlw $2, %xmm0
393 ; SSE2-NEXT: pand {{.*}}(%rip), %xmm0
394 ; SSE2-NEXT: pand %xmm3, %xmm0
395 ; SSE2-NEXT: por %xmm4, %xmm0
396 ; SSE2-NEXT: paddb %xmm2, %xmm2
397 ; SSE2-NEXT: pcmpgtb %xmm2, %xmm1
398 ; SSE2-NEXT: movdqa %xmm1, %xmm2
399 ; SSE2-NEXT: pandn %xmm0, %xmm2
400 ; SSE2-NEXT: psrlw $1, %xmm0
401 ; SSE2-NEXT: pand {{.*}}(%rip), %xmm0
402 ; SSE2-NEXT: pand %xmm1, %xmm0
403 ; SSE2-NEXT: por %xmm2, %xmm0
406 ; SSE41-LABEL: splatvar_shift_v16i8:
408 ; SSE41-NEXT: movdqa %xmm0, %xmm2
409 ; SSE41-NEXT: pxor %xmm0, %xmm0
410 ; SSE41-NEXT: pshufb %xmm0, %xmm1
411 ; SSE41-NEXT: psllw $5, %xmm1
412 ; SSE41-NEXT: movdqa %xmm1, %xmm3
413 ; SSE41-NEXT: paddb %xmm3, %xmm3
414 ; SSE41-NEXT: movdqa %xmm2, %xmm4
415 ; SSE41-NEXT: psrlw $4, %xmm4
416 ; SSE41-NEXT: pand {{.*}}(%rip), %xmm4
417 ; SSE41-NEXT: movdqa %xmm1, %xmm0
418 ; SSE41-NEXT: pblendvb %xmm4, %xmm2
419 ; SSE41-NEXT: movdqa %xmm2, %xmm1
420 ; SSE41-NEXT: psrlw $2, %xmm1
421 ; SSE41-NEXT: pand {{.*}}(%rip), %xmm1
422 ; SSE41-NEXT: movdqa %xmm3, %xmm0
423 ; SSE41-NEXT: pblendvb %xmm1, %xmm2
424 ; SSE41-NEXT: movdqa %xmm2, %xmm1
425 ; SSE41-NEXT: psrlw $1, %xmm1
426 ; SSE41-NEXT: pand {{.*}}(%rip), %xmm1
427 ; SSE41-NEXT: paddb %xmm3, %xmm3
428 ; SSE41-NEXT: movdqa %xmm3, %xmm0
429 ; SSE41-NEXT: pblendvb %xmm1, %xmm2
430 ; SSE41-NEXT: movdqa %xmm2, %xmm0
433 ; AVX1-LABEL: splatvar_shift_v16i8:
435 ; AVX1-NEXT: vpxor %xmm2, %xmm2, %xmm2
436 ; AVX1-NEXT: vpshufb %xmm2, %xmm1, %xmm1
437 ; AVX1-NEXT: vpsllw $5, %xmm1, %xmm1
438 ; AVX1-NEXT: vpaddb %xmm1, %xmm1, %xmm2
439 ; AVX1-NEXT: vpsrlw $4, %xmm0, %xmm3
440 ; AVX1-NEXT: vpand {{.*}}(%rip), %xmm3, %xmm3
441 ; AVX1-NEXT: vpblendvb %xmm1, %xmm3, %xmm0, %xmm0
442 ; AVX1-NEXT: vpsrlw $2, %xmm0, %xmm1
443 ; AVX1-NEXT: vpand {{.*}}(%rip), %xmm1, %xmm1
444 ; AVX1-NEXT: vpblendvb %xmm2, %xmm1, %xmm0, %xmm0
445 ; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm1
446 ; AVX1-NEXT: vpand {{.*}}(%rip), %xmm1, %xmm1
447 ; AVX1-NEXT: vpaddb %xmm2, %xmm2, %xmm2
448 ; AVX1-NEXT: vpblendvb %xmm2, %xmm1, %xmm0, %xmm0
451 ; AVX2-LABEL: splatvar_shift_v16i8:
453 ; AVX2-NEXT: vpbroadcastb %xmm1, %xmm1
454 ; AVX2-NEXT: vpsllw $5, %xmm1, %xmm1
455 ; AVX2-NEXT: vpsrlw $4, %xmm0, %xmm2
456 ; AVX2-NEXT: vpand {{.*}}(%rip), %xmm2, %xmm2
457 ; AVX2-NEXT: vpblendvb %xmm1, %xmm2, %xmm0, %xmm0
458 ; AVX2-NEXT: vpsrlw $2, %xmm0, %xmm2
459 ; AVX2-NEXT: vpand {{.*}}(%rip), %xmm2, %xmm2
460 ; AVX2-NEXT: vpaddb %xmm1, %xmm1, %xmm1
461 ; AVX2-NEXT: vpblendvb %xmm1, %xmm2, %xmm0, %xmm0
462 ; AVX2-NEXT: vpsrlw $1, %xmm0, %xmm2
463 ; AVX2-NEXT: vpand {{.*}}(%rip), %xmm2, %xmm2
464 ; AVX2-NEXT: vpaddb %xmm1, %xmm1, %xmm1
465 ; AVX2-NEXT: vpblendvb %xmm1, %xmm2, %xmm0, %xmm0
467 %splat = shufflevector <16 x i8> %b, <16 x i8> undef, <16 x i32> zeroinitializer
468 %shift = lshr <16 x i8> %a, %splat
476 define <2 x i64> @constant_shift_v2i64(<2 x i64> %a) {
477 ; SSE2-LABEL: constant_shift_v2i64:
479 ; SSE2-NEXT: movdqa %xmm0, %xmm1
480 ; SSE2-NEXT: psrlq $7, %xmm1
481 ; SSE2-NEXT: psrlq $1, %xmm0
482 ; SSE2-NEXT: movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1]
483 ; SSE2-NEXT: movapd %xmm1, %xmm0
486 ; SSE41-LABEL: constant_shift_v2i64:
488 ; SSE41-NEXT: movdqa %xmm0, %xmm1
489 ; SSE41-NEXT: psrlq $7, %xmm1
490 ; SSE41-NEXT: psrlq $1, %xmm0
491 ; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5,6,7]
494 ; AVX1-LABEL: constant_shift_v2i64:
496 ; AVX1-NEXT: vpsrlq $7, %xmm0, %xmm1
497 ; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm0
498 ; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5,6,7]
501 ; AVX2-LABEL: constant_shift_v2i64:
503 ; AVX2-NEXT: vpsrlvq {{.*}}(%rip), %xmm0, %xmm0
505 %shift = lshr <2 x i64> %a, <i64 1, i64 7>
509 define <4 x i32> @constant_shift_v4i32(<4 x i32> %a) {
510 ; SSE2-LABEL: constant_shift_v4i32:
512 ; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[3,1,2,3]
513 ; SSE2-NEXT: movd %xmm1, %eax
514 ; SSE2-NEXT: shrl $7, %eax
515 ; SSE2-NEXT: movd %eax, %xmm1
516 ; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm0[1,1,2,3]
517 ; SSE2-NEXT: movd %xmm2, %eax
518 ; SSE2-NEXT: shrl $5, %eax
519 ; SSE2-NEXT: movd %eax, %xmm2
520 ; SSE2-NEXT: punpckldq {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1]
521 ; SSE2-NEXT: movd %xmm0, %eax
522 ; SSE2-NEXT: shrl $4, %eax
523 ; SSE2-NEXT: movd %eax, %xmm1
524 ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
525 ; SSE2-NEXT: movd %xmm0, %eax
526 ; SSE2-NEXT: shrl $6, %eax
527 ; SSE2-NEXT: movd %eax, %xmm0
528 ; SSE2-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
529 ; SSE2-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
530 ; SSE2-NEXT: movdqa %xmm1, %xmm0
533 ; SSE41-LABEL: constant_shift_v4i32:
535 ; SSE41-NEXT: pextrd $1, %xmm0, %eax
536 ; SSE41-NEXT: shrl $5, %eax
537 ; SSE41-NEXT: movd %xmm0, %ecx
538 ; SSE41-NEXT: shrl $4, %ecx
539 ; SSE41-NEXT: movd %ecx, %xmm1
540 ; SSE41-NEXT: pinsrd $1, %eax, %xmm1
541 ; SSE41-NEXT: pextrd $2, %xmm0, %eax
542 ; SSE41-NEXT: shrl $6, %eax
543 ; SSE41-NEXT: pinsrd $2, %eax, %xmm1
544 ; SSE41-NEXT: pextrd $3, %xmm0, %eax
545 ; SSE41-NEXT: shrl $7, %eax
546 ; SSE41-NEXT: pinsrd $3, %eax, %xmm1
547 ; SSE41-NEXT: movdqa %xmm1, %xmm0
550 ; AVX1-LABEL: constant_shift_v4i32:
552 ; AVX1-NEXT: vpextrd $1, %xmm0, %eax
553 ; AVX1-NEXT: shrl $5, %eax
554 ; AVX1-NEXT: vmovd %xmm0, %ecx
555 ; AVX1-NEXT: shrl $4, %ecx
556 ; AVX1-NEXT: vmovd %ecx, %xmm1
557 ; AVX1-NEXT: vpinsrd $1, %eax, %xmm1, %xmm1
558 ; AVX1-NEXT: vpextrd $2, %xmm0, %eax
559 ; AVX1-NEXT: shrl $6, %eax
560 ; AVX1-NEXT: vpinsrd $2, %eax, %xmm1, %xmm1
561 ; AVX1-NEXT: vpextrd $3, %xmm0, %eax
562 ; AVX1-NEXT: shrl $7, %eax
563 ; AVX1-NEXT: vpinsrd $3, %eax, %xmm1, %xmm0
566 ; AVX2-LABEL: constant_shift_v4i32:
568 ; AVX2-NEXT: vpsrlvd {{.*}}(%rip), %xmm0, %xmm0
570 %shift = lshr <4 x i32> %a, <i32 4, i32 5, i32 6, i32 7>
574 define <8 x i16> @constant_shift_v8i16(<8 x i16> %a) {
575 ; SSE2-LABEL: constant_shift_v8i16:
577 ; SSE2-NEXT: movdqa %xmm0, %xmm1
578 ; SSE2-NEXT: psrlw $4, %xmm1
579 ; SSE2-NEXT: movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1]
580 ; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm1[0,2,2,3]
581 ; SSE2-NEXT: psrlw $2, %xmm1
582 ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,3,2,3]
583 ; SSE2-NEXT: punpckldq {{.*#+}} xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1]
584 ; SSE2-NEXT: movdqa {{.*#+}} xmm0 = [65535,0,65535,0,65535,0,65535,0]
585 ; SSE2-NEXT: movdqa %xmm2, %xmm1
586 ; SSE2-NEXT: pand %xmm0, %xmm1
587 ; SSE2-NEXT: psrlw $1, %xmm2
588 ; SSE2-NEXT: pandn %xmm2, %xmm0
589 ; SSE2-NEXT: por %xmm1, %xmm0
592 ; SSE41-LABEL: constant_shift_v8i16:
594 ; SSE41-NEXT: movdqa %xmm0, %xmm1
595 ; SSE41-NEXT: movdqa %xmm1, %xmm2
596 ; SSE41-NEXT: psrlw $8, %xmm2
597 ; SSE41-NEXT: movaps {{.*#+}} xmm0 = [0,4112,8224,12336,16448,20560,24672,28784]
598 ; SSE41-NEXT: pblendvb %xmm2, %xmm1
599 ; SSE41-NEXT: movdqa %xmm1, %xmm2
600 ; SSE41-NEXT: psrlw $4, %xmm2
601 ; SSE41-NEXT: movaps {{.*#+}} xmm0 = [0,8224,16448,24672,32896,41120,49344,57568]
602 ; SSE41-NEXT: pblendvb %xmm2, %xmm1
603 ; SSE41-NEXT: movdqa %xmm1, %xmm2
604 ; SSE41-NEXT: psrlw $2, %xmm2
605 ; SSE41-NEXT: movaps {{.*#+}} xmm0 = [0,16448,32896,49344,256,16704,33152,49600]
606 ; SSE41-NEXT: pblendvb %xmm2, %xmm1
607 ; SSE41-NEXT: movdqa %xmm1, %xmm2
608 ; SSE41-NEXT: psrlw $1, %xmm2
609 ; SSE41-NEXT: movaps {{.*#+}} xmm0 = [0,32896,256,33152,512,33408,768,33664]
610 ; SSE41-NEXT: pblendvb %xmm2, %xmm1
611 ; SSE41-NEXT: movdqa %xmm1, %xmm0
614 ; AVX1-LABEL: constant_shift_v8i16:
616 ; AVX1-NEXT: vpsrlw $8, %xmm0, %xmm1
617 ; AVX1-NEXT: vmovdqa {{.*}}(%rip), %xmm2 # xmm2 = [0,4112,8224,12336,16448,20560,24672,28784]
618 ; AVX1-NEXT: vpblendvb %xmm2, %xmm1, %xmm0, %xmm0
619 ; AVX1-NEXT: vpsrlw $4, %xmm0, %xmm1
620 ; AVX1-NEXT: vmovdqa {{.*}}(%rip), %xmm2 # xmm2 = [0,8224,16448,24672,32896,41120,49344,57568]
621 ; AVX1-NEXT: vpblendvb %xmm2, %xmm1, %xmm0, %xmm0
622 ; AVX1-NEXT: vpsrlw $2, %xmm0, %xmm1
623 ; AVX1-NEXT: vmovdqa {{.*}}(%rip), %xmm2 # xmm2 = [0,16448,32896,49344,256,16704,33152,49600]
624 ; AVX1-NEXT: vpblendvb %xmm2, %xmm1, %xmm0, %xmm0
625 ; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm1
626 ; AVX1-NEXT: vmovdqa {{.*}}(%rip), %xmm2 # xmm2 = [0,32896,256,33152,512,33408,768,33664]
627 ; AVX1-NEXT: vpblendvb %xmm2, %xmm1, %xmm0, %xmm0
630 ; AVX2-LABEL: constant_shift_v8i16:
632 ; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero
633 ; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm1 = mem[0],zero,mem[1],zero,mem[2],zero,mem[3],zero,mem[4],zero,mem[5],zero,mem[6],zero,mem[7],zero
634 ; AVX2-NEXT: vpsrlvd %ymm1, %ymm0, %ymm0
635 ; AVX2-NEXT: vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13],zero,zero,zero,zero,zero,zero,zero,zero,ymm0[16,17,20,21,24,25,28,29],zero,zero,zero,zero,zero,zero,zero,zero
636 ; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
637 ; AVX2-NEXT: vzeroupper
639 %shift = lshr <8 x i16> %a, <i16 0, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7>
643 define <16 x i8> @constant_shift_v16i8(<16 x i8> %a) {
644 ; SSE2-LABEL: constant_shift_v16i8:
646 ; SSE2-NEXT: movdqa {{.*#+}} xmm2 = [0,1,2,3,4,5,6,7,7,6,5,4,3,2,1,0]
647 ; SSE2-NEXT: psllw $5, %xmm2
648 ; SSE2-NEXT: pxor %xmm1, %xmm1
649 ; SSE2-NEXT: pxor %xmm3, %xmm3
650 ; SSE2-NEXT: pcmpgtb %xmm2, %xmm3
651 ; SSE2-NEXT: movdqa %xmm3, %xmm4
652 ; SSE2-NEXT: pandn %xmm0, %xmm4
653 ; SSE2-NEXT: psrlw $4, %xmm0
654 ; SSE2-NEXT: pand {{.*}}(%rip), %xmm0
655 ; SSE2-NEXT: pand %xmm3, %xmm0
656 ; SSE2-NEXT: por %xmm4, %xmm0
657 ; SSE2-NEXT: paddb %xmm2, %xmm2
658 ; SSE2-NEXT: pxor %xmm3, %xmm3
659 ; SSE2-NEXT: pcmpgtb %xmm2, %xmm3
660 ; SSE2-NEXT: movdqa %xmm3, %xmm4
661 ; SSE2-NEXT: pandn %xmm0, %xmm4
662 ; SSE2-NEXT: psrlw $2, %xmm0
663 ; SSE2-NEXT: pand {{.*}}(%rip), %xmm0
664 ; SSE2-NEXT: pand %xmm3, %xmm0
665 ; SSE2-NEXT: por %xmm4, %xmm0
666 ; SSE2-NEXT: paddb %xmm2, %xmm2
667 ; SSE2-NEXT: pcmpgtb %xmm2, %xmm1
668 ; SSE2-NEXT: movdqa %xmm1, %xmm2
669 ; SSE2-NEXT: pandn %xmm0, %xmm2
670 ; SSE2-NEXT: psrlw $1, %xmm0
671 ; SSE2-NEXT: pand {{.*}}(%rip), %xmm0
672 ; SSE2-NEXT: pand %xmm1, %xmm0
673 ; SSE2-NEXT: por %xmm2, %xmm0
676 ; SSE41-LABEL: constant_shift_v16i8:
678 ; SSE41-NEXT: movdqa %xmm0, %xmm1
679 ; SSE41-NEXT: movdqa {{.*#+}} xmm0 = [0,1,2,3,4,5,6,7,7,6,5,4,3,2,1,0]
680 ; SSE41-NEXT: psllw $5, %xmm0
681 ; SSE41-NEXT: movdqa %xmm1, %xmm2
682 ; SSE41-NEXT: psrlw $4, %xmm2
683 ; SSE41-NEXT: pand {{.*}}(%rip), %xmm2
684 ; SSE41-NEXT: pblendvb %xmm2, %xmm1
685 ; SSE41-NEXT: movdqa %xmm1, %xmm2
686 ; SSE41-NEXT: psrlw $2, %xmm2
687 ; SSE41-NEXT: pand {{.*}}(%rip), %xmm2
688 ; SSE41-NEXT: paddb %xmm0, %xmm0
689 ; SSE41-NEXT: pblendvb %xmm2, %xmm1
690 ; SSE41-NEXT: movdqa %xmm1, %xmm2
691 ; SSE41-NEXT: psrlw $1, %xmm2
692 ; SSE41-NEXT: pand {{.*}}(%rip), %xmm2
693 ; SSE41-NEXT: paddb %xmm0, %xmm0
694 ; SSE41-NEXT: pblendvb %xmm2, %xmm1
695 ; SSE41-NEXT: movdqa %xmm1, %xmm0
698 ; AVX-LABEL: constant_shift_v16i8:
700 ; AVX-NEXT: vmovdqa {{.*#+}} xmm1 = [0,1,2,3,4,5,6,7,7,6,5,4,3,2,1,0]
701 ; AVX-NEXT: vpsllw $5, %xmm1, %xmm1
702 ; AVX-NEXT: vpsrlw $4, %xmm0, %xmm2
703 ; AVX-NEXT: vpand {{.*}}(%rip), %xmm2, %xmm2
704 ; AVX-NEXT: vpblendvb %xmm1, %xmm2, %xmm0, %xmm0
705 ; AVX-NEXT: vpsrlw $2, %xmm0, %xmm2
706 ; AVX-NEXT: vpand {{.*}}(%rip), %xmm2, %xmm2
707 ; AVX-NEXT: vpaddb %xmm1, %xmm1, %xmm1
708 ; AVX-NEXT: vpblendvb %xmm1, %xmm2, %xmm0, %xmm0
709 ; AVX-NEXT: vpsrlw $1, %xmm0, %xmm2
710 ; AVX-NEXT: vpand {{.*}}(%rip), %xmm2, %xmm2
711 ; AVX-NEXT: vpaddb %xmm1, %xmm1, %xmm1
712 ; AVX-NEXT: vpblendvb %xmm1, %xmm2, %xmm0, %xmm0
714 %shift = lshr <16 x i8> %a, <i8 0, i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 7, i8 6, i8 5, i8 4, i8 3, i8 2, i8 1, i8 0>
719 ; Uniform Constant Shifts
722 define <2 x i64> @splatconstant_shift_v2i64(<2 x i64> %a) {
723 ; SSE-LABEL: splatconstant_shift_v2i64:
725 ; SSE-NEXT: psrlq $7, %xmm0
728 ; AVX-LABEL: splatconstant_shift_v2i64:
730 ; AVX-NEXT: vpsrlq $7, %xmm0, %xmm0
732 %shift = lshr <2 x i64> %a, <i64 7, i64 7>
736 define <4 x i32> @splatconstant_shift_v4i32(<4 x i32> %a) {
737 ; SSE-LABEL: splatconstant_shift_v4i32:
739 ; SSE-NEXT: psrld $5, %xmm0
742 ; AVX-LABEL: splatconstant_shift_v4i32:
744 ; AVX-NEXT: vpsrld $5, %xmm0, %xmm0
746 %shift = lshr <4 x i32> %a, <i32 5, i32 5, i32 5, i32 5>
750 define <8 x i16> @splatconstant_shift_v8i16(<8 x i16> %a) {
751 ; SSE-LABEL: splatconstant_shift_v8i16:
753 ; SSE-NEXT: psrlw $3, %xmm0
756 ; AVX-LABEL: splatconstant_shift_v8i16:
758 ; AVX-NEXT: vpsrlw $3, %xmm0, %xmm0
760 %shift = lshr <8 x i16> %a, <i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3>
764 define <16 x i8> @splatconstant_shift_v16i8(<16 x i8> %a) {
765 ; SSE-LABEL: splatconstant_shift_v16i8:
767 ; SSE-NEXT: psrlw $3, %xmm0
768 ; SSE-NEXT: pand {{.*}}(%rip), %xmm0
771 ; AVX-LABEL: splatconstant_shift_v16i8:
773 ; AVX-NEXT: vpsrlw $3, %xmm0
774 ; AVX-NEXT: vpand {{.*}}(%rip), %xmm0
776 %shift = lshr <16 x i8> %a, <i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3>