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 = [0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255]
259 ; SSE2-NEXT: andps %xmm2, %xmm1
260 ; SSE2-NEXT: andnps %xmm0, %xmm2
261 ; SSE2-NEXT: orps %xmm1, %xmm2
262 ; SSE2-NEXT: movaps %xmm2, %xmm0
265 ; SSSE3-LABEL: vsel_i8:
266 ; SSSE3: # BB#0: # %entry
267 ; SSSE3-NEXT: pshufb {{.*#+}} xmm0 = xmm0[0],zero,zero,zero,xmm0[4],zero,zero,zero,xmm0[8],zero,zero,zero,xmm0[12],zero,zero,zero
268 ; SSSE3-NEXT: pshufb {{.*#+}} xmm1 = zero,xmm1[1,2,3],zero,xmm1[5,6,7],zero,xmm1[9,10,11],zero,xmm1[13,14,15]
269 ; SSSE3-NEXT: por %xmm1, %xmm0
272 ; SSE41-LABEL: vsel_i8:
273 ; SSE41: # BB#0: # %entry
274 ; SSE41-NEXT: movdqa %xmm0, %xmm2
275 ; SSE41-NEXT: movaps {{.*#+}} xmm0 = [0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255]
276 ; SSE41-NEXT: pblendvb %xmm1, %xmm2
277 ; SSE41-NEXT: movdqa %xmm2, %xmm0
280 ; AVX-LABEL: vsel_i8:
281 ; AVX: # BB#0: # %entry
282 ; AVX-NEXT: vmovdqa {{.*#+}} xmm2 = [0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255]
283 ; AVX-NEXT: vpblendvb %xmm2, %xmm1, %xmm0, %xmm0
286 %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
293 define <8 x float> @vsel_float8(<8 x float> %v1, <8 x float> %v2) {
294 ; SSE2-LABEL: vsel_float8:
295 ; SSE2: # BB#0: # %entry
296 ; SSE2-NEXT: movss {{.*#+}} xmm2 = xmm0[0],xmm2[1,2,3]
297 ; SSE2-NEXT: movss {{.*#+}} xmm3 = xmm1[0],xmm3[1,2,3]
298 ; SSE2-NEXT: movaps %xmm2, %xmm0
299 ; SSE2-NEXT: movaps %xmm3, %xmm1
302 ; SSSE3-LABEL: vsel_float8:
303 ; SSSE3: # BB#0: # %entry
304 ; SSSE3-NEXT: movss {{.*#+}} xmm2 = xmm0[0],xmm2[1,2,3]
305 ; SSSE3-NEXT: movss {{.*#+}} xmm3 = xmm1[0],xmm3[1,2,3]
306 ; SSSE3-NEXT: movaps %xmm2, %xmm0
307 ; SSSE3-NEXT: movaps %xmm3, %xmm1
310 ; SSE41-LABEL: vsel_float8:
311 ; SSE41: # BB#0: # %entry
312 ; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm2[1,2,3]
313 ; SSE41-NEXT: blendps {{.*#+}} xmm1 = xmm1[0],xmm3[1,2,3]
316 ; AVX-LABEL: vsel_float8:
317 ; AVX: # BB#0: # %entry
318 ; AVX-NEXT: vblendps {{.*#+}} ymm0 = ymm0[0],ymm1[1,2,3],ymm0[4],ymm1[5,6,7]
321 %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
322 ret <8 x float> %vsel
325 define <8 x i32> @vsel_i328(<8 x i32> %v1, <8 x i32> %v2) {
326 ; SSE2-LABEL: vsel_i328:
327 ; SSE2: # BB#0: # %entry
328 ; SSE2-NEXT: movss {{.*#+}} xmm2 = xmm0[0],xmm2[1,2,3]
329 ; SSE2-NEXT: movss {{.*#+}} xmm3 = xmm1[0],xmm3[1,2,3]
330 ; SSE2-NEXT: movaps %xmm2, %xmm0
331 ; SSE2-NEXT: movaps %xmm3, %xmm1
334 ; SSSE3-LABEL: vsel_i328:
335 ; SSSE3: # BB#0: # %entry
336 ; SSSE3-NEXT: movss {{.*#+}} xmm2 = xmm0[0],xmm2[1,2,3]
337 ; SSSE3-NEXT: movss {{.*#+}} xmm3 = xmm1[0],xmm3[1,2,3]
338 ; SSSE3-NEXT: movaps %xmm2, %xmm0
339 ; SSSE3-NEXT: movaps %xmm3, %xmm1
342 ; SSE41-LABEL: vsel_i328:
343 ; SSE41: # BB#0: # %entry
344 ; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3,4,5,6,7]
345 ; SSE41-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0,1],xmm3[2,3,4,5,6,7]
348 ; AVX1-LABEL: vsel_i328:
349 ; AVX1: # BB#0: # %entry
350 ; AVX1-NEXT: vblendps {{.*#+}} ymm0 = ymm0[0],ymm1[1,2,3],ymm0[4],ymm1[5,6,7]
353 ; AVX2-LABEL: vsel_i328:
354 ; AVX2: # BB#0: # %entry
355 ; AVX2-NEXT: vpblendd {{.*#+}} ymm0 = ymm0[0],ymm1[1,2,3],ymm0[4],ymm1[5,6,7]
358 %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
362 define <8 x double> @vsel_double8(<8 x double> %v1, <8 x double> %v2) {
363 ; SSE2-LABEL: vsel_double8:
364 ; SSE2: # BB#0: # %entry
365 ; SSE2-NEXT: movsd {{.*#+}} xmm4 = xmm0[0],xmm4[1]
366 ; SSE2-NEXT: movsd {{.*#+}} xmm6 = xmm2[0],xmm6[1]
367 ; SSE2-NEXT: movapd %xmm4, %xmm0
368 ; SSE2-NEXT: movaps %xmm5, %xmm1
369 ; SSE2-NEXT: movapd %xmm6, %xmm2
370 ; SSE2-NEXT: movaps %xmm7, %xmm3
373 ; SSSE3-LABEL: vsel_double8:
374 ; SSSE3: # BB#0: # %entry
375 ; SSSE3-NEXT: movsd {{.*#+}} xmm4 = xmm0[0],xmm4[1]
376 ; SSSE3-NEXT: movsd {{.*#+}} xmm6 = xmm2[0],xmm6[1]
377 ; SSSE3-NEXT: movapd %xmm4, %xmm0
378 ; SSSE3-NEXT: movaps %xmm5, %xmm1
379 ; SSSE3-NEXT: movapd %xmm6, %xmm2
380 ; SSSE3-NEXT: movaps %xmm7, %xmm3
383 ; SSE41-LABEL: vsel_double8:
384 ; SSE41: # BB#0: # %entry
385 ; SSE41-NEXT: blendpd {{.*#+}} xmm0 = xmm0[0],xmm4[1]
386 ; SSE41-NEXT: blendpd {{.*#+}} xmm2 = xmm2[0],xmm6[1]
387 ; SSE41-NEXT: movaps %xmm5, %xmm1
388 ; SSE41-NEXT: movaps %xmm7, %xmm3
391 ; AVX-LABEL: vsel_double8:
392 ; AVX: # BB#0: # %entry
393 ; AVX-NEXT: vblendpd {{.*#+}} ymm0 = ymm0[0],ymm2[1,2,3]
394 ; AVX-NEXT: vblendpd {{.*#+}} ymm1 = ymm1[0],ymm3[1,2,3]
397 %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
398 ret <8 x double> %vsel
401 define <8 x i64> @vsel_i648(<8 x i64> %v1, <8 x i64> %v2) {
402 ; SSE2-LABEL: vsel_i648:
403 ; SSE2: # BB#0: # %entry
404 ; SSE2-NEXT: movsd {{.*#+}} xmm4 = xmm0[0],xmm4[1]
405 ; SSE2-NEXT: movsd {{.*#+}} xmm6 = xmm2[0],xmm6[1]
406 ; SSE2-NEXT: movapd %xmm4, %xmm0
407 ; SSE2-NEXT: movaps %xmm5, %xmm1
408 ; SSE2-NEXT: movapd %xmm6, %xmm2
409 ; SSE2-NEXT: movaps %xmm7, %xmm3
412 ; SSSE3-LABEL: vsel_i648:
413 ; SSSE3: # BB#0: # %entry
414 ; SSSE3-NEXT: movsd {{.*#+}} xmm4 = xmm0[0],xmm4[1]
415 ; SSSE3-NEXT: movsd {{.*#+}} xmm6 = xmm2[0],xmm6[1]
416 ; SSSE3-NEXT: movapd %xmm4, %xmm0
417 ; SSSE3-NEXT: movaps %xmm5, %xmm1
418 ; SSSE3-NEXT: movapd %xmm6, %xmm2
419 ; SSSE3-NEXT: movaps %xmm7, %xmm3
422 ; SSE41-LABEL: vsel_i648:
423 ; SSE41: # BB#0: # %entry
424 ; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm4[4,5,6,7]
425 ; SSE41-NEXT: pblendw {{.*#+}} xmm2 = xmm2[0,1,2,3],xmm6[4,5,6,7]
426 ; SSE41-NEXT: movaps %xmm5, %xmm1
427 ; SSE41-NEXT: movaps %xmm7, %xmm3
430 ; AVX1-LABEL: vsel_i648:
431 ; AVX1: # BB#0: # %entry
432 ; AVX1-NEXT: vblendpd {{.*#+}} ymm0 = ymm0[0],ymm2[1,2,3]
433 ; AVX1-NEXT: vblendpd {{.*#+}} ymm1 = ymm1[0],ymm3[1,2,3]
436 ; AVX2-LABEL: vsel_i648:
437 ; AVX2: # BB#0: # %entry
438 ; AVX2-NEXT: vpblendd {{.*#+}} ymm0 = ymm0[0,1],ymm2[2,3,4,5,6,7]
439 ; AVX2-NEXT: vpblendd {{.*#+}} ymm1 = ymm1[0,1],ymm3[2,3,4,5,6,7]
442 %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
446 define <4 x double> @vsel_double4(<4 x double> %v1, <4 x double> %v2) {
447 ; SSE2-LABEL: vsel_double4:
448 ; SSE2: # BB#0: # %entry
449 ; SSE2-NEXT: movsd {{.*#+}} xmm2 = xmm0[0],xmm2[1]
450 ; SSE2-NEXT: movsd {{.*#+}} xmm3 = xmm1[0],xmm3[1]
451 ; SSE2-NEXT: movapd %xmm2, %xmm0
452 ; SSE2-NEXT: movapd %xmm3, %xmm1
455 ; SSSE3-LABEL: vsel_double4:
456 ; SSSE3: # BB#0: # %entry
457 ; SSSE3-NEXT: movsd {{.*#+}} xmm2 = xmm0[0],xmm2[1]
458 ; SSSE3-NEXT: movsd {{.*#+}} xmm3 = xmm1[0],xmm3[1]
459 ; SSSE3-NEXT: movapd %xmm2, %xmm0
460 ; SSSE3-NEXT: movapd %xmm3, %xmm1
463 ; SSE41-LABEL: vsel_double4:
464 ; SSE41: # BB#0: # %entry
465 ; SSE41-NEXT: blendpd {{.*#+}} xmm0 = xmm0[0],xmm2[1]
466 ; SSE41-NEXT: blendpd {{.*#+}} xmm1 = xmm1[0],xmm3[1]
469 ; AVX-LABEL: vsel_double4:
470 ; AVX: # BB#0: # %entry
471 ; AVX-NEXT: vblendpd {{.*#+}} ymm0 = ymm0[0],ymm1[1],ymm0[2],ymm1[3]
474 %vsel = select <4 x i1> <i1 true, i1 false, i1 true, i1 false>, <4 x double> %v1, <4 x double> %v2
475 ret <4 x double> %vsel
478 define <2 x double> @testa(<2 x double> %x, <2 x double> %y) {
480 ; SSE2: # BB#0: # %entry
481 ; SSE2-NEXT: movapd %xmm1, %xmm2
482 ; SSE2-NEXT: cmplepd %xmm0, %xmm2
483 ; SSE2-NEXT: andpd %xmm2, %xmm0
484 ; SSE2-NEXT: andnpd %xmm1, %xmm2
485 ; SSE2-NEXT: orpd %xmm2, %xmm0
488 ; SSSE3-LABEL: testa:
489 ; SSSE3: # BB#0: # %entry
490 ; SSSE3-NEXT: movapd %xmm1, %xmm2
491 ; SSSE3-NEXT: cmplepd %xmm0, %xmm2
492 ; SSSE3-NEXT: andpd %xmm2, %xmm0
493 ; SSSE3-NEXT: andnpd %xmm1, %xmm2
494 ; SSSE3-NEXT: orpd %xmm2, %xmm0
497 ; SSE41-LABEL: testa:
498 ; SSE41: # BB#0: # %entry
499 ; SSE41-NEXT: movapd %xmm0, %xmm2
500 ; SSE41-NEXT: movapd %xmm1, %xmm0
501 ; SSE41-NEXT: cmplepd %xmm2, %xmm0
502 ; SSE41-NEXT: blendvpd %xmm2, %xmm1
503 ; SSE41-NEXT: movapd %xmm1, %xmm0
507 ; AVX: # BB#0: # %entry
508 ; AVX-NEXT: vcmplepd %xmm0, %xmm1, %xmm2
509 ; AVX-NEXT: vblendvpd %xmm2, %xmm0, %xmm1, %xmm0
512 %max_is_x = fcmp oge <2 x double> %x, %y
513 %max = select <2 x i1> %max_is_x, <2 x double> %x, <2 x double> %y
514 ret <2 x double> %max
517 define <2 x double> @testb(<2 x double> %x, <2 x double> %y) {
519 ; SSE2: # BB#0: # %entry
520 ; SSE2-NEXT: movapd %xmm1, %xmm2
521 ; SSE2-NEXT: cmpnlepd %xmm0, %xmm2
522 ; SSE2-NEXT: andpd %xmm2, %xmm0
523 ; SSE2-NEXT: andnpd %xmm1, %xmm2
524 ; SSE2-NEXT: orpd %xmm2, %xmm0
527 ; SSSE3-LABEL: testb:
528 ; SSSE3: # BB#0: # %entry
529 ; SSSE3-NEXT: movapd %xmm1, %xmm2
530 ; SSSE3-NEXT: cmpnlepd %xmm0, %xmm2
531 ; SSSE3-NEXT: andpd %xmm2, %xmm0
532 ; SSSE3-NEXT: andnpd %xmm1, %xmm2
533 ; SSSE3-NEXT: orpd %xmm2, %xmm0
536 ; SSE41-LABEL: testb:
537 ; SSE41: # BB#0: # %entry
538 ; SSE41-NEXT: movapd %xmm0, %xmm2
539 ; SSE41-NEXT: movapd %xmm1, %xmm0
540 ; SSE41-NEXT: cmpnlepd %xmm2, %xmm0
541 ; SSE41-NEXT: blendvpd %xmm2, %xmm1
542 ; SSE41-NEXT: movapd %xmm1, %xmm0
546 ; AVX: # BB#0: # %entry
547 ; AVX-NEXT: vcmpnlepd %xmm0, %xmm1, %xmm2
548 ; AVX-NEXT: vblendvpd %xmm2, %xmm0, %xmm1, %xmm0
551 %min_is_x = fcmp ult <2 x double> %x, %y
552 %min = select <2 x i1> %min_is_x, <2 x double> %x, <2 x double> %y
553 ret <2 x double> %min
556 ; If we can figure out a blend has a constant mask, we should emit the
557 ; blend instruction with an immediate mask
558 define <4 x double> @constant_blendvpd_avx(<4 x double> %xy, <4 x double> %ab) {
559 ; SSE2-LABEL: constant_blendvpd_avx:
560 ; SSE2: # BB#0: # %entry
561 ; SSE2-NEXT: movsd {{.*#+}} xmm3 = xmm1[0],xmm3[1]
562 ; SSE2-NEXT: movaps %xmm2, %xmm0
563 ; SSE2-NEXT: movapd %xmm3, %xmm1
566 ; SSSE3-LABEL: constant_blendvpd_avx:
567 ; SSSE3: # BB#0: # %entry
568 ; SSSE3-NEXT: movsd {{.*#+}} xmm3 = xmm1[0],xmm3[1]
569 ; SSSE3-NEXT: movaps %xmm2, %xmm0
570 ; SSSE3-NEXT: movapd %xmm3, %xmm1
573 ; SSE41-LABEL: constant_blendvpd_avx:
574 ; SSE41: # BB#0: # %entry
575 ; SSE41-NEXT: blendpd {{.*#+}} xmm1 = xmm1[0],xmm3[1]
576 ; SSE41-NEXT: movaps %xmm2, %xmm0
579 ; AVX-LABEL: constant_blendvpd_avx:
580 ; AVX: # BB#0: # %entry
581 ; AVX-NEXT: vblendpd {{.*#+}} ymm0 = ymm1[0,1],ymm0[2],ymm1[3]
584 %select = select <4 x i1> <i1 false, i1 false, i1 true, i1 false>, <4 x double> %xy, <4 x double> %ab
585 ret <4 x double> %select
588 define <8 x float> @constant_blendvps_avx(<8 x float> %xyzw, <8 x float> %abcd) {
589 ; SSE2-LABEL: constant_blendvps_avx:
590 ; SSE2: # BB#0: # %entry
591 ; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,0],xmm2[2,0]
592 ; SSE2-NEXT: shufps {{.*#+}} xmm2 = xmm2[0,1],xmm0[2,0]
593 ; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[3,0],xmm3[2,0]
594 ; SSE2-NEXT: shufps {{.*#+}} xmm3 = xmm3[0,1],xmm1[2,0]
595 ; SSE2-NEXT: movaps %xmm2, %xmm0
596 ; SSE2-NEXT: movaps %xmm3, %xmm1
599 ; SSSE3-LABEL: constant_blendvps_avx:
600 ; SSSE3: # BB#0: # %entry
601 ; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,0],xmm2[2,0]
602 ; SSSE3-NEXT: shufps {{.*#+}} xmm2 = xmm2[0,1],xmm0[2,0]
603 ; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[3,0],xmm3[2,0]
604 ; SSSE3-NEXT: shufps {{.*#+}} xmm3 = xmm3[0,1],xmm1[2,0]
605 ; SSSE3-NEXT: movaps %xmm2, %xmm0
606 ; SSSE3-NEXT: movaps %xmm3, %xmm1
609 ; SSE41-LABEL: constant_blendvps_avx:
610 ; SSE41: # BB#0: # %entry
611 ; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm2[0,1,2],xmm0[3]
612 ; SSE41-NEXT: blendps {{.*#+}} xmm1 = xmm3[0,1,2],xmm1[3]
615 ; AVX-LABEL: constant_blendvps_avx:
616 ; AVX: # BB#0: # %entry
617 ; AVX-NEXT: vblendps {{.*#+}} ymm0 = ymm1[0,1,2],ymm0[3],ymm1[4,5,6],ymm0[7]
620 %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
621 ret <8 x float> %select
624 define <32 x i8> @constant_pblendvb_avx2(<32 x i8> %xyzw, <32 x i8> %abcd) {
625 ; SSE2-LABEL: constant_pblendvb_avx2:
626 ; SSE2: # BB#0: # %entry
627 ; SSE2-NEXT: movaps {{.*#+}} xmm4 = [255,255,0,255,0,0,0,255,255,255,0,255,0,0,0,255]
628 ; SSE2-NEXT: movaps %xmm4, %xmm5
629 ; SSE2-NEXT: andnps %xmm0, %xmm5
630 ; SSE2-NEXT: andps %xmm4, %xmm2
631 ; SSE2-NEXT: orps %xmm2, %xmm5
632 ; SSE2-NEXT: andps %xmm4, %xmm3
633 ; SSE2-NEXT: andnps %xmm1, %xmm4
634 ; SSE2-NEXT: orps %xmm3, %xmm4
635 ; SSE2-NEXT: movaps %xmm5, %xmm0
636 ; SSE2-NEXT: movaps %xmm4, %xmm1
639 ; SSSE3-LABEL: constant_pblendvb_avx2:
640 ; SSSE3: # BB#0: # %entry
641 ; SSSE3-NEXT: movdqa {{.*#+}} xmm4 = [128,128,2,128,4,5,6,128,128,128,10,128,12,13,14,128]
642 ; SSSE3-NEXT: pshufb %xmm4, %xmm0
643 ; SSSE3-NEXT: movdqa {{.*#+}} xmm5 = [0,1,128,3,128,128,128,7,8,9,128,11,128,128,128,15]
644 ; SSSE3-NEXT: pshufb %xmm5, %xmm2
645 ; SSSE3-NEXT: por %xmm2, %xmm0
646 ; SSSE3-NEXT: pshufb %xmm4, %xmm1
647 ; SSSE3-NEXT: pshufb %xmm5, %xmm3
648 ; SSSE3-NEXT: por %xmm3, %xmm1
651 ; SSE41-LABEL: constant_pblendvb_avx2:
652 ; SSE41: # BB#0: # %entry
653 ; SSE41-NEXT: movdqa %xmm0, %xmm4
654 ; SSE41-NEXT: movaps {{.*#+}} xmm0 = [255,255,0,255,0,0,0,255,255,255,0,255,0,0,0,255]
655 ; SSE41-NEXT: pblendvb %xmm2, %xmm4
656 ; SSE41-NEXT: pblendvb %xmm3, %xmm1
657 ; SSE41-NEXT: movdqa %xmm4, %xmm0
660 ; AVX1-LABEL: constant_pblendvb_avx2:
661 ; AVX1: # BB#0: # %entry
662 ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2
663 ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3
664 ; AVX1-NEXT: vmovdqa .LCPI18_0(%rip), %xmm4 # xmm4 = [255,255,0,255,0,0,0,255,255,255,0,255,0,0,0,255]
665 ; AVX1-NEXT: vpblendvb %xmm4, %xmm2, %xmm3, %xmm2
666 ; AVX1-NEXT: vpblendvb %xmm4, %xmm1, %xmm0, %xmm0
667 ; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0
670 ; AVX2-LABEL: constant_pblendvb_avx2:
671 ; AVX2: # BB#0: # %entry
672 ; AVX2-NEXT: vmovdqa {{.*#+}} ymm2 = [0,0,255,0,255,255,255,0,0,0,255,0,255,255,255,0,0,0,255,0,255,255,255,0,0,0,255,0,255,255,255,0]
673 ; AVX2-NEXT: vpblendvb %ymm2, %ymm0, %ymm1, %ymm0
676 %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
677 ret <32 x i8> %select
680 declare <8 x float> @llvm.x86.avx.blendv.ps.256(<8 x float>, <8 x float>, <8 x float>)
681 declare <4 x double> @llvm.x86.avx.blendv.pd.256(<4 x double>, <4 x double>, <4 x double>)
683 ;; 4 tests for shufflevectors that optimize to blend + immediate
684 define <4 x float> @blend_shufflevector_4xfloat(<4 x float> %a, <4 x float> %b) {
685 ; SSE2-LABEL: blend_shufflevector_4xfloat:
686 ; SSE2: # BB#0: # %entry
687 ; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[1,3]
688 ; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2,1,3]
691 ; SSSE3-LABEL: blend_shufflevector_4xfloat:
692 ; SSSE3: # BB#0: # %entry
693 ; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[1,3]
694 ; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2,1,3]
697 ; SSE41-LABEL: blend_shufflevector_4xfloat:
698 ; SSE41: # BB#0: # %entry
699 ; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
702 ; AVX-LABEL: blend_shufflevector_4xfloat:
703 ; AVX: # BB#0: # %entry
704 ; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
707 %select = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
708 ret <4 x float> %select
711 define <8 x float> @blend_shufflevector_8xfloat(<8 x float> %a, <8 x float> %b) {
712 ; SSE2-LABEL: blend_shufflevector_8xfloat:
713 ; SSE2: # BB#0: # %entry
714 ; SSE2-NEXT: movss {{.*#+}} xmm2 = xmm0[0],xmm2[1,2,3]
715 ; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm3[3,0]
716 ; SSE2-NEXT: shufps {{.*#+}} xmm3 = xmm3[0,1],xmm1[0,2]
717 ; SSE2-NEXT: movaps %xmm2, %xmm0
718 ; SSE2-NEXT: movaps %xmm3, %xmm1
721 ; SSSE3-LABEL: blend_shufflevector_8xfloat:
722 ; SSSE3: # BB#0: # %entry
723 ; SSSE3-NEXT: movss {{.*#+}} xmm2 = xmm0[0],xmm2[1,2,3]
724 ; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm3[3,0]
725 ; SSSE3-NEXT: shufps {{.*#+}} xmm3 = xmm3[0,1],xmm1[0,2]
726 ; SSSE3-NEXT: movaps %xmm2, %xmm0
727 ; SSSE3-NEXT: movaps %xmm3, %xmm1
730 ; SSE41-LABEL: blend_shufflevector_8xfloat:
731 ; SSE41: # BB#0: # %entry
732 ; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm2[1,2,3]
733 ; SSE41-NEXT: blendps {{.*#+}} xmm1 = xmm3[0,1],xmm1[2],xmm3[3]
736 ; AVX-LABEL: blend_shufflevector_8xfloat:
737 ; AVX: # BB#0: # %entry
738 ; AVX-NEXT: vblendps {{.*#+}} ymm0 = ymm0[0],ymm1[1,2,3,4,5],ymm0[6],ymm1[7]
741 %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>
742 ret <8 x float> %select
745 define <4 x double> @blend_shufflevector_4xdouble(<4 x double> %a, <4 x double> %b) {
746 ; SSE2-LABEL: blend_shufflevector_4xdouble:
747 ; SSE2: # BB#0: # %entry
748 ; SSE2-NEXT: movsd {{.*#+}} xmm2 = xmm0[0],xmm2[1]
749 ; SSE2-NEXT: movapd %xmm2, %xmm0
752 ; SSSE3-LABEL: blend_shufflevector_4xdouble:
753 ; SSSE3: # BB#0: # %entry
754 ; SSSE3-NEXT: movsd {{.*#+}} xmm2 = xmm0[0],xmm2[1]
755 ; SSSE3-NEXT: movapd %xmm2, %xmm0
758 ; SSE41-LABEL: blend_shufflevector_4xdouble:
759 ; SSE41: # BB#0: # %entry
760 ; SSE41-NEXT: blendpd {{.*#+}} xmm0 = xmm0[0],xmm2[1]
763 ; AVX-LABEL: blend_shufflevector_4xdouble:
764 ; AVX: # BB#0: # %entry
765 ; AVX-NEXT: vblendpd {{.*#+}} ymm0 = ymm0[0],ymm1[1],ymm0[2,3]
768 %select = shufflevector <4 x double> %a, <4 x double> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 3>
769 ret <4 x double> %select
772 define <4 x i64> @blend_shufflevector_4xi64(<4 x i64> %a, <4 x i64> %b) {
773 ; SSE2-LABEL: blend_shufflevector_4xi64:
774 ; SSE2: # BB#0: # %entry
775 ; SSE2-NEXT: movsd {{.*#+}} xmm0 = xmm2[0],xmm0[1]
776 ; SSE2-NEXT: movaps %xmm3, %xmm1
779 ; SSSE3-LABEL: blend_shufflevector_4xi64:
780 ; SSSE3: # BB#0: # %entry
781 ; SSSE3-NEXT: movsd {{.*#+}} xmm0 = xmm2[0],xmm0[1]
782 ; SSSE3-NEXT: movaps %xmm3, %xmm1
785 ; SSE41-LABEL: blend_shufflevector_4xi64:
786 ; SSE41: # BB#0: # %entry
787 ; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm2[0,1,2,3],xmm0[4,5,6,7]
788 ; SSE41-NEXT: movaps %xmm3, %xmm1
791 ; AVX1-LABEL: blend_shufflevector_4xi64:
792 ; AVX1: # BB#0: # %entry
793 ; AVX1-NEXT: vblendpd {{.*#+}} ymm0 = ymm1[0],ymm0[1],ymm1[2,3]
796 ; AVX2-LABEL: blend_shufflevector_4xi64:
797 ; AVX2: # BB#0: # %entry
798 ; AVX2-NEXT: vpblendd {{.*#+}} ymm0 = ymm1[0,1],ymm0[2,3],ymm1[4,5,6,7]
801 %select = shufflevector <4 x i64> %a, <4 x i64> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 7>
802 ret <4 x i64> %select