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