[X86][SSE] Vectorized v4i32 non-uniform shifts.
[oota-llvm.git] / test / CodeGen / X86 / vector-shift-ashr-128.ll
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
5
6 ;
7 ; Variable Shifts
8 ;
9
10 define <2 x i64> @var_shift_v2i64(<2 x i64> %a, <2 x i64> %b) {
11 ; SSE2-LABEL: var_shift_v2i64:
12 ; SSE2:       # BB#0:
13 ; SSE2-NEXT:    movd %xmm0, %rax
14 ; SSE2-NEXT:    movd %xmm1, %rcx
15 ; SSE2-NEXT:    sarq %cl, %rax
16 ; SSE2-NEXT:    movd %rax, %xmm2
17 ; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
18 ; SSE2-NEXT:    movd %xmm0, %rax
19 ; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[2,3,0,1]
20 ; SSE2-NEXT:    movd %xmm0, %rcx
21 ; SSE2-NEXT:    sarq %cl, %rax
22 ; SSE2-NEXT:    movd %rax, %xmm0
23 ; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm0[0]
24 ; SSE2-NEXT:    movdqa %xmm2, %xmm0
25 ; SSE2-NEXT:    retq
26 ;
27 ; SSE41-LABEL: var_shift_v2i64:
28 ; SSE41:       # BB#0:
29 ; SSE41-NEXT:    pextrq $1, %xmm0, %rax
30 ; SSE41-NEXT:    pextrq $1, %xmm1, %rcx
31 ; SSE41-NEXT:    sarq %cl, %rax
32 ; SSE41-NEXT:    movd %rax, %xmm2
33 ; SSE41-NEXT:    movd %xmm0, %rax
34 ; SSE41-NEXT:    movd %xmm1, %rcx
35 ; SSE41-NEXT:    sarq %cl, %rax
36 ; SSE41-NEXT:    movd %rax, %xmm0
37 ; SSE41-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm2[0]
38 ; SSE41-NEXT:    retq
39 ;
40 ; AVX-LABEL: var_shift_v2i64:
41 ; AVX:       # BB#0:
42 ; AVX-NEXT:    vpextrq $1, %xmm0, %rax
43 ; AVX-NEXT:    vpextrq $1, %xmm1, %rcx
44 ; AVX-NEXT:    sarq %cl, %rax
45 ; AVX-NEXT:    vmovq %rax, %xmm2
46 ; AVX-NEXT:    vmovq %xmm0, %rax
47 ; AVX-NEXT:    vmovq %xmm1, %rcx
48 ; AVX-NEXT:    sarq %cl, %rax
49 ; AVX-NEXT:    vmovq %rax, %xmm0
50 ; AVX-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm2[0]
51 ; AVX-NEXT:    retq
52   %shift = ashr <2 x i64> %a, %b
53   ret <2 x i64> %shift
54 }
55
56 define <4 x i32> @var_shift_v4i32(<4 x i32> %a, <4 x i32> %b) {
57 ; SSE2-LABEL: var_shift_v4i32:
58 ; SSE2:       # BB#0:
59 ; SSE2-NEXT:    movdqa %xmm1, %xmm2
60 ; SSE2-NEXT:    psrldq {{.*#+}} xmm2 = xmm2[12,13,14,15],zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero
61 ; SSE2-NEXT:    movdqa %xmm0, %xmm3
62 ; SSE2-NEXT:    psrad %xmm2, %xmm3
63 ; SSE2-NEXT:    movdqa %xmm1, %xmm2
64 ; SSE2-NEXT:    psrlq $32, %xmm2
65 ; SSE2-NEXT:    movdqa %xmm0, %xmm4
66 ; SSE2-NEXT:    psrad %xmm2, %xmm4
67 ; SSE2-NEXT:    movsd {{.*#+}} xmm3 = xmm4[0],xmm3[1]
68 ; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm3[1,3,2,3]
69 ; SSE2-NEXT:    pxor %xmm3, %xmm3
70 ; SSE2-NEXT:    movdqa %xmm1, %xmm4
71 ; SSE2-NEXT:    punpckhdq {{.*#+}} xmm4 = xmm4[2],xmm3[2],xmm4[3],xmm3[3]
72 ; SSE2-NEXT:    movdqa %xmm0, %xmm5
73 ; SSE2-NEXT:    psrad %xmm4, %xmm5
74 ; SSE2-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
75 ; SSE2-NEXT:    psrad %xmm1, %xmm0
76 ; SSE2-NEXT:    movsd {{.*#+}} xmm5 = xmm0[0],xmm5[1]
77 ; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm5[0,2,2,3]
78 ; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
79 ; SSE2-NEXT:    retq
80 ;
81 ; SSE41-LABEL: var_shift_v4i32:
82 ; SSE41:       # BB#0:
83 ; SSE41-NEXT:    movdqa %xmm1, %xmm2
84 ; SSE41-NEXT:    psrldq {{.*#+}} xmm2 = xmm2[12,13,14,15],zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero
85 ; SSE41-NEXT:    movdqa %xmm0, %xmm3
86 ; SSE41-NEXT:    psrad %xmm2, %xmm3
87 ; SSE41-NEXT:    movdqa %xmm1, %xmm2
88 ; SSE41-NEXT:    psrlq $32, %xmm2
89 ; SSE41-NEXT:    movdqa %xmm0, %xmm4
90 ; SSE41-NEXT:    psrad %xmm2, %xmm4
91 ; SSE41-NEXT:    pblendw {{.*#+}} xmm4 = xmm4[0,1,2,3],xmm3[4,5,6,7]
92 ; SSE41-NEXT:    pxor %xmm2, %xmm2
93 ; SSE41-NEXT:    pmovzxdq {{.*#+}} xmm3 = xmm1[0],zero,xmm1[1],zero
94 ; SSE41-NEXT:    punpckhdq {{.*#+}} xmm1 = xmm1[2],xmm2[2],xmm1[3],xmm2[3]
95 ; SSE41-NEXT:    movdqa %xmm0, %xmm2
96 ; SSE41-NEXT:    psrad %xmm1, %xmm2
97 ; SSE41-NEXT:    psrad %xmm3, %xmm0
98 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm2[4,5,6,7]
99 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm4[2,3],xmm0[4,5],xmm4[6,7]
100 ; SSE41-NEXT:    retq
101 ;
102 ; AVX1-LABEL: var_shift_v4i32:
103 ; AVX1:       # BB#0:
104 ; AVX1-NEXT:    vpsrldq {{.*#+}} xmm2 = xmm1[12,13,14,15],zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero
105 ; AVX1-NEXT:    vpsrad %xmm2, %xmm0, %xmm2
106 ; AVX1-NEXT:    vpsrlq $32, %xmm1, %xmm3
107 ; AVX1-NEXT:    vpsrad %xmm3, %xmm0, %xmm3
108 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm2 = xmm3[0,1,2,3],xmm2[4,5,6,7]
109 ; AVX1-NEXT:    vpxor %xmm3, %xmm3, %xmm3
110 ; AVX1-NEXT:    vpunpckhdq {{.*#+}} xmm3 = xmm1[2],xmm3[2],xmm1[3],xmm3[3]
111 ; AVX1-NEXT:    vpsrad %xmm3, %xmm0, %xmm3
112 ; AVX1-NEXT:    vpmovzxdq {{.*#+}} xmm1 = xmm1[0],zero,xmm1[1],zero
113 ; AVX1-NEXT:    vpsrad %xmm1, %xmm0, %xmm0
114 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm3[4,5,6,7]
115 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7]
116 ; AVX1-NEXT:    retq
117 ;
118 ; AVX2-LABEL: var_shift_v4i32:
119 ; AVX2:       # BB#0:
120 ; AVX2-NEXT:    vpsravd %xmm1, %xmm0, %xmm0
121 ; AVX2-NEXT:    retq
122   %shift = ashr <4 x i32> %a, %b
123   ret <4 x i32> %shift
124 }
125
126 define <8 x i16> @var_shift_v8i16(<8 x i16> %a, <8 x i16> %b) {
127 ; SSE2-LABEL: var_shift_v8i16:
128 ; SSE2:       # BB#0:
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:    psraw $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:    psraw $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:    psraw $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:    psraw $1, %xmm0
158 ; SSE2-NEXT:    pand %xmm1, %xmm0
159 ; SSE2-NEXT:    por %xmm2, %xmm0
160 ; SSE2-NEXT:    retq
161 ;
162 ; SSE41-LABEL: var_shift_v8i16:
163 ; SSE41:       # BB#0:
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:    psraw $8, %xmm4
173 ; SSE41-NEXT:    movdqa %xmm1, %xmm0
174 ; SSE41-NEXT:    pblendvb %xmm4, %xmm2
175 ; SSE41-NEXT:    movdqa %xmm2, %xmm1
176 ; SSE41-NEXT:    psraw $4, %xmm1
177 ; SSE41-NEXT:    movdqa %xmm3, %xmm0
178 ; SSE41-NEXT:    pblendvb %xmm1, %xmm2
179 ; SSE41-NEXT:    movdqa %xmm2, %xmm1
180 ; SSE41-NEXT:    psraw $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:    psraw $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
190 ; SSE41-NEXT:    retq
191 ;
192 ; AVX1-LABEL: var_shift_v8i16:
193 ; AVX1:       # BB#0:
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:    vpsraw $8, %xmm0, %xmm3
199 ; AVX1-NEXT:    vpblendvb %xmm1, %xmm3, %xmm0, %xmm0
200 ; AVX1-NEXT:    vpsraw $4, %xmm0, %xmm1
201 ; AVX1-NEXT:    vpblendvb %xmm2, %xmm1, %xmm0, %xmm0
202 ; AVX1-NEXT:    vpsraw $2, %xmm0, %xmm1
203 ; AVX1-NEXT:    vpaddw %xmm2, %xmm2, %xmm2
204 ; AVX1-NEXT:    vpblendvb %xmm2, %xmm1, %xmm0, %xmm0
205 ; AVX1-NEXT:    vpsraw $1, %xmm0, %xmm1
206 ; AVX1-NEXT:    vpaddw %xmm2, %xmm2, %xmm2
207 ; AVX1-NEXT:    vpblendvb %xmm2, %xmm1, %xmm0, %xmm0
208 ; AVX1-NEXT:    retq
209 ;
210 ; AVX2-LABEL: var_shift_v8i16:
211 ; AVX2:       # BB#0:
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:    vpmovsxwd %xmm0, %ymm0
214 ; AVX2-NEXT:    vpsravd %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
218 ; AVX2-NEXT:    retq
219   %shift = ashr <8 x i16> %a, %b
220   ret <8 x i16> %shift
221 }
222
223 define <16 x i8> @var_shift_v16i8(<16 x i8> %a, <16 x i8> %b) {
224 ; SSE2-LABEL: var_shift_v16i8:
225 ; SSE2:       # BB#0:
226 ; SSE2-NEXT:    punpckhbw {{.*#+}} xmm2 = xmm2[8],xmm0[8],xmm2[9],xmm0[9],xmm2[10],xmm0[10],xmm2[11],xmm0[11],xmm2[12],xmm0[12],xmm2[13],xmm0[13],xmm2[14],xmm0[14],xmm2[15],xmm0[15]
227 ; SSE2-NEXT:    psllw $5, %xmm1
228 ; SSE2-NEXT:    punpckhbw {{.*#+}} xmm4 = xmm4[8],xmm1[8],xmm4[9],xmm1[9],xmm4[10],xmm1[10],xmm4[11],xmm1[11],xmm4[12],xmm1[12],xmm4[13],xmm1[13],xmm4[14],xmm1[14],xmm4[15],xmm1[15]
229 ; SSE2-NEXT:    pxor %xmm3, %xmm3
230 ; SSE2-NEXT:    pxor %xmm5, %xmm5
231 ; SSE2-NEXT:    pcmpgtw %xmm4, %xmm5
232 ; SSE2-NEXT:    movdqa %xmm5, %xmm6
233 ; SSE2-NEXT:    pandn %xmm2, %xmm6
234 ; SSE2-NEXT:    psraw $4, %xmm2
235 ; SSE2-NEXT:    pand %xmm5, %xmm2
236 ; SSE2-NEXT:    por %xmm6, %xmm2
237 ; SSE2-NEXT:    paddw %xmm4, %xmm4
238 ; SSE2-NEXT:    pxor %xmm5, %xmm5
239 ; SSE2-NEXT:    pcmpgtw %xmm4, %xmm5
240 ; SSE2-NEXT:    movdqa %xmm5, %xmm6
241 ; SSE2-NEXT:    pandn %xmm2, %xmm6
242 ; SSE2-NEXT:    psraw $2, %xmm2
243 ; SSE2-NEXT:    pand %xmm5, %xmm2
244 ; SSE2-NEXT:    por %xmm6, %xmm2
245 ; SSE2-NEXT:    paddw %xmm4, %xmm4
246 ; SSE2-NEXT:    pxor %xmm5, %xmm5
247 ; SSE2-NEXT:    pcmpgtw %xmm4, %xmm5
248 ; SSE2-NEXT:    movdqa %xmm5, %xmm4
249 ; SSE2-NEXT:    pandn %xmm2, %xmm4
250 ; SSE2-NEXT:    psraw $1, %xmm2
251 ; SSE2-NEXT:    pand %xmm5, %xmm2
252 ; SSE2-NEXT:    por %xmm4, %xmm2
253 ; SSE2-NEXT:    psrlw $8, %xmm2
254 ; SSE2-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
255 ; SSE2-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
256 ; SSE2-NEXT:    pxor %xmm4, %xmm4
257 ; SSE2-NEXT:    pcmpgtw %xmm1, %xmm4
258 ; SSE2-NEXT:    movdqa %xmm4, %xmm5
259 ; SSE2-NEXT:    pandn %xmm0, %xmm5
260 ; SSE2-NEXT:    psraw $4, %xmm0
261 ; SSE2-NEXT:    pand %xmm4, %xmm0
262 ; SSE2-NEXT:    por %xmm5, %xmm0
263 ; SSE2-NEXT:    paddw %xmm1, %xmm1
264 ; SSE2-NEXT:    pxor %xmm4, %xmm4
265 ; SSE2-NEXT:    pcmpgtw %xmm1, %xmm4
266 ; SSE2-NEXT:    movdqa %xmm4, %xmm5
267 ; SSE2-NEXT:    pandn %xmm0, %xmm5
268 ; SSE2-NEXT:    psraw $2, %xmm0
269 ; SSE2-NEXT:    pand %xmm4, %xmm0
270 ; SSE2-NEXT:    por %xmm5, %xmm0
271 ; SSE2-NEXT:    paddw %xmm1, %xmm1
272 ; SSE2-NEXT:    pcmpgtw %xmm1, %xmm3
273 ; SSE2-NEXT:    movdqa %xmm3, %xmm1
274 ; SSE2-NEXT:    pandn %xmm0, %xmm1
275 ; SSE2-NEXT:    psraw $1, %xmm0
276 ; SSE2-NEXT:    pand %xmm3, %xmm0
277 ; SSE2-NEXT:    por %xmm1, %xmm0
278 ; SSE2-NEXT:    psrlw $8, %xmm0
279 ; SSE2-NEXT:    packuswb %xmm2, %xmm0
280 ; SSE2-NEXT:    retq
281 ;
282 ; SSE41-LABEL: var_shift_v16i8:
283 ; SSE41:       # BB#0:
284 ; SSE41-NEXT:    movdqa %xmm0, %xmm2
285 ; SSE41-NEXT:    psllw $5, %xmm1
286 ; SSE41-NEXT:    punpckhbw {{.*#+}} xmm0 = xmm0[8],xmm1[8],xmm0[9],xmm1[9],xmm0[10],xmm1[10],xmm0[11],xmm1[11],xmm0[12],xmm1[12],xmm0[13],xmm1[13],xmm0[14],xmm1[14],xmm0[15],xmm1[15]
287 ; SSE41-NEXT:    punpckhbw {{.*#+}} xmm3 = xmm3[8],xmm2[8],xmm3[9],xmm2[9],xmm3[10],xmm2[10],xmm3[11],xmm2[11],xmm3[12],xmm2[12],xmm3[13],xmm2[13],xmm3[14],xmm2[14],xmm3[15],xmm2[15]
288 ; SSE41-NEXT:    movdqa %xmm3, %xmm4
289 ; SSE41-NEXT:    psraw $4, %xmm4
290 ; SSE41-NEXT:    pblendvb %xmm4, %xmm3
291 ; SSE41-NEXT:    movdqa %xmm3, %xmm4
292 ; SSE41-NEXT:    psraw $2, %xmm4
293 ; SSE41-NEXT:    paddw %xmm0, %xmm0
294 ; SSE41-NEXT:    pblendvb %xmm4, %xmm3
295 ; SSE41-NEXT:    movdqa %xmm3, %xmm4
296 ; SSE41-NEXT:    psraw $1, %xmm4
297 ; SSE41-NEXT:    paddw %xmm0, %xmm0
298 ; SSE41-NEXT:    pblendvb %xmm4, %xmm3
299 ; SSE41-NEXT:    psrlw $8, %xmm3
300 ; SSE41-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3],xmm0[4],xmm1[4],xmm0[5],xmm1[5],xmm0[6],xmm1[6],xmm0[7],xmm1[7]
301 ; SSE41-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1],xmm1[2],xmm2[2],xmm1[3],xmm2[3],xmm1[4],xmm2[4],xmm1[5],xmm2[5],xmm1[6],xmm2[6],xmm1[7],xmm2[7]
302 ; SSE41-NEXT:    movdqa %xmm1, %xmm2
303 ; SSE41-NEXT:    psraw $4, %xmm2
304 ; SSE41-NEXT:    pblendvb %xmm2, %xmm1
305 ; SSE41-NEXT:    movdqa %xmm1, %xmm2
306 ; SSE41-NEXT:    psraw $2, %xmm2
307 ; SSE41-NEXT:    paddw %xmm0, %xmm0
308 ; SSE41-NEXT:    pblendvb %xmm2, %xmm1
309 ; SSE41-NEXT:    movdqa %xmm1, %xmm2
310 ; SSE41-NEXT:    psraw $1, %xmm2
311 ; SSE41-NEXT:    paddw %xmm0, %xmm0
312 ; SSE41-NEXT:    pblendvb %xmm2, %xmm1
313 ; SSE41-NEXT:    psrlw $8, %xmm1
314 ; SSE41-NEXT:    packuswb %xmm3, %xmm1
315 ; SSE41-NEXT:    movdqa %xmm1, %xmm0
316 ; SSE41-NEXT:    retq
317 ;
318 ; AVX-LABEL: var_shift_v16i8:
319 ; AVX:       # BB#0:
320 ; AVX-NEXT:    vpsllw $5, %xmm1, %xmm1
321 ; AVX-NEXT:    vpunpckhbw {{.*#+}} xmm2 = xmm0[8],xmm1[8],xmm0[9],xmm1[9],xmm0[10],xmm1[10],xmm0[11],xmm1[11],xmm0[12],xmm1[12],xmm0[13],xmm1[13],xmm0[14],xmm1[14],xmm0[15],xmm1[15]
322 ; AVX-NEXT:    vpunpckhbw {{.*#+}} xmm3 = xmm0[8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15]
323 ; AVX-NEXT:    vpsraw $4, %xmm3, %xmm4
324 ; AVX-NEXT:    vpblendvb %xmm2, %xmm4, %xmm3, %xmm3
325 ; AVX-NEXT:    vpsraw $2, %xmm3, %xmm4
326 ; AVX-NEXT:    vpaddw %xmm2, %xmm2, %xmm2
327 ; AVX-NEXT:    vpblendvb %xmm2, %xmm4, %xmm3, %xmm3
328 ; AVX-NEXT:    vpsraw $1, %xmm3, %xmm4
329 ; AVX-NEXT:    vpaddw %xmm2, %xmm2, %xmm2
330 ; AVX-NEXT:    vpblendvb %xmm2, %xmm4, %xmm3, %xmm2
331 ; AVX-NEXT:    vpsrlw $8, %xmm2, %xmm2
332 ; AVX-NEXT:    vpunpcklbw {{.*#+}} xmm1 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3],xmm0[4],xmm1[4],xmm0[5],xmm1[5],xmm0[6],xmm1[6],xmm0[7],xmm1[7]
333 ; AVX-NEXT:    vpunpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
334 ; AVX-NEXT:    vpsraw $4, %xmm0, %xmm3
335 ; AVX-NEXT:    vpblendvb %xmm1, %xmm3, %xmm0, %xmm0
336 ; AVX-NEXT:    vpsraw $2, %xmm0, %xmm3
337 ; AVX-NEXT:    vpaddw %xmm1, %xmm1, %xmm1
338 ; AVX-NEXT:    vpblendvb %xmm1, %xmm3, %xmm0, %xmm0
339 ; AVX-NEXT:    vpsraw $1, %xmm0, %xmm3
340 ; AVX-NEXT:    vpaddw %xmm1, %xmm1, %xmm1
341 ; AVX-NEXT:    vpblendvb %xmm1, %xmm3, %xmm0, %xmm0
342 ; AVX-NEXT:    vpsrlw $8, %xmm0, %xmm0
343 ; AVX-NEXT:    vpackuswb %xmm2, %xmm0, %xmm0
344 ; AVX-NEXT:    retq
345   %shift = ashr <16 x i8> %a, %b
346   ret <16 x i8> %shift
347 }
348
349 ;
350 ; Uniform Variable Shifts
351 ;
352
353 define <2 x i64> @splatvar_shift_v2i64(<2 x i64> %a, <2 x i64> %b) {
354 ; SSE2-LABEL: splatvar_shift_v2i64:
355 ; SSE2:       # BB#0:
356 ; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm1[0,1,0,1]
357 ; SSE2-NEXT:    movd %xmm0, %rax
358 ; SSE2-NEXT:    movd %xmm2, %rcx
359 ; SSE2-NEXT:    sarq %cl, %rax
360 ; SSE2-NEXT:    movd %rax, %xmm1
361 ; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
362 ; SSE2-NEXT:    movd %xmm0, %rax
363 ; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[2,3,0,1]
364 ; SSE2-NEXT:    movd %xmm0, %rcx
365 ; SSE2-NEXT:    sarq %cl, %rax
366 ; SSE2-NEXT:    movd %rax, %xmm0
367 ; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm0[0]
368 ; SSE2-NEXT:    movdqa %xmm1, %xmm0
369 ; SSE2-NEXT:    retq
370 ;
371 ; SSE41-LABEL: splatvar_shift_v2i64:
372 ; SSE41:       # BB#0:
373 ; SSE41-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,1,0,1]
374 ; SSE41-NEXT:    pextrq $1, %xmm0, %rax
375 ; SSE41-NEXT:    pextrq $1, %xmm1, %rcx
376 ; SSE41-NEXT:    sarq %cl, %rax
377 ; SSE41-NEXT:    movd %rax, %xmm2
378 ; SSE41-NEXT:    movd %xmm0, %rax
379 ; SSE41-NEXT:    movd %xmm1, %rcx
380 ; SSE41-NEXT:    sarq %cl, %rax
381 ; SSE41-NEXT:    movd %rax, %xmm0
382 ; SSE41-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm2[0]
383 ; SSE41-NEXT:    retq
384 ;
385 ; AVX1-LABEL: splatvar_shift_v2i64:
386 ; AVX1:       # BB#0:
387 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm1 = xmm1[0,1,0,1]
388 ; AVX1-NEXT:    vpextrq $1, %xmm0, %rax
389 ; AVX1-NEXT:    vpextrq $1, %xmm1, %rcx
390 ; AVX1-NEXT:    sarq %cl, %rax
391 ; AVX1-NEXT:    vmovq %rax, %xmm2
392 ; AVX1-NEXT:    vmovq %xmm0, %rax
393 ; AVX1-NEXT:    vmovq %xmm1, %rcx
394 ; AVX1-NEXT:    sarq %cl, %rax
395 ; AVX1-NEXT:    vmovq %rax, %xmm0
396 ; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm2[0]
397 ; AVX1-NEXT:    retq
398 ;
399 ; AVX2-LABEL: splatvar_shift_v2i64:
400 ; AVX2:       # BB#0:
401 ; AVX2-NEXT:    vpbroadcastq %xmm1, %xmm1
402 ; AVX2-NEXT:    vpextrq $1, %xmm0, %rax
403 ; AVX2-NEXT:    vpextrq $1, %xmm1, %rcx
404 ; AVX2-NEXT:    sarq %cl, %rax
405 ; AVX2-NEXT:    vmovq %rax, %xmm2
406 ; AVX2-NEXT:    vmovq %xmm0, %rax
407 ; AVX2-NEXT:    vmovq %xmm1, %rcx
408 ; AVX2-NEXT:    sarq %cl, %rax
409 ; AVX2-NEXT:    vmovq %rax, %xmm0
410 ; AVX2-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm2[0]
411 ; AVX2-NEXT:    retq
412   %splat = shufflevector <2 x i64> %b, <2 x i64> undef, <2 x i32> zeroinitializer
413   %shift = ashr <2 x i64> %a, %splat
414   ret <2 x i64> %shift
415 }
416
417 define <4 x i32> @splatvar_shift_v4i32(<4 x i32> %a, <4 x i32> %b) {
418 ; SSE2-LABEL: splatvar_shift_v4i32:
419 ; SSE2:       # BB#0:
420 ; SSE2-NEXT:    xorps %xmm2, %xmm2
421 ; SSE2-NEXT:    movss {{.*#+}} xmm2 = xmm1[0],xmm2[1,2,3]
422 ; SSE2-NEXT:    psrad %xmm2, %xmm0
423 ; SSE2-NEXT:    retq
424 ;
425 ; SSE41-LABEL: splatvar_shift_v4i32:
426 ; SSE41:       # BB#0:
427 ; SSE41-NEXT:    pxor %xmm2, %xmm2
428 ; SSE41-NEXT:    pblendw {{.*#+}} xmm2 = xmm1[0,1],xmm2[2,3,4,5,6,7]
429 ; SSE41-NEXT:    psrad %xmm2, %xmm0
430 ; SSE41-NEXT:    retq
431 ;
432 ; AVX-LABEL: splatvar_shift_v4i32:
433 ; AVX:       # BB#0:
434 ; AVX-NEXT:    vpxor %xmm2, %xmm2, %xmm2
435 ; AVX-NEXT:    vpblendw {{.*#+}} xmm1 = xmm1[0,1],xmm2[2,3,4,5,6,7]
436 ; AVX-NEXT:    vpsrad %xmm1, %xmm0, %xmm0
437 ; AVX-NEXT:    retq
438   %splat = shufflevector <4 x i32> %b, <4 x i32> undef, <4 x i32> zeroinitializer
439   %shift = ashr <4 x i32> %a, %splat
440   ret <4 x i32> %shift
441 }
442
443 define <8 x i16> @splatvar_shift_v8i16(<8 x i16> %a, <8 x i16> %b) {
444 ; SSE2-LABEL: splatvar_shift_v8i16:
445 ; SSE2:       # BB#0:
446 ; SSE2-NEXT:    movd %xmm1, %eax
447 ; SSE2-NEXT:    movzwl %ax, %eax
448 ; SSE2-NEXT:    movd %eax, %xmm1
449 ; SSE2-NEXT:    psraw %xmm1, %xmm0
450 ; SSE2-NEXT:    retq
451 ;
452 ; SSE41-LABEL: splatvar_shift_v8i16:
453 ; SSE41:       # BB#0:
454 ; SSE41-NEXT:    pxor %xmm2, %xmm2
455 ; SSE41-NEXT:    pblendw {{.*#+}} xmm2 = xmm1[0],xmm2[1,2,3,4,5,6,7]
456 ; SSE41-NEXT:    psraw %xmm2, %xmm0
457 ; SSE41-NEXT:    retq
458 ;
459 ; AVX-LABEL: splatvar_shift_v8i16:
460 ; AVX:       # BB#0:
461 ; AVX-NEXT:    vpxor %xmm2, %xmm2, %xmm2
462 ; AVX-NEXT:    vpblendw {{.*#+}} xmm1 = xmm1[0],xmm2[1,2,3,4,5,6,7]
463 ; AVX-NEXT:    vpsraw %xmm1, %xmm0, %xmm0
464 ; AVX-NEXT:    retq
465   %splat = shufflevector <8 x i16> %b, <8 x i16> undef, <8 x i32> zeroinitializer
466   %shift = ashr <8 x i16> %a, %splat
467   ret <8 x i16> %shift
468 }
469
470 define <16 x i8> @splatvar_shift_v16i8(<16 x i8> %a, <16 x i8> %b) {
471 ; SSE2-LABEL: splatvar_shift_v16i8:
472 ; SSE2:       # BB#0:
473 ; SSE2-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
474 ; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,1,0,3]
475 ; SSE2-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,0,0,0,4,5,6,7]
476 ; SSE2-NEXT:    pshufhw {{.*#+}} xmm3 = xmm1[0,1,2,3,4,4,4,4]
477 ; SSE2-NEXT:    punpckhbw {{.*#+}} xmm1 = xmm1[8],xmm0[8],xmm1[9],xmm0[9],xmm1[10],xmm0[10],xmm1[11],xmm0[11],xmm1[12],xmm0[12],xmm1[13],xmm0[13],xmm1[14],xmm0[14],xmm1[15],xmm0[15]
478 ; SSE2-NEXT:    psllw $5, %xmm3
479 ; SSE2-NEXT:    punpckhbw {{.*#+}} xmm4 = xmm4[8],xmm3[8],xmm4[9],xmm3[9],xmm4[10],xmm3[10],xmm4[11],xmm3[11],xmm4[12],xmm3[12],xmm4[13],xmm3[13],xmm4[14],xmm3[14],xmm4[15],xmm3[15]
480 ; SSE2-NEXT:    pxor %xmm2, %xmm2
481 ; SSE2-NEXT:    pxor %xmm5, %xmm5
482 ; SSE2-NEXT:    pcmpgtw %xmm4, %xmm5
483 ; SSE2-NEXT:    movdqa %xmm5, %xmm6
484 ; SSE2-NEXT:    pandn %xmm1, %xmm6
485 ; SSE2-NEXT:    psraw $4, %xmm1
486 ; SSE2-NEXT:    pand %xmm5, %xmm1
487 ; SSE2-NEXT:    por %xmm6, %xmm1
488 ; SSE2-NEXT:    paddw %xmm4, %xmm4
489 ; SSE2-NEXT:    pxor %xmm5, %xmm5
490 ; SSE2-NEXT:    pcmpgtw %xmm4, %xmm5
491 ; SSE2-NEXT:    movdqa %xmm5, %xmm6
492 ; SSE2-NEXT:    pandn %xmm1, %xmm6
493 ; SSE2-NEXT:    psraw $2, %xmm1
494 ; SSE2-NEXT:    pand %xmm5, %xmm1
495 ; SSE2-NEXT:    por %xmm6, %xmm1
496 ; SSE2-NEXT:    paddw %xmm4, %xmm4
497 ; SSE2-NEXT:    pxor %xmm5, %xmm5
498 ; SSE2-NEXT:    pcmpgtw %xmm4, %xmm5
499 ; SSE2-NEXT:    movdqa %xmm5, %xmm4
500 ; SSE2-NEXT:    pandn %xmm1, %xmm4
501 ; SSE2-NEXT:    psraw $1, %xmm1
502 ; SSE2-NEXT:    pand %xmm5, %xmm1
503 ; SSE2-NEXT:    por %xmm4, %xmm1
504 ; SSE2-NEXT:    psrlw $8, %xmm1
505 ; SSE2-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
506 ; SSE2-NEXT:    punpcklbw {{.*#+}} xmm3 = xmm3[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
507 ; SSE2-NEXT:    pxor %xmm4, %xmm4
508 ; SSE2-NEXT:    pcmpgtw %xmm3, %xmm4
509 ; SSE2-NEXT:    movdqa %xmm4, %xmm5
510 ; SSE2-NEXT:    pandn %xmm0, %xmm5
511 ; SSE2-NEXT:    psraw $4, %xmm0
512 ; SSE2-NEXT:    pand %xmm4, %xmm0
513 ; SSE2-NEXT:    por %xmm5, %xmm0
514 ; SSE2-NEXT:    paddw %xmm3, %xmm3
515 ; SSE2-NEXT:    pxor %xmm4, %xmm4
516 ; SSE2-NEXT:    pcmpgtw %xmm3, %xmm4
517 ; SSE2-NEXT:    movdqa %xmm4, %xmm5
518 ; SSE2-NEXT:    pandn %xmm0, %xmm5
519 ; SSE2-NEXT:    psraw $2, %xmm0
520 ; SSE2-NEXT:    pand %xmm4, %xmm0
521 ; SSE2-NEXT:    por %xmm5, %xmm0
522 ; SSE2-NEXT:    paddw %xmm3, %xmm3
523 ; SSE2-NEXT:    pcmpgtw %xmm3, %xmm2
524 ; SSE2-NEXT:    movdqa %xmm2, %xmm3
525 ; SSE2-NEXT:    pandn %xmm0, %xmm3
526 ; SSE2-NEXT:    psraw $1, %xmm0
527 ; SSE2-NEXT:    pand %xmm2, %xmm0
528 ; SSE2-NEXT:    por %xmm3, %xmm0
529 ; SSE2-NEXT:    psrlw $8, %xmm0
530 ; SSE2-NEXT:    packuswb %xmm1, %xmm0
531 ; SSE2-NEXT:    retq
532 ;
533 ; SSE41-LABEL: splatvar_shift_v16i8:
534 ; SSE41:       # BB#0:
535 ; SSE41-NEXT:    movdqa %xmm0, %xmm2
536 ; SSE41-NEXT:    pxor %xmm0, %xmm0
537 ; SSE41-NEXT:    pshufb %xmm0, %xmm1
538 ; SSE41-NEXT:    psllw $5, %xmm1
539 ; SSE41-NEXT:    punpckhbw {{.*#+}} xmm0 = xmm0[8],xmm1[8],xmm0[9],xmm1[9],xmm0[10],xmm1[10],xmm0[11],xmm1[11],xmm0[12],xmm1[12],xmm0[13],xmm1[13],xmm0[14],xmm1[14],xmm0[15],xmm1[15]
540 ; SSE41-NEXT:    punpckhbw {{.*#+}} xmm3 = xmm3[8],xmm2[8],xmm3[9],xmm2[9],xmm3[10],xmm2[10],xmm3[11],xmm2[11],xmm3[12],xmm2[12],xmm3[13],xmm2[13],xmm3[14],xmm2[14],xmm3[15],xmm2[15]
541 ; SSE41-NEXT:    movdqa %xmm3, %xmm4
542 ; SSE41-NEXT:    psraw $4, %xmm4
543 ; SSE41-NEXT:    pblendvb %xmm4, %xmm3
544 ; SSE41-NEXT:    movdqa %xmm3, %xmm4
545 ; SSE41-NEXT:    psraw $2, %xmm4
546 ; SSE41-NEXT:    paddw %xmm0, %xmm0
547 ; SSE41-NEXT:    pblendvb %xmm4, %xmm3
548 ; SSE41-NEXT:    movdqa %xmm3, %xmm4
549 ; SSE41-NEXT:    psraw $1, %xmm4
550 ; SSE41-NEXT:    paddw %xmm0, %xmm0
551 ; SSE41-NEXT:    pblendvb %xmm4, %xmm3
552 ; SSE41-NEXT:    psrlw $8, %xmm3
553 ; SSE41-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3],xmm0[4],xmm1[4],xmm0[5],xmm1[5],xmm0[6],xmm1[6],xmm0[7],xmm1[7]
554 ; SSE41-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1],xmm1[2],xmm2[2],xmm1[3],xmm2[3],xmm1[4],xmm2[4],xmm1[5],xmm2[5],xmm1[6],xmm2[6],xmm1[7],xmm2[7]
555 ; SSE41-NEXT:    movdqa %xmm1, %xmm2
556 ; SSE41-NEXT:    psraw $4, %xmm2
557 ; SSE41-NEXT:    pblendvb %xmm2, %xmm1
558 ; SSE41-NEXT:    movdqa %xmm1, %xmm2
559 ; SSE41-NEXT:    psraw $2, %xmm2
560 ; SSE41-NEXT:    paddw %xmm0, %xmm0
561 ; SSE41-NEXT:    pblendvb %xmm2, %xmm1
562 ; SSE41-NEXT:    movdqa %xmm1, %xmm2
563 ; SSE41-NEXT:    psraw $1, %xmm2
564 ; SSE41-NEXT:    paddw %xmm0, %xmm0
565 ; SSE41-NEXT:    pblendvb %xmm2, %xmm1
566 ; SSE41-NEXT:    psrlw $8, %xmm1
567 ; SSE41-NEXT:    packuswb %xmm3, %xmm1
568 ; SSE41-NEXT:    movdqa %xmm1, %xmm0
569 ; SSE41-NEXT:    retq
570 ;
571 ; AVX1-LABEL: splatvar_shift_v16i8:
572 ; AVX1:       # BB#0:
573 ; AVX1-NEXT:    vpxor %xmm2, %xmm2, %xmm2
574 ; AVX1-NEXT:    vpshufb %xmm2, %xmm1, %xmm1
575 ; AVX1-NEXT:    vpsllw $5, %xmm1, %xmm1
576 ; AVX1-NEXT:    vpunpckhbw {{.*#+}} xmm2 = xmm0[8],xmm1[8],xmm0[9],xmm1[9],xmm0[10],xmm1[10],xmm0[11],xmm1[11],xmm0[12],xmm1[12],xmm0[13],xmm1[13],xmm0[14],xmm1[14],xmm0[15],xmm1[15]
577 ; AVX1-NEXT:    vpunpckhbw {{.*#+}} xmm3 = xmm0[8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15]
578 ; AVX1-NEXT:    vpsraw $4, %xmm3, %xmm4
579 ; AVX1-NEXT:    vpblendvb %xmm2, %xmm4, %xmm3, %xmm3
580 ; AVX1-NEXT:    vpsraw $2, %xmm3, %xmm4
581 ; AVX1-NEXT:    vpaddw %xmm2, %xmm2, %xmm2
582 ; AVX1-NEXT:    vpblendvb %xmm2, %xmm4, %xmm3, %xmm3
583 ; AVX1-NEXT:    vpsraw $1, %xmm3, %xmm4
584 ; AVX1-NEXT:    vpaddw %xmm2, %xmm2, %xmm2
585 ; AVX1-NEXT:    vpblendvb %xmm2, %xmm4, %xmm3, %xmm2
586 ; AVX1-NEXT:    vpsrlw $8, %xmm2, %xmm2
587 ; AVX1-NEXT:    vpunpcklbw {{.*#+}} xmm1 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3],xmm0[4],xmm1[4],xmm0[5],xmm1[5],xmm0[6],xmm1[6],xmm0[7],xmm1[7]
588 ; AVX1-NEXT:    vpunpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
589 ; AVX1-NEXT:    vpsraw $4, %xmm0, %xmm3
590 ; AVX1-NEXT:    vpblendvb %xmm1, %xmm3, %xmm0, %xmm0
591 ; AVX1-NEXT:    vpsraw $2, %xmm0, %xmm3
592 ; AVX1-NEXT:    vpaddw %xmm1, %xmm1, %xmm1
593 ; AVX1-NEXT:    vpblendvb %xmm1, %xmm3, %xmm0, %xmm0
594 ; AVX1-NEXT:    vpsraw $1, %xmm0, %xmm3
595 ; AVX1-NEXT:    vpaddw %xmm1, %xmm1, %xmm1
596 ; AVX1-NEXT:    vpblendvb %xmm1, %xmm3, %xmm0, %xmm0
597 ; AVX1-NEXT:    vpsrlw $8, %xmm0, %xmm0
598 ; AVX1-NEXT:    vpackuswb %xmm2, %xmm0, %xmm0
599 ; AVX1-NEXT:    retq
600 ;
601 ; AVX2-LABEL: splatvar_shift_v16i8:
602 ; AVX2:       # BB#0:
603 ; AVX2-NEXT:    vpbroadcastb %xmm1, %xmm1
604 ; AVX2-NEXT:    vpsllw $5, %xmm1, %xmm1
605 ; AVX2-NEXT:    vpunpckhbw {{.*#+}} xmm2 = xmm0[8],xmm1[8],xmm0[9],xmm1[9],xmm0[10],xmm1[10],xmm0[11],xmm1[11],xmm0[12],xmm1[12],xmm0[13],xmm1[13],xmm0[14],xmm1[14],xmm0[15],xmm1[15]
606 ; AVX2-NEXT:    vpunpckhbw {{.*#+}} xmm3 = xmm0[8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15]
607 ; AVX2-NEXT:    vpsraw $4, %xmm3, %xmm4
608 ; AVX2-NEXT:    vpblendvb %xmm2, %xmm4, %xmm3, %xmm3
609 ; AVX2-NEXT:    vpsraw $2, %xmm3, %xmm4
610 ; AVX2-NEXT:    vpaddw %xmm2, %xmm2, %xmm2
611 ; AVX2-NEXT:    vpblendvb %xmm2, %xmm4, %xmm3, %xmm3
612 ; AVX2-NEXT:    vpsraw $1, %xmm3, %xmm4
613 ; AVX2-NEXT:    vpaddw %xmm2, %xmm2, %xmm2
614 ; AVX2-NEXT:    vpblendvb %xmm2, %xmm4, %xmm3, %xmm2
615 ; AVX2-NEXT:    vpsrlw $8, %xmm2, %xmm2
616 ; AVX2-NEXT:    vpunpcklbw {{.*#+}} xmm1 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3],xmm0[4],xmm1[4],xmm0[5],xmm1[5],xmm0[6],xmm1[6],xmm0[7],xmm1[7]
617 ; AVX2-NEXT:    vpunpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
618 ; AVX2-NEXT:    vpsraw $4, %xmm0, %xmm3
619 ; AVX2-NEXT:    vpblendvb %xmm1, %xmm3, %xmm0, %xmm0
620 ; AVX2-NEXT:    vpsraw $2, %xmm0, %xmm3
621 ; AVX2-NEXT:    vpaddw %xmm1, %xmm1, %xmm1
622 ; AVX2-NEXT:    vpblendvb %xmm1, %xmm3, %xmm0, %xmm0
623 ; AVX2-NEXT:    vpsraw $1, %xmm0, %xmm3
624 ; AVX2-NEXT:    vpaddw %xmm1, %xmm1, %xmm1
625 ; AVX2-NEXT:    vpblendvb %xmm1, %xmm3, %xmm0, %xmm0
626 ; AVX2-NEXT:    vpsrlw $8, %xmm0, %xmm0
627 ; AVX2-NEXT:    vpackuswb %xmm2, %xmm0, %xmm0
628 ; AVX2-NEXT:    retq
629   %splat = shufflevector <16 x i8> %b, <16 x i8> undef, <16 x i32> zeroinitializer
630   %shift = ashr <16 x i8> %a, %splat
631   ret <16 x i8> %shift
632 }
633
634 ;
635 ; Constant Shifts
636 ;
637
638 define <2 x i64> @constant_shift_v2i64(<2 x i64> %a) {
639 ; SSE2-LABEL: constant_shift_v2i64:
640 ; SSE2:       # BB#0:
641 ; SSE2-NEXT:    movd %xmm0, %rax
642 ; SSE2-NEXT:    sarq %rax
643 ; SSE2-NEXT:    movd %rax, %xmm1
644 ; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
645 ; SSE2-NEXT:    movd %xmm0, %rax
646 ; SSE2-NEXT:    sarq $7, %rax
647 ; SSE2-NEXT:    movd %rax, %xmm0
648 ; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm0[0]
649 ; SSE2-NEXT:    movdqa %xmm1, %xmm0
650 ; SSE2-NEXT:    retq
651 ;
652 ; SSE41-LABEL: constant_shift_v2i64:
653 ; SSE41:       # BB#0:
654 ; SSE41-NEXT:    pextrq $1, %xmm0, %rax
655 ; SSE41-NEXT:    sarq $7, %rax
656 ; SSE41-NEXT:    movd %rax, %xmm1
657 ; SSE41-NEXT:    movd %xmm0, %rax
658 ; SSE41-NEXT:    sarq %rax
659 ; SSE41-NEXT:    movd %rax, %xmm0
660 ; SSE41-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
661 ; SSE41-NEXT:    retq
662 ;
663 ; AVX-LABEL: constant_shift_v2i64:
664 ; AVX:       # BB#0:
665 ; AVX-NEXT:    vpextrq $1, %xmm0, %rax
666 ; AVX-NEXT:    sarq $7, %rax
667 ; AVX-NEXT:    vmovq %rax, %xmm1
668 ; AVX-NEXT:    vmovq %xmm0, %rax
669 ; AVX-NEXT:    sarq %rax
670 ; AVX-NEXT:    vmovq %rax, %xmm0
671 ; AVX-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
672 ; AVX-NEXT:    retq
673   %shift = ashr <2 x i64> %a, <i64 1, i64 7>
674   ret <2 x i64> %shift
675 }
676
677 define <4 x i32> @constant_shift_v4i32(<4 x i32> %a) {
678 ; SSE2-LABEL: constant_shift_v4i32:
679 ; SSE2:       # BB#0:
680 ; SSE2-NEXT:    movdqa %xmm0, %xmm1
681 ; SSE2-NEXT:    psrad $7, %xmm1
682 ; SSE2-NEXT:    movdqa %xmm0, %xmm2
683 ; SSE2-NEXT:    psrad $5, %xmm2
684 ; SSE2-NEXT:    movsd {{.*#+}} xmm1 = xmm2[0],xmm1[1]
685 ; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[1,3,2,3]
686 ; SSE2-NEXT:    movdqa %xmm0, %xmm2
687 ; SSE2-NEXT:    psrad $6, %xmm2
688 ; SSE2-NEXT:    psrad $4, %xmm0
689 ; SSE2-NEXT:    movsd {{.*#+}} xmm2 = xmm0[0],xmm2[1]
690 ; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3]
691 ; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
692 ; SSE2-NEXT:    retq
693 ;
694 ; SSE41-LABEL: constant_shift_v4i32:
695 ; SSE41:       # BB#0:
696 ; SSE41-NEXT:    movdqa %xmm0, %xmm1
697 ; SSE41-NEXT:    psrad $7, %xmm1
698 ; SSE41-NEXT:    movdqa %xmm0, %xmm2
699 ; SSE41-NEXT:    psrad $5, %xmm2
700 ; SSE41-NEXT:    pblendw {{.*#+}} xmm2 = xmm2[0,1,2,3],xmm1[4,5,6,7]
701 ; SSE41-NEXT:    movdqa %xmm0, %xmm1
702 ; SSE41-NEXT:    psrad $6, %xmm1
703 ; SSE41-NEXT:    psrad $4, %xmm0
704 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5,6,7]
705 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7]
706 ; SSE41-NEXT:    retq
707 ;
708 ; AVX1-LABEL: constant_shift_v4i32:
709 ; AVX1:       # BB#0:
710 ; AVX1-NEXT:    vpsrad $7, %xmm0, %xmm1
711 ; AVX1-NEXT:    vpsrad $5, %xmm0, %xmm2
712 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm1 = xmm2[0,1,2,3],xmm1[4,5,6,7]
713 ; AVX1-NEXT:    vpsrad $6, %xmm0, %xmm2
714 ; AVX1-NEXT:    vpsrad $4, %xmm0, %xmm0
715 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm2[4,5,6,7]
716 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7]
717 ; AVX1-NEXT:    retq
718 ;
719 ; AVX2-LABEL: constant_shift_v4i32:
720 ; AVX2:       # BB#0:
721 ; AVX2-NEXT:    vpsravd {{.*}}(%rip), %xmm0, %xmm0
722 ; AVX2-NEXT:    retq
723   %shift = ashr <4 x i32> %a, <i32 4, i32 5, i32 6, i32 7>
724   ret <4 x i32> %shift
725 }
726
727 define <8 x i16> @constant_shift_v8i16(<8 x i16> %a) {
728 ; SSE2-LABEL: constant_shift_v8i16:
729 ; SSE2:       # BB#0:
730 ; SSE2-NEXT:    movdqa %xmm0, %xmm1
731 ; SSE2-NEXT:    psraw $4, %xmm1
732 ; SSE2-NEXT:    movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1]
733 ; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm1[0,2,2,3]
734 ; SSE2-NEXT:    psraw $2, %xmm1
735 ; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,3,2,3]
736 ; SSE2-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1]
737 ; SSE2-NEXT:    movdqa {{.*#+}} xmm0 = [65535,0,65535,0,65535,0,65535,0]
738 ; SSE2-NEXT:    movdqa %xmm2, %xmm1
739 ; SSE2-NEXT:    pand %xmm0, %xmm1
740 ; SSE2-NEXT:    psraw $1, %xmm2
741 ; SSE2-NEXT:    pandn %xmm2, %xmm0
742 ; SSE2-NEXT:    por %xmm1, %xmm0
743 ; SSE2-NEXT:    retq
744 ;
745 ; SSE41-LABEL: constant_shift_v8i16:
746 ; SSE41:       # BB#0:
747 ; SSE41-NEXT:    movdqa %xmm0, %xmm1
748 ; SSE41-NEXT:    movdqa %xmm1, %xmm2
749 ; SSE41-NEXT:    psraw $8, %xmm2
750 ; SSE41-NEXT:    movaps {{.*#+}} xmm0 = [0,4112,8224,12336,16448,20560,24672,28784]
751 ; SSE41-NEXT:    pblendvb %xmm2, %xmm1
752 ; SSE41-NEXT:    movdqa %xmm1, %xmm2
753 ; SSE41-NEXT:    psraw $4, %xmm2
754 ; SSE41-NEXT:    movaps {{.*#+}} xmm0 = [0,8224,16448,24672,32896,41120,49344,57568]
755 ; SSE41-NEXT:    pblendvb %xmm2, %xmm1
756 ; SSE41-NEXT:    movdqa %xmm1, %xmm2
757 ; SSE41-NEXT:    psraw $2, %xmm2
758 ; SSE41-NEXT:    movaps {{.*#+}} xmm0 = [0,16448,32896,49344,256,16704,33152,49600]
759 ; SSE41-NEXT:    pblendvb %xmm2, %xmm1
760 ; SSE41-NEXT:    movdqa %xmm1, %xmm2
761 ; SSE41-NEXT:    psraw $1, %xmm2
762 ; SSE41-NEXT:    movaps {{.*#+}} xmm0 = [0,32896,256,33152,512,33408,768,33664]
763 ; SSE41-NEXT:    pblendvb %xmm2, %xmm1
764 ; SSE41-NEXT:    movdqa %xmm1, %xmm0
765 ; SSE41-NEXT:    retq
766 ;
767 ; AVX1-LABEL: constant_shift_v8i16:
768 ; AVX1:       # BB#0:
769 ; AVX1-NEXT:    vpsraw $8, %xmm0, %xmm1
770 ; AVX1-NEXT:    vmovdqa {{.*#+}} xmm2 = [0,4112,8224,12336,16448,20560,24672,28784]
771 ; AVX1-NEXT:    vpblendvb %xmm2, %xmm1, %xmm0, %xmm0
772 ; AVX1-NEXT:    vpsraw $4, %xmm0, %xmm1
773 ; AVX1-NEXT:    vmovdqa {{.*#+}} xmm2 = [0,8224,16448,24672,32896,41120,49344,57568]
774 ; AVX1-NEXT:    vpblendvb %xmm2, %xmm1, %xmm0, %xmm0
775 ; AVX1-NEXT:    vpsraw $2, %xmm0, %xmm1
776 ; AVX1-NEXT:    vmovdqa {{.*#+}} xmm2 = [0,16448,32896,49344,256,16704,33152,49600]
777 ; AVX1-NEXT:    vpblendvb %xmm2, %xmm1, %xmm0, %xmm0
778 ; AVX1-NEXT:    vpsraw $1, %xmm0, %xmm1
779 ; AVX1-NEXT:    vmovdqa {{.*#+}} xmm2 = [0,32896,256,33152,512,33408,768,33664]
780 ; AVX1-NEXT:    vpblendvb %xmm2, %xmm1, %xmm0, %xmm0
781 ; AVX1-NEXT:    retq
782 ;
783 ; AVX2-LABEL: constant_shift_v8i16:
784 ; AVX2:       # BB#0:
785 ; AVX2-NEXT:    vpmovsxwd %xmm0, %ymm0
786 ; 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
787 ; AVX2-NEXT:    vpsravd %ymm1, %ymm0, %ymm0
788 ; 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
789 ; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
790 ; AVX2-NEXT:    vzeroupper
791 ; AVX2-NEXT:    retq
792   %shift = ashr <8 x i16> %a, <i16 0, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7>
793   ret <8 x i16> %shift
794 }
795
796 define <16 x i8> @constant_shift_v16i8(<16 x i8> %a) {
797 ; SSE2-LABEL: constant_shift_v16i8:
798 ; SSE2:       # BB#0:
799 ; SSE2-NEXT:    punpckhbw {{.*#+}} xmm1 = xmm1[8],xmm0[8],xmm1[9],xmm0[9],xmm1[10],xmm0[10],xmm1[11],xmm0[11],xmm1[12],xmm0[12],xmm1[13],xmm0[13],xmm1[14],xmm0[14],xmm1[15],xmm0[15]
800 ; SSE2-NEXT:    movdqa {{.*#+}} xmm3 = [0,1,2,3,4,5,6,7,7,6,5,4,3,2,1,0]
801 ; SSE2-NEXT:    psllw $5, %xmm3
802 ; SSE2-NEXT:    punpckhbw {{.*#+}} xmm4 = xmm4[8],xmm3[8],xmm4[9],xmm3[9],xmm4[10],xmm3[10],xmm4[11],xmm3[11],xmm4[12],xmm3[12],xmm4[13],xmm3[13],xmm4[14],xmm3[14],xmm4[15],xmm3[15]
803 ; SSE2-NEXT:    pxor %xmm2, %xmm2
804 ; SSE2-NEXT:    pxor %xmm5, %xmm5
805 ; SSE2-NEXT:    pcmpgtw %xmm4, %xmm5
806 ; SSE2-NEXT:    movdqa %xmm5, %xmm6
807 ; SSE2-NEXT:    pandn %xmm1, %xmm6
808 ; SSE2-NEXT:    psraw $4, %xmm1
809 ; SSE2-NEXT:    pand %xmm5, %xmm1
810 ; SSE2-NEXT:    por %xmm6, %xmm1
811 ; SSE2-NEXT:    paddw %xmm4, %xmm4
812 ; SSE2-NEXT:    pxor %xmm5, %xmm5
813 ; SSE2-NEXT:    pcmpgtw %xmm4, %xmm5
814 ; SSE2-NEXT:    movdqa %xmm5, %xmm6
815 ; SSE2-NEXT:    pandn %xmm1, %xmm6
816 ; SSE2-NEXT:    psraw $2, %xmm1
817 ; SSE2-NEXT:    pand %xmm5, %xmm1
818 ; SSE2-NEXT:    por %xmm6, %xmm1
819 ; SSE2-NEXT:    paddw %xmm4, %xmm4
820 ; SSE2-NEXT:    pxor %xmm5, %xmm5
821 ; SSE2-NEXT:    pcmpgtw %xmm4, %xmm5
822 ; SSE2-NEXT:    movdqa %xmm5, %xmm4
823 ; SSE2-NEXT:    pandn %xmm1, %xmm4
824 ; SSE2-NEXT:    psraw $1, %xmm1
825 ; SSE2-NEXT:    pand %xmm5, %xmm1
826 ; SSE2-NEXT:    por %xmm4, %xmm1
827 ; SSE2-NEXT:    psrlw $8, %xmm1
828 ; SSE2-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
829 ; SSE2-NEXT:    punpcklbw {{.*#+}} xmm3 = xmm3[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
830 ; SSE2-NEXT:    pxor %xmm4, %xmm4
831 ; SSE2-NEXT:    pcmpgtw %xmm3, %xmm4
832 ; SSE2-NEXT:    movdqa %xmm4, %xmm5
833 ; SSE2-NEXT:    pandn %xmm0, %xmm5
834 ; SSE2-NEXT:    psraw $4, %xmm0
835 ; SSE2-NEXT:    pand %xmm4, %xmm0
836 ; SSE2-NEXT:    por %xmm5, %xmm0
837 ; SSE2-NEXT:    paddw %xmm3, %xmm3
838 ; SSE2-NEXT:    pxor %xmm4, %xmm4
839 ; SSE2-NEXT:    pcmpgtw %xmm3, %xmm4
840 ; SSE2-NEXT:    movdqa %xmm4, %xmm5
841 ; SSE2-NEXT:    pandn %xmm0, %xmm5
842 ; SSE2-NEXT:    psraw $2, %xmm0
843 ; SSE2-NEXT:    pand %xmm4, %xmm0
844 ; SSE2-NEXT:    por %xmm5, %xmm0
845 ; SSE2-NEXT:    paddw %xmm3, %xmm3
846 ; SSE2-NEXT:    pcmpgtw %xmm3, %xmm2
847 ; SSE2-NEXT:    movdqa %xmm2, %xmm3
848 ; SSE2-NEXT:    pandn %xmm0, %xmm3
849 ; SSE2-NEXT:    psraw $1, %xmm0
850 ; SSE2-NEXT:    pand %xmm2, %xmm0
851 ; SSE2-NEXT:    por %xmm3, %xmm0
852 ; SSE2-NEXT:    psrlw $8, %xmm0
853 ; SSE2-NEXT:    packuswb %xmm1, %xmm0
854 ; SSE2-NEXT:    retq
855 ;
856 ; SSE41-LABEL: constant_shift_v16i8:
857 ; SSE41:       # BB#0:
858 ; SSE41-NEXT:    movdqa %xmm0, %xmm1
859 ; SSE41-NEXT:    movdqa {{.*#+}} xmm3 = [0,1,2,3,4,5,6,7,7,6,5,4,3,2,1,0]
860 ; SSE41-NEXT:    psllw $5, %xmm3
861 ; SSE41-NEXT:    punpckhbw {{.*#+}} xmm0 = xmm0[8],xmm3[8],xmm0[9],xmm3[9],xmm0[10],xmm3[10],xmm0[11],xmm3[11],xmm0[12],xmm3[12],xmm0[13],xmm3[13],xmm0[14],xmm3[14],xmm0[15],xmm3[15]
862 ; SSE41-NEXT:    punpckhbw {{.*#+}} xmm2 = xmm2[8],xmm1[8],xmm2[9],xmm1[9],xmm2[10],xmm1[10],xmm2[11],xmm1[11],xmm2[12],xmm1[12],xmm2[13],xmm1[13],xmm2[14],xmm1[14],xmm2[15],xmm1[15]
863 ; SSE41-NEXT:    movdqa %xmm2, %xmm4
864 ; SSE41-NEXT:    psraw $4, %xmm4
865 ; SSE41-NEXT:    pblendvb %xmm4, %xmm2
866 ; SSE41-NEXT:    movdqa %xmm2, %xmm4
867 ; SSE41-NEXT:    psraw $2, %xmm4
868 ; SSE41-NEXT:    paddw %xmm0, %xmm0
869 ; SSE41-NEXT:    pblendvb %xmm4, %xmm2
870 ; SSE41-NEXT:    movdqa %xmm2, %xmm4
871 ; SSE41-NEXT:    psraw $1, %xmm4
872 ; SSE41-NEXT:    paddw %xmm0, %xmm0
873 ; SSE41-NEXT:    pblendvb %xmm4, %xmm2
874 ; SSE41-NEXT:    psrlw $8, %xmm2
875 ; SSE41-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1],xmm0[2],xmm3[2],xmm0[3],xmm3[3],xmm0[4],xmm3[4],xmm0[5],xmm3[5],xmm0[6],xmm3[6],xmm0[7],xmm3[7]
876 ; SSE41-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
877 ; SSE41-NEXT:    movdqa %xmm1, %xmm3
878 ; SSE41-NEXT:    psraw $4, %xmm3
879 ; SSE41-NEXT:    pblendvb %xmm3, %xmm1
880 ; SSE41-NEXT:    movdqa %xmm1, %xmm3
881 ; SSE41-NEXT:    psraw $2, %xmm3
882 ; SSE41-NEXT:    paddw %xmm0, %xmm0
883 ; SSE41-NEXT:    pblendvb %xmm3, %xmm1
884 ; SSE41-NEXT:    movdqa %xmm1, %xmm3
885 ; SSE41-NEXT:    psraw $1, %xmm3
886 ; SSE41-NEXT:    paddw %xmm0, %xmm0
887 ; SSE41-NEXT:    pblendvb %xmm3, %xmm1
888 ; SSE41-NEXT:    psrlw $8, %xmm1
889 ; SSE41-NEXT:    packuswb %xmm2, %xmm1
890 ; SSE41-NEXT:    movdqa %xmm1, %xmm0
891 ; SSE41-NEXT:    retq
892 ;
893 ; AVX-LABEL: constant_shift_v16i8:
894 ; AVX:       # BB#0:
895 ; AVX-NEXT:    vmovdqa {{.*#+}} xmm1 = [0,1,2,3,4,5,6,7,7,6,5,4,3,2,1,0]
896 ; AVX-NEXT:    vpsllw $5, %xmm1, %xmm1
897 ; AVX-NEXT:    vpunpckhbw {{.*#+}} xmm2 = xmm0[8],xmm1[8],xmm0[9],xmm1[9],xmm0[10],xmm1[10],xmm0[11],xmm1[11],xmm0[12],xmm1[12],xmm0[13],xmm1[13],xmm0[14],xmm1[14],xmm0[15],xmm1[15]
898 ; AVX-NEXT:    vpunpckhbw {{.*#+}} xmm3 = xmm0[8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15]
899 ; AVX-NEXT:    vpsraw $4, %xmm3, %xmm4
900 ; AVX-NEXT:    vpblendvb %xmm2, %xmm4, %xmm3, %xmm3
901 ; AVX-NEXT:    vpsraw $2, %xmm3, %xmm4
902 ; AVX-NEXT:    vpaddw %xmm2, %xmm2, %xmm2
903 ; AVX-NEXT:    vpblendvb %xmm2, %xmm4, %xmm3, %xmm3
904 ; AVX-NEXT:    vpsraw $1, %xmm3, %xmm4
905 ; AVX-NEXT:    vpaddw %xmm2, %xmm2, %xmm2
906 ; AVX-NEXT:    vpblendvb %xmm2, %xmm4, %xmm3, %xmm2
907 ; AVX-NEXT:    vpsrlw $8, %xmm2, %xmm2
908 ; AVX-NEXT:    vpunpcklbw {{.*#+}} xmm1 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3],xmm0[4],xmm1[4],xmm0[5],xmm1[5],xmm0[6],xmm1[6],xmm0[7],xmm1[7]
909 ; AVX-NEXT:    vpunpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
910 ; AVX-NEXT:    vpsraw $4, %xmm0, %xmm3
911 ; AVX-NEXT:    vpblendvb %xmm1, %xmm3, %xmm0, %xmm0
912 ; AVX-NEXT:    vpsraw $2, %xmm0, %xmm3
913 ; AVX-NEXT:    vpaddw %xmm1, %xmm1, %xmm1
914 ; AVX-NEXT:    vpblendvb %xmm1, %xmm3, %xmm0, %xmm0
915 ; AVX-NEXT:    vpsraw $1, %xmm0, %xmm3
916 ; AVX-NEXT:    vpaddw %xmm1, %xmm1, %xmm1
917 ; AVX-NEXT:    vpblendvb %xmm1, %xmm3, %xmm0, %xmm0
918 ; AVX-NEXT:    vpsrlw $8, %xmm0, %xmm0
919 ; AVX-NEXT:    vpackuswb %xmm2, %xmm0, %xmm0
920 ; AVX-NEXT:    retq
921   %shift = ashr <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>
922   ret <16 x i8> %shift
923 }
924
925 ;
926 ; Uniform Constant Shifts
927 ;
928
929 define <2 x i64> @splatconstant_shift_v2i64(<2 x i64> %a) {
930 ; SSE2-LABEL: splatconstant_shift_v2i64:
931 ; SSE2:       # BB#0:
932 ; SSE2-NEXT:    movdqa %xmm0, %xmm1
933 ; SSE2-NEXT:    psrad $7, %xmm1
934 ; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[1,3,2,3]
935 ; SSE2-NEXT:    psrlq $7, %xmm0
936 ; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
937 ; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
938 ; SSE2-NEXT:    retq
939 ;
940 ; SSE41-LABEL: splatconstant_shift_v2i64:
941 ; SSE41:       # BB#0:
942 ; SSE41-NEXT:    movdqa %xmm0, %xmm1
943 ; SSE41-NEXT:    psrad $7, %xmm1
944 ; SSE41-NEXT:    psrlq $7, %xmm0
945 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7]
946 ; SSE41-NEXT:    retq
947 ;
948 ; AVX1-LABEL: splatconstant_shift_v2i64:
949 ; AVX1:       # BB#0:
950 ; AVX1-NEXT:    vpsrad $7, %xmm0, %xmm1
951 ; AVX1-NEXT:    vpsrlq $7, %xmm0, %xmm0
952 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7]
953 ; AVX1-NEXT:    retq
954 ;
955 ; AVX2-LABEL: splatconstant_shift_v2i64:
956 ; AVX2:       # BB#0:
957 ; AVX2-NEXT:    vpsrad $7, %xmm0, %xmm1
958 ; AVX2-NEXT:    vpsrlq $7, %xmm0, %xmm0
959 ; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
960 ; AVX2-NEXT:    retq
961   %shift = ashr <2 x i64> %a, <i64 7, i64 7>
962   ret <2 x i64> %shift
963 }
964
965 define <4 x i32> @splatconstant_shift_v4i32(<4 x i32> %a) {
966 ; SSE-LABEL: splatconstant_shift_v4i32:
967 ; SSE:       # BB#0:
968 ; SSE-NEXT:    psrad $5, %xmm0
969 ; SSE-NEXT:    retq
970 ;
971 ; AVX-LABEL: splatconstant_shift_v4i32:
972 ; AVX:       # BB#0:
973 ; AVX-NEXT:    vpsrad $5, %xmm0, %xmm0
974 ; AVX-NEXT:    retq
975   %shift = ashr <4 x i32> %a, <i32 5, i32 5, i32 5, i32 5>
976   ret <4 x i32> %shift
977 }
978
979 define <8 x i16> @splatconstant_shift_v8i16(<8 x i16> %a) {
980 ; SSE-LABEL: splatconstant_shift_v8i16:
981 ; SSE:       # BB#0:
982 ; SSE-NEXT:    psraw $3, %xmm0
983 ; SSE-NEXT:    retq
984 ;
985 ; AVX-LABEL: splatconstant_shift_v8i16:
986 ; AVX:       # BB#0:
987 ; AVX-NEXT:    vpsraw $3, %xmm0, %xmm0
988 ; AVX-NEXT:    retq
989   %shift = ashr <8 x i16> %a, <i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3>
990   ret <8 x i16> %shift
991 }
992
993 define <16 x i8> @splatconstant_shift_v16i8(<16 x i8> %a) {
994 ; SSE-LABEL: splatconstant_shift_v16i8:
995 ; SSE:       # BB#0:
996 ; SSE-NEXT:    psrlw $3, %xmm0
997 ; SSE-NEXT:    pand {{.*}}(%rip), %xmm0
998 ; SSE-NEXT:    movdqa {{.*#+}} xmm1 = [16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16]
999 ; SSE-NEXT:    pxor %xmm1, %xmm0
1000 ; SSE-NEXT:    psubb %xmm1, %xmm0
1001 ; SSE-NEXT:    retq
1002 ;
1003 ; AVX-LABEL: splatconstant_shift_v16i8:
1004 ; AVX:       # BB#0:
1005 ; AVX-NEXT:    vpsrlw $3, %xmm0, %xmm0
1006 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
1007 ; AVX-NEXT:    vmovdqa {{.*#+}} xmm1 = [16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16]
1008 ; AVX-NEXT:    vpxor %xmm1, %xmm0, %xmm0
1009 ; AVX-NEXT:    vpsubb %xmm1, %xmm0, %xmm0
1010 ; AVX-NEXT:    retq
1011   %shift = ashr <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>
1012   ret <16 x i8> %shift
1013 }