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: andps {{.*}}(%rip), %xmm1
13 ; SSE2-NEXT: andps {{.*}}(%rip), %xmm0
14 ; SSE2-NEXT: orps %xmm1, %xmm0
17 ; SSSE3-LABEL: vsel_float:
18 ; SSSE3: # BB#0: # %entry
19 ; SSSE3-NEXT: andps {{.*}}(%rip), %xmm1
20 ; SSSE3-NEXT: andps {{.*}}(%rip), %xmm0
21 ; SSSE3-NEXT: orps %xmm1, %xmm0
24 ; SSE41-LABEL: vsel_float:
25 ; SSE41: # BB#0: # %entry
26 ; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
29 ; AVX-LABEL: vsel_float:
30 ; AVX: # BB#0: # %entry
31 ; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
34 %vsel = select <4 x i1> <i1 true, i1 false, i1 true, i1 false>, <4 x float> %v1, <4 x float> %v2
38 define <4 x float> @vsel_float2(<4 x float> %v1, <4 x float> %v2) {
39 ; SSE2-LABEL: vsel_float2:
40 ; SSE2: # BB#0: # %entry
41 ; SSE2-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]
42 ; SSE2-NEXT: movaps %xmm1, %xmm0
45 ; SSSE3-LABEL: vsel_float2:
46 ; SSSE3: # BB#0: # %entry
47 ; SSSE3-NEXT: movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]
48 ; SSSE3-NEXT: movaps %xmm1, %xmm0
51 ; SSE41-LABEL: vsel_float2:
52 ; SSE41: # BB#0: # %entry
53 ; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]
56 ; AVX-LABEL: vsel_float2:
57 ; AVX: # BB#0: # %entry
58 ; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]
61 %vsel = select <4 x i1> <i1 true, i1 false, i1 false, i1 false>, <4 x float> %v1, <4 x float> %v2
65 define <4 x i8> @vsel_4xi8(<4 x i8> %v1, <4 x i8> %v2) {
66 ; SSE2-LABEL: vsel_4xi8:
67 ; SSE2: # BB#0: # %entry
68 ; SSE2-NEXT: andps {{.*}}(%rip), %xmm1
69 ; SSE2-NEXT: andps {{.*}}(%rip), %xmm0
70 ; SSE2-NEXT: orps %xmm1, %xmm0
73 ; SSSE3-LABEL: vsel_4xi8:
74 ; SSSE3: # BB#0: # %entry
75 ; SSSE3-NEXT: andps {{.*}}(%rip), %xmm1
76 ; SSSE3-NEXT: andps {{.*}}(%rip), %xmm0
77 ; SSSE3-NEXT: orps %xmm1, %xmm0
80 ; SSE41-LABEL: vsel_4xi8:
81 ; SSE41: # BB#0: # %entry
82 ; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5],xmm0[6,7]
85 ; AVX1-LABEL: vsel_4xi8:
86 ; AVX1: # BB#0: # %entry
87 ; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5],xmm0[6,7]
90 ; AVX2-LABEL: vsel_4xi8:
91 ; AVX2: # BB#0: # %entry
92 ; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0,1],xmm1[2],xmm0[3]
95 %vsel = select <4 x i1> <i1 true, i1 true, i1 false, i1 true>, <4 x i8> %v1, <4 x i8> %v2
99 define <4 x i16> @vsel_4xi16(<4 x i16> %v1, <4 x i16> %v2) {
100 ; SSE2-LABEL: vsel_4xi16:
101 ; SSE2: # BB#0: # %entry
102 ; SSE2-NEXT: andps {{.*}}(%rip), %xmm1
103 ; SSE2-NEXT: andps {{.*}}(%rip), %xmm0
104 ; SSE2-NEXT: orps %xmm1, %xmm0
107 ; SSSE3-LABEL: vsel_4xi16:
108 ; SSSE3: # BB#0: # %entry
109 ; SSSE3-NEXT: andps {{.*}}(%rip), %xmm1
110 ; SSSE3-NEXT: andps {{.*}}(%rip), %xmm0
111 ; SSSE3-NEXT: orps %xmm1, %xmm0
114 ; SSE41-LABEL: vsel_4xi16:
115 ; SSE41: # BB#0: # %entry
116 ; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5,6,7]
119 ; AVX1-LABEL: vsel_4xi16:
120 ; AVX1: # BB#0: # %entry
121 ; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5,6,7]
124 ; AVX2-LABEL: vsel_4xi16:
125 ; AVX2: # BB#0: # %entry
126 ; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2,3]
129 %vsel = select <4 x i1> <i1 true, i1 false, i1 true, i1 true>, <4 x i16> %v1, <4 x i16> %v2
133 define <4 x i32> @vsel_i32(<4 x i32> %v1, <4 x i32> %v2) {
134 ; SSE2-LABEL: vsel_i32:
135 ; SSE2: # BB#0: # %entry
136 ; SSE2-NEXT: andps {{.*}}(%rip), %xmm1
137 ; SSE2-NEXT: andps {{.*}}(%rip), %xmm0
138 ; SSE2-NEXT: orps %xmm1, %xmm0
141 ; SSSE3-LABEL: vsel_i32:
142 ; SSSE3: # BB#0: # %entry
143 ; SSSE3-NEXT: andps {{.*}}(%rip), %xmm1
144 ; SSSE3-NEXT: andps {{.*}}(%rip), %xmm0
145 ; SSSE3-NEXT: orps %xmm1, %xmm0
148 ; SSE41-LABEL: vsel_i32:
149 ; SSE41: # BB#0: # %entry
150 ; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7]
153 ; AVX1-LABEL: vsel_i32:
154 ; AVX1: # BB#0: # %entry
155 ; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7]
158 ; AVX2-LABEL: vsel_i32:
159 ; AVX2: # BB#0: # %entry
160 ; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
163 %vsel = select <4 x i1> <i1 true, i1 false, i1 true, i1 false>, <4 x i32> %v1, <4 x i32> %v2
167 define <2 x double> @vsel_double(<2 x double> %v1, <2 x double> %v2) {
168 ; SSE2-LABEL: vsel_double:
169 ; SSE2: # BB#0: # %entry
170 ; SSE2-NEXT: movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1]
171 ; SSE2-NEXT: movapd %xmm1, %xmm0
174 ; SSSE3-LABEL: vsel_double:
175 ; SSSE3: # BB#0: # %entry
176 ; SSSE3-NEXT: movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1]
177 ; SSSE3-NEXT: movapd %xmm1, %xmm0
180 ; SSE41-LABEL: vsel_double:
181 ; SSE41: # BB#0: # %entry
182 ; SSE41-NEXT: blendpd {{.*#+}} xmm0 = xmm0[0],xmm1[1]
185 ; AVX-LABEL: vsel_double:
186 ; AVX: # BB#0: # %entry
187 ; AVX-NEXT: vblendpd {{.*#+}} xmm0 = xmm0[0],xmm1[1]
190 %vsel = select <2 x i1> <i1 true, i1 false>, <2 x double> %v1, <2 x double> %v2
191 ret <2 x double> %vsel
194 define <2 x i64> @vsel_i64(<2 x i64> %v1, <2 x i64> %v2) {
195 ; SSE2-LABEL: vsel_i64:
196 ; SSE2: # BB#0: # %entry
197 ; SSE2-NEXT: movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1]
198 ; SSE2-NEXT: movapd %xmm1, %xmm0
201 ; SSSE3-LABEL: vsel_i64:
202 ; SSSE3: # BB#0: # %entry
203 ; SSSE3-NEXT: movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1]
204 ; SSSE3-NEXT: movapd %xmm1, %xmm0
207 ; SSE41-LABEL: vsel_i64:
208 ; SSE41: # BB#0: # %entry
209 ; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5,6,7]
212 ; AVX1-LABEL: vsel_i64:
213 ; AVX1: # BB#0: # %entry
214 ; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5,6,7]
217 ; AVX2-LABEL: vsel_i64:
218 ; AVX2: # BB#0: # %entry
219 ; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]
222 %vsel = select <2 x i1> <i1 true, i1 false>, <2 x i64> %v1, <2 x i64> %v2
226 define <8 x i16> @vsel_8xi16(<8 x i16> %v1, <8 x i16> %v2) {
227 ; SSE2-LABEL: vsel_8xi16:
228 ; SSE2: # BB#0: # %entry
229 ; SSE2-NEXT: andps {{.*}}(%rip), %xmm1
230 ; SSE2-NEXT: andps {{.*}}(%rip), %xmm0
231 ; SSE2-NEXT: orps %xmm1, %xmm0
234 ; SSSE3-LABEL: vsel_8xi16:
235 ; SSSE3: # BB#0: # %entry
236 ; SSSE3-NEXT: andps {{.*}}(%rip), %xmm1
237 ; SSSE3-NEXT: andps {{.*}}(%rip), %xmm0
238 ; SSSE3-NEXT: orps %xmm1, %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: andps {{.*}}(%rip), %xmm1
259 ; SSE2-NEXT: andps {{.*}}(%rip), %xmm0
260 ; SSE2-NEXT: orps %xmm1, %xmm0
263 ; SSSE3-LABEL: vsel_i8:
264 ; SSSE3: # BB#0: # %entry
265 ; SSSE3-NEXT: andps {{.*}}(%rip), %xmm1
266 ; SSSE3-NEXT: andps {{.*}}(%rip), %xmm0
267 ; SSSE3-NEXT: orps %xmm1, %xmm0
270 ; SSE41-LABEL: vsel_i8:
271 ; SSE41: # BB#0: # %entry
272 ; SSE41-NEXT: movdqa %xmm0, %xmm2
273 ; SSE41-NEXT: movaps {{.*#+}} xmm0 = [255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0]
274 ; SSE41-NEXT: pblendvb %xmm2, %xmm1
275 ; SSE41-NEXT: movdqa %xmm1, %xmm0
278 ; AVX-LABEL: vsel_i8:
279 ; AVX: # BB#0: # %entry
280 ; AVX-NEXT: vmovdqa {{.*#+}} xmm2 = [255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0]
281 ; AVX-NEXT: vpblendvb %xmm2, %xmm0, %xmm1, %xmm0
284 %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
291 define <8 x float> @vsel_float8(<8 x float> %v1, <8 x float> %v2) {
292 ; SSE2-LABEL: vsel_float8:
293 ; SSE2: # BB#0: # %entry
294 ; SSE2-NEXT: movss {{.*#+}} xmm2 = xmm0[0],xmm2[1,2,3]
295 ; SSE2-NEXT: movss {{.*#+}} xmm3 = xmm1[0],xmm3[1,2,3]
296 ; SSE2-NEXT: movaps %xmm2, %xmm0
297 ; SSE2-NEXT: movaps %xmm3, %xmm1
300 ; SSSE3-LABEL: vsel_float8:
301 ; SSSE3: # BB#0: # %entry
302 ; SSSE3-NEXT: movss {{.*#+}} xmm2 = xmm0[0],xmm2[1,2,3]
303 ; SSSE3-NEXT: movss {{.*#+}} xmm3 = xmm1[0],xmm3[1,2,3]
304 ; SSSE3-NEXT: movaps %xmm2, %xmm0
305 ; SSSE3-NEXT: movaps %xmm3, %xmm1
308 ; SSE41-LABEL: vsel_float8:
309 ; SSE41: # BB#0: # %entry
310 ; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm2[1,2,3]
311 ; SSE41-NEXT: blendps {{.*#+}} xmm1 = xmm1[0],xmm3[1,2,3]
314 ; AVX-LABEL: vsel_float8:
315 ; AVX: # BB#0: # %entry
316 ; AVX-NEXT: vblendps {{.*#+}} ymm0 = ymm0[0],ymm1[1,2,3],ymm0[4],ymm1[5,6,7]
319 %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
320 ret <8 x float> %vsel
323 define <8 x i32> @vsel_i328(<8 x i32> %v1, <8 x i32> %v2) {
324 ; SSE2-LABEL: vsel_i328:
325 ; SSE2: # BB#0: # %entry
326 ; SSE2-NEXT: movss {{.*#+}} xmm2 = xmm0[0],xmm2[1,2,3]
327 ; SSE2-NEXT: movss {{.*#+}} xmm3 = xmm1[0],xmm3[1,2,3]
328 ; SSE2-NEXT: movaps %xmm2, %xmm0
329 ; SSE2-NEXT: movaps %xmm3, %xmm1
332 ; SSSE3-LABEL: vsel_i328:
333 ; SSSE3: # BB#0: # %entry
334 ; SSSE3-NEXT: movss {{.*#+}} xmm2 = xmm0[0],xmm2[1,2,3]
335 ; SSSE3-NEXT: movss {{.*#+}} xmm3 = xmm1[0],xmm3[1,2,3]
336 ; SSSE3-NEXT: movaps %xmm2, %xmm0
337 ; SSSE3-NEXT: movaps %xmm3, %xmm1
340 ; SSE41-LABEL: vsel_i328:
341 ; SSE41: # BB#0: # %entry
342 ; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3,4,5,6,7]
343 ; SSE41-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0,1],xmm3[2,3,4,5,6,7]
346 ; AVX1-LABEL: vsel_i328:
347 ; AVX1: # BB#0: # %entry
348 ; AVX1-NEXT: vblendps {{.*#+}} ymm0 = ymm0[0],ymm1[1,2,3],ymm0[4],ymm1[5,6,7]
351 ; AVX2-LABEL: vsel_i328:
352 ; AVX2: # BB#0: # %entry
353 ; AVX2-NEXT: vpblendd {{.*#+}} ymm0 = ymm0[0],ymm1[1,2,3],ymm0[4],ymm1[5,6,7]
356 %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
360 define <8 x double> @vsel_double8(<8 x double> %v1, <8 x double> %v2) {
361 ; SSE2-LABEL: vsel_double8:
362 ; SSE2: # BB#0: # %entry
363 ; SSE2-NEXT: movsd {{.*#+}} xmm4 = xmm0[0],xmm4[1]
364 ; SSE2-NEXT: movsd {{.*#+}} xmm6 = xmm2[0],xmm6[1]
365 ; SSE2-NEXT: movapd %xmm4, %xmm0
366 ; SSE2-NEXT: movaps %xmm5, %xmm1
367 ; SSE2-NEXT: movapd %xmm6, %xmm2
368 ; SSE2-NEXT: movaps %xmm7, %xmm3
371 ; SSSE3-LABEL: vsel_double8:
372 ; SSSE3: # BB#0: # %entry
373 ; SSSE3-NEXT: movsd {{.*#+}} xmm4 = xmm0[0],xmm4[1]
374 ; SSSE3-NEXT: movsd {{.*#+}} xmm6 = xmm2[0],xmm6[1]
375 ; SSSE3-NEXT: movapd %xmm4, %xmm0
376 ; SSSE3-NEXT: movaps %xmm5, %xmm1
377 ; SSSE3-NEXT: movapd %xmm6, %xmm2
378 ; SSSE3-NEXT: movaps %xmm7, %xmm3
381 ; SSE41-LABEL: vsel_double8:
382 ; SSE41: # BB#0: # %entry
383 ; SSE41-NEXT: blendpd {{.*#+}} xmm0 = xmm0[0],xmm4[1]
384 ; SSE41-NEXT: blendpd {{.*#+}} xmm2 = xmm2[0],xmm6[1]
385 ; SSE41-NEXT: movaps %xmm5, %xmm1
386 ; SSE41-NEXT: movaps %xmm7, %xmm3
389 ; AVX-LABEL: vsel_double8:
390 ; AVX: # BB#0: # %entry
391 ; AVX-NEXT: vblendpd {{.*#+}} ymm0 = ymm0[0],ymm2[1,2,3]
392 ; AVX-NEXT: vblendpd {{.*#+}} ymm1 = ymm1[0],ymm3[1,2,3]
395 %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
396 ret <8 x double> %vsel
399 define <8 x i64> @vsel_i648(<8 x i64> %v1, <8 x i64> %v2) {
400 ; SSE2-LABEL: vsel_i648:
401 ; SSE2: # BB#0: # %entry
402 ; SSE2-NEXT: movsd {{.*#+}} xmm4 = xmm0[0],xmm4[1]
403 ; SSE2-NEXT: movsd {{.*#+}} xmm6 = xmm2[0],xmm6[1]
404 ; SSE2-NEXT: movapd %xmm4, %xmm0
405 ; SSE2-NEXT: movaps %xmm5, %xmm1
406 ; SSE2-NEXT: movapd %xmm6, %xmm2
407 ; SSE2-NEXT: movaps %xmm7, %xmm3
410 ; SSSE3-LABEL: vsel_i648:
411 ; SSSE3: # BB#0: # %entry
412 ; SSSE3-NEXT: movsd {{.*#+}} xmm4 = xmm0[0],xmm4[1]
413 ; SSSE3-NEXT: movsd {{.*#+}} xmm6 = xmm2[0],xmm6[1]
414 ; SSSE3-NEXT: movapd %xmm4, %xmm0
415 ; SSSE3-NEXT: movaps %xmm5, %xmm1
416 ; SSSE3-NEXT: movapd %xmm6, %xmm2
417 ; SSSE3-NEXT: movaps %xmm7, %xmm3
420 ; SSE41-LABEL: vsel_i648:
421 ; SSE41: # BB#0: # %entry
422 ; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm4[4,5,6,7]
423 ; SSE41-NEXT: pblendw {{.*#+}} xmm2 = xmm2[0,1,2,3],xmm6[4,5,6,7]
424 ; SSE41-NEXT: movaps %xmm5, %xmm1
425 ; SSE41-NEXT: movaps %xmm7, %xmm3
428 ; AVX1-LABEL: vsel_i648:
429 ; AVX1: # BB#0: # %entry
430 ; AVX1-NEXT: vblendpd {{.*#+}} ymm0 = ymm0[0],ymm2[1,2,3]
431 ; AVX1-NEXT: vblendpd {{.*#+}} ymm1 = ymm1[0],ymm3[1,2,3]
434 ; AVX2-LABEL: vsel_i648:
435 ; AVX2: # BB#0: # %entry
436 ; AVX2-NEXT: vpblendd {{.*#+}} ymm0 = ymm0[0,1],ymm2[2,3,4,5,6,7]
437 ; AVX2-NEXT: vpblendd {{.*#+}} ymm1 = ymm1[0,1],ymm3[2,3,4,5,6,7]
440 %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
444 define <4 x double> @vsel_double4(<4 x double> %v1, <4 x double> %v2) {
445 ; SSE2-LABEL: vsel_double4:
446 ; SSE2: # BB#0: # %entry
447 ; SSE2-NEXT: movsd {{.*#+}} xmm2 = xmm0[0],xmm2[1]
448 ; SSE2-NEXT: movsd {{.*#+}} xmm3 = xmm1[0],xmm3[1]
449 ; SSE2-NEXT: movapd %xmm2, %xmm0
450 ; SSE2-NEXT: movapd %xmm3, %xmm1
453 ; SSSE3-LABEL: vsel_double4:
454 ; SSSE3: # BB#0: # %entry
455 ; SSSE3-NEXT: movsd {{.*#+}} xmm2 = xmm0[0],xmm2[1]
456 ; SSSE3-NEXT: movsd {{.*#+}} xmm3 = xmm1[0],xmm3[1]
457 ; SSSE3-NEXT: movapd %xmm2, %xmm0
458 ; SSSE3-NEXT: movapd %xmm3, %xmm1
461 ; SSE41-LABEL: vsel_double4:
462 ; SSE41: # BB#0: # %entry
463 ; SSE41-NEXT: blendpd {{.*#+}} xmm0 = xmm0[0],xmm2[1]
464 ; SSE41-NEXT: blendpd {{.*#+}} xmm1 = xmm1[0],xmm3[1]
467 ; AVX-LABEL: vsel_double4:
468 ; AVX: # BB#0: # %entry
469 ; AVX-NEXT: vblendpd {{.*#+}} ymm0 = ymm0[0],ymm1[1],ymm0[2],ymm1[3]
472 %vsel = select <4 x i1> <i1 true, i1 false, i1 true, i1 false>, <4 x double> %v1, <4 x double> %v2
473 ret <4 x double> %vsel
476 define <2 x double> @testa(<2 x double> %x, <2 x double> %y) {
478 ; SSE2: # BB#0: # %entry
479 ; SSE2-NEXT: movapd %xmm1, %xmm2
480 ; SSE2-NEXT: cmplepd %xmm0, %xmm2
481 ; SSE2-NEXT: andpd %xmm2, %xmm0
482 ; SSE2-NEXT: andnpd %xmm1, %xmm2
483 ; SSE2-NEXT: orpd %xmm2, %xmm0
486 ; SSSE3-LABEL: testa:
487 ; SSSE3: # BB#0: # %entry
488 ; SSSE3-NEXT: movapd %xmm1, %xmm2
489 ; SSSE3-NEXT: cmplepd %xmm0, %xmm2
490 ; SSSE3-NEXT: andpd %xmm2, %xmm0
491 ; SSSE3-NEXT: andnpd %xmm1, %xmm2
492 ; SSSE3-NEXT: orpd %xmm2, %xmm0
495 ; SSE41-LABEL: testa:
496 ; SSE41: # BB#0: # %entry
497 ; SSE41-NEXT: movapd %xmm0, %xmm2
498 ; SSE41-NEXT: movapd %xmm1, %xmm0
499 ; SSE41-NEXT: cmplepd %xmm2, %xmm0
500 ; SSE41-NEXT: blendvpd %xmm2, %xmm1
501 ; SSE41-NEXT: movapd %xmm1, %xmm0
505 ; AVX: # BB#0: # %entry
506 ; AVX-NEXT: vcmplepd %xmm0, %xmm1, %xmm2
507 ; AVX-NEXT: vblendvpd %xmm2, %xmm0, %xmm1, %xmm0
510 %max_is_x = fcmp oge <2 x double> %x, %y
511 %max = select <2 x i1> %max_is_x, <2 x double> %x, <2 x double> %y
512 ret <2 x double> %max
515 define <2 x double> @testb(<2 x double> %x, <2 x double> %y) {
517 ; SSE2: # BB#0: # %entry
518 ; SSE2-NEXT: movapd %xmm1, %xmm2
519 ; SSE2-NEXT: cmpnlepd %xmm0, %xmm2
520 ; SSE2-NEXT: andpd %xmm2, %xmm0
521 ; SSE2-NEXT: andnpd %xmm1, %xmm2
522 ; SSE2-NEXT: orpd %xmm2, %xmm0
525 ; SSSE3-LABEL: testb:
526 ; SSSE3: # BB#0: # %entry
527 ; SSSE3-NEXT: movapd %xmm1, %xmm2
528 ; SSSE3-NEXT: cmpnlepd %xmm0, %xmm2
529 ; SSSE3-NEXT: andpd %xmm2, %xmm0
530 ; SSSE3-NEXT: andnpd %xmm1, %xmm2
531 ; SSSE3-NEXT: orpd %xmm2, %xmm0
534 ; SSE41-LABEL: testb:
535 ; SSE41: # BB#0: # %entry
536 ; SSE41-NEXT: movapd %xmm0, %xmm2
537 ; SSE41-NEXT: movapd %xmm1, %xmm0
538 ; SSE41-NEXT: cmpnlepd %xmm2, %xmm0
539 ; SSE41-NEXT: blendvpd %xmm2, %xmm1
540 ; SSE41-NEXT: movapd %xmm1, %xmm0
544 ; AVX: # BB#0: # %entry
545 ; AVX-NEXT: vcmpnlepd %xmm0, %xmm1, %xmm2
546 ; AVX-NEXT: vblendvpd %xmm2, %xmm0, %xmm1, %xmm0
549 %min_is_x = fcmp ult <2 x double> %x, %y
550 %min = select <2 x i1> %min_is_x, <2 x double> %x, <2 x double> %y
551 ret <2 x double> %min
554 ; If we can figure out a blend has a constant mask, we should emit the
555 ; blend instruction with an immediate mask
556 define <4 x double> @constant_blendvpd_avx(<4 x double> %xy, <4 x double> %ab) {
557 ; SSE2-LABEL: constant_blendvpd_avx:
558 ; SSE2: # BB#0: # %entry
559 ; SSE2-NEXT: movsd {{.*#+}} xmm3 = xmm1[0],xmm3[1]
560 ; SSE2-NEXT: movaps %xmm2, %xmm0
561 ; SSE2-NEXT: movapd %xmm3, %xmm1
564 ; SSSE3-LABEL: constant_blendvpd_avx:
565 ; SSSE3: # BB#0: # %entry
566 ; SSSE3-NEXT: movsd {{.*#+}} xmm3 = xmm1[0],xmm3[1]
567 ; SSSE3-NEXT: movaps %xmm2, %xmm0
568 ; SSSE3-NEXT: movapd %xmm3, %xmm1
571 ; SSE41-LABEL: constant_blendvpd_avx:
572 ; SSE41: # BB#0: # %entry
573 ; SSE41-NEXT: blendpd {{.*#+}} xmm1 = xmm1[0],xmm3[1]
574 ; SSE41-NEXT: movaps %xmm2, %xmm0
577 ; AVX-LABEL: constant_blendvpd_avx:
578 ; AVX: # BB#0: # %entry
579 ; AVX-NEXT: vblendpd {{.*#+}} ymm0 = ymm1[0,1],ymm0[2],ymm1[3]
582 %select = select <4 x i1> <i1 false, i1 false, i1 true, i1 false>, <4 x double> %xy, <4 x double> %ab
583 ret <4 x double> %select
586 define <8 x float> @constant_blendvps_avx(<8 x float> %xyzw, <8 x float> %abcd) {
587 ; SSE2-LABEL: constant_blendvps_avx:
588 ; SSE2: # BB#0: # %entry
589 ; SSE2-NEXT: movaps {{.*#+}} xmm4 = [4294967295,4294967295,4294967295,0]
590 ; SSE2-NEXT: andps %xmm4, %xmm2
591 ; SSE2-NEXT: movaps {{.*#+}} xmm5 = [0,0,0,4294967295]
592 ; SSE2-NEXT: andps %xmm5, %xmm0
593 ; SSE2-NEXT: orps %xmm2, %xmm0
594 ; SSE2-NEXT: andps %xmm4, %xmm3
595 ; SSE2-NEXT: andps %xmm5, %xmm1
596 ; SSE2-NEXT: orps %xmm3, %xmm1
599 ; SSSE3-LABEL: constant_blendvps_avx:
600 ; SSSE3: # BB#0: # %entry
601 ; SSSE3-NEXT: movaps {{.*#+}} xmm4 = [4294967295,4294967295,4294967295,0]
602 ; SSSE3-NEXT: andps %xmm4, %xmm2
603 ; SSSE3-NEXT: movaps {{.*#+}} xmm5 = [0,0,0,4294967295]
604 ; SSSE3-NEXT: andps %xmm5, %xmm0
605 ; SSSE3-NEXT: orps %xmm2, %xmm0
606 ; SSSE3-NEXT: andps %xmm4, %xmm3
607 ; SSSE3-NEXT: andps %xmm5, %xmm1
608 ; SSSE3-NEXT: orps %xmm3, %xmm1
611 ; SSE41-LABEL: constant_blendvps_avx:
612 ; SSE41: # BB#0: # %entry
613 ; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm2[0,1,2],xmm0[3]
614 ; SSE41-NEXT: blendps {{.*#+}} xmm1 = xmm3[0,1,2],xmm1[3]
617 ; AVX-LABEL: constant_blendvps_avx:
618 ; AVX: # BB#0: # %entry
619 ; AVX-NEXT: vblendps {{.*#+}} ymm0 = ymm1[0,1,2],ymm0[3],ymm1[4,5,6],ymm0[7]
622 %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
623 ret <8 x float> %select
626 define <32 x i8> @constant_pblendvb_avx2(<32 x i8> %xyzw, <32 x i8> %abcd) {
627 ; SSE2-LABEL: constant_pblendvb_avx2:
628 ; SSE2: # BB#0: # %entry
629 ; SSE2-NEXT: movaps {{.*#+}} xmm4 = [255,255,0,255,0,0,0,255,255,255,0,255,0,0,0,255]
630 ; SSE2-NEXT: andps %xmm4, %xmm2
631 ; SSE2-NEXT: movaps {{.*#+}} xmm5 = [0,0,255,0,255,255,255,0,0,0,255,0,255,255,255,0]
632 ; SSE2-NEXT: andps %xmm5, %xmm0
633 ; SSE2-NEXT: orps %xmm2, %xmm0
634 ; SSE2-NEXT: andps %xmm4, %xmm3
635 ; SSE2-NEXT: andps %xmm5, %xmm1
636 ; SSE2-NEXT: orps %xmm3, %xmm1
639 ; SSSE3-LABEL: constant_pblendvb_avx2:
640 ; SSSE3: # BB#0: # %entry
641 ; SSSE3-NEXT: movaps {{.*#+}} xmm4 = [255,255,0,255,0,0,0,255,255,255,0,255,0,0,0,255]
642 ; SSSE3-NEXT: andps %xmm4, %xmm2
643 ; SSSE3-NEXT: movaps {{.*#+}} xmm5 = [0,0,255,0,255,255,255,0,0,0,255,0,255,255,255,0]
644 ; SSSE3-NEXT: andps %xmm5, %xmm0
645 ; SSSE3-NEXT: orps %xmm2, %xmm0
646 ; SSSE3-NEXT: andps %xmm4, %xmm3
647 ; SSSE3-NEXT: andps %xmm5, %xmm1
648 ; SSSE3-NEXT: orps %xmm3, %xmm1
651 ; SSE41-LABEL: constant_pblendvb_avx2:
652 ; SSE41: # BB#0: # %entry
653 ; SSE41-NEXT: movdqa %xmm0, %xmm4
654 ; SSE41-NEXT: movaps {{.*#+}} xmm0 = [0,0,255,0,255,255,255,0,0,0,255,0,255,255,255,0]
655 ; SSE41-NEXT: pblendvb %xmm4, %xmm2
656 ; SSE41-NEXT: pblendvb %xmm1, %xmm3
657 ; SSE41-NEXT: movdqa %xmm2, %xmm0
658 ; SSE41-NEXT: movdqa %xmm3, %xmm1
661 ; AVX1-LABEL: constant_pblendvb_avx2:
662 ; AVX1: # BB#0: # %entry
663 ; AVX1-NEXT: vandps {{.*}}(%rip), %ymm1, %ymm1
664 ; AVX1-NEXT: vandps {{.*}}(%rip), %ymm0, %ymm0
665 ; AVX1-NEXT: vorps %ymm1, %ymm0, %ymm0
668 ; AVX2-LABEL: constant_pblendvb_avx2:
669 ; AVX2: # BB#0: # %entry
670 ; 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]
671 ; AVX2-NEXT: vpblendvb %ymm2, %ymm0, %ymm1, %ymm0
674 %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
675 ret <32 x i8> %select
678 declare <8 x float> @llvm.x86.avx.blendv.ps.256(<8 x float>, <8 x float>, <8 x float>)
679 declare <4 x double> @llvm.x86.avx.blendv.pd.256(<4 x double>, <4 x double>, <4 x double>)
681 ;; 4 tests for shufflevectors that optimize to blend + immediate
682 define <4 x float> @blend_shufflevector_4xfloat(<4 x float> %a, <4 x float> %b) {
683 ; SSE2-LABEL: blend_shufflevector_4xfloat:
684 ; SSE2: # BB#0: # %entry
685 ; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[1,3]
686 ; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2,1,3]
689 ; SSSE3-LABEL: blend_shufflevector_4xfloat:
690 ; SSSE3: # BB#0: # %entry
691 ; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[1,3]
692 ; SSSE3-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2,1,3]
695 ; SSE41-LABEL: blend_shufflevector_4xfloat:
696 ; SSE41: # BB#0: # %entry
697 ; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
700 ; AVX-LABEL: blend_shufflevector_4xfloat:
701 ; AVX: # BB#0: # %entry
702 ; AVX-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
705 %select = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
706 ret <4 x float> %select
709 define <8 x float> @blend_shufflevector_8xfloat(<8 x float> %a, <8 x float> %b) {
710 ; SSE2-LABEL: blend_shufflevector_8xfloat:
711 ; SSE2: # BB#0: # %entry
712 ; SSE2-NEXT: movss {{.*#+}} xmm2 = xmm0[0],xmm2[1,2,3]
713 ; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm3[3,0]
714 ; SSE2-NEXT: shufps {{.*#+}} xmm3 = xmm3[0,1],xmm1[0,2]
715 ; SSE2-NEXT: movaps %xmm2, %xmm0
716 ; SSE2-NEXT: movaps %xmm3, %xmm1
719 ; SSSE3-LABEL: blend_shufflevector_8xfloat:
720 ; SSSE3: # BB#0: # %entry
721 ; SSSE3-NEXT: movss {{.*#+}} xmm2 = xmm0[0],xmm2[1,2,3]
722 ; SSSE3-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm3[3,0]
723 ; SSSE3-NEXT: shufps {{.*#+}} xmm3 = xmm3[0,1],xmm1[0,2]
724 ; SSSE3-NEXT: movaps %xmm2, %xmm0
725 ; SSSE3-NEXT: movaps %xmm3, %xmm1
728 ; SSE41-LABEL: blend_shufflevector_8xfloat:
729 ; SSE41: # BB#0: # %entry
730 ; SSE41-NEXT: blendps {{.*#+}} xmm0 = xmm0[0],xmm2[1,2,3]
731 ; SSE41-NEXT: blendps {{.*#+}} xmm1 = xmm3[0,1],xmm1[2],xmm3[3]
734 ; AVX-LABEL: blend_shufflevector_8xfloat:
735 ; AVX: # BB#0: # %entry
736 ; AVX-NEXT: vblendps {{.*#+}} ymm0 = ymm0[0],ymm1[1,2,3,4,5],ymm0[6],ymm1[7]
739 %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>
740 ret <8 x float> %select
743 define <4 x double> @blend_shufflevector_4xdouble(<4 x double> %a, <4 x double> %b) {
744 ; SSE2-LABEL: blend_shufflevector_4xdouble:
745 ; SSE2: # BB#0: # %entry
746 ; SSE2-NEXT: movsd {{.*#+}} xmm2 = xmm0[0],xmm2[1]
747 ; SSE2-NEXT: movapd %xmm2, %xmm0
750 ; SSSE3-LABEL: blend_shufflevector_4xdouble:
751 ; SSSE3: # BB#0: # %entry
752 ; SSSE3-NEXT: movsd {{.*#+}} xmm2 = xmm0[0],xmm2[1]
753 ; SSSE3-NEXT: movapd %xmm2, %xmm0
756 ; SSE41-LABEL: blend_shufflevector_4xdouble:
757 ; SSE41: # BB#0: # %entry
758 ; SSE41-NEXT: blendpd {{.*#+}} xmm0 = xmm0[0],xmm2[1]
761 ; AVX-LABEL: blend_shufflevector_4xdouble:
762 ; AVX: # BB#0: # %entry
763 ; AVX-NEXT: vblendpd {{.*#+}} ymm0 = ymm0[0],ymm1[1],ymm0[2,3]
766 %select = shufflevector <4 x double> %a, <4 x double> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 3>
767 ret <4 x double> %select
770 define <4 x i64> @blend_shufflevector_4xi64(<4 x i64> %a, <4 x i64> %b) {
771 ; SSE2-LABEL: blend_shufflevector_4xi64:
772 ; SSE2: # BB#0: # %entry
773 ; SSE2-NEXT: movsd {{.*#+}} xmm0 = xmm2[0],xmm0[1]
774 ; SSE2-NEXT: movaps %xmm3, %xmm1
777 ; SSSE3-LABEL: blend_shufflevector_4xi64:
778 ; SSSE3: # BB#0: # %entry
779 ; SSSE3-NEXT: movsd {{.*#+}} xmm0 = xmm2[0],xmm0[1]
780 ; SSSE3-NEXT: movaps %xmm3, %xmm1
783 ; SSE41-LABEL: blend_shufflevector_4xi64:
784 ; SSE41: # BB#0: # %entry
785 ; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm2[0,1,2,3],xmm0[4,5,6,7]
786 ; SSE41-NEXT: movaps %xmm3, %xmm1
789 ; AVX1-LABEL: blend_shufflevector_4xi64:
790 ; AVX1: # BB#0: # %entry
791 ; AVX1-NEXT: vblendpd {{.*#+}} ymm0 = ymm1[0],ymm0[1],ymm1[2,3]
794 ; AVX2-LABEL: blend_shufflevector_4xi64:
795 ; AVX2: # BB#0: # %entry
796 ; AVX2-NEXT: vpblendd {{.*#+}} ymm0 = ymm1[0,1],ymm0[2,3],ymm1[4,5,6,7]
799 %select = shufflevector <4 x i64> %a, <4 x i64> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 7>
800 ret <4 x i64> %select