[x86] Expand the ISA coverage of our blend test in preparation for
[oota-llvm.git] / test / CodeGen / X86 / vector-blend.ll
1 ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=x86-64 -mattr=+sse2 | FileCheck %s --check-prefix=SSE --check-prefix=SSE2
2 ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=x86-64 -mattr=+ssse3 | FileCheck %s --check-prefix=SSE --check-prefix=SSSE3
3 ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=x86-64 -mattr=+sse4.1 | FileCheck %s --check-prefix=SSE --check-prefix=SSE41
4 ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=x86-64 -mattr=+avx | FileCheck %s --check-prefix=AVX --check-prefix=AVX1
5 ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=x86-64 -mattr=+avx2 | FileCheck %s --check-prefix=AVX --check-prefix=AVX2
6
7 ; AVX128 tests:
8
9 define <4 x float> @vsel_float(<4 x float> %v1, <4 x float> %v2) {
10 ; SSE2-LABEL: vsel_float:
11 ; SSE2:       ## BB#0:
12 ; SSE2-NEXT:    andps {{.*}}, %xmm1
13 ; SSE2-NEXT:    andps {{.*}}, %xmm0
14 ; SSE2-NEXT:    orps %xmm1, %xmm0
15 ; SSE2-NEXT:    retq
16 ;
17 ; SSSE3-LABEL: vsel_float:
18 ; SSSE3:       ## BB#0:
19 ; SSSE3-NEXT:    andps {{.*}}, %xmm1
20 ; SSSE3-NEXT:    andps {{.*}}, %xmm0
21 ; SSSE3-NEXT:    orps %xmm1, %xmm0
22 ; SSSE3-NEXT:    retq
23 ;
24 ; SSE41-LABEL: vsel_float:
25 ; SSE41:       ## BB#0:
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:
31 ; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
32 ; AVX-NEXT:    retq
33   %vsel = select <4 x i1> <i1 true, i1 false, i1 true, i1 false>, <4 x float> %v1, <4 x float> %v2
34   ret <4 x float> %vsel
35 }
36
37 define <4 x float> @vsel_float2(<4 x float> %v1, <4 x float> %v2) {
38 ; SSE-LABEL: vsel_float2:
39 ; SSE:       ## BB#0:
40 ; SSE-NEXT:    movss %xmm0, %xmm1
41 ; SSE-NEXT:    movaps %xmm1, %xmm0
42 ; SSE-NEXT:    retq
43 ;
44 ; AVX-LABEL: vsel_float2:
45 ; AVX:       ## BB#0:
46 ; AVX-NEXT:    vmovss %xmm0, %xmm1, %xmm0
47 ; AVX-NEXT:    retq
48   %vsel = select <4 x i1> <i1 true, i1 false, i1 false, i1 false>, <4 x float> %v1, <4 x float> %v2
49   ret <4 x float> %vsel
50 }
51
52 define <4 x i32> @vsel_i32(<4 x i32> %v1, <4 x i32> %v2) {
53 ; SSE2-LABEL: vsel_i32:
54 ; SSE2:       ## BB#0:
55 ; SSE2-NEXT:    andps {{.*}}, %xmm1
56 ; SSE2-NEXT:    andps {{.*}}, %xmm0
57 ; SSE2-NEXT:    orps %xmm1, %xmm0
58 ; SSE2-NEXT:    retq
59 ;
60 ; SSSE3-LABEL: vsel_i32:
61 ; SSSE3:       ## BB#0:
62 ; SSSE3-NEXT:    andps {{.*}}, %xmm1
63 ; SSSE3-NEXT:    andps {{.*}}, %xmm0
64 ; SSSE3-NEXT:    orps %xmm1, %xmm0
65 ; SSSE3-NEXT:    retq
66 ;
67 ; SSE41-LABEL: vsel_i32:
68 ; SSE41:       ## BB#0:
69 ; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
70 ; SSE41-NEXT:    retq
71 ;
72 ; AVX1-LABEL: vsel_i32:
73 ; AVX1:       ## BB#0:
74 ; AVX1-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
75 ; AVX1-NEXT:    retq
76 ;
77 ; AVX2-LABEL: vsel_i32:
78 ; AVX2:       ## BB#0:
79 ; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
80 ; AVX2-NEXT:    retq
81   %vsel = select <4 x i1> <i1 true, i1 false, i1 true, i1 false>, <4 x i32> %v1, <4 x i32> %v2
82   ret <4 x i32> %vsel
83 }
84
85 define <2 x double> @vsel_double(<2 x double> %v1, <2 x double> %v2) {
86 ; SSE-LABEL: vsel_double:
87 ; SSE:       ## BB#0:
88 ; SSE-NEXT:    movsd %xmm0, %xmm1
89 ; SSE-NEXT:    movaps %xmm1, %xmm0
90 ; SSE-NEXT:    retq
91 ;
92 ; AVX-LABEL: vsel_double:
93 ; AVX:       ## BB#0:
94 ; AVX-NEXT:    vmovsd %xmm0, %xmm1, %xmm0
95 ; AVX-NEXT:    retq
96   %vsel = select <2 x i1> <i1 true, i1 false>, <2 x double> %v1, <2 x double> %v2
97   ret <2 x double> %vsel
98 }
99
100 define <2 x i64> @vsel_i64(<2 x i64> %v1, <2 x i64> %v2) {
101 ; SSE-LABEL: vsel_i64:
102 ; SSE:       ## BB#0:
103 ; SSE-NEXT:    movsd %xmm0, %xmm1
104 ; SSE-NEXT:    movaps %xmm1, %xmm0
105 ; SSE-NEXT:    retq
106 ;
107 ; AVX-LABEL: vsel_i64:
108 ; AVX:       ## BB#0:
109 ; AVX-NEXT:    vmovsd %xmm0, %xmm1, %xmm0
110 ; AVX-NEXT:    retq
111   %vsel = select <2 x i1> <i1 true, i1 false>, <2 x i64> %v1, <2 x i64> %v2
112   ret <2 x i64> %vsel
113 }
114
115 define <8 x i16> @vsel_8xi16(<8 x i16> %v1, <8 x i16> %v2) {
116 ; SSE2-LABEL: vsel_8xi16:
117 ; SSE2:       ## BB#0:
118 ; SSE2-NEXT:    andps {{.*}}, %xmm1
119 ; SSE2-NEXT:    andps {{.*}}, %xmm0
120 ; SSE2-NEXT:    orps %xmm1, %xmm0
121 ; SSE2-NEXT:    retq
122 ;
123 ; SSSE3-LABEL: vsel_8xi16:
124 ; SSSE3:       ## BB#0:
125 ; SSSE3-NEXT:    andps {{.*}}, %xmm1
126 ; SSSE3-NEXT:    andps {{.*}}, %xmm0
127 ; SSSE3-NEXT:    orps %xmm1, %xmm0
128 ; SSSE3-NEXT:    retq
129 ;
130 ; SSE41-LABEL: vsel_8xi16:
131 ; SSE41:       ## BB#0:
132 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3],xmm0[4],xmm1[5,6,7]
133 ; SSE41-NEXT:    retq
134 ;
135 ; AVX-LABEL: vsel_8xi16:
136 ; AVX:       ## BB#0:
137 ; AVX-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3],xmm0[4],xmm1[5,6,7]
138 ; AVX-NEXT:    retq
139   %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
140   ret <8 x i16> %vsel
141 }
142
143 define <16 x i8> @vsel_i8(<16 x i8> %v1, <16 x i8> %v2) {
144 ; SSE2-LABEL: vsel_i8:
145 ; SSE2:       ## BB#0:
146 ; SSE2-NEXT:    andps {{.*}}, %xmm1
147 ; SSE2-NEXT:    andps {{.*}}, %xmm0
148 ; SSE2-NEXT:    orps %xmm1, %xmm0
149 ; SSE2-NEXT:    retq
150 ;
151 ; SSSE3-LABEL: vsel_i8:
152 ; SSSE3:       ## BB#0:
153 ; SSSE3-NEXT:    andps {{.*}}, %xmm1
154 ; SSSE3-NEXT:    andps {{.*}}, %xmm0
155 ; SSSE3-NEXT:    orps %xmm1, %xmm0
156 ; SSSE3-NEXT:    retq
157 ;
158 ; SSE41-LABEL: vsel_i8:
159 ; SSE41:       ## BB#0:
160 ; SSE41-NEXT:    movdqa %xmm0, %xmm2
161 ; SSE41-NEXT:    movaps {{.*#+}} xmm0 = [255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0]
162 ; SSE41-NEXT:    pblendvb %xmm2, %xmm1
163 ; SSE41-NEXT:    movdqa %xmm1, %xmm0
164 ; SSE41-NEXT:    retq
165 ;
166 ; AVX-LABEL: vsel_i8:
167 ; AVX:       ## BB#0:
168 ; AVX-NEXT:    vmovdqa {{.*#+}} xmm2 = [255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0]
169 ; AVX-NEXT:    vpblendvb %xmm2, %xmm0, %xmm1, %xmm0
170 ; AVX-NEXT:    retq
171   %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
172   ret <16 x i8> %vsel
173 }
174
175
176 ; AVX256 tests:
177
178 define <8 x float> @vsel_float8(<8 x float> %v1, <8 x float> %v2) {
179 ; SSE-LABEL: vsel_float8:
180 ; SSE:       ## BB#0:
181 ; SSE-NEXT:    movss %xmm0, %xmm2
182 ; SSE-NEXT:    movss %xmm1, %xmm3
183 ; SSE-NEXT:    movaps %xmm2, %xmm0
184 ; SSE-NEXT:    movaps %xmm3, %xmm1
185 ; SSE-NEXT:    retq
186 ;
187 ; AVX-LABEL: vsel_float8:
188 ; AVX:       ## BB#0:
189 ; AVX-NEXT:    vblendps {{.*#+}} ymm0 = ymm0[0],ymm1[1,2,3],ymm0[4],ymm1[5,6,7]
190 ; AVX-NEXT:    retq
191   %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
192   ret <8 x float> %vsel
193 }
194
195 define <8 x i32> @vsel_i328(<8 x i32> %v1, <8 x i32> %v2) {
196 ; SSE-LABEL: vsel_i328:
197 ; SSE:       ## BB#0:
198 ; SSE-NEXT:    movss %xmm0, %xmm2
199 ; SSE-NEXT:    movss %xmm1, %xmm3
200 ; SSE-NEXT:    movaps %xmm2, %xmm0
201 ; SSE-NEXT:    movaps %xmm3, %xmm1
202 ; SSE-NEXT:    retq
203 ;
204 ; AVX1-LABEL: vsel_i328:
205 ; AVX1:       ## BB#0:
206 ; AVX1-NEXT:    vblendps {{.*#+}} ymm0 = ymm0[0],ymm1[1,2,3],ymm0[4],ymm1[5,6,7]
207 ; AVX1-NEXT:    retq
208 ;
209 ; AVX2-LABEL: vsel_i328:
210 ; AVX2:       ## BB#0:
211 ; AVX2-NEXT:    vpblendd {{.*#+}} ymm0 = ymm0[0],ymm1[1,2,3],ymm0[4],ymm1[5,6,7]
212 ; AVX2-NEXT:    retq
213   %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
214   ret <8 x i32> %vsel
215 }
216
217 define <8 x double> @vsel_double8(<8 x double> %v1, <8 x double> %v2) {
218 ; SSE2-LABEL: vsel_double8:
219 ; SSE2:       ## BB#0:
220 ; SSE2-NEXT:    movsd %xmm0, %xmm4
221 ; SSE2-NEXT:    movsd %xmm2, %xmm6
222 ; SSE2-NEXT:    movaps %xmm4, %xmm0
223 ; SSE2-NEXT:    movaps %xmm5, %xmm1
224 ; SSE2-NEXT:    movaps %xmm6, %xmm2
225 ; SSE2-NEXT:    movaps %xmm7, %xmm3
226 ; SSE2-NEXT:    retq
227 ;
228 ; SSSE3-LABEL: vsel_double8:
229 ; SSSE3:       ## BB#0:
230 ; SSSE3-NEXT:    movsd %xmm0, %xmm4
231 ; SSSE3-NEXT:    movsd %xmm2, %xmm6
232 ; SSSE3-NEXT:    movaps %xmm4, %xmm0
233 ; SSSE3-NEXT:    movaps %xmm5, %xmm1
234 ; SSSE3-NEXT:    movaps %xmm6, %xmm2
235 ; SSSE3-NEXT:    movaps %xmm7, %xmm3
236 ; SSSE3-NEXT:    retq
237 ;
238 ; SSE41-LABEL: vsel_double8:
239 ; SSE41:       ## BB#0:
240 ; SSE41-NEXT:    blendpd {{.*#+}} xmm0 = xmm0[0],xmm4[1]
241 ; SSE41-NEXT:    blendpd {{.*#+}} xmm1 = xmm5[0,1]
242 ; SSE41-NEXT:    blendpd {{.*#+}} xmm2 = xmm2[0],xmm6[1]
243 ; SSE41-NEXT:    blendpd {{.*#+}} xmm3 = xmm7[0,1]
244 ; SSE41-NEXT:    retq
245 ;
246 ; AVX-LABEL: vsel_double8:
247 ; AVX:       ## BB#0:
248 ; AVX-NEXT:    vblendpd {{.*#+}} ymm0 = ymm0[0],ymm2[1,2,3]
249 ; AVX-NEXT:    vblendpd {{.*#+}} ymm1 = ymm1[0],ymm3[1,2,3]
250 ; AVX-NEXT:    retq
251   %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
252   ret <8 x double> %vsel
253 }
254
255 define <8 x i64> @vsel_i648(<8 x i64> %v1, <8 x i64> %v2) {
256 ; SSE2-LABEL: vsel_i648:
257 ; SSE2:       ## BB#0:
258 ; SSE2-NEXT:    movsd %xmm0, %xmm4
259 ; SSE2-NEXT:    movsd %xmm2, %xmm6
260 ; SSE2-NEXT:    movaps %xmm4, %xmm0
261 ; SSE2-NEXT:    movaps %xmm5, %xmm1
262 ; SSE2-NEXT:    movaps %xmm6, %xmm2
263 ; SSE2-NEXT:    movaps %xmm7, %xmm3
264 ; SSE2-NEXT:    retq
265 ;
266 ; SSSE3-LABEL: vsel_i648:
267 ; SSSE3:       ## BB#0:
268 ; SSSE3-NEXT:    movsd %xmm0, %xmm4
269 ; SSSE3-NEXT:    movsd %xmm2, %xmm6
270 ; SSSE3-NEXT:    movaps %xmm4, %xmm0
271 ; SSSE3-NEXT:    movaps %xmm5, %xmm1
272 ; SSSE3-NEXT:    movaps %xmm6, %xmm2
273 ; SSSE3-NEXT:    movaps %xmm7, %xmm3
274 ; SSSE3-NEXT:    retq
275 ;
276 ; SSE41-LABEL: vsel_i648:
277 ; SSE41:       ## BB#0:
278 ; SSE41-NEXT:    blendpd {{.*#+}} xmm0 = xmm0[0],xmm4[1]
279 ; SSE41-NEXT:    blendpd {{.*#+}} xmm1 = xmm5[0,1]
280 ; SSE41-NEXT:    blendpd {{.*#+}} xmm2 = xmm2[0],xmm6[1]
281 ; SSE41-NEXT:    blendpd {{.*#+}} xmm3 = xmm7[0,1]
282 ; SSE41-NEXT:    retq
283 ;
284 ; AVX-LABEL: vsel_i648:
285 ; AVX:       ## BB#0:
286 ; AVX-NEXT:    vblendpd {{.*#+}} ymm0 = ymm0[0],ymm2[1,2,3]
287 ; AVX-NEXT:    vblendpd {{.*#+}} ymm1 = ymm1[0],ymm3[1,2,3]
288 ; AVX-NEXT:    retq
289   %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
290   ret <8 x i64> %vsel
291 }
292
293 define <4 x double> @vsel_double4(<4 x double> %v1, <4 x double> %v2) {
294 ; SSE-LABEL: vsel_double4:
295 ; SSE:       ## BB#0:
296 ; SSE-NEXT:    movsd %xmm0, %xmm2
297 ; SSE-NEXT:    movsd %xmm1, %xmm3
298 ; SSE-NEXT:    movaps %xmm2, %xmm0
299 ; SSE-NEXT:    movaps %xmm3, %xmm1
300 ; SSE-NEXT:    retq
301 ;
302 ; AVX-LABEL: vsel_double4:
303 ; AVX:       ## BB#0:
304 ; AVX-NEXT:    vblendpd {{.*#+}} ymm0 = ymm0[0],ymm1[1],ymm0[2],ymm1[3]
305 ; AVX-NEXT:    retq
306   %vsel = select <4 x i1> <i1 true, i1 false, i1 true, i1 false>, <4 x double> %v1, <4 x double> %v2
307   ret <4 x double> %vsel
308 }
309
310 define <2 x double> @testa(<2 x double> %x, <2 x double> %y) {
311 ; SSE2-LABEL: testa:
312 ; SSE2:       ## BB#0:
313 ; SSE2-NEXT:    movapd %xmm1, %xmm2
314 ; SSE2-NEXT:    cmplepd %xmm0, %xmm2
315 ; SSE2-NEXT:    andpd %xmm2, %xmm0
316 ; SSE2-NEXT:    andnpd %xmm1, %xmm2
317 ; SSE2-NEXT:    orpd %xmm2, %xmm0
318 ; SSE2-NEXT:    retq
319 ;
320 ; SSSE3-LABEL: testa:
321 ; SSSE3:       ## BB#0:
322 ; SSSE3-NEXT:    movapd %xmm1, %xmm2
323 ; SSSE3-NEXT:    cmplepd %xmm0, %xmm2
324 ; SSSE3-NEXT:    andpd %xmm2, %xmm0
325 ; SSSE3-NEXT:    andnpd %xmm1, %xmm2
326 ; SSSE3-NEXT:    orpd %xmm2, %xmm0
327 ; SSSE3-NEXT:    retq
328 ;
329 ; SSE41-LABEL: testa:
330 ; SSE41:       ## BB#0:
331 ; SSE41-NEXT:    movapd %xmm0, %xmm2
332 ; SSE41-NEXT:    movapd %xmm1, %xmm0
333 ; SSE41-NEXT:    cmplepd %xmm2, %xmm0
334 ; SSE41-NEXT:    blendvpd %xmm2, %xmm1
335 ; SSE41-NEXT:    movapd %xmm1, %xmm0
336 ; SSE41-NEXT:    retq
337 ;
338 ; AVX-LABEL: testa:
339 ; AVX:       ## BB#0:
340 ; AVX-NEXT:    vcmplepd %xmm0, %xmm1, %xmm2
341 ; AVX-NEXT:    vblendvpd %xmm2, %xmm0, %xmm1, %xmm0
342 ; AVX-NEXT:    retq
343   %max_is_x = fcmp oge <2 x double> %x, %y
344   %max = select <2 x i1> %max_is_x, <2 x double> %x, <2 x double> %y
345   ret <2 x double> %max
346 }
347
348 define <2 x double> @testb(<2 x double> %x, <2 x double> %y) {
349 ; SSE2-LABEL: testb:
350 ; SSE2:       ## BB#0:
351 ; SSE2-NEXT:    movapd %xmm1, %xmm2
352 ; SSE2-NEXT:    cmpnlepd %xmm0, %xmm2
353 ; SSE2-NEXT:    andpd %xmm2, %xmm0
354 ; SSE2-NEXT:    andnpd %xmm1, %xmm2
355 ; SSE2-NEXT:    orpd %xmm2, %xmm0
356 ; SSE2-NEXT:    retq
357 ;
358 ; SSSE3-LABEL: testb:
359 ; SSSE3:       ## BB#0:
360 ; SSSE3-NEXT:    movapd %xmm1, %xmm2
361 ; SSSE3-NEXT:    cmpnlepd %xmm0, %xmm2
362 ; SSSE3-NEXT:    andpd %xmm2, %xmm0
363 ; SSSE3-NEXT:    andnpd %xmm1, %xmm2
364 ; SSSE3-NEXT:    orpd %xmm2, %xmm0
365 ; SSSE3-NEXT:    retq
366 ;
367 ; SSE41-LABEL: testb:
368 ; SSE41:       ## BB#0:
369 ; SSE41-NEXT:    movapd %xmm0, %xmm2
370 ; SSE41-NEXT:    movapd %xmm1, %xmm0
371 ; SSE41-NEXT:    cmpnlepd %xmm2, %xmm0
372 ; SSE41-NEXT:    blendvpd %xmm2, %xmm1
373 ; SSE41-NEXT:    movapd %xmm1, %xmm0
374 ; SSE41-NEXT:    retq
375 ;
376 ; AVX-LABEL: testb:
377 ; AVX:       ## BB#0:
378 ; AVX-NEXT:    vcmpnlepd %xmm0, %xmm1, %xmm2
379 ; AVX-NEXT:    vblendvpd %xmm2, %xmm0, %xmm1, %xmm0
380 ; AVX-NEXT:    retq
381   %min_is_x = fcmp ult <2 x double> %x, %y
382   %min = select <2 x i1> %min_is_x, <2 x double> %x, <2 x double> %y
383   ret <2 x double> %min
384 }
385
386 ; If we can figure out a blend has a constant mask, we should emit the
387 ; blend instruction with an immediate mask
388 define <4 x double> @constant_blendvpd_avx(<4 x double> %xy, <4 x double> %ab) {
389 ; SSE-LABEL: constant_blendvpd_avx:
390 ; SSE:       ## BB#0:
391 ; SSE-NEXT:    movsd %xmm1, %xmm3
392 ; SSE-NEXT:    movaps %xmm2, %xmm0
393 ; SSE-NEXT:    movaps %xmm3, %xmm1
394 ; SSE-NEXT:    retq
395 ;
396 ; AVX-LABEL: constant_blendvpd_avx:
397 ; AVX:       ## BB#0:
398 ; AVX-NEXT:    vblendpd {{.*#+}} ymm0 = ymm1[0,1],ymm0[2],ymm1[3]
399 ; AVX-NEXT:    retq
400   %1 = select <4 x i1> <i1 false, i1 false, i1 true, i1 false>, <4 x double> %xy, <4 x double> %ab
401   ret <4 x double> %1
402 }
403
404 define <8 x float> @constant_blendvps_avx(<8 x float> %xyzw, <8 x float> %abcd) {
405 ; SSE2-LABEL: constant_blendvps_avx:
406 ; SSE2:       ## BB#0:
407 ; SSE2-NEXT:    movaps {{.*#+}} xmm4 = [4294967295,4294967295,4294967295,0]
408 ; SSE2-NEXT:    andps %xmm4, %xmm2
409 ; SSE2-NEXT:    movaps {{.*#+}} xmm5 = [0,0,0,4294967295]
410 ; SSE2-NEXT:    andps %xmm5, %xmm0
411 ; SSE2-NEXT:    orps %xmm2, %xmm0
412 ; SSE2-NEXT:    andps %xmm4, %xmm3
413 ; SSE2-NEXT:    andps %xmm5, %xmm1
414 ; SSE2-NEXT:    orps %xmm3, %xmm1
415 ; SSE2-NEXT:    retq
416 ;
417 ; SSSE3-LABEL: constant_blendvps_avx:
418 ; SSSE3:       ## BB#0:
419 ; SSSE3-NEXT:    movaps {{.*#+}} xmm4 = [4294967295,4294967295,4294967295,0]
420 ; SSSE3-NEXT:    andps %xmm4, %xmm2
421 ; SSSE3-NEXT:    movaps {{.*#+}} xmm5 = [0,0,0,4294967295]
422 ; SSSE3-NEXT:    andps %xmm5, %xmm0
423 ; SSSE3-NEXT:    orps %xmm2, %xmm0
424 ; SSSE3-NEXT:    andps %xmm4, %xmm3
425 ; SSSE3-NEXT:    andps %xmm5, %xmm1
426 ; SSSE3-NEXT:    orps %xmm3, %xmm1
427 ; SSSE3-NEXT:    retq
428 ;
429 ; SSE41-LABEL: constant_blendvps_avx:
430 ; SSE41:       ## BB#0:
431 ; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm2[0,1,2],xmm0[3]
432 ; SSE41-NEXT:    blendps {{.*#+}} xmm1 = xmm3[0,1,2],xmm1[3]
433 ; SSE41-NEXT:    retq
434 ;
435 ; AVX-LABEL: constant_blendvps_avx:
436 ; AVX:       ## BB#0:
437 ; AVX-NEXT:    vblendps {{.*#+}} ymm0 = ymm1[0,1,2],ymm0[3],ymm1[4,5,6],ymm0[7]
438 ; AVX-NEXT:    retq
439   %1 = 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
440   ret <8 x float> %1
441 }
442
443 declare <8 x float> @llvm.x86.avx.blendv.ps.256(<8 x float>, <8 x float>, <8 x float>)
444 declare <4 x double> @llvm.x86.avx.blendv.pd.256(<4 x double>, <4 x double>, <4 x double>)
445
446 ;; 4 tests for shufflevectors that optimize to blend + immediate
447 define <4 x float> @blend_shufflevector_4xfloat(<4 x float> %a, <4 x float> %b) {
448 ; SSE2-LABEL: blend_shufflevector_4xfloat:
449 ; SSE2:       ## BB#0:
450 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[1,3]
451 ; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
452 ; SSE2-NEXT:    retq
453 ;
454 ; SSSE3-LABEL: blend_shufflevector_4xfloat:
455 ; SSSE3:       ## BB#0:
456 ; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[1,3]
457 ; SSSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
458 ; SSSE3-NEXT:    retq
459 ;
460 ; SSE41-LABEL: blend_shufflevector_4xfloat:
461 ; SSE41:       ## BB#0:
462 ; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
463 ; SSE41-NEXT:    retq
464 ;
465 ; AVX-LABEL: blend_shufflevector_4xfloat:
466 ; AVX:       ## BB#0:
467 ; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
468 ; AVX-NEXT:    retq
469   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
470   ret <4 x float> %1
471 }
472
473 define <8 x float> @blend_shufflevector_8xfloat(<8 x float> %a, <8 x float> %b) {
474 ; SSE2-LABEL: blend_shufflevector_8xfloat:
475 ; SSE2:       ## BB#0:
476 ; SSE2-NEXT:    movss %xmm0, %xmm2
477 ; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[2,0],xmm3[3,0]
478 ; SSE2-NEXT:    shufps {{.*#+}} xmm3 = xmm3[0,1],xmm1[0,2]
479 ; SSE2-NEXT:    movaps %xmm2, %xmm0
480 ; SSE2-NEXT:    movaps %xmm3, %xmm1
481 ; SSE2-NEXT:    retq
482 ;
483 ; SSSE3-LABEL: blend_shufflevector_8xfloat:
484 ; SSSE3:       ## BB#0:
485 ; SSSE3-NEXT:    movss %xmm0, %xmm2
486 ; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[2,0],xmm3[3,0]
487 ; SSSE3-NEXT:    shufps {{.*#+}} xmm3 = xmm3[0,1],xmm1[0,2]
488 ; SSSE3-NEXT:    movaps %xmm2, %xmm0
489 ; SSSE3-NEXT:    movaps %xmm3, %xmm1
490 ; SSSE3-NEXT:    retq
491 ;
492 ; SSE41-LABEL: blend_shufflevector_8xfloat:
493 ; SSE41:       ## BB#0:
494 ; SSE41-NEXT:    blendps {{.*#+}} xmm3 = xmm3[0,1],xmm1[2],xmm3[3]
495 ; SSE41-NEXT:    movss %xmm0, %xmm2
496 ; SSE41-NEXT:    movaps %xmm2, %xmm0
497 ; SSE41-NEXT:    movaps %xmm3, %xmm1
498 ; SSE41-NEXT:    retq
499 ;
500 ; AVX-LABEL: blend_shufflevector_8xfloat:
501 ; AVX:       ## BB#0:
502 ; AVX-NEXT:    vblendps {{.*#+}} ymm0 = ymm0[0],ymm1[1,2,3,4,5],ymm0[6],ymm1[7]
503 ; AVX-NEXT:    retq
504   %1 = 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>
505   ret <8 x float> %1
506 }
507
508 define <4 x double> @blend_shufflevector_4xdouble(<4 x double> %a, <4 x double> %b) {
509 ; SSE-LABEL: blend_shufflevector_4xdouble:
510 ; SSE:       ## BB#0:
511 ; SSE-NEXT:    movsd %xmm0, %xmm2
512 ; SSE-NEXT:    movaps %xmm2, %xmm0
513 ; SSE-NEXT:    retq
514 ;
515 ; AVX-LABEL: blend_shufflevector_4xdouble:
516 ; AVX:       ## BB#0:
517 ; AVX-NEXT:    vblendpd {{.*#+}} ymm0 = ymm0[0],ymm1[1],ymm0[2,3]
518 ; AVX-NEXT:    retq
519   %1 = shufflevector <4 x double> %a, <4 x double> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 3>
520   ret <4 x double> %1
521 }
522
523 define <4 x i64> @blend_shufflevector_4xi64(<4 x i64> %a, <4 x i64> %b) {
524 ; SSE-LABEL: blend_shufflevector_4xi64:
525 ; SSE:       ## BB#0:
526 ; SSE-NEXT:    movsd %xmm2, %xmm0
527 ; SSE-NEXT:    movaps %xmm3, %xmm1
528 ; SSE-NEXT:    retq
529 ;
530 ; AVX-LABEL: blend_shufflevector_4xi64:
531 ; AVX:       ## BB#0:
532 ; AVX-NEXT:    vblendpd {{.*#+}} ymm0 = ymm1[0],ymm0[1],ymm1[2,3]
533 ; AVX-NEXT:    retq
534   %1 = shufflevector <4 x i64> %a, <4 x i64> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 7>
535   ret <4 x i64> %1
536 }