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
6
7; AVX128 tests:
8
9define <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
15; SSE2-NEXT:    retq
16;
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
22; SSSE3-NEXT:    retq
23;
24; SSE41-LABEL: vsel_float:
25; SSE41:       # BB#0: # %entry
26; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
27; SSE41-NEXT:    retq
28;
29; AVX-LABEL: vsel_float:
30; AVX:       # BB#0: # %entry
31; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
32; AVX-NEXT:    retq
33entry:
34  %vsel = select <4 x i1> <i1 true, i1 false, i1 true, i1 false>, <4 x float> %v1, <4 x float> %v2
35  ret <4 x float> %vsel
36}
37
38define <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 %xmm0, %xmm1
42; SSE2-NEXT:    movaps %xmm1, %xmm0
43; SSE2-NEXT:    retq
44;
45; SSSE3-LABEL: vsel_float2:
46; SSSE3:       # BB#0: # %entry
47; SSSE3-NEXT:    movss %xmm0, %xmm1
48; SSSE3-NEXT:    movaps %xmm1, %xmm0
49; SSSE3-NEXT:    retq
50;
51; SSE41-LABEL: vsel_float2:
52; SSE41:       # BB#0: # %entry
53; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]
54; SSE41-NEXT:    retq
55;
56; AVX-LABEL: vsel_float2:
57; AVX:       # BB#0: # %entry
58; AVX-NEXT:    blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]
59; AVX-NEXT:    retq
60entry:
61  %vsel = select <4 x i1> <i1 true, i1 false, i1 false, i1 false>, <4 x float> %v1, <4 x float> %v2
62  ret <4 x float> %vsel
63}
64
65define <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
71; SSE2-NEXT:    retq
72;
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
78; SSSE3-NEXT:    retq
79;
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]
83; SSE41-NEXT:    retq
84;
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]
88; AVX1-NEXT:    retq
89;
90; AVX2-LABEL: vsel_4xi8:
91; AVX2:       # BB#0: # %entry
92; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm0[0,1],xmm1[2],xmm0[3]
93; AVX2-NEXT:    retq
94entry:
95  %vsel = select <4 x i1> <i1 true, i1 true, i1 false, i1 true>, <4 x i8> %v1, <4 x i8> %v2
96  ret <4 x i8> %vsel
97}
98
99define <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
105; SSE2-NEXT:    retq
106;
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
112; SSSE3-NEXT:    retq
113;
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]
117; SSE41-NEXT:    retq
118;
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]
122; AVX1-NEXT:    retq
123;
124; AVX2-LABEL: vsel_4xi16:
125; AVX2:       # BB#0: # %entry
126; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2,3]
127; AVX2-NEXT:    retq
128entry:
129  %vsel = select <4 x i1> <i1 true, i1 false, i1 true, i1 true>, <4 x i16> %v1, <4 x i16> %v2
130  ret <4 x i16> %vsel
131}
132
133define <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
139; SSE2-NEXT:    retq
140;
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
146; SSSE3-NEXT:    retq
147;
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]
151; SSE41-NEXT:    retq
152;
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]
156; AVX1-NEXT:    retq
157;
158; AVX2-LABEL: vsel_i32:
159; AVX2:       # BB#0: # %entry
160; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
161; AVX2-NEXT:    retq
162entry:
163  %vsel = select <4 x i1> <i1 true, i1 false, i1 true, i1 false>, <4 x i32> %v1, <4 x i32> %v2
164  ret <4 x i32> %vsel
165}
166
167define <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 %xmm0, %xmm1
171; SSE2-NEXT:    movaps %xmm1, %xmm0
172; SSE2-NEXT:    retq
173;
174; SSSE3-LABEL: vsel_double:
175; SSSE3:       # BB#0: # %entry
176; SSSE3-NEXT:    movsd %xmm0, %xmm1
177; SSSE3-NEXT:    movaps %xmm1, %xmm0
178; SSSE3-NEXT:    retq
179;
180; SSE41-LABEL: vsel_double:
181; SSE41:       # BB#0: # %entry
182; SSE41-NEXT:    blendpd {{.*#+}} xmm0 = xmm0[0],xmm1[1]
183; SSE41-NEXT:    retq
184;
185; AVX-LABEL: vsel_double:
186; AVX:       # BB#0: # %entry
187; AVX-NEXT:    vblendpd {{.*#+}} xmm0 = xmm0[0],xmm1[1]
188; AVX-NEXT:    retq
189entry:
190  %vsel = select <2 x i1> <i1 true, i1 false>, <2 x double> %v1, <2 x double> %v2
191  ret <2 x double> %vsel
192}
193
194define <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 %xmm0, %xmm1
198; SSE2-NEXT:    movaps %xmm1, %xmm0
199; SSE2-NEXT:    retq
200;
201; SSSE3-LABEL: vsel_i64:
202; SSSE3:       # BB#0: # %entry
203; SSSE3-NEXT:    movsd %xmm0, %xmm1
204; SSSE3-NEXT:    movaps %xmm1, %xmm0
205; SSSE3-NEXT:    retq
206;
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]
210; SSE41-NEXT:    retq
211;
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]
215; AVX1-NEXT:    retq
216;
217; AVX2-LABEL: vsel_i64:
218; AVX2:       # BB#0: # %entry
219; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]
220; AVX2-NEXT:    retq
221entry:
222  %vsel = select <2 x i1> <i1 true, i1 false>, <2 x i64> %v1, <2 x i64> %v2
223  ret <2 x i64> %vsel
224}
225
226define <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
232; SSE2-NEXT:    retq
233;
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
239; SSSE3-NEXT:    retq
240;
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]
244; SSE41-NEXT:    retq
245;
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]
249; AVX-NEXT:    retq
250entry:
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
252  ret <8 x i16> %vsel
253}
254
255define <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
261; SSE2-NEXT:    retq
262;
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
268; SSSE3-NEXT:    retq
269;
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
276; SSE41-NEXT:    retq
277;
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
282; AVX-NEXT:    retq
283entry:
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
285  ret <16 x i8> %vsel
286}
287
288
289; AVX256 tests:
290
291define <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 %xmm0, %xmm2
295; SSE2-NEXT:    movss %xmm1, %xmm3
296; SSE2-NEXT:    movaps %xmm2, %xmm0
297; SSE2-NEXT:    movaps %xmm3, %xmm1
298; SSE2-NEXT:    retq
299;
300; SSSE3-LABEL: vsel_float8:
301; SSSE3:       # BB#0: # %entry
302; SSSE3-NEXT:    movss %xmm0, %xmm2
303; SSSE3-NEXT:    movss %xmm1, %xmm3
304; SSSE3-NEXT:    movaps %xmm2, %xmm0
305; SSSE3-NEXT:    movaps %xmm3, %xmm1
306; SSSE3-NEXT:    retq
307;
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]
312; SSE41-NEXT:    retq
313;
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]
317; AVX-NEXT:    retq
318entry:
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
321}
322
323define <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 %xmm0, %xmm2
327; SSE2-NEXT:    movss %xmm1, %xmm3
328; SSE2-NEXT:    movaps %xmm2, %xmm0
329; SSE2-NEXT:    movaps %xmm3, %xmm1
330; SSE2-NEXT:    retq
331;
332; SSSE3-LABEL: vsel_i328:
333; SSSE3:       # BB#0: # %entry
334; SSSE3-NEXT:    movss %xmm0, %xmm2
335; SSSE3-NEXT:    movss %xmm1, %xmm3
336; SSSE3-NEXT:    movaps %xmm2, %xmm0
337; SSSE3-NEXT:    movaps %xmm3, %xmm1
338; SSSE3-NEXT:    retq
339;
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]
344; SSE41-NEXT:    retq
345;
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]
349; AVX1-NEXT:    retq
350;
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]
354; AVX2-NEXT:    retq
355entry:
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
357  ret <8 x i32> %vsel
358}
359
360define <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 %xmm0, %xmm4
364; SSE2-NEXT:    movsd %xmm2, %xmm6
365; SSE2-NEXT:    movaps %xmm4, %xmm0
366; SSE2-NEXT:    movaps %xmm5, %xmm1
367; SSE2-NEXT:    movaps %xmm6, %xmm2
368; SSE2-NEXT:    movaps %xmm7, %xmm3
369; SSE2-NEXT:    retq
370;
371; SSSE3-LABEL: vsel_double8:
372; SSSE3:       # BB#0: # %entry
373; SSSE3-NEXT:    movsd %xmm0, %xmm4
374; SSSE3-NEXT:    movsd %xmm2, %xmm6
375; SSSE3-NEXT:    movaps %xmm4, %xmm0
376; SSSE3-NEXT:    movaps %xmm5, %xmm1
377; SSSE3-NEXT:    movaps %xmm6, %xmm2
378; SSSE3-NEXT:    movaps %xmm7, %xmm3
379; SSSE3-NEXT:    retq
380;
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
387; SSE41-NEXT:    retq
388;
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]
393; AVX-NEXT:    retq
394entry:
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
397}
398
399define <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 %xmm0, %xmm4
403; SSE2-NEXT:    movsd %xmm2, %xmm6
404; SSE2-NEXT:    movaps %xmm4, %xmm0
405; SSE2-NEXT:    movaps %xmm5, %xmm1
406; SSE2-NEXT:    movaps %xmm6, %xmm2
407; SSE2-NEXT:    movaps %xmm7, %xmm3
408; SSE2-NEXT:    retq
409;
410; SSSE3-LABEL: vsel_i648:
411; SSSE3:       # BB#0: # %entry
412; SSSE3-NEXT:    movsd %xmm0, %xmm4
413; SSSE3-NEXT:    movsd %xmm2, %xmm6
414; SSSE3-NEXT:    movaps %xmm4, %xmm0
415; SSSE3-NEXT:    movaps %xmm5, %xmm1
416; SSSE3-NEXT:    movaps %xmm6, %xmm2
417; SSSE3-NEXT:    movaps %xmm7, %xmm3
418; SSSE3-NEXT:    retq
419;
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
426; SSE41-NEXT:    retq
427;
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]
432; AVX1-NEXT:    retq
433;
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]
438; AVX2-NEXT:    retq
439entry:
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
441  ret <8 x i64> %vsel
442}
443
444define <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 %xmm0, %xmm2
448; SSE2-NEXT:    movsd %xmm1, %xmm3
449; SSE2-NEXT:    movaps %xmm2, %xmm0
450; SSE2-NEXT:    movaps %xmm3, %xmm1
451; SSE2-NEXT:    retq
452;
453; SSSE3-LABEL: vsel_double4:
454; SSSE3:       # BB#0: # %entry
455; SSSE3-NEXT:    movsd %xmm0, %xmm2
456; SSSE3-NEXT:    movsd %xmm1, %xmm3
457; SSSE3-NEXT:    movaps %xmm2, %xmm0
458; SSSE3-NEXT:    movaps %xmm3, %xmm1
459; SSSE3-NEXT:    retq
460;
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]
465; SSE41-NEXT:    retq
466;
467; AVX-LABEL: vsel_double4:
468; AVX:       # BB#0: # %entry
469; AVX-NEXT:    vblendpd {{.*#+}} ymm0 = ymm0[0],ymm1[1],ymm0[2],ymm1[3]
470; AVX-NEXT:    retq
471entry:
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
474}
475
476define <2 x double> @testa(<2 x double> %x, <2 x double> %y) {
477; SSE2-LABEL: testa:
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
484; SSE2-NEXT:    retq
485;
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
493; SSSE3-NEXT:    retq
494;
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
502; SSE41-NEXT:    retq
503;
504; AVX-LABEL: testa:
505; AVX:       # BB#0: # %entry
506; AVX-NEXT:    vcmplepd %xmm0, %xmm1, %xmm2
507; AVX-NEXT:    vblendvpd %xmm2, %xmm0, %xmm1, %xmm0
508; AVX-NEXT:    retq
509entry:
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
513}
514
515define <2 x double> @testb(<2 x double> %x, <2 x double> %y) {
516; SSE2-LABEL: testb:
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
523; SSE2-NEXT:    retq
524;
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
532; SSSE3-NEXT:    retq
533;
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
541; SSE41-NEXT:    retq
542;
543; AVX-LABEL: testb:
544; AVX:       # BB#0: # %entry
545; AVX-NEXT:    vcmpnlepd %xmm0, %xmm1, %xmm2
546; AVX-NEXT:    vblendvpd %xmm2, %xmm0, %xmm1, %xmm0
547; AVX-NEXT:    retq
548entry:
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
552}
553
554; If we can figure out a blend has a constant mask, we should emit the
555; blend instruction with an immediate mask
556define <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 %xmm1, %xmm3
560; SSE2-NEXT:    movaps %xmm2, %xmm0
561; SSE2-NEXT:    movaps %xmm3, %xmm1
562; SSE2-NEXT:    retq
563;
564; SSSE3-LABEL: constant_blendvpd_avx:
565; SSSE3:       # BB#0: # %entry
566; SSSE3-NEXT:    movsd %xmm1, %xmm3
567; SSSE3-NEXT:    movaps %xmm2, %xmm0
568; SSSE3-NEXT:    movaps %xmm3, %xmm1
569; SSSE3-NEXT:    retq
570;
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
575; SSE41-NEXT:    retq
576;
577; AVX-LABEL: constant_blendvpd_avx:
578; AVX:       # BB#0: # %entry
579; AVX-NEXT:    vblendpd {{.*#+}} ymm0 = ymm1[0,1],ymm0[2],ymm1[3]
580; AVX-NEXT:    retq
581entry:
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
584}
585
586define <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
597; SSE2-NEXT:    retq
598;
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
609; SSSE3-NEXT:    retq
610;
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]
615; SSE41-NEXT:    retq
616;
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]
620; AVX-NEXT:    retq
621entry:
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
624}
625
626define <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
637; SSE2-NEXT:    retq
638;
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
649; SSSE3-NEXT:    retq
650;
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
659; SSE41-NEXT:    retq
660;
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
666; AVX1-NEXT:    retq
667;
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
672; AVX2-NEXT:    retq
673entry:
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
676}
677
678declare <8 x float> @llvm.x86.avx.blendv.ps.256(<8 x float>, <8 x float>, <8 x float>)
679declare <4 x double> @llvm.x86.avx.blendv.pd.256(<4 x double>, <4 x double>, <4 x double>)
680
681;; 4 tests for shufflevectors that optimize to blend + immediate
682define <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]
687; SSE2-NEXT:    retq
688;
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]
693; SSSE3-NEXT:    retq
694;
695; SSE41-LABEL: blend_shufflevector_4xfloat:
696; SSE41:       # BB#0: # %entry
697; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
698; SSE41-NEXT:    retq
699;
700; AVX-LABEL: blend_shufflevector_4xfloat:
701; AVX:       # BB#0: # %entry
702; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
703; AVX-NEXT:    retq
704entry:
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
707}
708
709define <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 %xmm0, %xmm2
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
717; SSE2-NEXT:    retq
718;
719; SSSE3-LABEL: blend_shufflevector_8xfloat:
720; SSSE3:       # BB#0: # %entry
721; SSSE3-NEXT:    movss %xmm0, %xmm2
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
726; SSSE3-NEXT:    retq
727;
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]
732; SSE41-NEXT:    retq
733;
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]
737; AVX-NEXT:    retq
738entry:
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
741}
742
743define <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 %xmm0, %xmm2
747; SSE2-NEXT:    movaps %xmm2, %xmm0
748; SSE2-NEXT:    retq
749;
750; SSSE3-LABEL: blend_shufflevector_4xdouble:
751; SSSE3:       # BB#0: # %entry
752; SSSE3-NEXT:    movsd %xmm0, %xmm2
753; SSSE3-NEXT:    movaps %xmm2, %xmm0
754; SSSE3-NEXT:    retq
755;
756; SSE41-LABEL: blend_shufflevector_4xdouble:
757; SSE41:       # BB#0: # %entry
758; SSE41-NEXT:    blendpd {{.*#+}} xmm0 = xmm0[0],xmm2[1]
759; SSE41-NEXT:    retq
760;
761; AVX-LABEL: blend_shufflevector_4xdouble:
762; AVX:       # BB#0: # %entry
763; AVX-NEXT:    vblendpd {{.*#+}} ymm0 = ymm0[0],ymm1[1],ymm0[2,3]
764; AVX-NEXT:    retq
765entry:
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
768}
769
770define <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 %xmm2, %xmm0
774; SSE2-NEXT:    movaps %xmm3, %xmm1
775; SSE2-NEXT:    retq
776;
777; SSSE3-LABEL: blend_shufflevector_4xi64:
778; SSSE3:       # BB#0: # %entry
779; SSSE3-NEXT:    movsd %xmm2, %xmm0
780; SSSE3-NEXT:    movaps %xmm3, %xmm1
781; SSSE3-NEXT:    retq
782;
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
787; SSE41-NEXT:    retq
788;
789; AVX1-LABEL: blend_shufflevector_4xi64:
790; AVX1:       # BB#0: # %entry
791; AVX1-NEXT:    vblendpd {{.*#+}} ymm0 = ymm1[0],ymm0[1],ymm1[2,3]
792; AVX1-NEXT:    retq
793;
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]
797; AVX2-NEXT:    retq
798entry:
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
801}
802