1 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+sse2 | FileCheck %s --check-prefix=SSE2
2 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+ssse3 | FileCheck %s --check-prefix=SSSE3
3 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+sse4.1 | FileCheck %s --check-prefix=SSE41
4 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+avx | FileCheck %s --check-prefix=AVX --check-prefix=AVX1
5 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+avx2 | FileCheck %s --check-prefix=AVX --check-prefix=AVX2
9 define <4 x float> @vsel_float(<4 x float> %v1, <4 x float> %v2) {
10 ; SSE2-LABEL: vsel_float:
11 ; SSE2: # BB#0: # %entry
12 ; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[1,3]
13 ; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2,1,3]
16 ; SSSE3-LABEL: vsel_float:
17 ; SSSE3: # BB#0: # %entry
18 ; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[1,3]
19 ; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2,1,3]
22 ; SSE41-LABEL: vsel_float:
23 ; SSE41: # BB#0: # %entry
24 ; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
27 ; AVX-LABEL: vsel_float:
28 ; AVX: # BB#0: # %entry
29 ; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
32 %vsel = select <4 x i1> <i1 true, i1 false, i1 true, i1 false>, <4 x float> %v1, <4 x float> %v2
36 define <4 x float> @vsel_float2(<4 x float> %v1, <4 x float> %v2) {
37 ; SSE2-LABEL: vsel_float2:
38 ; SSE2: # BB#0: # %entry
39 ; SSE2-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]
40 ; SSE2-NEXT: movaps %xmm1, %xmm0
43 ; SSSE3-LABEL: vsel_float2:
44 ; SSSE3: # BB#0: # %entry
45 ; SSSE3-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]
46 ; SSSE3-NEXT: movaps %xmm1, %xmm0
49 ; SSE41-LABEL: vsel_float2:
50 ; SSE41: # BB#0: # %entry
51 ; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]
54 ; AVX-LABEL: vsel_float2:
55 ; AVX: # BB#0: # %entry
56 ; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]
59 %vsel = select <4 x i1> <i1 true, i1 false, i1 false, i1 false>, <4 x float> %v1, <4 x float> %v2
63 define <4 x i8> @vsel_4xi8(<4 x i8> %v1, <4 x i8> %v2) {
64 ; SSE2-LABEL: vsel_4xi8:
65 ; SSE2: # BB#0: # %entry
66 ; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[3,0]
67 ; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0,2]
70 ; SSSE3-LABEL: vsel_4xi8:
71 ; SSSE3: # BB#0: # %entry
72 ; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[3,0]
73 ; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0,2]
76 ; SSE41-LABEL: vsel_4xi8:
77 ; SSE41: # BB#0: # %entry
78 ; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5],xmm0[6,7]
81 ; AVX1-LABEL: vsel_4xi8:
82 ; AVX1: # BB#0: # %entry
83 ; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5],xmm0[6,7]
86 ; AVX2-LABEL: vsel_4xi8:
87 ; AVX2: # BB#0: # %entry
88 ; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0,1],xmm1[2],xmm0[3]
91 %vsel = select <4 x i1> <i1 true, i1 true, i1 false, i1 true>, <4 x i8> %v1, <4 x i8> %v2
95 define <4 x i16> @vsel_4xi16(<4 x i16> %v1, <4 x i16> %v2) {
96 ; SSE2-LABEL: vsel_4xi16:
97 ; SSE2: # BB#0: # %entry
98 ; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[1,0],xmm0[0,0]
99 ; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[2,3]
100 ; SSE2-NEXT: movaps %xmm1, %xmm0
103 ; SSSE3-LABEL: vsel_4xi16:
104 ; SSSE3: # BB#0: # %entry
105 ; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[1,0],xmm0[0,0]
106 ; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[2,3]
107 ; SSSE3-NEXT: movaps %xmm1, %xmm0
110 ; SSE41-LABEL: vsel_4xi16:
111 ; SSE41: # BB#0: # %entry
112 ; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5,6,7]
115 ; AVX1-LABEL: vsel_4xi16:
116 ; AVX1: # BB#0: # %entry
117 ; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5,6,7]
120 ; AVX2-LABEL: vsel_4xi16:
121 ; AVX2: # BB#0: # %entry
122 ; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2,3]
125 %vsel = select <4 x i1> <i1 true, i1 false, i1 true, i1 true>, <4 x i16> %v1, <4 x i16> %v2
129 define <4 x i32> @vsel_i32(<4 x i32> %v1, <4 x i32> %v2) {
130 ; SSE2-LABEL: vsel_i32:
131 ; SSE2: # BB#0: # %entry
132 ; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,3,2,3]
133 ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
134 ; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
137 ; SSSE3-LABEL: vsel_i32:
138 ; SSSE3: # BB#0: # %entry
139 ; SSSE3-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,3,2,3]
140 ; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
141 ; SSSE3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
144 ; SSE41-LABEL: vsel_i32:
145 ; SSE41: # BB#0: # %entry
146 ; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7]
149 ; AVX1-LABEL: vsel_i32:
150 ; AVX1: # BB#0: # %entry
151 ; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7]
154 ; AVX2-LABEL: vsel_i32:
155 ; AVX2: # BB#0: # %entry
156 ; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
159 %vsel = select <4 x i1> <i1 true, i1 false, i1 true, i1 false>, <4 x i32> %v1, <4 x i32> %v2
163 define <2 x double> @vsel_double(<2 x double> %v1, <2 x double> %v2) {
164 ; SSE2-LABEL: vsel_double:
165 ; SSE2: # BB#0: # %entry
166 ; SSE2-NEXT: movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1]
167 ; SSE2-NEXT: movapd %xmm1, %xmm0
170 ; SSSE3-LABEL: vsel_double:
171 ; SSSE3: # BB#0: # %entry
172 ; SSSE3-NEXT: movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1]
173 ; SSSE3-NEXT: movapd %xmm1, %xmm0
176 ; SSE41-LABEL: vsel_double:
177 ; SSE41: # BB#0: # %entry
178 ; SSE41-NEXT: blendpd {{.*#+}} xmm0 = xmm0[0],xmm1[1]
181 ; AVX-LABEL: vsel_double:
182 ; AVX: # BB#0: # %entry
183 ; AVX-NEXT: vblendpd {{.*#+}} xmm0 = xmm0[0],xmm1[1]
186 %vsel = select <2 x i1> <i1 true, i1 false>, <2 x double> %v1, <2 x double> %v2
187 ret <2 x double> %vsel
190 define <2 x i64> @vsel_i64(<2 x i64> %v1, <2 x i64> %v2) {
191 ; SSE2-LABEL: vsel_i64:
192 ; SSE2: # BB#0: # %entry
193 ; SSE2-NEXT: movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1]
194 ; SSE2-NEXT: movapd %xmm1, %xmm0
197 ; SSSE3-LABEL: vsel_i64:
198 ; SSSE3: # BB#0: # %entry
199 ; SSSE3-NEXT: movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1]
200 ; SSSE3-NEXT: movapd %xmm1, %xmm0
203 ; SSE41-LABEL: vsel_i64:
204 ; SSE41: # BB#0: # %entry
205 ; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5,6,7]
208 ; AVX1-LABEL: vsel_i64:
209 ; AVX1: # BB#0: # %entry
210 ; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5,6,7]
213 ; AVX2-LABEL: vsel_i64:
214 ; AVX2: # BB#0: # %entry
215 ; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]
218 %vsel = select <2 x i1> <i1 true, i1 false>, <2 x i64> %v1, <2 x i64> %v2
222 define <8 x i16> @vsel_8xi16(<8 x i16> %v1, <8 x i16> %v2) {
223 ; SSE2-LABEL: vsel_8xi16:
224 ; SSE2: # BB#0: # %entry
225 ; SSE2-NEXT: movaps {{.*#+}} xmm2 = [0,65535,65535,65535,0,65535,65535,65535]
226 ; SSE2-NEXT: andps %xmm2, %xmm1
227 ; SSE2-NEXT: andnps %xmm0, %xmm2
228 ; SSE2-NEXT: orps %xmm1, %xmm2
229 ; SSE2-NEXT: movaps %xmm2, %xmm0
232 ; SSSE3-LABEL: vsel_8xi16:
233 ; SSSE3: # BB#0: # %entry
234 ; SSSE3-NEXT: movaps {{.*#+}} xmm2 = [0,65535,65535,65535,0,65535,65535,65535]
235 ; SSSE3-NEXT: andps %xmm2, %xmm1
236 ; SSSE3-NEXT: andnps %xmm0, %xmm2
237 ; SSSE3-NEXT: orps %xmm1, %xmm2
238 ; SSSE3-NEXT: movaps %xmm2, %xmm0
241 ; SSE41-LABEL: vsel_8xi16:
242 ; SSE41: # BB#0: # %entry
243 ; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3],xmm0[4],xmm1[5,6,7]
246 ; AVX-LABEL: vsel_8xi16:
247 ; AVX: # BB#0: # %entry
248 ; AVX-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3],xmm0[4],xmm1[5,6,7]
251 %vsel = select <8 x i1> <i1 true, i1 false, i1 false, i1 false, i1 true, i1 false, i1 false, i1 false>, <8 x i16> %v1, <8 x i16> %v2
255 define <16 x i8> @vsel_i8(<16 x i8> %v1, <16 x i8> %v2) {
256 ; SSE2-LABEL: vsel_i8:
257 ; SSE2: # BB#0: # %entry
258 ; SSE2-NEXT: movaps {{.*#+}} xmm2 = [255,0,0,0,255,0,0,0,255,255,255,255,255,255,255,255]
259 ; SSE2-NEXT: andps %xmm2, %xmm0
260 ; SSE2-NEXT: andnps %xmm1, %xmm2
261 ; SSE2-NEXT: orps %xmm2, %xmm0
264 ; SSSE3-LABEL: vsel_i8:
265 ; SSSE3: # BB#0: # %entry
266 ; SSSE3-NEXT: pshufb {{.*#+}} xmm1 = zero,xmm1[1,2,3],zero,xmm1[5,6,7],zero,zero,zero,zero,zero,zero,zero,zero
267 ; SSSE3-NEXT: pshufb {{.*#+}} xmm0 = xmm0[0],zero,zero,zero,xmm0[4],zero,zero,zero,xmm0[8,9,10,11,12,13,14,15]
268 ; SSSE3-NEXT: por %xmm1, %xmm0
271 ; SSE41-LABEL: vsel_i8:
272 ; SSE41: # BB#0: # %entry
273 ; SSE41-NEXT: movdqa %xmm0, %xmm2
274 ; SSE41-NEXT: movaps {{.*#+}} xmm0 = [255,0,0,0,255,0,0,0,255,255,255,255,255,255,255,255]
275 ; SSE41-NEXT: pblendvb %xmm2, %xmm1
276 ; SSE41-NEXT: movdqa %xmm1, %xmm0
279 ; AVX-LABEL: vsel_i8:
280 ; AVX: # BB#0: # %entry
281 ; AVX-NEXT: vmovdqa {{.*#+}} xmm2 = [255,0,0,0,255,0,0,0,255,255,255,255,255,255,255,255]
282 ; AVX-NEXT: vpblendvb %xmm2, %xmm0, %xmm1, %xmm0
285 %vsel = select <16 x i1> <i1 true, i1 false, i1 false, i1 false, i1 true, i1 false, i1 false, i1 false, i1 true, i1 false, i1 false, i1 false, i1 true, i1 false, i1 false, i1 false>, <16 x i8> %v1, <16 x i8> %v2
292 define <8 x float> @vsel_float8(<8 x float> %v1, <8 x float> %v2) {
293 ; SSE2-LABEL: vsel_float8:
294 ; SSE2: # BB#0: # %entry
295 ; SSE2-NEXT: movss {{.*#+}} xmm2 = xmm0[0],xmm2[1,2,3]
296 ; SSE2-NEXT: movss {{.*#+}} xmm3 = xmm1[0],xmm3[1,2,3]
297 ; SSE2-NEXT: movaps %xmm2, %xmm0
298 ; SSE2-NEXT: movaps %xmm3, %xmm1
301 ; SSSE3-LABEL: vsel_float8:
302 ; SSSE3: # BB#0: # %entry
303 ; SSSE3-NEXT: movss {{.*#+}} xmm2 = xmm0[0],xmm2[1,2,3]
304 ; SSSE3-NEXT: movss {{.*#+}} xmm3 = xmm1[0],xmm3[1,2,3]
305 ; SSSE3-NEXT: movaps %xmm2, %xmm0
306 ; SSSE3-NEXT: movaps %xmm3, %xmm1
309 ; SSE41-LABEL: vsel_float8:
310 ; SSE41: # BB#0: # %entry
311 ; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm2[1,2,3]
312 ; SSE41-NEXT: blendps {{.*#+}} xmm1 = xmm1[0],xmm3[1,2,3]
315 ; AVX-LABEL: vsel_float8:
316 ; AVX: # BB#0: # %entry
317 ; AVX-NEXT: vblendps {{.*#+}} ymm0 = ymm0[0],ymm1[1,2,3],ymm0[4],ymm1[5,6,7]
320 %vsel = select <8 x i1> <i1 true, i1 false, i1 false, i1 false, i1 true, i1 false, i1 false, i1 false>, <8 x float> %v1, <8 x float> %v2
321 ret <8 x float> %vsel
324 define <8 x i32> @vsel_i328(<8 x i32> %v1, <8 x i32> %v2) {
325 ; SSE2-LABEL: vsel_i328:
326 ; SSE2: # BB#0: # %entry
327 ; SSE2-NEXT: movss {{.*#+}} xmm2 = xmm0[0],xmm2[1,2,3]
328 ; SSE2-NEXT: movss {{.*#+}} xmm3 = xmm1[0],xmm3[1,2,3]
329 ; SSE2-NEXT: movaps %xmm2, %xmm0
330 ; SSE2-NEXT: movaps %xmm3, %xmm1
333 ; SSSE3-LABEL: vsel_i328:
334 ; SSSE3: # BB#0: # %entry
335 ; SSSE3-NEXT: movss {{.*#+}} xmm2 = xmm0[0],xmm2[1,2,3]
336 ; SSSE3-NEXT: movss {{.*#+}} xmm3 = xmm1[0],xmm3[1,2,3]
337 ; SSSE3-NEXT: movaps %xmm2, %xmm0
338 ; SSSE3-NEXT: movaps %xmm3, %xmm1
341 ; SSE41-LABEL: vsel_i328:
342 ; SSE41: # BB#0: # %entry
343 ; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3,4,5,6,7]
344 ; SSE41-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0,1],xmm3[2,3,4,5,6,7]
347 ; AVX1-LABEL: vsel_i328:
348 ; AVX1: # BB#0: # %entry
349 ; AVX1-NEXT: vblendps {{.*#+}} ymm0 = ymm0[0],ymm1[1,2,3],ymm0[4],ymm1[5,6,7]
352 ; AVX2-LABEL: vsel_i328:
353 ; AVX2: # BB#0: # %entry
354 ; AVX2-NEXT: vpblendd {{.*#+}} ymm0 = ymm0[0],ymm1[1,2,3],ymm0[4],ymm1[5,6,7]
357 %vsel = select <8 x i1> <i1 true, i1 false, i1 false, i1 false, i1 true, i1 false, i1 false, i1 false>, <8 x i32> %v1, <8 x i32> %v2
361 define <8 x double> @vsel_double8(<8 x double> %v1, <8 x double> %v2) {
362 ; SSE2-LABEL: vsel_double8:
363 ; SSE2: # BB#0: # %entry
364 ; SSE2-NEXT: movsd {{.*#+}} xmm4 = xmm0[0],xmm4[1]
365 ; SSE2-NEXT: movsd {{.*#+}} xmm6 = xmm2[0],xmm6[1]
366 ; SSE2-NEXT: movapd %xmm4, %xmm0
367 ; SSE2-NEXT: movaps %xmm5, %xmm1
368 ; SSE2-NEXT: movapd %xmm6, %xmm2
369 ; SSE2-NEXT: movaps %xmm7, %xmm3
372 ; SSSE3-LABEL: vsel_double8:
373 ; SSSE3: # BB#0: # %entry
374 ; SSSE3-NEXT: movsd {{.*#+}} xmm4 = xmm0[0],xmm4[1]
375 ; SSSE3-NEXT: movsd {{.*#+}} xmm6 = xmm2[0],xmm6[1]
376 ; SSSE3-NEXT: movapd %xmm4, %xmm0
377 ; SSSE3-NEXT: movaps %xmm5, %xmm1
378 ; SSSE3-NEXT: movapd %xmm6, %xmm2
379 ; SSSE3-NEXT: movaps %xmm7, %xmm3
382 ; SSE41-LABEL: vsel_double8:
383 ; SSE41: # BB#0: # %entry
384 ; SSE41-NEXT: blendpd {{.*#+}} xmm0 = xmm0[0],xmm4[1]
385 ; SSE41-NEXT: blendpd {{.*#+}} xmm2 = xmm2[0],xmm6[1]
386 ; SSE41-NEXT: movaps %xmm5, %xmm1
387 ; SSE41-NEXT: movaps %xmm7, %xmm3
390 ; AVX-LABEL: vsel_double8:
391 ; AVX: # BB#0: # %entry
392 ; AVX-NEXT: vblendpd {{.*#+}} ymm0 = ymm0[0],ymm2[1,2,3]
393 ; AVX-NEXT: vblendpd {{.*#+}} ymm1 = ymm1[0],ymm3[1,2,3]
396 %vsel = select <8 x i1> <i1 true, i1 false, i1 false, i1 false, i1 true, i1 false, i1 false, i1 false>, <8 x double> %v1, <8 x double> %v2
397 ret <8 x double> %vsel
400 define <8 x i64> @vsel_i648(<8 x i64> %v1, <8 x i64> %v2) {
401 ; SSE2-LABEL: vsel_i648:
402 ; SSE2: # BB#0: # %entry
403 ; SSE2-NEXT: movsd {{.*#+}} xmm4 = xmm0[0],xmm4[1]
404 ; SSE2-NEXT: movsd {{.*#+}} xmm6 = xmm2[0],xmm6[1]
405 ; SSE2-NEXT: movapd %xmm4, %xmm0
406 ; SSE2-NEXT: movaps %xmm5, %xmm1
407 ; SSE2-NEXT: movapd %xmm6, %xmm2
408 ; SSE2-NEXT: movaps %xmm7, %xmm3
411 ; SSSE3-LABEL: vsel_i648:
412 ; SSSE3: # BB#0: # %entry
413 ; SSSE3-NEXT: movsd {{.*#+}} xmm4 = xmm0[0],xmm4[1]
414 ; SSSE3-NEXT: movsd {{.*#+}} xmm6 = xmm2[0],xmm6[1]
415 ; SSSE3-NEXT: movapd %xmm4, %xmm0
416 ; SSSE3-NEXT: movaps %xmm5, %xmm1
417 ; SSSE3-NEXT: movapd %xmm6, %xmm2
418 ; SSSE3-NEXT: movaps %xmm7, %xmm3
421 ; SSE41-LABEL: vsel_i648:
422 ; SSE41: # BB#0: # %entry
423 ; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm4[4,5,6,7]
424 ; SSE41-NEXT: pblendw {{.*#+}} xmm2 = xmm2[0,1,2,3],xmm6[4,5,6,7]
425 ; SSE41-NEXT: movaps %xmm5, %xmm1
426 ; SSE41-NEXT: movaps %xmm7, %xmm3
429 ; AVX1-LABEL: vsel_i648:
430 ; AVX1: # BB#0: # %entry
431 ; AVX1-NEXT: vblendpd {{.*#+}} ymm0 = ymm0[0],ymm2[1,2,3]
432 ; AVX1-NEXT: vblendpd {{.*#+}} ymm1 = ymm1[0],ymm3[1,2,3]
435 ; AVX2-LABEL: vsel_i648:
436 ; AVX2: # BB#0: # %entry
437 ; AVX2-NEXT: vpblendd {{.*#+}} ymm0 = ymm0[0,1],ymm2[2,3,4,5,6,7]
438 ; AVX2-NEXT: vpblendd {{.*#+}} ymm1 = ymm1[0,1],ymm3[2,3,4,5,6,7]
441 %vsel = select <8 x i1> <i1 true, i1 false, i1 false, i1 false, i1 true, i1 false, i1 false, i1 false>, <8 x i64> %v1, <8 x i64> %v2
445 define <4 x double> @vsel_double4(<4 x double> %v1, <4 x double> %v2) {
446 ; SSE2-LABEL: vsel_double4:
447 ; SSE2: # BB#0: # %entry
448 ; SSE2-NEXT: movsd {{.*#+}} xmm2 = xmm0[0],xmm2[1]
449 ; SSE2-NEXT: movsd {{.*#+}} xmm3 = xmm1[0],xmm3[1]
450 ; SSE2-NEXT: movapd %xmm2, %xmm0
451 ; SSE2-NEXT: movapd %xmm3, %xmm1
454 ; SSSE3-LABEL: vsel_double4:
455 ; SSSE3: # BB#0: # %entry
456 ; SSSE3-NEXT: movsd {{.*#+}} xmm2 = xmm0[0],xmm2[1]
457 ; SSSE3-NEXT: movsd {{.*#+}} xmm3 = xmm1[0],xmm3[1]
458 ; SSSE3-NEXT: movapd %xmm2, %xmm0
459 ; SSSE3-NEXT: movapd %xmm3, %xmm1
462 ; SSE41-LABEL: vsel_double4:
463 ; SSE41: # BB#0: # %entry
464 ; SSE41-NEXT: blendpd {{.*#+}} xmm0 = xmm0[0],xmm2[1]
465 ; SSE41-NEXT: blendpd {{.*#+}} xmm1 = xmm1[0],xmm3[1]
468 ; AVX-LABEL: vsel_double4:
469 ; AVX: # BB#0: # %entry
470 ; AVX-NEXT: vblendpd {{.*#+}} ymm0 = ymm0[0],ymm1[1],ymm0[2],ymm1[3]
473 %vsel = select <4 x i1> <i1 true, i1 false, i1 true, i1 false>, <4 x double> %v1, <4 x double> %v2
474 ret <4 x double> %vsel
477 define <2 x double> @testa(<2 x double> %x, <2 x double> %y) {
479 ; SSE2: # BB#0: # %entry
480 ; SSE2-NEXT: movapd %xmm1, %xmm2
481 ; SSE2-NEXT: cmplepd %xmm0, %xmm2
482 ; SSE2-NEXT: andpd %xmm2, %xmm0
483 ; SSE2-NEXT: andnpd %xmm1, %xmm2
484 ; SSE2-NEXT: orpd %xmm2, %xmm0
487 ; SSSE3-LABEL: testa:
488 ; SSSE3: # BB#0: # %entry
489 ; SSSE3-NEXT: movapd %xmm1, %xmm2
490 ; SSSE3-NEXT: cmplepd %xmm0, %xmm2
491 ; SSSE3-NEXT: andpd %xmm2, %xmm0
492 ; SSSE3-NEXT: andnpd %xmm1, %xmm2
493 ; SSSE3-NEXT: orpd %xmm2, %xmm0
496 ; SSE41-LABEL: testa:
497 ; SSE41: # BB#0: # %entry
498 ; SSE41-NEXT: movapd %xmm0, %xmm2
499 ; SSE41-NEXT: movapd %xmm1, %xmm0
500 ; SSE41-NEXT: cmplepd %xmm2, %xmm0
501 ; SSE41-NEXT: blendvpd %xmm2, %xmm1
502 ; SSE41-NEXT: movapd %xmm1, %xmm0
506 ; AVX: # BB#0: # %entry
507 ; AVX-NEXT: vcmplepd %xmm0, %xmm1, %xmm2
508 ; AVX-NEXT: vblendvpd %xmm2, %xmm0, %xmm1, %xmm0
511 %max_is_x = fcmp oge <2 x double> %x, %y
512 %max = select <2 x i1> %max_is_x, <2 x double> %x, <2 x double> %y
513 ret <2 x double> %max
516 define <2 x double> @testb(<2 x double> %x, <2 x double> %y) {
518 ; SSE2: # BB#0: # %entry
519 ; SSE2-NEXT: movapd %xmm1, %xmm2
520 ; SSE2-NEXT: cmpnlepd %xmm0, %xmm2
521 ; SSE2-NEXT: andpd %xmm2, %xmm0
522 ; SSE2-NEXT: andnpd %xmm1, %xmm2
523 ; SSE2-NEXT: orpd %xmm2, %xmm0
526 ; SSSE3-LABEL: testb:
527 ; SSSE3: # BB#0: # %entry
528 ; SSSE3-NEXT: movapd %xmm1, %xmm2
529 ; SSSE3-NEXT: cmpnlepd %xmm0, %xmm2
530 ; SSSE3-NEXT: andpd %xmm2, %xmm0
531 ; SSSE3-NEXT: andnpd %xmm1, %xmm2
532 ; SSSE3-NEXT: orpd %xmm2, %xmm0
535 ; SSE41-LABEL: testb:
536 ; SSE41: # BB#0: # %entry
537 ; SSE41-NEXT: movapd %xmm0, %xmm2
538 ; SSE41-NEXT: movapd %xmm1, %xmm0
539 ; SSE41-NEXT: cmpnlepd %xmm2, %xmm0
540 ; SSE41-NEXT: blendvpd %xmm2, %xmm1
541 ; SSE41-NEXT: movapd %xmm1, %xmm0
545 ; AVX: # BB#0: # %entry
546 ; AVX-NEXT: vcmpnlepd %xmm0, %xmm1, %xmm2
547 ; AVX-NEXT: vblendvpd %xmm2, %xmm0, %xmm1, %xmm0
550 %min_is_x = fcmp ult <2 x double> %x, %y
551 %min = select <2 x i1> %min_is_x, <2 x double> %x, <2 x double> %y
552 ret <2 x double> %min
555 ; If we can figure out a blend has a constant mask, we should emit the
556 ; blend instruction with an immediate mask
557 define <4 x double> @constant_blendvpd_avx(<4 x double> %xy, <4 x double> %ab) {
558 ; SSE2-LABEL: constant_blendvpd_avx:
559 ; SSE2: # BB#0: # %entry
560 ; SSE2-NEXT: movsd {{.*#+}} xmm3 = xmm1[0],xmm3[1]
561 ; SSE2-NEXT: movaps %xmm2, %xmm0
562 ; SSE2-NEXT: movapd %xmm3, %xmm1
565 ; SSSE3-LABEL: constant_blendvpd_avx:
566 ; SSSE3: # BB#0: # %entry
567 ; SSSE3-NEXT: movsd {{.*#+}} xmm3 = xmm1[0],xmm3[1]
568 ; SSSE3-NEXT: movaps %xmm2, %xmm0
569 ; SSSE3-NEXT: movapd %xmm3, %xmm1
572 ; SSE41-LABEL: constant_blendvpd_avx:
573 ; SSE41: # BB#0: # %entry
574 ; SSE41-NEXT: blendpd {{.*#+}} xmm1 = xmm1[0],xmm3[1]
575 ; SSE41-NEXT: movaps %xmm2, %xmm0
578 ; AVX-LABEL: constant_blendvpd_avx:
579 ; AVX: # BB#0: # %entry
580 ; AVX-NEXT: vblendpd {{.*#+}} ymm0 = ymm1[0,1],ymm0[2],ymm1[3]
583 %select = select <4 x i1> <i1 false, i1 false, i1 true, i1 false>, <4 x double> %xy, <4 x double> %ab
584 ret <4 x double> %select
587 define <8 x float> @constant_blendvps_avx(<8 x float> %xyzw, <8 x float> %abcd) {
588 ; SSE2-LABEL: constant_blendvps_avx:
589 ; SSE2: # BB#0: # %entry
590 ; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,0],xmm2[2,0]
591 ; SSE2-NEXT: shufps {{.*#+}} xmm2 = xmm2[0,1],xmm0[2,0]
592 ; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[3,0],xmm3[2,0]
593 ; SSE2-NEXT: shufps {{.*#+}} xmm3 = xmm3[0,1],xmm1[2,0]
594 ; SSE2-NEXT: movaps %xmm2, %xmm0
595 ; SSE2-NEXT: movaps %xmm3, %xmm1
598 ; SSSE3-LABEL: constant_blendvps_avx:
599 ; SSSE3: # BB#0: # %entry
600 ; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,0],xmm2[2,0]
601 ; SSSE3-NEXT: shufps {{.*#+}} xmm2 = xmm2[0,1],xmm0[2,0]
602 ; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[3,0],xmm3[2,0]
603 ; SSSE3-NEXT: shufps {{.*#+}} xmm3 = xmm3[0,1],xmm1[2,0]
604 ; SSSE3-NEXT: movaps %xmm2, %xmm0
605 ; SSSE3-NEXT: movaps %xmm3, %xmm1
608 ; SSE41-LABEL: constant_blendvps_avx:
609 ; SSE41: # BB#0: # %entry
610 ; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm2[0,1,2],xmm0[3]
611 ; SSE41-NEXT: blendps {{.*#+}} xmm1 = xmm3[0,1,2],xmm1[3]
614 ; AVX-LABEL: constant_blendvps_avx:
615 ; AVX: # BB#0: # %entry
616 ; AVX-NEXT: vblendps {{.*#+}} ymm0 = ymm1[0,1,2],ymm0[3],ymm1[4,5,6],ymm0[7]
619 %select = select <8 x i1> <i1 false, i1 false, i1 false, i1 true, i1 false, i1 false, i1 false, i1 true>, <8 x float> %xyzw, <8 x float> %abcd
620 ret <8 x float> %select
623 define <32 x i8> @constant_pblendvb_avx2(<32 x i8> %xyzw, <32 x i8> %abcd) {
624 ; SSE2-LABEL: constant_pblendvb_avx2:
625 ; SSE2: # BB#0: # %entry
626 ; SSE2-NEXT: movaps {{.*#+}} xmm4 = [0,0,255,0,255,255,255,0,255,255,255,255,255,255,255,255]
627 ; SSE2-NEXT: movaps %xmm4, %xmm5
628 ; SSE2-NEXT: andnps %xmm2, %xmm5
629 ; SSE2-NEXT: andps %xmm4, %xmm0
630 ; SSE2-NEXT: orps %xmm5, %xmm0
631 ; SSE2-NEXT: andps %xmm4, %xmm1
632 ; SSE2-NEXT: andnps %xmm3, %xmm4
633 ; SSE2-NEXT: orps %xmm4, %xmm1
636 ; SSSE3-LABEL: constant_pblendvb_avx2:
637 ; SSSE3: # BB#0: # %entry
638 ; SSSE3-NEXT: movdqa {{.*#+}} xmm4 = [0,1,128,3,128,128,128,7,128,128,128,128,128,128,128,128]
639 ; SSSE3-NEXT: pshufb %xmm4, %xmm2
640 ; SSSE3-NEXT: movdqa {{.*#+}} xmm5 = [128,128,2,128,4,5,6,128,8,9,10,11,12,13,14,15]
641 ; SSSE3-NEXT: pshufb %xmm5, %xmm0
642 ; SSSE3-NEXT: por %xmm2, %xmm0
643 ; SSSE3-NEXT: pshufb %xmm4, %xmm3
644 ; SSSE3-NEXT: pshufb %xmm5, %xmm1
645 ; SSSE3-NEXT: por %xmm3, %xmm1
648 ; SSE41-LABEL: constant_pblendvb_avx2:
649 ; SSE41: # BB#0: # %entry
650 ; SSE41-NEXT: movdqa %xmm0, %xmm4
651 ; SSE41-NEXT: movaps {{.*#+}} xmm0 = [0,0,255,0,255,255,255,0,255,255,255,255,255,255,255,255]
652 ; SSE41-NEXT: pblendvb %xmm4, %xmm2
653 ; SSE41-NEXT: pblendvb %xmm1, %xmm3
654 ; SSE41-NEXT: movdqa %xmm2, %xmm0
655 ; SSE41-NEXT: movdqa %xmm3, %xmm1
658 ; AVX1-LABEL: constant_pblendvb_avx2:
659 ; AVX1: # BB#0: # %entry
660 ; AVX1-NEXT: vmovdqa {{.*#+}} xmm2 = [0,0,255,0,255,255,255,0,255,255,255,255,255,255,255,255]
661 ; AVX1-NEXT: vpblendvb %xmm2, %xmm0, %xmm1, %xmm1
662 ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0
663 ; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0
666 ; AVX2-LABEL: constant_pblendvb_avx2:
667 ; AVX2: # BB#0: # %entry
668 ; AVX2-NEXT: vmovdqa {{.*#+}} ymm2 = [0,0,255,0,255,255,255,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255]
669 ; AVX2-NEXT: vpblendvb %ymm2, %ymm0, %ymm1, %ymm0
672 %select = select <32 x i1> <i1 false, i1 false, i1 true, i1 false, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 true, i1 false, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 true, i1 false, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 true, i1 false, i1 true, i1 true, i1 true, i1 false>, <32 x i8> %xyzw, <32 x i8> %abcd
673 ret <32 x i8> %select
676 declare <8 x float> @llvm.x86.avx.blendv.ps.256(<8 x float>, <8 x float>, <8 x float>)
677 declare <4 x double> @llvm.x86.avx.blendv.pd.256(<4 x double>, <4 x double>, <4 x double>)
679 ;; 4 tests for shufflevectors that optimize to blend + immediate
680 define <4 x float> @blend_shufflevector_4xfloat(<4 x float> %a, <4 x float> %b) {
681 ; SSE2-LABEL: blend_shufflevector_4xfloat:
682 ; SSE2: # BB#0: # %entry
683 ; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[1,3]
684 ; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2,1,3]
687 ; SSSE3-LABEL: blend_shufflevector_4xfloat:
688 ; SSSE3: # BB#0: # %entry
689 ; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[1,3]
690 ; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2,1,3]
693 ; SSE41-LABEL: blend_shufflevector_4xfloat:
694 ; SSE41: # BB#0: # %entry
695 ; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
698 ; AVX-LABEL: blend_shufflevector_4xfloat:
699 ; AVX: # BB#0: # %entry
700 ; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
703 %select = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
704 ret <4 x float> %select
707 define <8 x float> @blend_shufflevector_8xfloat(<8 x float> %a, <8 x float> %b) {
708 ; SSE2-LABEL: blend_shufflevector_8xfloat:
709 ; SSE2: # BB#0: # %entry
710 ; SSE2-NEXT: movss {{.*#+}} xmm2 = xmm0[0],xmm2[1,2,3]
711 ; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm3[3,0]
712 ; SSE2-NEXT: shufps {{.*#+}} xmm3 = xmm3[0,1],xmm1[0,2]
713 ; SSE2-NEXT: movaps %xmm2, %xmm0
714 ; SSE2-NEXT: movaps %xmm3, %xmm1
717 ; SSSE3-LABEL: blend_shufflevector_8xfloat:
718 ; SSSE3: # BB#0: # %entry
719 ; SSSE3-NEXT: movss {{.*#+}} xmm2 = xmm0[0],xmm2[1,2,3]
720 ; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm3[3,0]
721 ; SSSE3-NEXT: shufps {{.*#+}} xmm3 = xmm3[0,1],xmm1[0,2]
722 ; SSSE3-NEXT: movaps %xmm2, %xmm0
723 ; SSSE3-NEXT: movaps %xmm3, %xmm1
726 ; SSE41-LABEL: blend_shufflevector_8xfloat:
727 ; SSE41: # BB#0: # %entry
728 ; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm2[1,2,3]
729 ; SSE41-NEXT: blendps {{.*#+}} xmm1 = xmm3[0,1],xmm1[2],xmm3[3]
732 ; AVX-LABEL: blend_shufflevector_8xfloat:
733 ; AVX: # BB#0: # %entry
734 ; AVX-NEXT: vblendps {{.*#+}} ymm0 = ymm0[0],ymm1[1,2,3,4,5],ymm0[6],ymm1[7]
737 %select = shufflevector <8 x float> %a, <8 x float> %b, <8 x i32> <i32 0, i32 9, i32 10, i32 11, i32 12, i32 13, i32 6, i32 15>
738 ret <8 x float> %select
741 define <4 x double> @blend_shufflevector_4xdouble(<4 x double> %a, <4 x double> %b) {
742 ; SSE2-LABEL: blend_shufflevector_4xdouble:
743 ; SSE2: # BB#0: # %entry
744 ; SSE2-NEXT: movsd {{.*#+}} xmm2 = xmm0[0],xmm2[1]
745 ; SSE2-NEXT: movapd %xmm2, %xmm0
748 ; SSSE3-LABEL: blend_shufflevector_4xdouble:
749 ; SSSE3: # BB#0: # %entry
750 ; SSSE3-NEXT: movsd {{.*#+}} xmm2 = xmm0[0],xmm2[1]
751 ; SSSE3-NEXT: movapd %xmm2, %xmm0
754 ; SSE41-LABEL: blend_shufflevector_4xdouble:
755 ; SSE41: # BB#0: # %entry
756 ; SSE41-NEXT: blendpd {{.*#+}} xmm0 = xmm0[0],xmm2[1]
759 ; AVX-LABEL: blend_shufflevector_4xdouble:
760 ; AVX: # BB#0: # %entry
761 ; AVX-NEXT: vblendpd {{.*#+}} ymm0 = ymm0[0],ymm1[1],ymm0[2,3]
764 %select = shufflevector <4 x double> %a, <4 x double> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 3>
765 ret <4 x double> %select
768 define <4 x i64> @blend_shufflevector_4xi64(<4 x i64> %a, <4 x i64> %b) {
769 ; SSE2-LABEL: blend_shufflevector_4xi64:
770 ; SSE2: # BB#0: # %entry
771 ; SSE2-NEXT: movsd {{.*#+}} xmm0 = xmm2[0],xmm0[1]
772 ; SSE2-NEXT: movaps %xmm3, %xmm1
775 ; SSSE3-LABEL: blend_shufflevector_4xi64:
776 ; SSSE3: # BB#0: # %entry
777 ; SSSE3-NEXT: movsd {{.*#+}} xmm0 = xmm2[0],xmm0[1]
778 ; SSSE3-NEXT: movaps %xmm3, %xmm1
781 ; SSE41-LABEL: blend_shufflevector_4xi64:
782 ; SSE41: # BB#0: # %entry
783 ; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm2[0,1,2,3],xmm0[4,5,6,7]
784 ; SSE41-NEXT: movaps %xmm3, %xmm1
787 ; AVX1-LABEL: blend_shufflevector_4xi64:
788 ; AVX1: # BB#0: # %entry
789 ; AVX1-NEXT: vblendpd {{.*#+}} ymm0 = ymm1[0],ymm0[1],ymm1[2,3]
792 ; AVX2-LABEL: blend_shufflevector_4xi64:
793 ; AVX2: # BB#0: # %entry
794 ; AVX2-NEXT: vpblendd {{.*#+}} ymm0 = ymm1[0,1],ymm0[2,3],ymm1[4,5,6,7]
797 %select = shufflevector <4 x i64> %a, <4 x i64> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 7>
798 ret <4 x i64> %select