[X86][SSE3] Just use an explicit SSE3 target attribute - not a cpu type.
[oota-llvm.git] / test / CodeGen / X86 / vector-shift-shl-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:    pshufd {{.*#+}} xmm3 = xmm1[2,3,0,1]
14 ; SSE2-NEXT:    movdqa %xmm0, %xmm2
15 ; SSE2-NEXT:    psllq  %xmm3, %xmm2
16 ; SSE2-NEXT:    psllq  %xmm1, %xmm0
17 ; SSE2-NEXT:    movsd  {{.*#+}} xmm2 = xmm0[0],xmm2[1]
18 ; SSE2-NEXT:    movapd %xmm2, %xmm0
19 ; SSE2-NEXT:    retq
20 ;
21 ; SSE41-LABEL: var_shift_v2i64:
22 ; SSE41:       # BB#0:
23 ; SSE41-NEXT:    movdqa  %xmm0, %xmm2
24 ; SSE41-NEXT:    psllq   %xmm1, %xmm2
25 ; SSE41-NEXT:    pshufd  {{.*#+}} xmm1 = xmm1[2,3,0,1]
26 ; SSE41-NEXT:    psllq   %xmm1, %xmm0
27 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm2[0,1,2,3],xmm0[4,5,6,7]
28 ; SSE41-NEXT:    retq
29 ;
30 ; AVX1-LABEL: var_shift_v2i64:
31 ; AVX1:       # BB#0:
32 ; AVX1-NEXT:    vpsllq   %xmm1, %xmm0, %xmm2
33 ; AVX1-NEXT:    vpshufd  {{.*#+}} xmm1 = xmm1[2,3,0,1]
34 ; AVX1-NEXT:    vpsllq   %xmm1, %xmm0, %xmm0
35 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm2[0,1,2,3],xmm0[4,5,6,7]
36 ; AVX1-NEXT:    retq
37 ;
38 ; AVX2-LABEL: var_shift_v2i64:
39 ; AVX2:       # BB#0:
40 ; AVX2-NEXT:    vpsllvq %xmm1, %xmm0, %xmm0
41 ; AVX2-NEXT:    retq
42   %shift = shl <2 x i64> %a, %b
43   ret <2 x i64> %shift
44 }
45
46 define <4 x i32> @var_shift_v4i32(<4 x i32> %a, <4 x i32> %b) {
47 ; SSE2-LABEL: var_shift_v4i32:
48 ; SSE2:       # BB#0:
49 ; SSE2-NEXT:    pslld     $23, %xmm1
50 ; SSE2-NEXT:    paddd     {{.*}}(%rip), %xmm1
51 ; SSE2-NEXT:    cvttps2dq %xmm1, %xmm1
52 ; SSE2-NEXT:    pshufd    {{.*#+}} xmm2 = xmm1[1,1,3,3]
53 ; SSE2-NEXT:    pmuludq   %xmm0, %xmm1
54 ; SSE2-NEXT:    pshufd    {{.*#+}} xmm1 = xmm1[0,2,2,3]
55 ; SSE2-NEXT:    pshufd    {{.*#+}} xmm0 = xmm0[1,1,3,3]
56 ; SSE2-NEXT:    pmuludq   %xmm2, %xmm0
57 ; SSE2-NEXT:    pshufd    {{.*#+}} xmm0 = xmm0[0,2,2,3]
58 ; SSE2-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
59 ; SSE2-NEXT:    movdqa    %xmm1, %xmm0
60 ; SSE2-NEXT:    retq
61 ;
62 ; SSE41-LABEL: var_shift_v4i32:
63 ; SSE41:       # BB#0:
64 ; SSE41-NEXT:    pslld     $23, %xmm1
65 ; SSE41-NEXT:    paddd     {{.*}}(%rip), %xmm1
66 ; SSE41-NEXT:    cvttps2dq %xmm1, %xmm1
67 ; SSE41-NEXT:    pmulld    %xmm1, %xmm0
68 ; SSE41-NEXT:    retq
69 ;
70 ; AVX1-LABEL: var_shift_v4i32:
71 ; AVX1:       # BB#0:
72 ; AVX1-NEXT:    vpslld     $23, %xmm1, %xmm1
73 ; AVX1-NEXT:    vpaddd     {{.*}}(%rip), %xmm1, %xmm1
74 ; AVX1-NEXT:    vcvttps2dq %xmm1, %xmm1
75 ; AVX1-NEXT:    vpmulld    %xmm0, %xmm1, %xmm0
76 ; AVX1-NEXT:    retq
77 ;
78 ; AVX2-LABEL: var_shift_v4i32:
79 ; AVX2:       # BB#0:
80 ; AVX2-NEXT:    vpsllvd %xmm1, %xmm0, %xmm0
81 ; AVX2-NEXT:    retq
82   %shift = shl <4 x i32> %a, %b
83   ret <4 x i32> %shift
84 }
85
86 define <8 x i16> @var_shift_v8i16(<8 x i16> %a, <8 x i16> %b) {
87 ; SSE2-LABEL: var_shift_v8i16:
88 ; SSE2:       # BB#0:
89 ; SSE2-NEXT:    psllw  $12, %xmm1
90 ; SSE2-NEXT:    movdqa %xmm1, %xmm2
91 ; SSE2-NEXT:    psraw  $15, %xmm2
92 ; SSE2-NEXT:    movdqa %xmm2, %xmm3
93 ; SSE2-NEXT:    pandn  %xmm0, %xmm3
94 ; SSE2-NEXT:    psllw  $8, %xmm0
95 ; SSE2-NEXT:    pand   %xmm2, %xmm0
96 ; SSE2-NEXT:    por    %xmm3, %xmm0
97 ; SSE2-NEXT:    paddw  %xmm1, %xmm1
98 ; SSE2-NEXT:    movdqa %xmm1, %xmm2
99 ; SSE2-NEXT:    psraw  $15, %xmm2
100 ; SSE2-NEXT:    movdqa %xmm2, %xmm3
101 ; SSE2-NEXT:    pandn  %xmm0, %xmm3
102 ; SSE2-NEXT:    psllw  $4, %xmm0
103 ; SSE2-NEXT:    pand   %xmm2, %xmm0
104 ; SSE2-NEXT:    por    %xmm3, %xmm0
105 ; SSE2-NEXT:    paddw  %xmm1, %xmm1
106 ; SSE2-NEXT:    movdqa %xmm1, %xmm2
107 ; SSE2-NEXT:    psraw  $15, %xmm2
108 ; SSE2-NEXT:    movdqa %xmm2, %xmm3
109 ; SSE2-NEXT:    pandn  %xmm0, %xmm3
110 ; SSE2-NEXT:    psllw  $2, %xmm0
111 ; SSE2-NEXT:    pand   %xmm2, %xmm0
112 ; SSE2-NEXT:    por    %xmm3, %xmm0
113 ; SSE2-NEXT:    paddw  %xmm1, %xmm1
114 ; SSE2-NEXT:    psraw  $15, %xmm1
115 ; SSE2-NEXT:    movdqa %xmm1, %xmm2
116 ; SSE2-NEXT:    pandn  %xmm0, %xmm2
117 ; SSE2-NEXT:    psllw  $1, %xmm0
118 ; SSE2-NEXT:    pand   %xmm1, %xmm0
119 ; SSE2-NEXT:    por    %xmm2, %xmm0
120 ; SSE2-NEXT:    retq
121 ;
122 ; SSE41-LABEL: var_shift_v8i16:
123 ; SSE41:       # BB#0:
124 ; SSE41-NEXT:    movdqa   %xmm0, %xmm2
125 ; SSE41-NEXT:    movdqa   %xmm1, %xmm0
126 ; SSE41-NEXT:    psllw    $12, %xmm0
127 ; SSE41-NEXT:    psllw    $4, %xmm1
128 ; SSE41-NEXT:    por      %xmm0, %xmm1
129 ; SSE41-NEXT:    movdqa   %xmm1, %xmm3
130 ; SSE41-NEXT:    paddw    %xmm3, %xmm3
131 ; SSE41-NEXT:    movdqa   %xmm2, %xmm4
132 ; SSE41-NEXT:    psllw    $8, %xmm4
133 ; SSE41-NEXT:    movdqa   %xmm1, %xmm0
134 ; SSE41-NEXT:    pblendvb %xmm4, %xmm2
135 ; SSE41-NEXT:    movdqa   %xmm2, %xmm1
136 ; SSE41-NEXT:    psllw    $4, %xmm1
137 ; SSE41-NEXT:    movdqa   %xmm3, %xmm0
138 ; SSE41-NEXT:    pblendvb %xmm1, %xmm2
139 ; SSE41-NEXT:    movdqa   %xmm2, %xmm1
140 ; SSE41-NEXT:    psllw    $2, %xmm1
141 ; SSE41-NEXT:    paddw    %xmm3, %xmm3
142 ; SSE41-NEXT:    movdqa   %xmm3, %xmm0
143 ; SSE41-NEXT:    pblendvb %xmm1, %xmm2
144 ; SSE41-NEXT:    movdqa   %xmm2, %xmm1
145 ; SSE41-NEXT:    psllw    $1, %xmm1
146 ; SSE41-NEXT:    paddw    %xmm3, %xmm3
147 ; SSE41-NEXT:    movdqa   %xmm3, %xmm0
148 ; SSE41-NEXT:    pblendvb %xmm1, %xmm2
149 ; SSE41-NEXT:    movdqa   %xmm2, %xmm0
150 ; SSE41-NEXT:    retq
151 ;
152 ; AVX1-LABEL: var_shift_v8i16:
153 ; AVX1:       # BB#0:
154 ; AVX1-NEXT:    vpsllw    $12, %xmm1, %xmm2
155 ; AVX1-NEXT:    vpsllw    $4, %xmm1, %xmm1
156 ; AVX1-NEXT:    vpor      %xmm2, %xmm1, %xmm1
157 ; AVX1-NEXT:    vpaddw    %xmm1, %xmm1, %xmm2
158 ; AVX1-NEXT:    vpsllw    $8, %xmm0, %xmm3
159 ; AVX1-NEXT:    vpblendvb %xmm1, %xmm3, %xmm0, %xmm0
160 ; AVX1-NEXT:    vpsllw    $4, %xmm0, %xmm1
161 ; AVX1-NEXT:    vpblendvb %xmm2, %xmm1, %xmm0, %xmm0
162 ; AVX1-NEXT:    vpsllw    $2, %xmm0, %xmm1
163 ; AVX1-NEXT:    vpaddw    %xmm2, %xmm2, %xmm2
164 ; AVX1-NEXT:    vpblendvb %xmm2, %xmm1, %xmm0, %xmm0
165 ; AVX1-NEXT:    vpsllw    $1, %xmm0, %xmm1
166 ; AVX1-NEXT:    vpaddw    %xmm2, %xmm2, %xmm2
167 ; AVX1-NEXT:    vpblendvb %xmm2, %xmm1, %xmm0, %xmm0
168 ; AVX1-NEXT:    retq
169 ;
170 ; AVX2-LABEL: var_shift_v8i16:
171 ; AVX2:       # BB#0:
172 ; 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
173 ; AVX2-NEXT:    vpmovzxwd {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero
174 ; AVX2-NEXT:    vpsllvd   %ymm1, %ymm0, %ymm0
175 ; 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
176 ; AVX2-NEXT:    vpermq    {{.*#+}} ymm0 = ymm0[0,2,2,3]
177 ; AVX2-NEXT:    vzeroupper
178 ; AVX2-NEXT:    retq
179   %shift = shl <8 x i16> %a, %b
180   ret <8 x i16> %shift
181 }
182
183 define <16 x i8> @var_shift_v16i8(<16 x i8> %a, <16 x i8> %b) {
184 ; SSE2-LABEL: var_shift_v16i8:
185 ; SSE2:       # BB#0:
186 ; SSE2-NEXT:  psllw   $5, %xmm1
187 ; SSE2-NEXT:  pxor    %xmm2, %xmm2
188 ; SSE2-NEXT:  pxor    %xmm3, %xmm3
189 ; SSE2-NEXT:  pcmpgtb %xmm1, %xmm3
190 ; SSE2-NEXT:  movdqa  %xmm3, %xmm4
191 ; SSE2-NEXT:  pandn   %xmm0, %xmm4
192 ; SSE2-NEXT:  psllw   $4, %xmm0
193 ; SSE2-NEXT:  pand    {{.*}}(%rip), %xmm0
194 ; SSE2-NEXT:  pand    %xmm3, %xmm0
195 ; SSE2-NEXT:  por     %xmm4, %xmm0
196 ; SSE2-NEXT:  paddb   %xmm1, %xmm1
197 ; SSE2-NEXT:  pxor    %xmm3, %xmm3
198 ; SSE2-NEXT:  pcmpgtb %xmm1, %xmm3
199 ; SSE2-NEXT:  movdqa  %xmm3, %xmm4
200 ; SSE2-NEXT:  pandn   %xmm0, %xmm4
201 ; SSE2-NEXT:  psllw   $2, %xmm0
202 ; SSE2-NEXT:  pand    {{.*}}(%rip), %xmm0
203 ; SSE2-NEXT:  pand    %xmm3, %xmm0
204 ; SSE2-NEXT:  por     %xmm4, %xmm0
205 ; SSE2-NEXT:  paddb   %xmm1, %xmm1
206 ; SSE2-NEXT:  pcmpgtb %xmm1, %xmm2
207 ; SSE2-NEXT:  movdqa  %xmm2, %xmm1
208 ; SSE2-NEXT:  pandn   %xmm0, %xmm1
209 ; SSE2-NEXT:  paddb   %xmm0, %xmm0
210 ; SSE2-NEXT:  pand    %xmm2, %xmm0
211 ; SSE2-NEXT:  por     %xmm1, %xmm0
212 ; SSE2-NEXT:  retq
213 ;
214 ; SSE41-LABEL: var_shift_v16i8:
215 ; SSE41:       # BB#0:
216 ; SSE41-NEXT:    movdqa   %xmm0, %xmm2
217 ; SSE41-NEXT:    psllw    $5, %xmm1
218 ; SSE41-NEXT:    movdqa   %xmm2, %xmm3
219 ; SSE41-NEXT:    psllw    $4, %xmm3
220 ; SSE41-NEXT:    pand     {{.*}}(%rip), %xmm3
221 ; SSE41-NEXT:    movdqa   %xmm1, %xmm0
222 ; SSE41-NEXT:    pblendvb %xmm3, %xmm2
223 ; SSE41-NEXT:    movdqa   %xmm2, %xmm3
224 ; SSE41-NEXT:    psllw    $2, %xmm3
225 ; SSE41-NEXT:    pand     {{.*}}(%rip), %xmm3
226 ; SSE41-NEXT:    paddb    %xmm1, %xmm1
227 ; SSE41-NEXT:    movdqa   %xmm1, %xmm0
228 ; SSE41-NEXT:    pblendvb %xmm3, %xmm2
229 ; SSE41-NEXT:    movdqa   %xmm2, %xmm3
230 ; SSE41-NEXT:    paddb    %xmm3, %xmm3
231 ; SSE41-NEXT:    paddb    %xmm1, %xmm1
232 ; SSE41-NEXT:    movdqa   %xmm1, %xmm0
233 ; SSE41-NEXT:    pblendvb %xmm3, %xmm2
234 ; SSE41-NEXT:    movdqa   %xmm2, %xmm0
235 ; SSE41-NEXT:    retq
236 ;
237 ; AVX-LABEL: var_shift_v16i8:
238 ; AVX:       # BB#0:
239 ; AVX-NEXT:    vpsllw    $5, %xmm1, %xmm1
240 ; AVX-NEXT:    vpsllw    $4, %xmm0, %xmm2
241 ; AVX-NEXT:    vpand     {{.*}}(%rip), %xmm2, %xmm2
242 ; AVX-NEXT:    vpblendvb %xmm1, %xmm2, %xmm0, %xmm0
243 ; AVX-NEXT:    vpsllw    $2, %xmm0, %xmm2
244 ; AVX-NEXT:    vpand     {{.*}}(%rip), %xmm2, %xmm2
245 ; AVX-NEXT:    vpaddb    %xmm1, %xmm1, %xmm1
246 ; AVX-NEXT:    vpblendvb %xmm1, %xmm2, %xmm0, %xmm0
247 ; AVX-NEXT:    vpaddb    %xmm0, %xmm0, %xmm2
248 ; AVX-NEXT:    vpaddb    %xmm1, %xmm1, %xmm1
249 ; AVX-NEXT:    vpblendvb %xmm1, %xmm2, %xmm0, %xmm0
250 ; AVX-NEXT:    retq
251   %shift = shl <16 x i8> %a, %b
252   ret <16 x i8> %shift
253 }
254
255 ;
256 ; Uniform Variable Shifts
257 ;
258
259 define <2 x i64> @splatvar_shift_v2i64(<2 x i64> %a, <2 x i64> %b) {
260 ; SSE-LABEL: splatvar_shift_v2i64:
261 ; SSE:       # BB#0:
262 ; SSE-NEXT:    psllq %xmm1, %xmm0
263 ; SSE-NEXT:    retq
264 ;
265 ; AVX-LABEL: splatvar_shift_v2i64:
266 ; AVX:       # BB#0:
267 ; AVX-NEXT:    vpsllq %xmm1, %xmm0, %xmm0
268 ; AVX-NEXT:    retq
269   %splat = shufflevector <2 x i64> %b, <2 x i64> undef, <2 x i32> zeroinitializer
270   %shift = shl <2 x i64> %a, %splat
271   ret <2 x i64> %shift
272 }
273
274 define <4 x i32> @splatvar_shift_v4i32(<4 x i32> %a, <4 x i32> %b) {
275 ; SSE2-LABEL: splatvar_shift_v4i32:
276 ; SSE2:       # BB#0:
277 ; SSE2-NEXT:    xorps %xmm2, %xmm2
278 ; SSE2-NEXT:    movss {{.*#+}} xmm2 = xmm1[0],xmm2[1,2,3]
279 ; SSE2-NEXT:    pslld %xmm2, %xmm0
280 ; SSE2-NEXT:    retq
281 ;
282 ; SSE41-LABEL: splatvar_shift_v4i32:
283 ; SSE41:       # BB#0:
284 ; SSE41-NEXT:    pxor %xmm2, %xmm2
285 ; SSE41-NEXT:    pblendw {{.*#+}} xmm2 = xmm1[0,1],xmm2[2,3,4,5,6,7]
286 ; SSE41-NEXT:    pslld %xmm2, %xmm0
287 ; SSE41-NEXT:    retq
288 ;
289 ; AVX-LABEL: splatvar_shift_v4i32:
290 ; AVX:       # BB#0:
291 ; AVX-NEXT:    vpxor %xmm2, %xmm2, %xmm2
292 ; AVX-NEXT:    vpblendw {{.*#+}} xmm1 = xmm1[0,1],xmm2[2,3,4,5,6,7]
293 ; AVX-NEXT:    vpslld %xmm1, %xmm0, %xmm0
294 ; AVX-NEXT:    retq
295   %splat = shufflevector <4 x i32> %b, <4 x i32> undef, <4 x i32> zeroinitializer
296   %shift = shl <4 x i32> %a, %splat
297   ret <4 x i32> %shift
298 }
299
300 define <8 x i16> @splatvar_shift_v8i16(<8 x i16> %a, <8 x i16> %b) {
301 ; SSE2-LABEL: splatvar_shift_v8i16:
302 ; SSE2:       # BB#0:
303 ; SSE2-NEXT:    movd   %xmm1, %eax
304 ; SSE2-NEXT:    movzwl %ax, %eax
305 ; SSE2-NEXT:    movd   %eax, %xmm1
306 ; SSE2-NEXT:    psllw  %xmm1, %xmm0
307 ; SSE2-NEXT:    retq
308 ;
309 ; SSE41-LABEL: splatvar_shift_v8i16:
310 ; SSE41:       # BB#0:
311 ; SSE41-NEXT:    pxor %xmm2, %xmm2
312 ; SSE41-NEXT:    pblendw {{.*#+}} xmm2 = xmm1[0],xmm2[1,2,3,4,5,6,7]
313 ; SSE41-NEXT:    psllw %xmm2, %xmm0
314 ; SSE41-NEXT:    retq
315 ;
316 ; AVX-LABEL: splatvar_shift_v8i16:
317 ; AVX:       # BB#0:
318 ; AVX-NEXT:    vpxor %xmm2, %xmm2, %xmm2
319 ; AVX-NEXT:    vpblendw {{.*#+}} xmm1 = xmm1[0],xmm2[1,2,3,4,5,6,7]
320 ; AVX-NEXT:    vpsllw %xmm1, %xmm0, %xmm0
321 ; AVX-NEXT:    retq
322   %splat = shufflevector <8 x i16> %b, <8 x i16> undef, <8 x i32> zeroinitializer
323   %shift = shl <8 x i16> %a, %splat
324   ret <8 x i16> %shift
325 }
326
327 define <16 x i8> @splatvar_shift_v16i8(<16 x i8> %a, <16 x i8> %b) {
328 ; SSE2-LABEL: splatvar_shift_v16i8:
329 ; SSE2:       # BB#0:
330 ; SSE2-NEXT:  punpcklbw {{.*#+}} xmm1 = xmm1[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
331 ; SSE2-NEXT:  pshufd    {{.*#+}} xmm1 = xmm1[0,1,0,3]
332 ; SSE2-NEXT:  pshuflw   {{.*#+}} xmm1 = xmm1[0,0,0,0,4,5,6,7]
333 ; SSE2-NEXT:  pshufhw   {{.*#+}} xmm2 = xmm1[0,1,2,3,4,4,4,4]
334 ; SSE2-NEXT:  psllw     $5, %xmm2
335 ; SSE2-NEXT:  pxor      %xmm1, %xmm1
336 ; SSE2-NEXT:  pxor      %xmm3, %xmm3
337 ; SSE2-NEXT:  pcmpgtb   %xmm2, %xmm3
338 ; SSE2-NEXT:  movdqa    %xmm3, %xmm4
339 ; SSE2-NEXT:  pandn     %xmm0, %xmm4
340 ; SSE2-NEXT:  psllw     $4, %xmm0
341 ; SSE2-NEXT:  pand      {{.*}}(%rip), %xmm0
342 ; SSE2-NEXT:  pand      %xmm3, %xmm0
343 ; SSE2-NEXT:  por       %xmm4, %xmm0
344 ; SSE2-NEXT:  paddb     %xmm2, %xmm2
345 ; SSE2-NEXT:  pxor      %xmm3, %xmm3
346 ; SSE2-NEXT:  pcmpgtb   %xmm2, %xmm3
347 ; SSE2-NEXT:  movdqa    %xmm3, %xmm4
348 ; SSE2-NEXT:  pandn     %xmm0, %xmm4
349 ; SSE2-NEXT:  psllw     $2, %xmm0
350 ; SSE2-NEXT:  pand      {{.*}}(%rip), %xmm0
351 ; SSE2-NEXT:  pand      %xmm3, %xmm0
352 ; SSE2-NEXT:  por       %xmm4, %xmm0
353 ; SSE2-NEXT:  paddb     %xmm2, %xmm2
354 ; SSE2-NEXT:  pcmpgtb   %xmm2, %xmm1
355 ; SSE2-NEXT:  movdqa    %xmm1, %xmm2
356 ; SSE2-NEXT:  pandn     %xmm0, %xmm2
357 ; SSE2-NEXT:  paddb     %xmm0, %xmm0
358 ; SSE2-NEXT:  pand      %xmm1, %xmm0
359 ; SSE2-NEXT:  por       %xmm2, %xmm0
360 ; SSE2-NEXT:  retq
361 ;
362 ; SSE41-LABEL: splatvar_shift_v16i8:
363 ; SSE41:       # BB#0:
364 ; SSE41-NEXT:    movdqa   %xmm0, %xmm2
365 ; SSE41-NEXT:    pxor     %xmm0, %xmm0
366 ; SSE41-NEXT:    pshufb   %xmm0, %xmm1
367 ; SSE41-NEXT:    psllw    $5, %xmm1
368 ; SSE41-NEXT:    movdqa   %xmm1, %xmm3
369 ; SSE41-NEXT:    paddb    %xmm3, %xmm3
370 ; SSE41-NEXT:    movdqa   %xmm2, %xmm4
371 ; SSE41-NEXT:    psllw    $4, %xmm4
372 ; SSE41-NEXT:    pand     {{.*}}(%rip), %xmm4
373 ; SSE41-NEXT:    movdqa   %xmm1, %xmm0
374 ; SSE41-NEXT:    pblendvb %xmm4, %xmm2
375 ; SSE41-NEXT:    movdqa   %xmm2, %xmm1
376 ; SSE41-NEXT:    psllw    $2, %xmm1
377 ; SSE41-NEXT:    pand     {{.*}}(%rip), %xmm1
378 ; SSE41-NEXT:    movdqa   %xmm3, %xmm0
379 ; SSE41-NEXT:    pblendvb %xmm1, %xmm2
380 ; SSE41-NEXT:    movdqa   %xmm2, %xmm1
381 ; SSE41-NEXT:    paddb    %xmm1, %xmm1
382 ; SSE41-NEXT:    paddb    %xmm3, %xmm3
383 ; SSE41-NEXT:    movdqa   %xmm3, %xmm0
384 ; SSE41-NEXT:    pblendvb %xmm1, %xmm2
385 ; SSE41-NEXT:    movdqa   %xmm2, %xmm0
386 ; SSE41-NEXT:    retq
387 ;
388 ; AVX1-LABEL: splatvar_shift_v16i8:
389 ; AVX1:       # BB#0:
390 ; AVX1-NEXT:    vpxor     %xmm2, %xmm2, %xmm2
391 ; AVX1-NEXT:    vpshufb   %xmm2, %xmm1, %xmm1
392 ; AVX1-NEXT:    vpsllw    $5, %xmm1, %xmm1
393 ; AVX1-NEXT:    vpaddb    %xmm1, %xmm1, %xmm2
394 ; AVX1-NEXT:    vpsllw    $4, %xmm0, %xmm3
395 ; AVX1-NEXT:    vpand     {{.*}}(%rip), %xmm3, %xmm3
396 ; AVX1-NEXT:    vpblendvb %xmm1, %xmm3, %xmm0, %xmm0
397 ; AVX1-NEXT:    vpsllw    $2, %xmm0, %xmm1
398 ; AVX1-NEXT:    vpand     {{.*}}(%rip), %xmm1, %xmm1
399 ; AVX1-NEXT:    vpblendvb %xmm2, %xmm1, %xmm0, %xmm0
400 ; AVX1-NEXT:    vpaddb    %xmm0, %xmm0, %xmm1
401 ; AVX1-NEXT:    vpaddb    %xmm2, %xmm2, %xmm2
402 ; AVX1-NEXT:    vpblendvb %xmm2, %xmm1, %xmm0, %xmm0
403 ; AVX1-NEXT:    retq
404 ;
405 ; AVX2-LABEL: splatvar_shift_v16i8:
406 ; AVX2:       # BB#0:
407 ; AVX2-NEXT:    vpbroadcastb %xmm1, %xmm1
408 ; AVX2-NEXT:    vpsllw       $5, %xmm1, %xmm1
409 ; AVX2-NEXT:    vpsllw       $4, %xmm0, %xmm2
410 ; AVX2-NEXT:    vpand        {{.*}}(%rip), %xmm2, %xmm2
411 ; AVX2-NEXT:    vpblendvb    %xmm1, %xmm2, %xmm0, %xmm0
412 ; AVX2-NEXT:    vpsllw       $2, %xmm0, %xmm2
413 ; AVX2-NEXT:    vpand        {{.*}}(%rip), %xmm2, %xmm2
414 ; AVX2-NEXT:    vpaddb       %xmm1, %xmm1, %xmm1
415 ; AVX2-NEXT:    vpblendvb    %xmm1, %xmm2, %xmm0, %xmm0
416 ; AVX2-NEXT:    vpaddb       %xmm0, %xmm0, %xmm2
417 ; AVX2-NEXT:    vpaddb       %xmm1, %xmm1, %xmm1
418 ; AVX2-NEXT:    vpblendvb    %xmm1, %xmm2, %xmm0, %xmm0
419 ; AVX2-NEXT:    retq
420   %splat = shufflevector <16 x i8> %b, <16 x i8> undef, <16 x i32> zeroinitializer
421   %shift = shl <16 x i8> %a, %splat
422   ret <16 x i8> %shift
423 }
424
425 ;
426 ; Constant Shifts
427 ;
428
429 define <2 x i64> @constant_shift_v2i64(<2 x i64> %a) {
430 ; SSE2-LABEL: constant_shift_v2i64:
431 ; SSE2:       # BB#0:
432 ; SSE2-NEXT:    movdqa %xmm0, %xmm1
433 ; SSE2-NEXT:    psllq  $7, %xmm1
434 ; SSE2-NEXT:    psllq  $1, %xmm0
435 ; SSE2-NEXT:    movsd  {{.*#+}} xmm1 = xmm0[0],xmm1[1]
436 ; SSE2-NEXT:    movapd %xmm1, %xmm0
437 ; SSE2-NEXT:    retq
438 ;
439 ; SSE41-LABEL: constant_shift_v2i64:
440 ; SSE41:       # BB#0:
441 ; SSE41-NEXT:    movdqa  %xmm0, %xmm1
442 ; SSE41-NEXT:    psllq   $7, %xmm1
443 ; SSE41-NEXT:    psllq   $1, %xmm0
444 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5,6,7]
445 ; SSE41-NEXT:    retq
446 ;
447 ; AVX1-LABEL: constant_shift_v2i64:
448 ; AVX1:       # BB#0:
449 ; AVX1-NEXT:    vpsllq  $7, %xmm0, %xmm1
450 ; AVX1-NEXT:    vpsllq  $1, %xmm0, %xmm0
451 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5,6,7]
452 ; AVX1-NEXT:    retq
453 ;
454 ; AVX2-LABEL: constant_shift_v2i64:
455 ; AVX2:       # BB#0:
456 ; AVX2-NEXT:    vpsllvq {{.*}}(%rip), %xmm0, %xmm0
457 ; AVX2-NEXT:    retq
458   %shift = shl <2 x i64> %a, <i64 1, i64 7>
459   ret <2 x i64> %shift
460 }
461
462 define <4 x i32> @constant_shift_v4i32(<4 x i32> %a) {
463 ; SSE2-LABEL: constant_shift_v4i32:
464 ; SSE2:       # BB#0:
465 ; SSE2-NEXT:    movdqa    {{.*#+}} xmm1 = [16,32,64,128]
466 ; SSE2-NEXT:    pshufd    {{.*#+}} xmm2 = xmm0[1,1,3,3]
467 ; SSE2-NEXT:    pmuludq   %xmm1, %xmm0
468 ; SSE2-NEXT:    pshufd    {{.*#+}} xmm0 = xmm0[0,2,2,3]
469 ; SSE2-NEXT:    pshufd    {{.*#+}} xmm1 = xmm1[1,1,3,3]
470 ; SSE2-NEXT:    pmuludq   %xmm2, %xmm1
471 ; SSE2-NEXT:    pshufd    {{.*#+}} xmm1 = xmm1[0,2,2,3]
472 ; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
473 ; SSE2-NEXT:    retq
474 ;
475 ; SSE41-LABEL: constant_shift_v4i32:
476 ; SSE41:       # BB#0:
477 ; SSE41-NEXT:    pmulld {{.*}}(%rip), %xmm0
478 ; SSE41-NEXT:    retq
479 ;
480 ; AVX1-LABEL: constant_shift_v4i32:
481 ; AVX1:       # BB#0:
482 ; AVX1-NEXT:    vpmulld {{.*}}(%rip), %xmm0, %xmm0
483 ; AVX1-NEXT:    retq
484 ;
485 ; AVX2-LABEL: constant_shift_v4i32:
486 ; AVX2:       # BB#0:
487 ; AVX2-NEXT:    vpsllvd {{.*}}(%rip), %xmm0, %xmm0
488 ; AVX2-NEXT:    retq
489   %shift = shl <4 x i32> %a, <i32 4, i32 5, i32 6, i32 7>
490   ret <4 x i32> %shift
491 }
492
493 define <8 x i16> @constant_shift_v8i16(<8 x i16> %a) {
494 ; SSE-LABEL: constant_shift_v8i16:
495 ; SSE:       # BB#0:
496 ; SSE-NEXT:    pmullw {{.*}}(%rip), %xmm0
497 ; SSE-NEXT:    retq
498 ;
499 ; AVX-LABEL: constant_shift_v8i16:
500 ; AVX:       # BB#0:
501 ; AVX-NEXT:    vpmullw {{.*}}(%rip), %xmm0, %xmm0
502 ; AVX-NEXT:    retq
503   %shift = shl <8 x i16> %a, <i16 0, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7>
504   ret <8 x i16> %shift
505 }
506
507 define <16 x i8> @constant_shift_v16i8(<16 x i8> %a) {
508 ; SSE2-LABEL: constant_shift_v16i8:
509 ; SSE2:       # BB#0:
510 ; SSE2-NEXT:    movdqa  {{.*#+}} xmm2 = [0,1,2,3,4,5,6,7,7,6,5,4,3,2,1,0]
511 ; SSE2-NEXT:    psllw   $5, %xmm2
512 ; SSE2-NEXT:    pxor    %xmm1, %xmm1
513 ; SSE2-NEXT:    pxor    %xmm3, %xmm3
514 ; SSE2-NEXT:    pcmpgtb %xmm2, %xmm3
515 ; SSE2-NEXT:    movdqa  %xmm3, %xmm4
516 ; SSE2-NEXT:    pandn   %xmm0, %xmm4
517 ; SSE2-NEXT:    psllw   $4, %xmm0
518 ; SSE2-NEXT:    pand    {{.*}}(%rip), %xmm0
519 ; SSE2-NEXT:    pand    %xmm3, %xmm0
520 ; SSE2-NEXT:    por     %xmm4, %xmm0
521 ; SSE2-NEXT:    paddb   %xmm2, %xmm2
522 ; SSE2-NEXT:    pxor    %xmm3, %xmm3
523 ; SSE2-NEXT:    pcmpgtb %xmm2, %xmm3
524 ; SSE2-NEXT:    movdqa  %xmm3, %xmm4
525 ; SSE2-NEXT:    pandn   %xmm0, %xmm4
526 ; SSE2-NEXT:    psllw   $2, %xmm0
527 ; SSE2-NEXT:    pand    {{.*}}(%rip), %xmm0
528 ; SSE2-NEXT:    pand    %xmm3, %xmm0
529 ; SSE2-NEXT:    por     %xmm4, %xmm0
530 ; SSE2-NEXT:    paddb   %xmm2, %xmm2
531 ; SSE2-NEXT:    pcmpgtb %xmm2, %xmm1
532 ; SSE2-NEXT:    movdqa  %xmm1, %xmm2
533 ; SSE2-NEXT:    pandn   %xmm0, %xmm2
534 ; SSE2-NEXT:    paddb   %xmm0, %xmm0
535 ; SSE2-NEXT:    pand    %xmm1, %xmm0
536 ; SSE2-NEXT:    por     %xmm2, %xmm0
537 ; SSE2-NEXT:    retq
538 ;
539 ; SSE41-LABEL: constant_shift_v16i8:
540 ; SSE41:       # BB#0:
541 ; SSE41-NEXT:    movdqa   %xmm0, %xmm1
542 ; SSE41-NEXT:    movdqa   {{.*#+}} xmm0 = [0,1,2,3,4,5,6,7,7,6,5,4,3,2,1,0]
543 ; SSE41-NEXT:    psllw    $5, %xmm0
544 ; SSE41-NEXT:    movdqa   %xmm1, %xmm2
545 ; SSE41-NEXT:    psllw    $4, %xmm2
546 ; SSE41-NEXT:    pand     {{.*}}(%rip), %xmm2
547 ; SSE41-NEXT:    pblendvb %xmm2, %xmm1
548 ; SSE41-NEXT:    movdqa   %xmm1, %xmm2
549 ; SSE41-NEXT:    psllw    $2, %xmm2
550 ; SSE41-NEXT:    pand     {{.*}}(%rip), %xmm2
551 ; SSE41-NEXT:    paddb    %xmm0, %xmm0
552 ; SSE41-NEXT:    pblendvb %xmm2, %xmm1
553 ; SSE41-NEXT:    movdqa   %xmm1, %xmm2
554 ; SSE41-NEXT:    paddb    %xmm2, %xmm2
555 ; SSE41-NEXT:    paddb    %xmm0, %xmm0
556 ; SSE41-NEXT:    pblendvb %xmm2, %xmm1
557 ; SSE41-NEXT:    movdqa   %xmm1, %xmm0
558 ; SSE41-NEXT:    retq
559 ;
560 ; AVX-LABEL: constant_shift_v16i8:
561 ; AVX:       # BB#0:
562 ; AVX-NEXT:    vmovdqa   {{.*#+}} xmm1 = [0,1,2,3,4,5,6,7,7,6,5,4,3,2,1,0]
563 ; AVX-NEXT:    vpsllw    $5, %xmm1, %xmm1
564 ; AVX-NEXT:    vpsllw    $4, %xmm0, %xmm2
565 ; AVX-NEXT:    vpand     {{.*}}(%rip), %xmm2, %xmm2
566 ; AVX-NEXT:    vpblendvb %xmm1, %xmm2, %xmm0, %xmm0
567 ; AVX-NEXT:    vpsllw    $2, %xmm0, %xmm2
568 ; AVX-NEXT:    vpand     {{.*}}(%rip), %xmm2, %xmm2
569 ; AVX-NEXT:    vpaddb    %xmm1, %xmm1, %xmm1
570 ; AVX-NEXT:    vpblendvb %xmm1, %xmm2, %xmm0, %xmm0
571 ; AVX-NEXT:    vpaddb    %xmm0, %xmm0, %xmm2
572 ; AVX-NEXT:    vpaddb    %xmm1, %xmm1, %xmm1
573 ; AVX-NEXT:    vpblendvb %xmm1, %xmm2, %xmm0, %xmm0
574 ; AVX-NEXT:    retq
575   %shift = shl <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>
576   ret <16 x i8> %shift
577 }
578
579 ;
580 ; Uniform Constant Shifts
581 ;
582
583 define <2 x i64> @splatconstant_shift_v2i64(<2 x i64> %a) {
584 ; SSE-LABEL: splatconstant_shift_v2i64:
585 ; SSE:       # BB#0:
586 ; SSE-NEXT:    psllq $7, %xmm0
587 ; SSE-NEXT:    retq
588 ;
589 ; AVX-LABEL: splatconstant_shift_v2i64:
590 ; AVX:       # BB#0:
591 ; AVX-NEXT:    vpsllq $7, %xmm0, %xmm0
592 ; AVX-NEXT:    retq
593   %shift = shl <2 x i64> %a, <i64 7, i64 7>
594   ret <2 x i64> %shift
595 }
596
597 define <4 x i32> @splatconstant_shift_v4i32(<4 x i32> %a) {
598 ; SSE-LABEL: splatconstant_shift_v4i32:
599 ; SSE:       # BB#0:
600 ; SSE-NEXT:    pslld $5, %xmm0
601 ; SSE-NEXT:    retq
602 ;
603 ; AVX-LABEL: splatconstant_shift_v4i32:
604 ; AVX:       # BB#0:
605 ; AVX-NEXT:    vpslld $5, %xmm0, %xmm0
606 ; AVX-NEXT:    retq
607   %shift = shl <4 x i32> %a, <i32 5, i32 5, i32 5, i32 5>
608   ret <4 x i32> %shift
609 }
610
611 define <8 x i16> @splatconstant_shift_v8i16(<8 x i16> %a) {
612 ; SSE-LABEL: splatconstant_shift_v8i16:
613 ; SSE:       # BB#0:
614 ; SSE-NEXT:    psllw $3, %xmm0
615 ; SSE-NEXT:    retq
616 ;
617 ; AVX-LABEL: splatconstant_shift_v8i16:
618 ; AVX:       # BB#0:
619 ; AVX-NEXT:    vpsllw $3, %xmm0, %xmm0
620 ; AVX-NEXT:    retq
621   %shift = shl <8 x i16> %a, <i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3>
622   ret <8 x i16> %shift
623 }
624
625 define <16 x i8> @splatconstant_shift_v16i8(<16 x i8> %a) {
626 ; SSE-LABEL: splatconstant_shift_v16i8:
627 ; SSE:       # BB#0:
628 ; SSE-NEXT:    psllw     $3, %xmm0
629 ; SSE-NEXT:    pand      {{.*}}(%rip), %xmm0
630 ; SSE-NEXT:    retq
631 ;
632 ; AVX-LABEL: splatconstant_shift_v16i8:
633 ; AVX:       # BB#0:
634 ; AVX-NEXT:    vpsllw    $3, %xmm0
635 ; AVX-NEXT:    vpand     {{.*}}(%rip), %xmm0
636 ; AVX-NEXT:    retq
637   %shift = shl <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>
638   ret <16 x i8> %shift
639 }