[x86] Teach the 128-bit vector shuffle lowering routines to take
[oota-llvm.git] / test / CodeGen / X86 / vector-shuffle-combining.ll
1 ; RUN: llc < %s -mcpu=x86-64 -mattr=+sse2 -x86-experimental-vector-shuffle-legality | FileCheck %s --check-prefix=ALL --check-prefix=SSE --check-prefix=SSE2
2 ; RUN: llc < %s -mcpu=x86-64 -mattr=+ssse3 -x86-experimental-vector-shuffle-legality | FileCheck %s --check-prefix=ALL --check-prefix=SSE --check-prefix=SSSE3
3 ; RUN: llc < %s -mcpu=x86-64 -mattr=+sse4.1 -x86-experimental-vector-shuffle-legality | FileCheck %s --check-prefix=ALL --check-prefix=SSE --check-prefix=SSE41
4 ; RUN: llc < %s -mcpu=x86-64 -mattr=+avx -x86-experimental-vector-shuffle-legality | FileCheck %s --check-prefix=ALL --check-prefix=AVX --check-prefix=AVX1
5 ; RUN: llc < %s -mcpu=x86-64 -mattr=+avx2 -x86-experimental-vector-shuffle-legality | FileCheck %s --check-prefix=ALL --check-prefix=AVX --check-prefix=AVX2
6 ;
7 ; Verify that the DAG combiner correctly folds bitwise operations across
8 ; shuffles, nested shuffles with undef, pairs of nested shuffles, and other
9 ; basic and always-safe patterns. Also test that the DAG combiner will combine
10 ; target-specific shuffle instructions where reasonable.
11
12 target triple = "x86_64-unknown-unknown"
13
14 declare <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32>, i8)
15 declare <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16>, i8)
16 declare <8 x i16> @llvm.x86.sse2.pshufh.w(<8 x i16>, i8)
17
18 define <4 x i32> @combine_pshufd1(<4 x i32> %a) {
19 ; ALL-LABEL: combine_pshufd1:
20 ; ALL:       # BB#0: # %entry
21 ; ALL-NEXT:    retq
22 entry:
23   %b = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %a, i8 27)
24   %c = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %b, i8 27)
25   ret <4 x i32> %c
26 }
27
28 define <4 x i32> @combine_pshufd2(<4 x i32> %a) {
29 ; ALL-LABEL: combine_pshufd2:
30 ; ALL:       # BB#0: # %entry
31 ; ALL-NEXT:    retq
32 entry:
33   %b = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %a, i8 27)
34   %b.cast = bitcast <4 x i32> %b to <8 x i16>
35   %c = call <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16> %b.cast, i8 -28)
36   %c.cast = bitcast <8 x i16> %c to <4 x i32>
37   %d = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %c.cast, i8 27)
38   ret <4 x i32> %d
39 }
40
41 define <4 x i32> @combine_pshufd3(<4 x i32> %a) {
42 ; ALL-LABEL: combine_pshufd3:
43 ; ALL:       # BB#0: # %entry
44 ; ALL-NEXT:    retq
45 entry:
46   %b = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %a, i8 27)
47   %b.cast = bitcast <4 x i32> %b to <8 x i16>
48   %c = call <8 x i16> @llvm.x86.sse2.pshufh.w(<8 x i16> %b.cast, i8 -28)
49   %c.cast = bitcast <8 x i16> %c to <4 x i32>
50   %d = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %c.cast, i8 27)
51   ret <4 x i32> %d
52 }
53
54 define <4 x i32> @combine_pshufd4(<4 x i32> %a) {
55 ; SSE-LABEL: combine_pshufd4:
56 ; SSE:       # BB#0: # %entry
57 ; SSE-NEXT:    pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,7,6,5,4]
58 ; SSE-NEXT:    retq
59 ;
60 ; AVX-LABEL: combine_pshufd4:
61 ; AVX:       # BB#0: # %entry
62 ; AVX-NEXT:    vpshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,7,6,5,4]
63 ; AVX-NEXT:    retq
64 entry:
65   %b = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %a, i8 -31)
66   %b.cast = bitcast <4 x i32> %b to <8 x i16>
67   %c = call <8 x i16> @llvm.x86.sse2.pshufh.w(<8 x i16> %b.cast, i8 27)
68   %c.cast = bitcast <8 x i16> %c to <4 x i32>
69   %d = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %c.cast, i8 -31)
70   ret <4 x i32> %d
71 }
72
73 define <4 x i32> @combine_pshufd5(<4 x i32> %a) {
74 ; SSE-LABEL: combine_pshufd5:
75 ; SSE:       # BB#0: # %entry
76 ; SSE-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[3,2,1,0,4,5,6,7]
77 ; SSE-NEXT:    retq
78 ;
79 ; AVX-LABEL: combine_pshufd5:
80 ; AVX:       # BB#0: # %entry
81 ; AVX-NEXT:    vpshuflw {{.*#+}} xmm0 = xmm0[3,2,1,0,4,5,6,7]
82 ; AVX-NEXT:    retq
83 entry:
84   %b = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %a, i8 -76)
85   %b.cast = bitcast <4 x i32> %b to <8 x i16>
86   %c = call <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16> %b.cast, i8 27)
87   %c.cast = bitcast <8 x i16> %c to <4 x i32>
88   %d = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %c.cast, i8 -76)
89   ret <4 x i32> %d
90 }
91
92 define <4 x i32> @combine_pshufd6(<4 x i32> %a) {
93 ; SSE-LABEL: combine_pshufd6:
94 ; SSE:       # BB#0: # %entry
95 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,0,0,0]
96 ; SSE-NEXT:    retq
97 ;
98 ; AVX-LABEL: combine_pshufd6:
99 ; AVX:       # BB#0: # %entry
100 ; AVX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,0,0,0]
101 ; AVX-NEXT:    retq
102 entry:
103   %b = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %a, i8 0)
104   %c = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %b, i8 8)
105   ret <4 x i32> %c
106 }
107
108 define <8 x i16> @combine_pshuflw1(<8 x i16> %a) {
109 ; ALL-LABEL: combine_pshuflw1:
110 ; ALL:       # BB#0: # %entry
111 ; ALL-NEXT:    retq
112 entry:
113   %b = call <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16> %a, i8 27)
114   %c = call <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16> %b, i8 27)
115   ret <8 x i16> %c
116 }
117
118 define <8 x i16> @combine_pshuflw2(<8 x i16> %a) {
119 ; ALL-LABEL: combine_pshuflw2:
120 ; ALL:       # BB#0: # %entry
121 ; ALL-NEXT:    retq
122 entry:
123   %b = call <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16> %a, i8 27)
124   %c = call <8 x i16> @llvm.x86.sse2.pshufh.w(<8 x i16> %b, i8 -28)
125   %d = call <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16> %c, i8 27)
126   ret <8 x i16> %d
127 }
128
129 define <8 x i16> @combine_pshuflw3(<8 x i16> %a) {
130 ; SSE-LABEL: combine_pshuflw3:
131 ; SSE:       # BB#0: # %entry
132 ; SSE-NEXT:    pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,7,6,5,4]
133 ; SSE-NEXT:    retq
134 ;
135 ; AVX-LABEL: combine_pshuflw3:
136 ; AVX:       # BB#0: # %entry
137 ; AVX-NEXT:    vpshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,7,6,5,4]
138 ; AVX-NEXT:    retq
139 entry:
140   %b = call <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16> %a, i8 27)
141   %c = call <8 x i16> @llvm.x86.sse2.pshufh.w(<8 x i16> %b, i8 27)
142   %d = call <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16> %c, i8 27)
143   ret <8 x i16> %d
144 }
145
146 define <8 x i16> @combine_pshufhw1(<8 x i16> %a) {
147 ; SSE-LABEL: combine_pshufhw1:
148 ; SSE:       # BB#0: # %entry
149 ; SSE-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[3,2,1,0,4,5,6,7]
150 ; SSE-NEXT:    retq
151 ;
152 ; AVX-LABEL: combine_pshufhw1:
153 ; AVX:       # BB#0: # %entry
154 ; AVX-NEXT:    vpshuflw {{.*#+}} xmm0 = xmm0[3,2,1,0,4,5,6,7]
155 ; AVX-NEXT:    retq
156 entry:
157   %b = call <8 x i16> @llvm.x86.sse2.pshufh.w(<8 x i16> %a, i8 27)
158   %c = call <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16> %b, i8 27)
159   %d = call <8 x i16> @llvm.x86.sse2.pshufh.w(<8 x i16> %c, i8 27)
160   ret <8 x i16> %d
161 }
162
163 define <4 x i32> @combine_bitwise_ops_test1(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
164 ; SSE-LABEL: combine_bitwise_ops_test1:
165 ; SSE:       # BB#0:
166 ; SSE-NEXT:    pand %xmm1, %xmm0
167 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
168 ; SSE-NEXT:    retq
169 ;
170 ; AVX-LABEL: combine_bitwise_ops_test1:
171 ; AVX:       # BB#0:
172 ; AVX-NEXT:    vpand %xmm1, %xmm0, %xmm0
173 ; AVX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
174 ; AVX-NEXT:    retq
175   %shuf1 = shufflevector <4 x i32> %a, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 1, i32 3>
176   %shuf2 = shufflevector <4 x i32> %b, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 1, i32 3>
177   %and = and <4 x i32> %shuf1, %shuf2
178   ret <4 x i32> %and
179 }
180
181 define <4 x i32> @combine_bitwise_ops_test2(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
182 ; SSE-LABEL: combine_bitwise_ops_test2:
183 ; SSE:       # BB#0:
184 ; SSE-NEXT:    por %xmm1, %xmm0
185 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
186 ; SSE-NEXT:    retq
187 ;
188 ; AVX-LABEL: combine_bitwise_ops_test2:
189 ; AVX:       # BB#0:
190 ; AVX-NEXT:    vpor %xmm1, %xmm0, %xmm0
191 ; AVX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
192 ; AVX-NEXT:    retq
193   %shuf1 = shufflevector <4 x i32> %a, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 1, i32 3>
194   %shuf2 = shufflevector <4 x i32> %b, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 1, i32 3>
195   %or = or <4 x i32> %shuf1, %shuf2
196   ret <4 x i32> %or
197 }
198
199 define <4 x i32> @combine_bitwise_ops_test3(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
200 ; SSE-LABEL: combine_bitwise_ops_test3:
201 ; SSE:       # BB#0:
202 ; SSE-NEXT:    pxor %xmm1, %xmm0
203 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
204 ; SSE-NEXT:    retq
205 ;
206 ; AVX-LABEL: combine_bitwise_ops_test3:
207 ; AVX:       # BB#0:
208 ; AVX-NEXT:    vpxor %xmm1, %xmm0, %xmm0
209 ; AVX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
210 ; AVX-NEXT:    retq
211   %shuf1 = shufflevector <4 x i32> %a, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 1, i32 3>
212   %shuf2 = shufflevector <4 x i32> %b, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 1, i32 3>
213   %xor = xor <4 x i32> %shuf1, %shuf2
214   ret <4 x i32> %xor
215 }
216
217 define <4 x i32> @combine_bitwise_ops_test4(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
218 ; SSE-LABEL: combine_bitwise_ops_test4:
219 ; SSE:       # BB#0:
220 ; SSE-NEXT:    pand %xmm1, %xmm0
221 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
222 ; SSE-NEXT:    retq
223 ;
224 ; AVX-LABEL: combine_bitwise_ops_test4:
225 ; AVX:       # BB#0:
226 ; AVX-NEXT:    vpand %xmm1, %xmm0, %xmm0
227 ; AVX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
228 ; AVX-NEXT:    retq
229   %shuf1 = shufflevector <4 x i32> %c, <4 x i32> %a, <4 x i32><i32 4, i32 6, i32 5, i32 7>
230   %shuf2 = shufflevector <4 x i32> %c, <4 x i32> %b, <4 x i32><i32 4, i32 6, i32 5, i32 7>
231   %and = and <4 x i32> %shuf1, %shuf2
232   ret <4 x i32> %and
233 }
234
235 define <4 x i32> @combine_bitwise_ops_test5(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
236 ; SSE-LABEL: combine_bitwise_ops_test5:
237 ; SSE:       # BB#0:
238 ; SSE-NEXT:    por %xmm1, %xmm0
239 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
240 ; SSE-NEXT:    retq
241 ;
242 ; AVX-LABEL: combine_bitwise_ops_test5:
243 ; AVX:       # BB#0:
244 ; AVX-NEXT:    vpor %xmm1, %xmm0, %xmm0
245 ; AVX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
246 ; AVX-NEXT:    retq
247   %shuf1 = shufflevector <4 x i32> %c, <4 x i32> %a, <4 x i32><i32 4, i32 6, i32 5, i32 7>
248   %shuf2 = shufflevector <4 x i32> %c, <4 x i32> %b, <4 x i32><i32 4, i32 6, i32 5, i32 7>
249   %or = or <4 x i32> %shuf1, %shuf2
250   ret <4 x i32> %or
251 }
252
253 define <4 x i32> @combine_bitwise_ops_test6(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
254 ; SSE-LABEL: combine_bitwise_ops_test6:
255 ; SSE:       # BB#0:
256 ; SSE-NEXT:    pxor %xmm1, %xmm0
257 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
258 ; SSE-NEXT:    retq
259 ;
260 ; AVX-LABEL: combine_bitwise_ops_test6:
261 ; AVX:       # BB#0:
262 ; AVX-NEXT:    vpxor %xmm1, %xmm0, %xmm0
263 ; AVX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
264 ; AVX-NEXT:    retq
265   %shuf1 = shufflevector <4 x i32> %c, <4 x i32> %a, <4 x i32><i32 4, i32 6, i32 5, i32 7>
266   %shuf2 = shufflevector <4 x i32> %c, <4 x i32> %b, <4 x i32><i32 4, i32 6, i32 5, i32 7>
267   %xor = xor <4 x i32> %shuf1, %shuf2
268   ret <4 x i32> %xor
269 }
270
271
272 ; Verify that DAGCombiner moves the shuffle after the xor/and/or even if shuffles
273 ; are not performing a swizzle operations.
274
275 define <4 x i32> @combine_bitwise_ops_test1b(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
276 ; SSE2-LABEL: combine_bitwise_ops_test1b:
277 ; SSE2:       # BB#0:
278 ; SSE2-NEXT:    andps %xmm1, %xmm0
279 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm2[1,3]
280 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2,1,3]
281 ; SSE2-NEXT:    retq
282 ;
283 ; SSSE3-LABEL: combine_bitwise_ops_test1b:
284 ; SSSE3:       # BB#0:
285 ; SSSE3-NEXT:    andps %xmm1, %xmm0
286 ; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm2[1,3]
287 ; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2,1,3]
288 ; SSSE3-NEXT:    retq
289 ;
290 ; SSE41-LABEL: combine_bitwise_ops_test1b:
291 ; SSE41:       # BB#0:
292 ; SSE41-NEXT:    pand %xmm1, %xmm0
293 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7]
294 ; SSE41-NEXT:    retq
295 ;
296 ; AVX1-LABEL: combine_bitwise_ops_test1b:
297 ; AVX1:       # BB#0:
298 ; AVX1-NEXT:    vpand %xmm1, %xmm0, %xmm0
299 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7]
300 ; AVX1-NEXT:    retq
301 ;
302 ; AVX2-LABEL: combine_bitwise_ops_test1b:
303 ; AVX2:       # BB#0:
304 ; AVX2-NEXT:    vpand %xmm1, %xmm0, %xmm0
305 ; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm0[0],xmm2[1],xmm0[2],xmm2[3]
306 ; AVX2-NEXT:    retq
307   %shuf1 = shufflevector <4 x i32> %a, <4 x i32> %c, <4 x i32><i32 0, i32 5, i32 2, i32 7>
308   %shuf2 = shufflevector <4 x i32> %b, <4 x i32> %c, <4 x i32><i32 0, i32 5, i32 2, i32 7>
309   %and = and <4 x i32> %shuf1, %shuf2
310   ret <4 x i32> %and
311 }
312
313 define <4 x i32> @combine_bitwise_ops_test2b(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
314 ; SSE2-LABEL: combine_bitwise_ops_test2b:
315 ; SSE2:       # BB#0:
316 ; SSE2-NEXT:    orps %xmm1, %xmm0
317 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm2[1,3]
318 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2,1,3]
319 ; SSE2-NEXT:    retq
320 ;
321 ; SSSE3-LABEL: combine_bitwise_ops_test2b:
322 ; SSSE3:       # BB#0:
323 ; SSSE3-NEXT:    orps %xmm1, %xmm0
324 ; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm2[1,3]
325 ; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2,1,3]
326 ; SSSE3-NEXT:    retq
327 ;
328 ; SSE41-LABEL: combine_bitwise_ops_test2b:
329 ; SSE41:       # BB#0:
330 ; SSE41-NEXT:    por %xmm1, %xmm0
331 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7]
332 ; SSE41-NEXT:    retq
333 ;
334 ; AVX1-LABEL: combine_bitwise_ops_test2b:
335 ; AVX1:       # BB#0:
336 ; AVX1-NEXT:    vpor %xmm1, %xmm0, %xmm0
337 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7]
338 ; AVX1-NEXT:    retq
339 ;
340 ; AVX2-LABEL: combine_bitwise_ops_test2b:
341 ; AVX2:       # BB#0:
342 ; AVX2-NEXT:    vpor %xmm1, %xmm0, %xmm0
343 ; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm0[0],xmm2[1],xmm0[2],xmm2[3]
344 ; AVX2-NEXT:    retq
345   %shuf1 = shufflevector <4 x i32> %a, <4 x i32> %c, <4 x i32><i32 0, i32 5, i32 2, i32 7>
346   %shuf2 = shufflevector <4 x i32> %b, <4 x i32> %c, <4 x i32><i32 0, i32 5, i32 2, i32 7>
347   %or = or <4 x i32> %shuf1, %shuf2
348   ret <4 x i32> %or
349 }
350
351 define <4 x i32> @combine_bitwise_ops_test3b(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
352 ; SSE2-LABEL: combine_bitwise_ops_test3b:
353 ; SSE2:       # BB#0:
354 ; SSE2-NEXT:    xorps %xmm1, %xmm0
355 ; SSE2-NEXT:    andps {{.*}}(%rip), %xmm0
356 ; SSE2-NEXT:    retq
357 ;
358 ; SSSE3-LABEL: combine_bitwise_ops_test3b:
359 ; SSSE3:       # BB#0:
360 ; SSSE3-NEXT:    xorps %xmm1, %xmm0
361 ; SSSE3-NEXT:    andps {{.*}}(%rip), %xmm0
362 ; SSSE3-NEXT:    retq
363 ;
364 ; SSE41-LABEL: combine_bitwise_ops_test3b:
365 ; SSE41:       # BB#0:
366 ; SSE41-NEXT:    pxor %xmm1, %xmm0
367 ; SSE41-NEXT:    pxor %xmm1, %xmm1
368 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7]
369 ; SSE41-NEXT:    retq
370 ;
371 ; AVX1-LABEL: combine_bitwise_ops_test3b:
372 ; AVX1:       # BB#0:
373 ; AVX1-NEXT:    vpxor %xmm1, %xmm0, %xmm0
374 ; AVX1-NEXT:    vpxor %xmm1, %xmm1, %xmm1
375 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7]
376 ; AVX1-NEXT:    retq
377 ;
378 ; AVX2-LABEL: combine_bitwise_ops_test3b:
379 ; AVX2:       # BB#0:
380 ; AVX2-NEXT:    vpxor %xmm1, %xmm0, %xmm0
381 ; AVX2-NEXT:    vpxor %xmm1, %xmm1, %xmm1
382 ; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
383 ; AVX2-NEXT:    retq
384   %shuf1 = shufflevector <4 x i32> %a, <4 x i32> %c, <4 x i32><i32 0, i32 5, i32 2, i32 7>
385   %shuf2 = shufflevector <4 x i32> %b, <4 x i32> %c, <4 x i32><i32 0, i32 5, i32 2, i32 7>
386   %xor = xor <4 x i32> %shuf1, %shuf2
387   ret <4 x i32> %xor
388 }
389
390 define <4 x i32> @combine_bitwise_ops_test4b(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
391 ; SSE2-LABEL: combine_bitwise_ops_test4b:
392 ; SSE2:       # BB#0:
393 ; SSE2-NEXT:    andps %xmm1, %xmm0
394 ; SSE2-NEXT:    shufps {{.*#+}} xmm2 = xmm2[0,2],xmm0[1,3]
395 ; SSE2-NEXT:    shufps {{.*#+}} xmm2 = xmm2[0,2,1,3]
396 ; SSE2-NEXT:    movaps %xmm2, %xmm0
397 ; SSE2-NEXT:    retq
398 ;
399 ; SSSE3-LABEL: combine_bitwise_ops_test4b:
400 ; SSSE3:       # BB#0:
401 ; SSSE3-NEXT:    andps %xmm1, %xmm0
402 ; SSSE3-NEXT:    shufps {{.*#+}} xmm2 = xmm2[0,2],xmm0[1,3]
403 ; SSSE3-NEXT:    shufps {{.*#+}} xmm2 = xmm2[0,2,1,3]
404 ; SSSE3-NEXT:    movaps %xmm2, %xmm0
405 ; SSSE3-NEXT:    retq
406 ;
407 ; SSE41-LABEL: combine_bitwise_ops_test4b:
408 ; SSE41:       # BB#0:
409 ; SSE41-NEXT:    pand %xmm1, %xmm0
410 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm2[0,1],xmm0[2,3],xmm2[4,5],xmm0[6,7]
411 ; SSE41-NEXT:    retq
412 ;
413 ; AVX1-LABEL: combine_bitwise_ops_test4b:
414 ; AVX1:       # BB#0:
415 ; AVX1-NEXT:    vpand %xmm1, %xmm0, %xmm0
416 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm2[0,1],xmm0[2,3],xmm2[4,5],xmm0[6,7]
417 ; AVX1-NEXT:    retq
418 ;
419 ; AVX2-LABEL: combine_bitwise_ops_test4b:
420 ; AVX2:       # BB#0:
421 ; AVX2-NEXT:    vpand %xmm1, %xmm0, %xmm0
422 ; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm2[0],xmm0[1],xmm2[2],xmm0[3]
423 ; AVX2-NEXT:    retq
424   %shuf1 = shufflevector <4 x i32> %c, <4 x i32> %a, <4 x i32><i32 0, i32 5, i32 2, i32 7>
425   %shuf2 = shufflevector <4 x i32> %c, <4 x i32> %b, <4 x i32><i32 0, i32 5, i32 2, i32 7>
426   %and = and <4 x i32> %shuf1, %shuf2
427   ret <4 x i32> %and
428 }
429
430 define <4 x i32> @combine_bitwise_ops_test5b(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
431 ; SSE2-LABEL: combine_bitwise_ops_test5b:
432 ; SSE2:       # BB#0:
433 ; SSE2-NEXT:    orps %xmm1, %xmm0
434 ; SSE2-NEXT:    shufps {{.*#+}} xmm2 = xmm2[0,2],xmm0[1,3]
435 ; SSE2-NEXT:    shufps {{.*#+}} xmm2 = xmm2[0,2,1,3]
436 ; SSE2-NEXT:    movaps %xmm2, %xmm0
437 ; SSE2-NEXT:    retq
438 ;
439 ; SSSE3-LABEL: combine_bitwise_ops_test5b:
440 ; SSSE3:       # BB#0:
441 ; SSSE3-NEXT:    orps %xmm1, %xmm0
442 ; SSSE3-NEXT:    shufps {{.*#+}} xmm2 = xmm2[0,2],xmm0[1,3]
443 ; SSSE3-NEXT:    shufps {{.*#+}} xmm2 = xmm2[0,2,1,3]
444 ; SSSE3-NEXT:    movaps %xmm2, %xmm0
445 ; SSSE3-NEXT:    retq
446 ;
447 ; SSE41-LABEL: combine_bitwise_ops_test5b:
448 ; SSE41:       # BB#0:
449 ; SSE41-NEXT:    por %xmm1, %xmm0
450 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm2[0,1],xmm0[2,3],xmm2[4,5],xmm0[6,7]
451 ; SSE41-NEXT:    retq
452 ;
453 ; AVX1-LABEL: combine_bitwise_ops_test5b:
454 ; AVX1:       # BB#0:
455 ; AVX1-NEXT:    vpor %xmm1, %xmm0, %xmm0
456 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm2[0,1],xmm0[2,3],xmm2[4,5],xmm0[6,7]
457 ; AVX1-NEXT:    retq
458 ;
459 ; AVX2-LABEL: combine_bitwise_ops_test5b:
460 ; AVX2:       # BB#0:
461 ; AVX2-NEXT:    vpor %xmm1, %xmm0, %xmm0
462 ; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm2[0],xmm0[1],xmm2[2],xmm0[3]
463 ; AVX2-NEXT:    retq
464   %shuf1 = shufflevector <4 x i32> %c, <4 x i32> %a, <4 x i32><i32 0, i32 5, i32 2, i32 7>
465   %shuf2 = shufflevector <4 x i32> %c, <4 x i32> %b, <4 x i32><i32 0, i32 5, i32 2, i32 7>
466   %or = or <4 x i32> %shuf1, %shuf2
467   ret <4 x i32> %or
468 }
469
470 define <4 x i32> @combine_bitwise_ops_test6b(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
471 ; SSE2-LABEL: combine_bitwise_ops_test6b:
472 ; SSE2:       # BB#0:
473 ; SSE2-NEXT:    xorps %xmm1, %xmm0
474 ; SSE2-NEXT:    andps {{.*}}(%rip), %xmm0
475 ; SSE2-NEXT:    retq
476 ;
477 ; SSSE3-LABEL: combine_bitwise_ops_test6b:
478 ; SSSE3:       # BB#0:
479 ; SSSE3-NEXT:    xorps %xmm1, %xmm0
480 ; SSSE3-NEXT:    andps {{.*}}(%rip), %xmm0
481 ; SSSE3-NEXT:    retq
482 ;
483 ; SSE41-LABEL: combine_bitwise_ops_test6b:
484 ; SSE41:       # BB#0:
485 ; SSE41-NEXT:    pxor %xmm1, %xmm0
486 ; SSE41-NEXT:    pxor %xmm1, %xmm1
487 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3],xmm1[4,5],xmm0[6,7]
488 ; SSE41-NEXT:    retq
489 ;
490 ; AVX1-LABEL: combine_bitwise_ops_test6b:
491 ; AVX1:       # BB#0:
492 ; AVX1-NEXT:    vpxor %xmm1, %xmm0, %xmm0
493 ; AVX1-NEXT:    vpxor %xmm1, %xmm1, %xmm1
494 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3],xmm1[4,5],xmm0[6,7]
495 ; AVX1-NEXT:    retq
496 ;
497 ; AVX2-LABEL: combine_bitwise_ops_test6b:
498 ; AVX2:       # BB#0:
499 ; AVX2-NEXT:    vpxor %xmm1, %xmm0, %xmm0
500 ; AVX2-NEXT:    vpxor %xmm1, %xmm1, %xmm1
501 ; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2],xmm0[3]
502 ; AVX2-NEXT:    retq
503   %shuf1 = shufflevector <4 x i32> %c, <4 x i32> %a, <4 x i32><i32 0, i32 5, i32 2, i32 7>
504   %shuf2 = shufflevector <4 x i32> %c, <4 x i32> %b, <4 x i32><i32 0, i32 5, i32 2, i32 7>
505   %xor = xor <4 x i32> %shuf1, %shuf2
506   ret <4 x i32> %xor
507 }
508
509 define <4 x i32> @combine_bitwise_ops_test1c(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
510 ; SSE2-LABEL: combine_bitwise_ops_test1c:
511 ; SSE2:       # BB#0:
512 ; SSE2-NEXT:    andps %xmm1, %xmm0
513 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm2[1,3]
514 ; SSE2-NEXT:    retq
515 ;
516 ; SSSE3-LABEL: combine_bitwise_ops_test1c:
517 ; SSSE3:       # BB#0:
518 ; SSSE3-NEXT:    andps %xmm1, %xmm0
519 ; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm2[1,3]
520 ; SSSE3-NEXT:    retq
521 ;
522 ; SSE41-LABEL: combine_bitwise_ops_test1c:
523 ; SSE41:       # BB#0:
524 ; SSE41-NEXT:    pand %xmm1, %xmm0
525 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7]
526 ; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
527 ; SSE41-NEXT:    retq
528 ;
529 ; AVX1-LABEL: combine_bitwise_ops_test1c:
530 ; AVX1:       # BB#0:
531 ; AVX1-NEXT:    vpand %xmm1, %xmm0, %xmm0
532 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7]
533 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
534 ; AVX1-NEXT:    retq
535 ;
536 ; AVX2-LABEL: combine_bitwise_ops_test1c:
537 ; AVX2:       # BB#0:
538 ; AVX2-NEXT:    vpand %xmm1, %xmm0, %xmm0
539 ; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm0[0],xmm2[1],xmm0[2],xmm2[3]
540 ; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
541 ; AVX2-NEXT:    retq
542   %shuf1 = shufflevector <4 x i32> %a, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 5, i32 7>
543   %shuf2 = shufflevector <4 x i32> %b, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 5, i32 7>
544   %and = and <4 x i32> %shuf1, %shuf2
545   ret <4 x i32> %and
546 }
547
548 define <4 x i32> @combine_bitwise_ops_test2c(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
549 ; SSE2-LABEL: combine_bitwise_ops_test2c:
550 ; SSE2:       # BB#0:
551 ; SSE2-NEXT:    orps %xmm1, %xmm0
552 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm2[1,3]
553 ; SSE2-NEXT:    retq
554 ;
555 ; SSSE3-LABEL: combine_bitwise_ops_test2c:
556 ; SSSE3:       # BB#0:
557 ; SSSE3-NEXT:    orps %xmm1, %xmm0
558 ; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm2[1,3]
559 ; SSSE3-NEXT:    retq
560 ;
561 ; SSE41-LABEL: combine_bitwise_ops_test2c:
562 ; SSE41:       # BB#0:
563 ; SSE41-NEXT:    por %xmm1, %xmm0
564 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7]
565 ; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
566 ; SSE41-NEXT:    retq
567 ;
568 ; AVX1-LABEL: combine_bitwise_ops_test2c:
569 ; AVX1:       # BB#0:
570 ; AVX1-NEXT:    vpor %xmm1, %xmm0, %xmm0
571 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7]
572 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
573 ; AVX1-NEXT:    retq
574 ;
575 ; AVX2-LABEL: combine_bitwise_ops_test2c:
576 ; AVX2:       # BB#0:
577 ; AVX2-NEXT:    vpor %xmm1, %xmm0, %xmm0
578 ; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm0[0],xmm2[1],xmm0[2],xmm2[3]
579 ; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
580 ; AVX2-NEXT:    retq
581   %shuf1 = shufflevector <4 x i32> %a, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 5, i32 7>
582   %shuf2 = shufflevector <4 x i32> %b, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 5, i32 7>
583   %or = or <4 x i32> %shuf1, %shuf2
584   ret <4 x i32> %or
585 }
586
587 define <4 x i32> @combine_bitwise_ops_test3c(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
588 ; SSE2-LABEL: combine_bitwise_ops_test3c:
589 ; SSE2:       # BB#0:
590 ; SSE2-NEXT:    xorps %xmm1, %xmm0
591 ; SSE2-NEXT:    xorps %xmm1, %xmm1
592 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[2,3]
593 ; SSE2-NEXT:    retq
594 ;
595 ; SSSE3-LABEL: combine_bitwise_ops_test3c:
596 ; SSSE3:       # BB#0:
597 ; SSSE3-NEXT:    xorps %xmm1, %xmm0
598 ; SSSE3-NEXT:    xorps %xmm1, %xmm1
599 ; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[2,3]
600 ; SSSE3-NEXT:    retq
601 ;
602 ; SSE41-LABEL: combine_bitwise_ops_test3c:
603 ; SSE41:       # BB#0:
604 ; SSE41-NEXT:    pxor %xmm1, %xmm0
605 ; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
606 ; SSE41-NEXT:    movq {{.*#+}} xmm0 = xmm0[0],zero
607 ; SSE41-NEXT:    retq
608 ;
609 ; AVX-LABEL: combine_bitwise_ops_test3c:
610 ; AVX:       # BB#0:
611 ; AVX-NEXT:    vpxor %xmm1, %xmm0, %xmm0
612 ; AVX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
613 ; AVX-NEXT:    vmovq {{.*#+}} xmm0 = xmm0[0],zero
614 ; AVX-NEXT:    retq
615   %shuf1 = shufflevector <4 x i32> %a, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 5, i32 7>
616   %shuf2 = shufflevector <4 x i32> %b, <4 x i32> %c, <4 x i32><i32 0, i32 2, i32 5, i32 7>
617   %xor = xor <4 x i32> %shuf1, %shuf2
618   ret <4 x i32> %xor
619 }
620
621 define <4 x i32> @combine_bitwise_ops_test4c(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
622 ; SSE2-LABEL: combine_bitwise_ops_test4c:
623 ; SSE2:       # BB#0:
624 ; SSE2-NEXT:    andps %xmm1, %xmm0
625 ; SSE2-NEXT:    shufps {{.*#+}} xmm2 = xmm2[0,2],xmm0[1,3]
626 ; SSE2-NEXT:    movaps %xmm2, %xmm0
627 ; SSE2-NEXT:    retq
628 ;
629 ; SSSE3-LABEL: combine_bitwise_ops_test4c:
630 ; SSSE3:       # BB#0:
631 ; SSSE3-NEXT:    andps %xmm1, %xmm0
632 ; SSSE3-NEXT:    shufps {{.*#+}} xmm2 = xmm2[0,2],xmm0[1,3]
633 ; SSSE3-NEXT:    movaps %xmm2, %xmm0
634 ; SSSE3-NEXT:    retq
635 ;
636 ; SSE41-LABEL: combine_bitwise_ops_test4c:
637 ; SSE41:       # BB#0:
638 ; SSE41-NEXT:    pand %xmm1, %xmm0
639 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm2[0,1],xmm0[2,3],xmm2[4,5],xmm0[6,7]
640 ; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
641 ; SSE41-NEXT:    retq
642 ;
643 ; AVX1-LABEL: combine_bitwise_ops_test4c:
644 ; AVX1:       # BB#0:
645 ; AVX1-NEXT:    vpand %xmm1, %xmm0, %xmm0
646 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm2[0,1],xmm0[2,3],xmm2[4,5],xmm0[6,7]
647 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
648 ; AVX1-NEXT:    retq
649 ;
650 ; AVX2-LABEL: combine_bitwise_ops_test4c:
651 ; AVX2:       # BB#0:
652 ; AVX2-NEXT:    vpand %xmm1, %xmm0, %xmm0
653 ; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm2[0],xmm0[1],xmm2[2],xmm0[3]
654 ; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
655 ; AVX2-NEXT:    retq
656   %shuf1 = shufflevector <4 x i32> %c, <4 x i32> %a, <4 x i32><i32 0, i32 2, i32 5, i32 7>
657   %shuf2 = shufflevector <4 x i32> %c, <4 x i32> %b, <4 x i32><i32 0, i32 2, i32 5, i32 7>
658   %and = and <4 x i32> %shuf1, %shuf2
659   ret <4 x i32> %and
660 }
661
662 define <4 x i32> @combine_bitwise_ops_test5c(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
663 ; SSE2-LABEL: combine_bitwise_ops_test5c:
664 ; SSE2:       # BB#0:
665 ; SSE2-NEXT:    orps %xmm1, %xmm0
666 ; SSE2-NEXT:    shufps {{.*#+}} xmm2 = xmm2[0,2],xmm0[1,3]
667 ; SSE2-NEXT:    movaps %xmm2, %xmm0
668 ; SSE2-NEXT:    retq
669 ;
670 ; SSSE3-LABEL: combine_bitwise_ops_test5c:
671 ; SSSE3:       # BB#0:
672 ; SSSE3-NEXT:    orps %xmm1, %xmm0
673 ; SSSE3-NEXT:    shufps {{.*#+}} xmm2 = xmm2[0,2],xmm0[1,3]
674 ; SSSE3-NEXT:    movaps %xmm2, %xmm0
675 ; SSSE3-NEXT:    retq
676 ;
677 ; SSE41-LABEL: combine_bitwise_ops_test5c:
678 ; SSE41:       # BB#0:
679 ; SSE41-NEXT:    por %xmm1, %xmm0
680 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm2[0,1],xmm0[2,3],xmm2[4,5],xmm0[6,7]
681 ; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
682 ; SSE41-NEXT:    retq
683 ;
684 ; AVX1-LABEL: combine_bitwise_ops_test5c:
685 ; AVX1:       # BB#0:
686 ; AVX1-NEXT:    vpor %xmm1, %xmm0, %xmm0
687 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm2[0,1],xmm0[2,3],xmm2[4,5],xmm0[6,7]
688 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
689 ; AVX1-NEXT:    retq
690 ;
691 ; AVX2-LABEL: combine_bitwise_ops_test5c:
692 ; AVX2:       # BB#0:
693 ; AVX2-NEXT:    vpor %xmm1, %xmm0, %xmm0
694 ; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm2[0],xmm0[1],xmm2[2],xmm0[3]
695 ; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
696 ; AVX2-NEXT:    retq
697   %shuf1 = shufflevector <4 x i32> %c, <4 x i32> %a, <4 x i32><i32 0, i32 2, i32 5, i32 7>
698   %shuf2 = shufflevector <4 x i32> %c, <4 x i32> %b, <4 x i32><i32 0, i32 2, i32 5, i32 7>
699   %or = or <4 x i32> %shuf1, %shuf2
700   ret <4 x i32> %or
701 }
702
703 define <4 x i32> @combine_bitwise_ops_test6c(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
704 ; SSE2-LABEL: combine_bitwise_ops_test6c:
705 ; SSE2:       # BB#0:
706 ; SSE2-NEXT:    xorps %xmm1, %xmm0
707 ; SSE2-NEXT:    xorps %xmm1, %xmm1
708 ; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,1],xmm0[1,3]
709 ; SSE2-NEXT:    movaps %xmm1, %xmm0
710 ; SSE2-NEXT:    retq
711 ;
712 ; SSSE3-LABEL: combine_bitwise_ops_test6c:
713 ; SSSE3:       # BB#0:
714 ; SSSE3-NEXT:    xorps %xmm1, %xmm0
715 ; SSSE3-NEXT:    xorps %xmm1, %xmm1
716 ; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,1],xmm0[1,3]
717 ; SSSE3-NEXT:    movaps %xmm1, %xmm0
718 ; SSSE3-NEXT:    retq
719 ;
720 ; SSE41-LABEL: combine_bitwise_ops_test6c:
721 ; SSE41:       # BB#0:
722 ; SSE41-NEXT:    pxor %xmm1, %xmm0
723 ; SSE41-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[0,1,1,3]
724 ; SSE41-NEXT:    pxor %xmm0, %xmm0
725 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5,6,7]
726 ; SSE41-NEXT:    retq
727 ;
728 ; AVX1-LABEL: combine_bitwise_ops_test6c:
729 ; AVX1:       # BB#0:
730 ; AVX1-NEXT:    vpxor %xmm1, %xmm0, %xmm0
731 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,1,1,3]
732 ; AVX1-NEXT:    vpxor %xmm1, %xmm1, %xmm1
733 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm1[0,1,2,3],xmm0[4,5,6,7]
734 ; AVX1-NEXT:    retq
735 ;
736 ; AVX2-LABEL: combine_bitwise_ops_test6c:
737 ; AVX2:       # BB#0:
738 ; AVX2-NEXT:    vpxor %xmm1, %xmm0, %xmm0
739 ; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,1,1,3]
740 ; AVX2-NEXT:    vpxor %xmm1, %xmm1, %xmm1
741 ; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3]
742 ; AVX2-NEXT:    retq
743   %shuf1 = shufflevector <4 x i32> %c, <4 x i32> %a, <4 x i32><i32 0, i32 2, i32 5, i32 7>
744   %shuf2 = shufflevector <4 x i32> %c, <4 x i32> %b, <4 x i32><i32 0, i32 2, i32 5, i32 7>
745   %xor = xor <4 x i32> %shuf1, %shuf2
746   ret <4 x i32> %xor
747 }
748
749 define <4 x i32> @combine_nested_undef_test1(<4 x i32> %A, <4 x i32> %B) {
750 ; SSE-LABEL: combine_nested_undef_test1:
751 ; SSE:       # BB#0:
752 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[3,1,0,1]
753 ; SSE-NEXT:    retq
754 ;
755 ; AVX-LABEL: combine_nested_undef_test1:
756 ; AVX:       # BB#0:
757 ; AVX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[3,1,0,1]
758 ; AVX-NEXT:    retq
759   %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 4, i32 3, i32 1>
760   %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 4, i32 0, i32 3>
761   ret <4 x i32> %2
762 }
763
764 define <4 x i32> @combine_nested_undef_test2(<4 x i32> %A, <4 x i32> %B) {
765 ; SSE-LABEL: combine_nested_undef_test2:
766 ; SSE:       # BB#0:
767 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,1,0,3]
768 ; SSE-NEXT:    retq
769 ;
770 ; AVX-LABEL: combine_nested_undef_test2:
771 ; AVX:       # BB#0:
772 ; AVX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[2,1,0,3]
773 ; AVX-NEXT:    retq
774   %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 5, i32 2, i32 3>
775   %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 4, i32 0, i32 3>
776   ret <4 x i32> %2
777 }
778
779 define <4 x i32> @combine_nested_undef_test3(<4 x i32> %A, <4 x i32> %B) {
780 ; SSE-LABEL: combine_nested_undef_test3:
781 ; SSE:       # BB#0:
782 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,1,0,3]
783 ; SSE-NEXT:    retq
784 ;
785 ; AVX-LABEL: combine_nested_undef_test3:
786 ; AVX:       # BB#0:
787 ; AVX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[2,1,0,3]
788 ; AVX-NEXT:    retq
789   %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 6, i32 2, i32 3>
790   %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 4, i32 0, i32 3>
791   ret <4 x i32> %2
792 }
793
794 define <4 x i32> @combine_nested_undef_test4(<4 x i32> %A, <4 x i32> %B) {
795 ; SSE-LABEL: combine_nested_undef_test4:
796 ; SSE:       # BB#0:
797 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1]
798 ; SSE-NEXT:    retq
799 ;
800 ; AVX1-LABEL: combine_nested_undef_test4:
801 ; AVX1:       # BB#0:
802 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,1,0,1]
803 ; AVX1-NEXT:    retq
804 ;
805 ; AVX2-LABEL: combine_nested_undef_test4:
806 ; AVX2:       # BB#0:
807 ; AVX2-NEXT:    vpbroadcastq %xmm0, %xmm0
808 ; AVX2-NEXT:    retq
809   %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 4, i32 7, i32 1>
810   %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 4, i32 4, i32 0, i32 3>
811   ret <4 x i32> %2
812 }
813
814 define <4 x i32> @combine_nested_undef_test5(<4 x i32> %A, <4 x i32> %B) {
815 ; SSE-LABEL: combine_nested_undef_test5:
816 ; SSE:       # BB#0:
817 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3]
818 ; SSE-NEXT:    retq
819 ;
820 ; AVX-LABEL: combine_nested_undef_test5:
821 ; AVX:       # BB#0:
822 ; AVX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[2,3,2,3]
823 ; AVX-NEXT:    retq
824   %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 5, i32 5, i32 2, i32 3>
825   %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 4, i32 4, i32 3>
826   ret <4 x i32> %2
827 }
828
829 define <4 x i32> @combine_nested_undef_test6(<4 x i32> %A, <4 x i32> %B) {
830 ; SSE-LABEL: combine_nested_undef_test6:
831 ; SSE:       # BB#0:
832 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
833 ; SSE-NEXT:    retq
834 ;
835 ; AVX-LABEL: combine_nested_undef_test6:
836 ; AVX:       # BB#0:
837 ; AVX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
838 ; AVX-NEXT:    retq
839   %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 6, i32 2, i32 4>
840   %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 4, i32 0, i32 4>
841   ret <4 x i32> %2
842 }
843
844 define <4 x i32> @combine_nested_undef_test7(<4 x i32> %A, <4 x i32> %B) {
845 ; SSE-LABEL: combine_nested_undef_test7:
846 ; SSE:       # BB#0:
847 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,0,2]
848 ; SSE-NEXT:    retq
849 ;
850 ; AVX-LABEL: combine_nested_undef_test7:
851 ; AVX:       # BB#0:
852 ; AVX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,0,2]
853 ; AVX-NEXT:    retq
854   %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
855   %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 2, i32 0, i32 2>
856   ret <4 x i32> %2
857 }
858
859 define <4 x i32> @combine_nested_undef_test8(<4 x i32> %A, <4 x i32> %B) {
860 ; SSE-LABEL: combine_nested_undef_test8:
861 ; SSE:       # BB#0:
862 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]
863 ; SSE-NEXT:    retq
864 ;
865 ; AVX-LABEL: combine_nested_undef_test8:
866 ; AVX:       # BB#0:
867 ; AVX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]
868 ; AVX-NEXT:    retq
869   %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
870   %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 1, i32 4, i32 3, i32 4>
871   ret <4 x i32> %2
872 }
873
874 define <4 x i32> @combine_nested_undef_test9(<4 x i32> %A, <4 x i32> %B) {
875 ; SSE-LABEL: combine_nested_undef_test9:
876 ; SSE:       # BB#0:
877 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,3,2,2]
878 ; SSE-NEXT:    retq
879 ;
880 ; AVX-LABEL: combine_nested_undef_test9:
881 ; AVX:       # BB#0:
882 ; AVX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[1,3,2,2]
883 ; AVX-NEXT:    retq
884   %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 1, i32 3, i32 2, i32 5>
885   %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 1, i32 4, i32 2>
886   ret <4 x i32> %2
887 }
888
889 define <4 x i32> @combine_nested_undef_test10(<4 x i32> %A, <4 x i32> %B) {
890 ; SSE-LABEL: combine_nested_undef_test10:
891 ; SSE:       # BB#0:
892 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,1,3]
893 ; SSE-NEXT:    retq
894 ;
895 ; AVX-LABEL: combine_nested_undef_test10:
896 ; AVX:       # BB#0:
897 ; AVX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[1,1,1,3]
898 ; AVX-NEXT:    retq
899   %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 1, i32 1, i32 5, i32 5>
900   %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 4, i32 1, i32 4>
901   ret <4 x i32> %2
902 }
903
904 define <4 x i32> @combine_nested_undef_test11(<4 x i32> %A, <4 x i32> %B) {
905 ; SSE-LABEL: combine_nested_undef_test11:
906 ; SSE:       # BB#0:
907 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,2,1]
908 ; SSE-NEXT:    retq
909 ;
910 ; AVX-LABEL: combine_nested_undef_test11:
911 ; AVX:       # BB#0:
912 ; AVX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[1,1,2,1]
913 ; AVX-NEXT:    retq
914   %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 1, i32 2, i32 5, i32 4>
915   %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 4, i32 1, i32 0>
916   ret <4 x i32> %2
917 }
918
919 define <4 x i32> @combine_nested_undef_test12(<4 x i32> %A, <4 x i32> %B) {
920 ; SSE-LABEL: combine_nested_undef_test12:
921 ; SSE:       # BB#0:
922 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1]
923 ; SSE-NEXT:    retq
924 ;
925 ; AVX1-LABEL: combine_nested_undef_test12:
926 ; AVX1:       # BB#0:
927 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,1,0,1]
928 ; AVX1-NEXT:    retq
929 ;
930 ; AVX2-LABEL: combine_nested_undef_test12:
931 ; AVX2:       # BB#0:
932 ; AVX2-NEXT:    vpbroadcastq %xmm0, %xmm0
933 ; AVX2-NEXT:    retq
934   %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 0, i32 2, i32 4>
935   %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 1, i32 4, i32 0, i32 4>
936   ret <4 x i32> %2
937 }
938
939 ; The following pair of shuffles is folded into vector %A.
940 define <4 x i32> @combine_nested_undef_test13(<4 x i32> %A, <4 x i32> %B) {
941 ; ALL-LABEL: combine_nested_undef_test13:
942 ; ALL:       # BB#0:
943 ; ALL-NEXT:    retq
944   %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 1, i32 4, i32 2, i32 6>
945   %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 4, i32 0, i32 2, i32 4>
946   ret <4 x i32> %2
947 }
948
949 ; The following pair of shuffles is folded into vector %B.
950 define <4 x i32> @combine_nested_undef_test14(<4 x i32> %A, <4 x i32> %B) {
951 ; SSE-LABEL: combine_nested_undef_test14:
952 ; SSE:       # BB#0:
953 ; SSE-NEXT:    movaps %xmm1, %xmm0
954 ; SSE-NEXT:    retq
955 ;
956 ; AVX-LABEL: combine_nested_undef_test14:
957 ; AVX:       # BB#0:
958 ; AVX-NEXT:    vmovaps %xmm1, %xmm0
959 ; AVX-NEXT:    retq
960   %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 6, i32 2, i32 4>
961   %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 3, i32 4, i32 1, i32 4>
962   ret <4 x i32> %2
963 }
964
965
966 ; Verify that we don't optimize the following cases. We expect more than one shuffle.
967 ;
968 ; FIXME: Many of these already don't make sense, and the rest should stop
969 ; making sense with th enew vector shuffle lowering. Revisit at least testing for
970 ; it.
971
972 define <4 x i32> @combine_nested_undef_test15(<4 x i32> %A, <4 x i32> %B) {
973 ; SSE2-LABEL: combine_nested_undef_test15:
974 ; SSE2:       # BB#0:
975 ; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[3,0]
976 ; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[0,1]
977 ; SSE2-NEXT:    movaps %xmm1, %xmm0
978 ; SSE2-NEXT:    retq
979 ;
980 ; SSSE3-LABEL: combine_nested_undef_test15:
981 ; SSSE3:       # BB#0:
982 ; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[3,0]
983 ; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[0,1]
984 ; SSSE3-NEXT:    movaps %xmm1, %xmm0
985 ; SSSE3-NEXT:    retq
986 ;
987 ; SSE41-LABEL: combine_nested_undef_test15:
988 ; SSE41:       # BB#0:
989 ; SSE41-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,0,1,1]
990 ; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[3,1,0,1]
991 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5,6,7]
992 ; SSE41-NEXT:    retq
993 ;
994 ; AVX1-LABEL: combine_nested_undef_test15:
995 ; AVX1:       # BB#0:
996 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm1 = xmm1[0,0,1,1]
997 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[3,1,0,1]
998 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5,6,7]
999 ; AVX1-NEXT:    retq
1000 ;
1001 ; AVX2-LABEL: combine_nested_undef_test15:
1002 ; AVX2:       # BB#0:
1003 ; AVX2-NEXT:    vpbroadcastd %xmm1, %xmm1
1004 ; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[3,1,0,1]
1005 ; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2,3]
1006 ; AVX2-NEXT:    retq
1007   %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 4, i32 3, i32 1>
1008   %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 1, i32 0, i32 3>
1009   ret <4 x i32> %2
1010 }
1011
1012 define <4 x i32> @combine_nested_undef_test16(<4 x i32> %A, <4 x i32> %B) {
1013 ; SSE2-LABEL: combine_nested_undef_test16:
1014 ; SSE2:       # BB#0:
1015 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[1,3]
1016 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2,1,3]
1017 ; SSE2-NEXT:    retq
1018 ;
1019 ; SSSE3-LABEL: combine_nested_undef_test16:
1020 ; SSSE3:       # BB#0:
1021 ; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[1,3]
1022 ; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2,1,3]
1023 ; SSSE3-NEXT:    retq
1024 ;
1025 ; SSE41-LABEL: combine_nested_undef_test16:
1026 ; SSE41:       # BB#0:
1027 ; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
1028 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7]
1029 ; SSE41-NEXT:    retq
1030 ;
1031 ; AVX1-LABEL: combine_nested_undef_test16:
1032 ; AVX1:       # BB#0:
1033 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
1034 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7]
1035 ; AVX1-NEXT:    retq
1036 ;
1037 ; AVX2-LABEL: combine_nested_undef_test16:
1038 ; AVX2:       # BB#0:
1039 ; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
1040 ; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
1041 ; AVX2-NEXT:    retq
1042   %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
1043   %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 1, i32 0, i32 3>
1044   ret <4 x i32> %2
1045 }
1046
1047 define <4 x i32> @combine_nested_undef_test17(<4 x i32> %A, <4 x i32> %B) {
1048 ; SSE2-LABEL: combine_nested_undef_test17:
1049 ; SSE2:       # BB#0:
1050 ; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[1,0]
1051 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,1],xmm1[0,2]
1052 ; SSE2-NEXT:    retq
1053 ;
1054 ; SSSE3-LABEL: combine_nested_undef_test17:
1055 ; SSSE3:       # BB#0:
1056 ; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[1,0]
1057 ; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,1],xmm1[0,2]
1058 ; SSSE3-NEXT:    retq
1059 ;
1060 ; SSE41-LABEL: combine_nested_undef_test17:
1061 ; SSE41:       # BB#0:
1062 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3,4,5,6,7]
1063 ; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[3,1,0,1]
1064 ; SSE41-NEXT:    retq
1065 ;
1066 ; AVX1-LABEL: combine_nested_undef_test17:
1067 ; AVX1:       # BB#0:
1068 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3,4,5,6,7]
1069 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[3,1,0,1]
1070 ; AVX1-NEXT:    retq
1071 ;
1072 ; AVX2-LABEL: combine_nested_undef_test17:
1073 ; AVX2:       # BB#0:
1074 ; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]
1075 ; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[3,1,0,1]
1076 ; AVX2-NEXT:    retq
1077   %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 1, i32 3, i32 1>
1078   %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 1, i32 0, i32 3>
1079   ret <4 x i32> %2
1080 }
1081
1082 define <4 x i32> @combine_nested_undef_test18(<4 x i32> %A, <4 x i32> %B) {
1083 ; SSE-LABEL: combine_nested_undef_test18:
1084 ; SSE:       # BB#0:
1085 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,0,3]
1086 ; SSE-NEXT:    retq
1087 ;
1088 ; AVX-LABEL: combine_nested_undef_test18:
1089 ; AVX:       # BB#0:
1090 ; AVX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm1[1,1,0,3]
1091 ; AVX-NEXT:    retq
1092   %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 5, i32 2, i32 7>
1093   %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 1, i32 1, i32 0, i32 3>
1094   ret <4 x i32> %2
1095 }
1096
1097 define <4 x i32> @combine_nested_undef_test19(<4 x i32> %A, <4 x i32> %B) {
1098 ; SSE2-LABEL: combine_nested_undef_test19:
1099 ; SSE2:       # BB#0:
1100 ; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[1,0],xmm0[0,0]
1101 ; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,2],xmm0[0,0]
1102 ; SSE2-NEXT:    movaps %xmm1, %xmm0
1103 ; SSE2-NEXT:    retq
1104 ;
1105 ; SSSE3-LABEL: combine_nested_undef_test19:
1106 ; SSSE3:       # BB#0:
1107 ; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[1,0],xmm0[0,0]
1108 ; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,2],xmm0[0,0]
1109 ; SSSE3-NEXT:    movaps %xmm1, %xmm0
1110 ; SSSE3-NEXT:    retq
1111 ;
1112 ; SSE41-LABEL: combine_nested_undef_test19:
1113 ; SSE41:       # BB#0:
1114 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5,6,7]
1115 ; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,0,0,0]
1116 ; SSE41-NEXT:    retq
1117 ;
1118 ; AVX1-LABEL: combine_nested_undef_test19:
1119 ; AVX1:       # BB#0:
1120 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5,6,7]
1121 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[1,0,0,0]
1122 ; AVX1-NEXT:    retq
1123 ;
1124 ; AVX2-LABEL: combine_nested_undef_test19:
1125 ; AVX2:       # BB#0:
1126 ; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2,3]
1127 ; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[1,0,0,0]
1128 ; AVX2-NEXT:    retq
1129   %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 4, i32 5, i32 6>
1130   %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 0, i32 0, i32 0>
1131   ret <4 x i32> %2
1132 }
1133
1134 define <4 x i32> @combine_nested_undef_test20(<4 x i32> %A, <4 x i32> %B) {
1135 ; SSE2-LABEL: combine_nested_undef_test20:
1136 ; SSE2:       # BB#0:
1137 ; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[2,3]
1138 ; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,2,3,1]
1139 ; SSE2-NEXT:    movaps %xmm1, %xmm0
1140 ; SSE2-NEXT:    retq
1141 ;
1142 ; SSSE3-LABEL: combine_nested_undef_test20:
1143 ; SSSE3:       # BB#0:
1144 ; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[2,3]
1145 ; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,2,3,1]
1146 ; SSSE3-NEXT:    movaps %xmm1, %xmm0
1147 ; SSSE3-NEXT:    retq
1148 ;
1149 ; SSE41-LABEL: combine_nested_undef_test20:
1150 ; SSE41:       # BB#0:
1151 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm1[0,1,2,3],xmm0[4,5,6,7]
1152 ; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,3,0]
1153 ; SSE41-NEXT:    retq
1154 ;
1155 ; AVX1-LABEL: combine_nested_undef_test20:
1156 ; AVX1:       # BB#0:
1157 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm1[0,1,2,3],xmm0[4,5,6,7]
1158 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,3,0]
1159 ; AVX1-NEXT:    retq
1160 ;
1161 ; AVX2-LABEL: combine_nested_undef_test20:
1162 ; AVX2:       # BB#0:
1163 ; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3]
1164 ; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,3,0]
1165 ; AVX2-NEXT:    retq
1166   %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 3, i32 2, i32 4, i32 4>
1167   %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 1, i32 0, i32 3>
1168   ret <4 x i32> %2
1169 }
1170
1171 define <4 x i32> @combine_nested_undef_test21(<4 x i32> %A, <4 x i32> %B) {
1172 ; SSE2-LABEL: combine_nested_undef_test21:
1173 ; SSE2:       # BB#0:
1174 ; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[1,1]
1175 ; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,2,1,3]
1176 ; SSE2-NEXT:    movaps %xmm1, %xmm0
1177 ; SSE2-NEXT:    retq
1178 ;
1179 ; SSSE3-LABEL: combine_nested_undef_test21:
1180 ; SSSE3:       # BB#0:
1181 ; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[1,1]
1182 ; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,2,1,3]
1183 ; SSSE3-NEXT:    movaps %xmm1, %xmm0
1184 ; SSSE3-NEXT:    retq
1185 ;
1186 ; SSE41-LABEL: combine_nested_undef_test21:
1187 ; SSE41:       # BB#0:
1188 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3],xmm1[4,5,6,7]
1189 ; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1]
1190 ; SSE41-NEXT:    retq
1191 ;
1192 ; AVX1-LABEL: combine_nested_undef_test21:
1193 ; AVX1:       # BB#0:
1194 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3],xmm1[4,5,6,7]
1195 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,1,0,1]
1196 ; AVX1-NEXT:    retq
1197 ;
1198 ; AVX2-LABEL: combine_nested_undef_test21:
1199 ; AVX2:       # BB#0:
1200 ; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3]
1201 ; AVX2-NEXT:    vpbroadcastq %xmm0, %xmm0
1202 ; AVX2-NEXT:    retq
1203   %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 1, i32 3, i32 1>
1204   %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 1, i32 0, i32 3>
1205   ret <4 x i32> %2
1206 }
1207
1208
1209 ; Test that we correctly combine shuffles according to rule
1210 ;  shuffle(shuffle(x, y), undef) -> shuffle(y, undef)
1211
1212 define <4 x i32> @combine_nested_undef_test22(<4 x i32> %A, <4 x i32> %B) {
1213 ; SSE-LABEL: combine_nested_undef_test22:
1214 ; SSE:       # BB#0:
1215 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,1,3]
1216 ; SSE-NEXT:    retq
1217 ;
1218 ; AVX-LABEL: combine_nested_undef_test22:
1219 ; AVX:       # BB#0:
1220 ; AVX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm1[1,1,1,3]
1221 ; AVX-NEXT:    retq
1222   %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 5, i32 2, i32 7>
1223   %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 3>
1224   ret <4 x i32> %2
1225 }
1226
1227 define <4 x i32> @combine_nested_undef_test23(<4 x i32> %A, <4 x i32> %B) {
1228 ; SSE-LABEL: combine_nested_undef_test23:
1229 ; SSE:       # BB#0:
1230 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[0,1,0,3]
1231 ; SSE-NEXT:    retq
1232 ;
1233 ; AVX-LABEL: combine_nested_undef_test23:
1234 ; AVX:       # BB#0:
1235 ; AVX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm1[0,1,0,3]
1236 ; AVX-NEXT:    retq
1237   %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 5, i32 2, i32 7>
1238   %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 1, i32 0, i32 3>
1239   ret <4 x i32> %2
1240 }
1241
1242 define <4 x i32> @combine_nested_undef_test24(<4 x i32> %A, <4 x i32> %B) {
1243 ; SSE-LABEL: combine_nested_undef_test24:
1244 ; SSE:       # BB#0:
1245 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[0,3,2,3]
1246 ; SSE-NEXT:    retq
1247 ;
1248 ; AVX-LABEL: combine_nested_undef_test24:
1249 ; AVX:       # BB#0:
1250 ; AVX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm1[0,3,2,3]
1251 ; AVX-NEXT:    retq
1252   %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 1, i32 6, i32 7>
1253   %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 3, i32 2, i32 4>
1254   ret <4 x i32> %2
1255 }
1256
1257 define <4 x i32> @combine_nested_undef_test25(<4 x i32> %A, <4 x i32> %B) {
1258 ; SSE-LABEL: combine_nested_undef_test25:
1259 ; SSE:       # BB#0:
1260 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1]
1261 ; SSE-NEXT:    retq
1262 ;
1263 ; AVX1-LABEL: combine_nested_undef_test25:
1264 ; AVX1:       # BB#0:
1265 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,1,0,1]
1266 ; AVX1-NEXT:    retq
1267 ;
1268 ; AVX2-LABEL: combine_nested_undef_test25:
1269 ; AVX2:       # BB#0:
1270 ; AVX2-NEXT:    vpbroadcastq %xmm0, %xmm0
1271 ; AVX2-NEXT:    retq
1272   %1 = shufflevector <4 x i32> %B, <4 x i32> %A, <4 x i32> <i32 1, i32 5, i32 2, i32 4>
1273   %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 3, i32 1, i32 3, i32 1>
1274   ret <4 x i32> %2
1275 }
1276
1277 define <4 x i32> @combine_nested_undef_test26(<4 x i32> %A, <4 x i32> %B) {
1278 ; SSE-LABEL: combine_nested_undef_test26:
1279 ; SSE:       # BB#0:
1280 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3]
1281 ; SSE-NEXT:    retq
1282 ;
1283 ; AVX-LABEL: combine_nested_undef_test26:
1284 ; AVX:       # BB#0:
1285 ; AVX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[2,3,2,3]
1286 ; AVX-NEXT:    retq
1287   %1 = shufflevector <4 x i32> %B, <4 x i32> %A, <4 x i32> <i32 1, i32 2, i32 6, i32 7>
1288   %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 3, i32 2, i32 3>
1289   ret <4 x i32> %2
1290 }
1291
1292 define <4 x i32> @combine_nested_undef_test27(<4 x i32> %A, <4 x i32> %B) {
1293 ; SSE-LABEL: combine_nested_undef_test27:
1294 ; SSE:       # BB#0:
1295 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1]
1296 ; SSE-NEXT:    retq
1297 ;
1298 ; AVX1-LABEL: combine_nested_undef_test27:
1299 ; AVX1:       # BB#0:
1300 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,1,0,1]
1301 ; AVX1-NEXT:    retq
1302 ;
1303 ; AVX2-LABEL: combine_nested_undef_test27:
1304 ; AVX2:       # BB#0:
1305 ; AVX2-NEXT:    vpbroadcastq %xmm0, %xmm0
1306 ; AVX2-NEXT:    retq
1307   %1 = shufflevector <4 x i32> %B, <4 x i32> %A, <4 x i32> <i32 2, i32 1, i32 5, i32 4>
1308   %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 3, i32 2, i32 3, i32 2>
1309   ret <4 x i32> %2
1310 }
1311
1312 define <4 x i32> @combine_nested_undef_test28(<4 x i32> %A, <4 x i32> %B) {
1313 ; SSE-LABEL: combine_nested_undef_test28:
1314 ; SSE:       # BB#0:
1315 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,1,1,0]
1316 ; SSE-NEXT:    retq
1317 ;
1318 ; AVX-LABEL: combine_nested_undef_test28:
1319 ; AVX:       # BB#0:
1320 ; AVX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,1,1,0]
1321 ; AVX-NEXT:    retq
1322   %1 = shufflevector <4 x i32> %B, <4 x i32> %A, <4 x i32> <i32 1, i32 2, i32 4, i32 5>
1323   %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 3, i32 3, i32 2>
1324   ret <4 x i32> %2
1325 }
1326
1327 define <4 x float> @combine_test1(<4 x float> %a, <4 x float> %b) {
1328 ; SSE-LABEL: combine_test1:
1329 ; SSE:       # BB#0:
1330 ; SSE-NEXT:    movaps %xmm1, %xmm0
1331 ; SSE-NEXT:    retq
1332 ;
1333 ; AVX-LABEL: combine_test1:
1334 ; AVX:       # BB#0:
1335 ; AVX-NEXT:    vmovaps %xmm1, %xmm0
1336 ; AVX-NEXT:    retq
1337   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
1338   %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
1339   ret <4 x float> %2
1340 }
1341
1342 define <4 x float> @combine_test2(<4 x float> %a, <4 x float> %b) {
1343 ; SSE2-LABEL: combine_test2:
1344 ; SSE2:       # BB#0:
1345 ; SSE2-NEXT:    movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]
1346 ; SSE2-NEXT:    movaps %xmm1, %xmm0
1347 ; SSE2-NEXT:    retq
1348 ;
1349 ; SSSE3-LABEL: combine_test2:
1350 ; SSSE3:       # BB#0:
1351 ; SSSE3-NEXT:    movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]
1352 ; SSSE3-NEXT:    movaps %xmm1, %xmm0
1353 ; SSSE3-NEXT:    retq
1354 ;
1355 ; SSE41-LABEL: combine_test2:
1356 ; SSE41:       # BB#0:
1357 ; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]
1358 ; SSE41-NEXT:    retq
1359 ;
1360 ; AVX-LABEL: combine_test2:
1361 ; AVX:       # BB#0:
1362 ; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]
1363 ; AVX-NEXT:    retq
1364   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
1365   %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 6, i32 3>
1366   ret <4 x float> %2
1367 }
1368
1369 define <4 x float> @combine_test3(<4 x float> %a, <4 x float> %b) {
1370 ; SSE-LABEL: combine_test3:
1371 ; SSE:       # BB#0:
1372 ; SSE-NEXT:    unpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1373 ; SSE-NEXT:    retq
1374 ;
1375 ; AVX-LABEL: combine_test3:
1376 ; AVX:       # BB#0:
1377 ; AVX-NEXT:    vunpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1378 ; AVX-NEXT:    retq
1379   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 1, i32 7>
1380   %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 2, i32 4, i32 1>
1381   ret <4 x float> %2
1382 }
1383
1384 define <4 x float> @combine_test4(<4 x float> %a, <4 x float> %b) {
1385 ; SSE-LABEL: combine_test4:
1386 ; SSE:       # BB#0:
1387 ; SSE-NEXT:    unpckhpd {{.*#+}} xmm1 = xmm1[1],xmm0[1]
1388 ; SSE-NEXT:    movapd %xmm1, %xmm0
1389 ; SSE-NEXT:    retq
1390 ;
1391 ; AVX-LABEL: combine_test4:
1392 ; AVX:       # BB#0:
1393 ; AVX-NEXT:    vunpckhpd {{.*#+}} xmm0 = xmm1[1],xmm0[1]
1394 ; AVX-NEXT:    retq
1395   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 2, i32 3, i32 5, i32 5>
1396   %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 6, i32 7, i32 0, i32 1>
1397   ret <4 x float> %2
1398 }
1399
1400 define <4 x float> @combine_test5(<4 x float> %a, <4 x float> %b) {
1401 ; SSE2-LABEL: combine_test5:
1402 ; SSE2:       # BB#0:
1403 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0]
1404 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3]
1405 ; SSE2-NEXT:    retq
1406 ;
1407 ; SSSE3-LABEL: combine_test5:
1408 ; SSSE3:       # BB#0:
1409 ; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0]
1410 ; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3]
1411 ; SSSE3-NEXT:    retq
1412 ;
1413 ; SSE41-LABEL: combine_test5:
1414 ; SSE41:       # BB#0:
1415 ; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3]
1416 ; SSE41-NEXT:    retq
1417 ;
1418 ; AVX-LABEL: combine_test5:
1419 ; AVX:       # BB#0:
1420 ; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3]
1421 ; AVX-NEXT:    retq
1422   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
1423   %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 2, i32 7>
1424   ret <4 x float> %2
1425 }
1426
1427 define <4 x i32> @combine_test6(<4 x i32> %a, <4 x i32> %b) {
1428 ; SSE-LABEL: combine_test6:
1429 ; SSE:       # BB#0:
1430 ; SSE-NEXT:    movaps %xmm1, %xmm0
1431 ; SSE-NEXT:    retq
1432 ;
1433 ; AVX-LABEL: combine_test6:
1434 ; AVX:       # BB#0:
1435 ; AVX-NEXT:    vmovaps %xmm1, %xmm0
1436 ; AVX-NEXT:    retq
1437   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
1438   %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
1439   ret <4 x i32> %2
1440 }
1441
1442 define <4 x i32> @combine_test7(<4 x i32> %a, <4 x i32> %b) {
1443 ; SSE2-LABEL: combine_test7:
1444 ; SSE2:       # BB#0:
1445 ; SSE2-NEXT:    movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]
1446 ; SSE2-NEXT:    movaps %xmm1, %xmm0
1447 ; SSE2-NEXT:    retq
1448 ;
1449 ; SSSE3-LABEL: combine_test7:
1450 ; SSSE3:       # BB#0:
1451 ; SSSE3-NEXT:    movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]
1452 ; SSSE3-NEXT:    movaps %xmm1, %xmm0
1453 ; SSSE3-NEXT:    retq
1454 ;
1455 ; SSE41-LABEL: combine_test7:
1456 ; SSE41:       # BB#0:
1457 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3,4,5,6,7]
1458 ; SSE41-NEXT:    retq
1459 ;
1460 ; AVX1-LABEL: combine_test7:
1461 ; AVX1:       # BB#0:
1462 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3,4,5,6,7]
1463 ; AVX1-NEXT:    retq
1464 ;
1465 ; AVX2-LABEL: combine_test7:
1466 ; AVX2:       # BB#0:
1467 ; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]
1468 ; AVX2-NEXT:    retq
1469   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
1470   %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 0, i32 1, i32 6, i32 3>
1471   ret <4 x i32> %2
1472 }
1473
1474 define <4 x i32> @combine_test8(<4 x i32> %a, <4 x i32> %b) {
1475 ; SSE-LABEL: combine_test8:
1476 ; SSE:       # BB#0:
1477 ; SSE-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1478 ; SSE-NEXT:    retq
1479 ;
1480 ; AVX-LABEL: combine_test8:
1481 ; AVX:       # BB#0:
1482 ; AVX-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1483 ; AVX-NEXT:    retq
1484   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 5, i32 1, i32 7>
1485   %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 0, i32 2, i32 4, i32 1>
1486   ret <4 x i32> %2
1487 }
1488
1489 define <4 x i32> @combine_test9(<4 x i32> %a, <4 x i32> %b) {
1490 ; SSE-LABEL: combine_test9:
1491 ; SSE:       # BB#0:
1492 ; SSE-NEXT:    punpckhqdq {{.*#+}} xmm1 = xmm1[1],xmm0[1]
1493 ; SSE-NEXT:    movdqa %xmm1, %xmm0
1494 ; SSE-NEXT:    retq
1495 ;
1496 ; AVX-LABEL: combine_test9:
1497 ; AVX:       # BB#0:
1498 ; AVX-NEXT:    vpunpckhqdq {{.*#+}} xmm0 = xmm1[1],xmm0[1]
1499 ; AVX-NEXT:    retq
1500   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 2, i32 3, i32 5, i32 5>
1501   %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 6, i32 7, i32 0, i32 1>
1502   ret <4 x i32> %2
1503 }
1504
1505 define <4 x i32> @combine_test10(<4 x i32> %a, <4 x i32> %b) {
1506 ; SSE2-LABEL: combine_test10:
1507 ; SSE2:       # BB#0:
1508 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0]
1509 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3]
1510 ; SSE2-NEXT:    retq
1511 ;
1512 ; SSSE3-LABEL: combine_test10:
1513 ; SSSE3:       # BB#0:
1514 ; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0]
1515 ; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3]
1516 ; SSSE3-NEXT:    retq
1517 ;
1518 ; SSE41-LABEL: combine_test10:
1519 ; SSE41:       # BB#0:
1520 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3],xmm1[4,5,6,7]
1521 ; SSE41-NEXT:    retq
1522 ;
1523 ; AVX1-LABEL: combine_test10:
1524 ; AVX1:       # BB#0:
1525 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3],xmm1[4,5,6,7]
1526 ; AVX1-NEXT:    retq
1527 ;
1528 ; AVX2-LABEL: combine_test10:
1529 ; AVX2:       # BB#0:
1530 ; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3]
1531 ; AVX2-NEXT:    retq
1532   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
1533   %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 0, i32 1, i32 2, i32 7>
1534   ret <4 x i32> %2
1535 }
1536
1537 define <4 x float> @combine_test11(<4 x float> %a, <4 x float> %b) {
1538 ; ALL-LABEL: combine_test11:
1539 ; ALL:       # BB#0:
1540 ; ALL-NEXT:    retq
1541   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
1542   %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
1543   ret <4 x float> %2
1544 }
1545
1546 define <4 x float> @combine_test12(<4 x float> %a, <4 x float> %b) {
1547 ; SSE2-LABEL: combine_test12:
1548 ; SSE2:       # BB#0:
1549 ; SSE2-NEXT:    movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]
1550 ; SSE2-NEXT:    movaps %xmm1, %xmm0
1551 ; SSE2-NEXT:    retq
1552 ;
1553 ; SSSE3-LABEL: combine_test12:
1554 ; SSSE3:       # BB#0:
1555 ; SSSE3-NEXT:    movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]
1556 ; SSSE3-NEXT:    movaps %xmm1, %xmm0
1557 ; SSSE3-NEXT:    retq
1558 ;
1559 ; SSE41-LABEL: combine_test12:
1560 ; SSE41:       # BB#0:
1561 ; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]
1562 ; SSE41-NEXT:    retq
1563 ;
1564 ; AVX-LABEL: combine_test12:
1565 ; AVX:       # BB#0:
1566 ; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]
1567 ; AVX-NEXT:    retq
1568   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 6, i32 7>
1569   %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 4, i32 1, i32 2, i32 3>
1570   ret <4 x float> %2
1571 }
1572
1573 define <4 x float> @combine_test13(<4 x float> %a, <4 x float> %b) {
1574 ; SSE-LABEL: combine_test13:
1575 ; SSE:       # BB#0:
1576 ; SSE-NEXT:    unpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1577 ; SSE-NEXT:    retq
1578 ;
1579 ; AVX-LABEL: combine_test13:
1580 ; AVX:       # BB#0:
1581 ; AVX-NEXT:    vunpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1582 ; AVX-NEXT:    retq
1583   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
1584   %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 4, i32 5, i32 2, i32 3>
1585   ret <4 x float> %2
1586 }
1587
1588 define <4 x float> @combine_test14(<4 x float> %a, <4 x float> %b) {
1589 ; SSE-LABEL: combine_test14:
1590 ; SSE:       # BB#0:
1591 ; SSE-NEXT:    unpckhpd {{.*#+}} xmm0 = xmm0[1],xmm1[1]
1592 ; SSE-NEXT:    retq
1593 ;
1594 ; AVX-LABEL: combine_test14:
1595 ; AVX:       # BB#0:
1596 ; AVX-NEXT:    vunpckhpd {{.*#+}} xmm0 = xmm0[1],xmm1[1]
1597 ; AVX-NEXT:    retq
1598   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 6, i32 7, i32 5, i32 5>
1599   %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 6, i32 7, i32 0, i32 1>
1600   ret <4 x float> %2
1601 }
1602
1603 define <4 x float> @combine_test15(<4 x float> %a, <4 x float> %b) {
1604 ; SSE2-LABEL: combine_test15:
1605 ; SSE2:       # BB#0:
1606 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0]
1607 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3]
1608 ; SSE2-NEXT:    retq
1609 ;
1610 ; SSSE3-LABEL: combine_test15:
1611 ; SSSE3:       # BB#0:
1612 ; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0]
1613 ; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3]
1614 ; SSSE3-NEXT:    retq
1615 ;
1616 ; SSE41-LABEL: combine_test15:
1617 ; SSE41:       # BB#0:
1618 ; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3]
1619 ; SSE41-NEXT:    retq
1620 ;
1621 ; AVX-LABEL: combine_test15:
1622 ; AVX:       # BB#0:
1623 ; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3]
1624 ; AVX-NEXT:    retq
1625   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 7>
1626   %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 0, i32 5, i32 2, i32 3>
1627   ret <4 x float> %2
1628 }
1629
1630 define <4 x i32> @combine_test16(<4 x i32> %a, <4 x i32> %b) {
1631 ; ALL-LABEL: combine_test16:
1632 ; ALL:       # BB#0:
1633 ; ALL-NEXT:    retq
1634   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
1635   %2 = shufflevector <4 x i32> %1, <4 x i32> %a, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
1636   ret <4 x i32> %2
1637 }
1638
1639 define <4 x i32> @combine_test17(<4 x i32> %a, <4 x i32> %b) {
1640 ; SSE2-LABEL: combine_test17:
1641 ; SSE2:       # BB#0:
1642 ; SSE2-NEXT:    movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]
1643 ; SSE2-NEXT:    movaps %xmm1, %xmm0
1644 ; SSE2-NEXT:    retq
1645 ;
1646 ; SSSE3-LABEL: combine_test17:
1647 ; SSSE3:       # BB#0:
1648 ; SSSE3-NEXT:    movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]
1649 ; SSSE3-NEXT:    movaps %xmm1, %xmm0
1650 ; SSSE3-NEXT:    retq
1651 ;
1652 ; SSE41-LABEL: combine_test17:
1653 ; SSE41:       # BB#0:
1654 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3,4,5,6,7]
1655 ; SSE41-NEXT:    retq
1656 ;
1657 ; AVX1-LABEL: combine_test17:
1658 ; AVX1:       # BB#0:
1659 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3,4,5,6,7]
1660 ; AVX1-NEXT:    retq
1661 ;
1662 ; AVX2-LABEL: combine_test17:
1663 ; AVX2:       # BB#0:
1664 ; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]
1665 ; AVX2-NEXT:    retq
1666   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 5, i32 6, i32 7>
1667   %2 = shufflevector <4 x i32> %1, <4 x i32> %a, <4 x i32> <i32 4, i32 1, i32 2, i32 3>
1668   ret <4 x i32> %2
1669 }
1670
1671 define <4 x i32> @combine_test18(<4 x i32> %a, <4 x i32> %b) {
1672 ; SSE-LABEL: combine_test18:
1673 ; SSE:       # BB#0:
1674 ; SSE-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1675 ; SSE-NEXT:    retq
1676 ;
1677 ; AVX-LABEL: combine_test18:
1678 ; AVX:       # BB#0:
1679 ; AVX-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1680 ; AVX-NEXT:    retq
1681   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
1682   %2 = shufflevector <4 x i32> %1, <4 x i32> %a, <4 x i32> <i32 4, i32 5, i32 2, i32 3>
1683   ret <4 x i32> %2
1684 }
1685
1686 define <4 x i32> @combine_test19(<4 x i32> %a, <4 x i32> %b) {
1687 ; SSE-LABEL: combine_test19:
1688 ; SSE:       # BB#0:
1689 ; SSE-NEXT:    punpckhqdq {{.*#+}} xmm0 = xmm0[1],xmm1[1]
1690 ; SSE-NEXT:    retq
1691 ;
1692 ; AVX-LABEL: combine_test19:
1693 ; AVX:       # BB#0:
1694 ; AVX-NEXT:    vpunpckhqdq {{.*#+}} xmm0 = xmm0[1],xmm1[1]
1695 ; AVX-NEXT:    retq
1696   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 6, i32 7, i32 5, i32 5>
1697   %2 = shufflevector <4 x i32> %1, <4 x i32> %a, <4 x i32> <i32 6, i32 7, i32 0, i32 1>
1698   ret <4 x i32> %2
1699 }
1700
1701 define <4 x i32> @combine_test20(<4 x i32> %a, <4 x i32> %b) {
1702 ; SSE2-LABEL: combine_test20:
1703 ; SSE2:       # BB#0:
1704 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0]
1705 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3]
1706 ; SSE2-NEXT:    retq
1707 ;
1708 ; SSSE3-LABEL: combine_test20:
1709 ; SSSE3:       # BB#0:
1710 ; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0]
1711 ; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3]
1712 ; SSSE3-NEXT:    retq
1713 ;
1714 ; SSE41-LABEL: combine_test20:
1715 ; SSE41:       # BB#0:
1716 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3],xmm1[4,5,6,7]
1717 ; SSE41-NEXT:    retq
1718 ;
1719 ; AVX1-LABEL: combine_test20:
1720 ; AVX1:       # BB#0:
1721 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3],xmm1[4,5,6,7]
1722 ; AVX1-NEXT:    retq
1723 ;
1724 ; AVX2-LABEL: combine_test20:
1725 ; AVX2:       # BB#0:
1726 ; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3]
1727 ; AVX2-NEXT:    retq
1728   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 7>
1729   %2 = shufflevector <4 x i32> %1, <4 x i32> %a, <4 x i32> <i32 0, i32 5, i32 2, i32 3>
1730   ret <4 x i32> %2
1731 }
1732
1733 define <4 x i32> @combine_test21(<8 x i32> %a, <4 x i32>* %ptr) {
1734 ; SSE-LABEL: combine_test21:
1735 ; SSE:       # BB#0:
1736 ; SSE-NEXT:    movdqa %xmm0, %xmm2
1737 ; SSE-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm1[0]
1738 ; SSE-NEXT:    punpckhqdq {{.*#+}} xmm0 = xmm0[1],xmm1[1]
1739 ; SSE-NEXT:    movdqa %xmm2, (%rdi)
1740 ; SSE-NEXT:    retq
1741 ;
1742 ; AVX1-LABEL: combine_test21:
1743 ; AVX1:       # BB#0:
1744 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
1745 ; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm2 = xmm0[0],xmm1[0]
1746 ; AVX1-NEXT:    vpunpckhqdq {{.*#+}} xmm0 = xmm0[1],xmm1[1]
1747 ; AVX1-NEXT:    vmovdqa %xmm2, (%rdi)
1748 ; AVX1-NEXT:    vzeroupper
1749 ; AVX1-NEXT:    retq
1750 ;
1751 ; AVX2-LABEL: combine_test21:
1752 ; AVX2:       # BB#0:
1753 ; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
1754 ; AVX2-NEXT:    vpunpcklqdq {{.*#+}} xmm2 = xmm0[0],xmm1[0]
1755 ; AVX2-NEXT:    vpunpckhqdq {{.*#+}} xmm0 = xmm0[1],xmm1[1]
1756 ; AVX2-NEXT:    vmovdqa %xmm2, (%rdi)
1757 ; AVX2-NEXT:    vzeroupper
1758 ; AVX2-NEXT:    retq
1759   %1 = shufflevector <8 x i32> %a, <8 x i32> %a, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
1760   %2 = shufflevector <8 x i32> %a, <8 x i32> %a, <4 x i32> <i32 2, i32 3, i32 6, i32 7>
1761   store <4 x i32> %1, <4 x i32>* %ptr, align 16
1762   ret <4 x i32> %2
1763 }
1764
1765 define <8 x float> @combine_test22(<2 x float>* %a, <2 x float>* %b) {
1766 ; SSE-LABEL: combine_test22:
1767 ; SSE:       # BB#0:
1768 ; SSE-NEXT:    movq {{.*#+}} xmm0 = mem[0],zero
1769 ; SSE-NEXT:    movhpd (%rsi), %xmm0
1770 ; SSE-NEXT:    retq
1771 ;
1772 ; AVX-LABEL: combine_test22:
1773 ; AVX:       # BB#0:
1774 ; AVX-NEXT:    vmovq {{.*#+}} xmm0 = mem[0],zero
1775 ; AVX-NEXT:    vmovhpd (%rsi), %xmm0, %xmm0
1776 ; AVX-NEXT:    retq
1777 ; Current AVX2 lowering of this is still awful, not adding a test case.
1778   %1 = load <2 x float>* %a, align 8
1779   %2 = load <2 x float>* %b, align 8
1780   %3 = shufflevector <2 x float> %1, <2 x float> %2, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef>
1781   ret <8 x float> %3
1782 }
1783
1784 ; Check some negative cases.
1785 ; FIXME: Do any of these really make sense? Are they redundant with the above tests?
1786
1787 define <4 x float> @combine_test1b(<4 x float> %a, <4 x float> %b) {
1788 ; SSE-LABEL: combine_test1b:
1789 ; SSE:       # BB#0:
1790 ; SSE-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,1,2,0]
1791 ; SSE-NEXT:    movaps %xmm1, %xmm0
1792 ; SSE-NEXT:    retq
1793 ;
1794 ; AVX-LABEL: combine_test1b:
1795 ; AVX:       # BB#0:
1796 ; AVX-NEXT:    vpermilps {{.*#+}} xmm0 = xmm1[0,1,2,0]
1797 ; AVX-NEXT:    retq
1798   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
1799   %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 0>
1800   ret <4 x float> %2
1801 }
1802
1803 define <4 x float> @combine_test2b(<4 x float> %a, <4 x float> %b) {
1804 ; SSE2-LABEL: combine_test2b:
1805 ; SSE2:       # BB#0:
1806 ; SSE2-NEXT:    movlhps {{.*#+}} xmm1 = xmm1[0,0]
1807 ; SSE2-NEXT:    movaps %xmm1, %xmm0
1808 ; SSE2-NEXT:    retq
1809 ;
1810 ; SSSE3-LABEL: combine_test2b:
1811 ; SSSE3:       # BB#0:
1812 ; SSSE3-NEXT:    movddup {{.*#+}} xmm0 = xmm1[0,0]
1813 ; SSSE3-NEXT:    retq
1814 ;
1815 ; SSE41-LABEL: combine_test2b:
1816 ; SSE41:       # BB#0:
1817 ; SSE41-NEXT:    movddup {{.*#+}} xmm0 = xmm1[0,0]
1818 ; SSE41-NEXT:    retq
1819 ;
1820 ; AVX-LABEL: combine_test2b:
1821 ; AVX:       # BB#0:
1822 ; AVX-NEXT:    vmovddup {{.*#+}} xmm0 = xmm1[0,0]
1823 ; AVX-NEXT:    retq
1824   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
1825   %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 0, i32 5>
1826   ret <4 x float> %2
1827 }
1828
1829 define <4 x float> @combine_test3b(<4 x float> %a, <4 x float> %b) {
1830 ; SSE2-LABEL: combine_test3b:
1831 ; SSE2:       # BB#0:
1832 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,0],xmm1[3,0]
1833 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[2,3]
1834 ; SSE2-NEXT:    retq
1835 ;
1836 ; SSSE3-LABEL: combine_test3b:
1837 ; SSSE3:       # BB#0:
1838 ; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,0],xmm1[3,0]
1839 ; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[2,3]
1840 ; SSSE3-NEXT:    retq
1841 ;
1842 ; SSE41-LABEL: combine_test3b:
1843 ; SSE41:       # BB#0:
1844 ; SSE41-NEXT:    blendpd {{.*#+}} xmm0 = xmm0[0],xmm1[1]
1845 ; SSE41-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,3,2,3]
1846 ; SSE41-NEXT:    retq
1847 ;
1848 ; AVX-LABEL: combine_test3b:
1849 ; AVX:       # BB#0:
1850 ; AVX-NEXT:    vblendpd {{.*#+}} xmm0 = xmm0[0],xmm1[1]
1851 ; AVX-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[0,3,2,3]
1852 ; AVX-NEXT:    retq
1853   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 0, i32 6, i32 3>
1854   %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 7, i32 2, i32 7>
1855   ret <4 x float> %2
1856 }
1857
1858 define <4 x float> @combine_test4b(<4 x float> %a, <4 x float> %b) {
1859 ; SSE-LABEL: combine_test4b:
1860 ; SSE:       # BB#0:
1861 ; SSE-NEXT:    shufps {{.*#+}} xmm1 = xmm1[1,1,2,3]
1862 ; SSE-NEXT:    movaps %xmm1, %xmm0
1863 ; SSE-NEXT:    retq
1864 ;
1865 ; AVX-LABEL: combine_test4b:
1866 ; AVX:       # BB#0:
1867 ; AVX-NEXT:    vpermilps {{.*#+}} xmm0 = xmm1[1,1,2,3]
1868 ; AVX-NEXT:    retq
1869   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
1870   %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 5, i32 5, i32 2, i32 7>
1871   ret <4 x float> %2
1872 }
1873
1874
1875 ; Verify that we correctly fold shuffles even when we use illegal vector types.
1876
1877 define <4 x i8> @combine_test1c(<4 x i8>* %a, <4 x i8>* %b) {
1878 ; SSE2-LABEL: combine_test1c:
1879 ; SSE2:       # BB#0:
1880 ; SSE2-NEXT:    movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
1881 ; SSE2-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7]
1882 ; SSE2-NEXT:    punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
1883 ; SSE2-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
1884 ; SSE2-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
1885 ; SSE2-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
1886 ; SSE2-NEXT:    movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]
1887 ; SSE2-NEXT:    retq
1888 ;
1889 ; SSSE3-LABEL: combine_test1c:
1890 ; SSSE3:       # BB#0:
1891 ; SSSE3-NEXT:    movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
1892 ; SSSE3-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7]
1893 ; SSSE3-NEXT:    punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
1894 ; SSSE3-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
1895 ; SSSE3-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
1896 ; SSSE3-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
1897 ; SSSE3-NEXT:    movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]
1898 ; SSSE3-NEXT:    retq
1899 ;
1900 ; SSE41-LABEL: combine_test1c:
1901 ; SSE41:       # BB#0:
1902 ; SSE41-NEXT:    pmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1903 ; SSE41-NEXT:    pmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1904 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3,4,5,6,7]
1905 ; SSE41-NEXT:    retq
1906 ;
1907 ; AVX1-LABEL: combine_test1c:
1908 ; AVX1:       # BB#0:
1909 ; AVX1-NEXT:    vpmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1910 ; AVX1-NEXT:    vpmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1911 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3,4,5,6,7]
1912 ; AVX1-NEXT:    retq
1913 ;
1914 ; AVX2-LABEL: combine_test1c:
1915 ; AVX2:       # BB#0:
1916 ; AVX2-NEXT:    vpmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1917 ; AVX2-NEXT:    vpmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1918 ; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]
1919 ; AVX2-NEXT:    retq
1920   %A = load <4 x i8>* %a
1921   %B = load <4 x i8>* %b
1922   %1 = shufflevector <4 x i8> %A, <4 x i8> %B, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
1923   %2 = shufflevector <4 x i8> %1, <4 x i8> %B, <4 x i32> <i32 0, i32 1, i32 6, i32 3>
1924   ret <4 x i8> %2
1925 }
1926
1927 define <4 x i8> @combine_test2c(<4 x i8>* %a, <4 x i8>* %b) {
1928 ; SSE2-LABEL: combine_test2c:
1929 ; SSE2:       # BB#0:
1930 ; SSE2-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
1931 ; SSE2-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
1932 ; SSE2-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
1933 ; SSE2-NEXT:    movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
1934 ; SSE2-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7]
1935 ; SSE2-NEXT:    punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
1936 ; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1937 ; SSE2-NEXT:    retq
1938 ;
1939 ; SSSE3-LABEL: combine_test2c:
1940 ; SSSE3:       # BB#0:
1941 ; SSSE3-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
1942 ; SSSE3-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
1943 ; SSSE3-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
1944 ; SSSE3-NEXT:    movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
1945 ; SSSE3-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7]
1946 ; SSSE3-NEXT:    punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
1947 ; SSSE3-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1948 ; SSSE3-NEXT:    retq
1949 ;
1950 ; SSE41-LABEL: combine_test2c:
1951 ; SSE41:       # BB#0:
1952 ; SSE41-NEXT:    pmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1953 ; SSE41-NEXT:    pmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1954 ; SSE41-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1955 ; SSE41-NEXT:    retq
1956 ;
1957 ; AVX-LABEL: combine_test2c:
1958 ; AVX:       # BB#0:
1959 ; AVX-NEXT:    vpmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1960 ; AVX-NEXT:    vpmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1961 ; AVX-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1962 ; AVX-NEXT:    retq
1963   %A = load <4 x i8>* %a
1964   %B = load <4 x i8>* %b
1965   %1 = shufflevector <4 x i8> %A, <4 x i8> %B, <4 x i32> <i32 0, i32 5, i32 1, i32 5>
1966   %2 = shufflevector <4 x i8> %1, <4 x i8> %B, <4 x i32> <i32 0, i32 2, i32 4, i32 1>
1967   ret <4 x i8> %2
1968 }
1969
1970 define <4 x i8> @combine_test3c(<4 x i8>* %a, <4 x i8>* %b) {
1971 ; SSE2-LABEL: combine_test3c:
1972 ; SSE2:       # BB#0:
1973 ; SSE2-NEXT:    movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
1974 ; SSE2-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7]
1975 ; SSE2-NEXT:    punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
1976 ; SSE2-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
1977 ; SSE2-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
1978 ; SSE2-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
1979 ; SSE2-NEXT:    punpckhqdq {{.*#+}} xmm0 = xmm0[1],xmm1[1]
1980 ; SSE2-NEXT:    retq
1981 ;
1982 ; SSSE3-LABEL: combine_test3c:
1983 ; SSSE3:       # BB#0:
1984 ; SSSE3-NEXT:    movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
1985 ; SSSE3-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7]
1986 ; SSSE3-NEXT:    punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
1987 ; SSSE3-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
1988 ; SSSE3-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
1989 ; SSSE3-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
1990 ; SSSE3-NEXT:    punpckhqdq {{.*#+}} xmm0 = xmm0[1],xmm1[1]
1991 ; SSSE3-NEXT:    retq
1992 ;
1993 ; SSE41-LABEL: combine_test3c:
1994 ; SSE41:       # BB#0:
1995 ; SSE41-NEXT:    pmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1996 ; SSE41-NEXT:    pmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1997 ; SSE41-NEXT:    punpckhqdq {{.*#+}} xmm0 = xmm0[1],xmm1[1]
1998 ; SSE41-NEXT:    retq
1999 ;
2000 ; AVX-LABEL: combine_test3c:
2001 ; AVX:       # BB#0:
2002 ; AVX-NEXT:    vpmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
2003 ; AVX-NEXT:    vpmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
2004 ; AVX-NEXT:    vpunpckhqdq {{.*#+}} xmm0 = xmm1[1],xmm0[1]
2005 ; AVX-NEXT:    retq
2006   %A = load <4 x i8>* %a
2007   %B = load <4 x i8>* %b
2008   %1 = shufflevector <4 x i8> %A, <4 x i8> %B, <4 x i32> <i32 2, i32 3, i32 5, i32 5>
2009   %2 = shufflevector <4 x i8> %1, <4 x i8> %B, <4 x i32> <i32 6, i32 7, i32 0, i32 1>
2010   ret <4 x i8> %2
2011 }
2012
2013 define <4 x i8> @combine_test4c(<4 x i8>* %a, <4 x i8>* %b) {
2014 ; SSE2-LABEL: combine_test4c:
2015 ; SSE2:       # BB#0:
2016 ; SSE2-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
2017 ; SSE2-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
2018 ; SSE2-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
2019 ; SSE2-NEXT:    movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
2020 ; SSE2-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7]
2021 ; SSE2-NEXT:    punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
2022 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0]
2023 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3]
2024 ; SSE2-NEXT:    retq
2025 ;
2026 ; SSSE3-LABEL: combine_test4c:
2027 ; SSSE3:       # BB#0:
2028 ; SSSE3-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
2029 ; SSSE3-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
2030 ; SSSE3-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
2031 ; SSSE3-NEXT:    movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
2032 ; SSSE3-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7]
2033 ; SSSE3-NEXT:    punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
2034 ; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0]
2035 ; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3]
2036 ; SSSE3-NEXT:    retq
2037 ;
2038 ; SSE41-LABEL: combine_test4c:
2039 ; SSE41:       # BB#0:
2040 ; SSE41-NEXT:    pmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
2041 ; SSE41-NEXT:    pmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
2042 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5,6,7]
2043 ; SSE41-NEXT:    retq
2044 ;
2045 ; AVX1-LABEL: combine_test4c:
2046 ; AVX1:       # BB#0:
2047 ; AVX1-NEXT:    vpmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
2048 ; AVX1-NEXT:    vpmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
2049 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3],xmm1[4,5,6,7]
2050 ; AVX1-NEXT:    retq
2051 ;
2052 ; AVX2-LABEL: combine_test4c:
2053 ; AVX2:       # BB#0:
2054 ; AVX2-NEXT:    vpmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
2055 ; AVX2-NEXT:    vpmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
2056 ; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3]
2057 ; AVX2-NEXT:    retq
2058   %A = load <4 x i8>* %a
2059   %B = load <4 x i8>* %b
2060   %1 = shufflevector <4 x i8> %A, <4 x i8> %B, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
2061   %2 = shufflevector <4 x i8> %1, <4 x i8> %B, <4 x i32> <i32 0, i32 1, i32 2, i32 7>
2062   ret <4 x i8> %2
2063 }
2064
2065
2066 ; The following test cases are generated from this C++ code
2067 ;
2068 ;__m128 blend_01(__m128 a, __m128 b)
2069 ;{
2070 ;  __m128 s = a;
2071 ;  s = _mm_blend_ps( s, b, 1<<0 );
2072 ;  s = _mm_blend_ps( s, b, 1<<1 );
2073 ;  return s;
2074 ;}
2075 ;
2076 ;__m128 blend_02(__m128 a, __m128 b)
2077 ;{
2078 ;  __m128 s = a;
2079 ;  s = _mm_blend_ps( s, b, 1<<0 );
2080 ;  s = _mm_blend_ps( s, b, 1<<2 );
2081 ;  return s;
2082 ;}
2083 ;
2084 ;__m128 blend_123(__m128 a, __m128 b)
2085 ;{
2086 ;  __m128 s = a;
2087 ;  s = _mm_blend_ps( s, b, 1<<1 );
2088 ;  s = _mm_blend_ps( s, b, 1<<2 );
2089 ;  s = _mm_blend_ps( s, b, 1<<3 );
2090 ;  return s;
2091 ;}
2092
2093 ; Ideally, we should collapse the following shuffles into a single one.
2094
2095 define <4 x float> @combine_blend_01(<4 x float> %a, <4 x float> %b) {
2096 ; SSE2-LABEL: combine_blend_01:
2097 ; SSE2:       # BB#0:
2098 ; SSE2-NEXT:    movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]
2099 ; SSE2-NEXT:    retq
2100 ;
2101 ; SSSE3-LABEL: combine_blend_01:
2102 ; SSSE3:       # BB#0:
2103 ; SSSE3-NEXT:    movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]
2104 ; SSSE3-NEXT:    retq
2105 ;
2106 ; SSE41-LABEL: combine_blend_01:
2107 ; SSE41:       # BB#0:
2108 ; SSE41-NEXT:    blendpd {{.*#+}} xmm0 = xmm1[0],xmm0[1]
2109 ; SSE41-NEXT:    retq
2110 ;
2111 ; AVX-LABEL: combine_blend_01:
2112 ; AVX:       # BB#0:
2113 ; AVX-NEXT:    vblendpd {{.*#+}} xmm0 = xmm1[0],xmm0[1]
2114 ; AVX-NEXT:    retq
2115   %shuffle = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 undef, i32 2, i32 3>
2116   %shuffle6 = shufflevector <4 x float> %shuffle, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 3>
2117   ret <4 x float> %shuffle6
2118 }
2119
2120 define <4 x float> @combine_blend_02(<4 x float> %a, <4 x float> %b) {
2121 ; SSE2-LABEL: combine_blend_02:
2122 ; SSE2:       # BB#0:
2123 ; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,2],xmm0[1,3]
2124 ; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,2,1,3]
2125 ; SSE2-NEXT:    movaps %xmm1, %xmm0
2126 ; SSE2-NEXT:    retq
2127 ;
2128 ; SSSE3-LABEL: combine_blend_02:
2129 ; SSSE3:       # BB#0:
2130 ; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,2],xmm0[1,3]
2131 ; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,2,1,3]
2132 ; SSSE3-NEXT:    movaps %xmm1, %xmm0
2133 ; SSSE3-NEXT:    retq
2134 ;
2135 ; SSE41-LABEL: combine_blend_02:
2136 ; SSE41:       # BB#0:
2137 ; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2],xmm0[3]
2138 ; SSE41-NEXT:    retq
2139 ;
2140 ; AVX-LABEL: combine_blend_02:
2141 ; AVX:       # BB#0:
2142 ; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2],xmm0[3]
2143 ; AVX-NEXT:    retq
2144   %shuffle = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 undef, i32 3>
2145   %shuffle6 = shufflevector <4 x float> %shuffle, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 6, i32 3>
2146   ret <4 x float> %shuffle6
2147 }
2148
2149 define <4 x float> @combine_blend_123(<4 x float> %a, <4 x float> %b) {
2150 ; SSE2-LABEL: combine_blend_123:
2151 ; SSE2:       # BB#0:
2152 ; SSE2-NEXT:    movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]
2153 ; SSE2-NEXT:    movaps %xmm1, %xmm0
2154 ; SSE2-NEXT:    retq
2155 ;
2156 ; SSSE3-LABEL: combine_blend_123:
2157 ; SSSE3:       # BB#0:
2158 ; SSSE3-NEXT:    movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]
2159 ; SSSE3-NEXT:    movaps %xmm1, %xmm0
2160 ; SSSE3-NEXT:    retq
2161 ;
2162 ; SSE41-LABEL: combine_blend_123:
2163 ; SSE41:       # BB#0:
2164 ; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]
2165 ; SSE41-NEXT:    retq
2166 ;
2167 ; AVX-LABEL: combine_blend_123:
2168 ; AVX:       # BB#0:
2169 ; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]
2170 ; AVX-NEXT:    retq
2171   %shuffle = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 undef, i32 undef>
2172   %shuffle6 = shufflevector <4 x float> %shuffle, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 6, i32 undef>
2173   %shuffle12 = shufflevector <4 x float> %shuffle6, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 2, i32 7>
2174   ret <4 x float> %shuffle12
2175 }
2176
2177 define <4 x i32> @combine_test_movhl_1(<4 x i32> %a, <4 x i32> %b) {
2178 ; SSE-LABEL: combine_test_movhl_1:
2179 ; SSE:       # BB#0:
2180 ; SSE-NEXT:    punpckhqdq {{.*#+}} xmm1 = xmm1[1],xmm0[1]
2181 ; SSE-NEXT:    movdqa %xmm1, %xmm0
2182 ; SSE-NEXT:    retq
2183 ;
2184 ; AVX-LABEL: combine_test_movhl_1:
2185 ; AVX:       # BB#0:
2186 ; AVX-NEXT:    vpunpckhqdq {{.*#+}} xmm0 = xmm1[1],xmm0[1]
2187 ; AVX-NEXT:    retq
2188   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 2, i32 7, i32 5, i32 3>
2189   %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 6, i32 1, i32 0, i32 3>
2190   ret <4 x i32> %2
2191 }
2192
2193 define <4 x i32> @combine_test_movhl_2(<4 x i32> %a, <4 x i32> %b) {
2194 ; SSE-LABEL: combine_test_movhl_2:
2195 ; SSE:       # BB#0:
2196 ; SSE-NEXT:    punpckhqdq {{.*#+}} xmm1 = xmm1[1],xmm0[1]
2197 ; SSE-NEXT:    movdqa %xmm1, %xmm0
2198 ; SSE-NEXT:    retq
2199 ;
2200 ; AVX-LABEL: combine_test_movhl_2:
2201 ; AVX:       # BB#0:
2202 ; AVX-NEXT:    vpunpckhqdq {{.*#+}} xmm0 = xmm1[1],xmm0[1]
2203 ; AVX-NEXT:    retq
2204   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 2, i32 0, i32 3, i32 6>
2205   %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 3, i32 7, i32 0, i32 2>
2206   ret <4 x i32> %2
2207 }
2208
2209 define <4 x i32> @combine_test_movhl_3(<4 x i32> %a, <4 x i32> %b) {
2210 ; SSE-LABEL: combine_test_movhl_3:
2211 ; SSE:       # BB#0:
2212 ; SSE-NEXT:    punpckhqdq {{.*#+}} xmm1 = xmm1[1],xmm0[1]
2213 ; SSE-NEXT:    movdqa %xmm1, %xmm0
2214 ; SSE-NEXT:    retq
2215 ;
2216 ; AVX-LABEL: combine_test_movhl_3:
2217 ; AVX:       # BB#0:
2218 ; AVX-NEXT:    vpunpckhqdq {{.*#+}} xmm0 = xmm1[1],xmm0[1]
2219 ; AVX-NEXT:    retq
2220   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 7, i32 6, i32 3, i32 2>
2221   %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 6, i32 0, i32 3, i32 2>
2222   ret <4 x i32> %2
2223 }
2224
2225
2226 ; Verify that we fold shuffles according to rule:
2227 ;  (shuffle(shuffle A, Undef, M0), B, M1) -> (shuffle A, B, M2)
2228
2229 define <4 x float> @combine_undef_input_test1(<4 x float> %a, <4 x float> %b) {
2230 ; SSE2-LABEL: combine_undef_input_test1:
2231 ; SSE2:       # BB#0:
2232 ; SSE2-NEXT:    movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]
2233 ; SSE2-NEXT:    retq
2234 ;
2235 ; SSSE3-LABEL: combine_undef_input_test1:
2236 ; SSSE3:       # BB#0:
2237 ; SSSE3-NEXT:    movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]
2238 ; SSSE3-NEXT:    retq
2239 ;
2240 ; SSE41-LABEL: combine_undef_input_test1:
2241 ; SSE41:       # BB#0:
2242 ; SSE41-NEXT:    blendpd {{.*#+}} xmm0 = xmm1[0],xmm0[1]
2243 ; SSE41-NEXT:    retq
2244 ;
2245 ; AVX-LABEL: combine_undef_input_test1:
2246 ; AVX:       # BB#0:
2247 ; AVX-NEXT:    vblendpd {{.*#+}} xmm0 = xmm1[0],xmm0[1]
2248 ; AVX-NEXT:    retq
2249   %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 4, i32 2, i32 3, i32 1>
2250   %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 4, i32 5, i32 1, i32 2>
2251   ret <4 x float> %2
2252 }
2253
2254 define <4 x float> @combine_undef_input_test2(<4 x float> %a, <4 x float> %b) {
2255 ; SSE-LABEL: combine_undef_input_test2:
2256 ; SSE:       # BB#0:
2257 ; SSE-NEXT:    unpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0]
2258 ; SSE-NEXT:    retq
2259 ;
2260 ; AVX-LABEL: combine_undef_input_test2:
2261 ; AVX:       # BB#0:
2262 ; AVX-NEXT:    vunpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0]
2263 ; AVX-NEXT:    retq
2264   %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 6, i32 0, i32 1, i32 7>
2265   %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 1, i32 2, i32 4, i32 5>
2266   ret <4 x float> %2
2267 }
2268
2269 define <4 x float> @combine_undef_input_test3(<4 x float> %a, <4 x float> %b) {
2270 ; SSE-LABEL: combine_undef_input_test3:
2271 ; SSE:       # BB#0:
2272 ; SSE-NEXT:    unpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0]
2273 ; SSE-NEXT:    retq
2274 ;
2275 ; AVX-LABEL: combine_undef_input_test3:
2276 ; AVX:       # BB#0:
2277 ; AVX-NEXT:    vunpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0]
2278 ; AVX-NEXT:    retq
2279   %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 5, i32 1, i32 7>
2280   %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 2, i32 4, i32 1>
2281   ret <4 x float> %2
2282 }
2283
2284 define <4 x float> @combine_undef_input_test4(<4 x float> %a, <4 x float> %b) {
2285 ; SSE-LABEL: combine_undef_input_test4:
2286 ; SSE:       # BB#0:
2287 ; SSE-NEXT:    unpckhpd {{.*#+}} xmm1 = xmm1[1],xmm0[1]
2288 ; SSE-NEXT:    movapd %xmm1, %xmm0
2289 ; SSE-NEXT:    retq
2290 ;
2291 ; AVX-LABEL: combine_undef_input_test4:
2292 ; AVX:       # BB#0:
2293 ; AVX-NEXT:    vunpckhpd {{.*#+}} xmm0 = xmm1[1],xmm0[1]
2294 ; AVX-NEXT:    retq
2295   %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 2, i32 3, i32 5, i32 5>
2296   %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 6, i32 7, i32 0, i32 1>
2297   ret <4 x float> %2
2298 }
2299
2300 define <4 x float> @combine_undef_input_test5(<4 x float> %a, <4 x float> %b) {
2301 ; SSE2-LABEL: combine_undef_input_test5:
2302 ; SSE2:       # BB#0:
2303 ; SSE2-NEXT:    movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1]
2304 ; SSE2-NEXT:    movapd %xmm1, %xmm0
2305 ; SSE2-NEXT:    retq
2306 ;
2307 ; SSSE3-LABEL: combine_undef_input_test5:
2308 ; SSSE3:       # BB#0:
2309 ; SSSE3-NEXT:    movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1]
2310 ; SSSE3-NEXT:    movapd %xmm1, %xmm0
2311 ; SSSE3-NEXT:    retq
2312 ;
2313 ; SSE41-LABEL: combine_undef_input_test5:
2314 ; SSE41:       # BB#0:
2315 ; SSE41-NEXT:    blendpd {{.*#+}} xmm0 = xmm0[0],xmm1[1]
2316 ; SSE41-NEXT:    retq
2317 ;
2318 ; AVX-LABEL: combine_undef_input_test5:
2319 ; AVX:       # BB#0:
2320 ; AVX-NEXT:    vblendpd {{.*#+}} xmm0 = xmm0[0],xmm1[1]
2321 ; AVX-NEXT:    retq
2322   %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 4, i32 1, i32 3>
2323   %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 2, i32 6, i32 7>
2324   ret <4 x float> %2
2325 }
2326
2327
2328 ; Verify that we fold shuffles according to rule:
2329 ;  (shuffle(shuffle A, Undef, M0), A, M1) -> (shuffle A, Undef, M2)
2330
2331 define <4 x float> @combine_undef_input_test6(<4 x float> %a) {
2332 ; ALL-LABEL: combine_undef_input_test6:
2333 ; ALL:       # BB#0:
2334 ; ALL-NEXT:    retq
2335   %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 4, i32 2, i32 3, i32 1>
2336   %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 4, i32 5, i32 1, i32 2>
2337   ret <4 x float> %2
2338 }
2339
2340 define <4 x float> @combine_undef_input_test7(<4 x float> %a) {
2341 ; SSE2-LABEL: combine_undef_input_test7:
2342 ; SSE2:       # BB#0:
2343 ; SSE2-NEXT:    movlhps {{.*#+}} xmm0 = xmm0[0,0]
2344 ; SSE2-NEXT:    retq
2345 ;
2346 ; SSSE3-LABEL: combine_undef_input_test7:
2347 ; SSSE3:       # BB#0:
2348 ; SSSE3-NEXT:    movddup {{.*#+}} xmm0 = xmm0[0,0]
2349 ; SSSE3-NEXT:    retq
2350 ;
2351 ; SSE41-LABEL: combine_undef_input_test7:
2352 ; SSE41:       # BB#0:
2353 ; SSE41-NEXT:    movddup {{.*#+}} xmm0 = xmm0[0,0]
2354 ; SSE41-NEXT:    retq
2355 ;
2356 ; AVX-LABEL: combine_undef_input_test7:
2357 ; AVX:       # BB#0:
2358 ; AVX-NEXT:    vmovddup {{.*#+}} xmm0 = xmm0[0,0]
2359 ; AVX-NEXT:    retq
2360   %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 6, i32 0, i32 1, i32 7>
2361   %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 1, i32 2, i32 4, i32 5>
2362   ret <4 x float> %2
2363 }
2364
2365 define <4 x float> @combine_undef_input_test8(<4 x float> %a) {
2366 ; SSE2-LABEL: combine_undef_input_test8:
2367 ; SSE2:       # BB#0:
2368 ; SSE2-NEXT:    movlhps {{.*#+}} xmm0 = xmm0[0,0]
2369 ; SSE2-NEXT:    retq
2370 ;
2371 ; SSSE3-LABEL: combine_undef_input_test8:
2372 ; SSSE3:       # BB#0:
2373 ; SSSE3-NEXT:    movddup {{.*#+}} xmm0 = xmm0[0,0]
2374 ; SSSE3-NEXT:    retq
2375 ;
2376 ; SSE41-LABEL: combine_undef_input_test8:
2377 ; SSE41:       # BB#0:
2378 ; SSE41-NEXT:    movddup {{.*#+}} xmm0 = xmm0[0,0]
2379 ; SSE41-NEXT:    retq
2380 ;
2381 ; AVX-LABEL: combine_undef_input_test8:
2382 ; AVX:       # BB#0:
2383 ; AVX-NEXT:    vmovddup {{.*#+}} xmm0 = xmm0[0,0]
2384 ; AVX-NEXT:    retq
2385   %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 5, i32 1, i32 7>
2386   %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 0, i32 2, i32 4, i32 1>
2387   ret <4 x float> %2
2388 }
2389
2390 define <4 x float> @combine_undef_input_test9(<4 x float> %a) {
2391 ; SSE-LABEL: combine_undef_input_test9:
2392 ; SSE:       # BB#0:
2393 ; SSE-NEXT:    movhlps {{.*#+}} xmm0 = xmm0[1,1]
2394 ; SSE-NEXT:    retq
2395 ;
2396 ; AVX-LABEL: combine_undef_input_test9:
2397 ; AVX:       # BB#0:
2398 ; AVX-NEXT:    vmovhlps {{.*#+}} xmm0 = xmm0[1,1]
2399 ; AVX-NEXT:    retq
2400   %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 2, i32 3, i32 5, i32 5>
2401   %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 6, i32 7, i32 0, i32 1>
2402   ret <4 x float> %2
2403 }
2404
2405 define <4 x float> @combine_undef_input_test10(<4 x float> %a) {
2406 ; ALL-LABEL: combine_undef_input_test10:
2407 ; ALL:       # BB#0:
2408 ; ALL-NEXT:    retq
2409   %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 4, i32 1, i32 3>
2410   %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 0, i32 2, i32 6, i32 7>
2411   ret <4 x float> %2
2412 }
2413
2414 define <4 x float> @combine_undef_input_test11(<4 x float> %a, <4 x float> %b) {
2415 ; SSE2-LABEL: combine_undef_input_test11:
2416 ; SSE2:       # BB#0:
2417 ; SSE2-NEXT:    movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]
2418 ; SSE2-NEXT:    retq
2419 ;
2420 ; SSSE3-LABEL: combine_undef_input_test11:
2421 ; SSSE3:       # BB#0:
2422 ; SSSE3-NEXT:    movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]
2423 ; SSSE3-NEXT:    retq
2424 ;
2425 ; SSE41-LABEL: combine_undef_input_test11:
2426 ; SSE41:       # BB#0:
2427 ; SSE41-NEXT:    blendpd {{.*#+}} xmm0 = xmm1[0],xmm0[1]
2428 ; SSE41-NEXT:    retq
2429 ;
2430 ; AVX-LABEL: combine_undef_input_test11:
2431 ; AVX:       # BB#0:
2432 ; AVX-NEXT:    vblendpd {{.*#+}} xmm0 = xmm1[0],xmm0[1]
2433 ; AVX-NEXT:    retq
2434   %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 4, i32 2, i32 3, i32 1>
2435   %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 0, i32 1, i32 5, i32 6>
2436   ret <4 x float> %2
2437 }
2438
2439 define <4 x float> @combine_undef_input_test12(<4 x float> %a, <4 x float> %b) {
2440 ; SSE-LABEL: combine_undef_input_test12:
2441 ; SSE:       # BB#0:
2442 ; SSE-NEXT:    unpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0]
2443 ; SSE-NEXT:    retq
2444 ;
2445 ; AVX-LABEL: combine_undef_input_test12:
2446 ; AVX:       # BB#0:
2447 ; AVX-NEXT:    vunpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0]
2448 ; AVX-NEXT:    retq
2449   %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 6, i32 0, i32 1, i32 7>
2450   %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 5, i32 6, i32 0, i32 1>
2451   ret <4 x float> %2
2452 }
2453
2454 define <4 x float> @combine_undef_input_test13(<4 x float> %a, <4 x float> %b) {
2455 ; SSE-LABEL: combine_undef_input_test13:
2456 ; SSE:       # BB#0:
2457 ; SSE-NEXT:    unpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0]
2458 ; SSE-NEXT:    retq
2459 ;
2460 ; AVX-LABEL: combine_undef_input_test13:
2461 ; AVX:       # BB#0:
2462 ; AVX-NEXT:    vunpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0]
2463 ; AVX-NEXT:    retq
2464   %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 5, i32 1, i32 7>
2465   %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 4, i32 5, i32 0, i32 5>
2466   ret <4 x float> %2
2467 }
2468
2469 define <4 x float> @combine_undef_input_test14(<4 x float> %a, <4 x float> %b) {
2470 ; SSE-LABEL: combine_undef_input_test14:
2471 ; SSE:       # BB#0:
2472 ; SSE-NEXT:    unpckhpd {{.*#+}} xmm1 = xmm1[1],xmm0[1]
2473 ; SSE-NEXT:    movapd %xmm1, %xmm0
2474 ; SSE-NEXT:    retq
2475 ;
2476 ; AVX-LABEL: combine_undef_input_test14:
2477 ; AVX:       # BB#0:
2478 ; AVX-NEXT:    vunpckhpd {{.*#+}} xmm0 = xmm1[1],xmm0[1]
2479 ; AVX-NEXT:    retq
2480   %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 2, i32 3, i32 5, i32 5>
2481   %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 2, i32 3, i32 4, i32 5>
2482   ret <4 x float> %2
2483 }
2484
2485 define <4 x float> @combine_undef_input_test15(<4 x float> %a, <4 x float> %b) {
2486 ; SSE2-LABEL: combine_undef_input_test15:
2487 ; SSE2:       # BB#0:
2488 ; SSE2-NEXT:    movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1]
2489 ; SSE2-NEXT:    movapd %xmm1, %xmm0
2490 ; SSE2-NEXT:    retq
2491 ;
2492 ; SSSE3-LABEL: combine_undef_input_test15:
2493 ; SSSE3:       # BB#0:
2494 ; SSSE3-NEXT:    movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1]
2495 ; SSSE3-NEXT:    movapd %xmm1, %xmm0
2496 ; SSSE3-NEXT:    retq
2497 ;
2498 ; SSE41-LABEL: combine_undef_input_test15:
2499 ; SSE41:       # BB#0:
2500 ; SSE41-NEXT:    blendpd {{.*#+}} xmm0 = xmm0[0],xmm1[1]
2501 ; SSE41-NEXT:    retq
2502 ;
2503 ; AVX-LABEL: combine_undef_input_test15:
2504 ; AVX:       # BB#0:
2505 ; AVX-NEXT:    vblendpd {{.*#+}} xmm0 = xmm0[0],xmm1[1]
2506 ; AVX-NEXT:    retq
2507   %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 4, i32 1, i32 3>
2508   %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 4, i32 6, i32 2, i32 3>
2509   ret <4 x float> %2
2510 }
2511
2512
2513 ; Verify that shuffles are canonicalized according to rules:
2514 ;  shuffle(B, shuffle(A, Undef)) -> shuffle(shuffle(A, Undef), B)
2515 ;
2516 ; This allows to trigger the following combine rule:
2517 ;  (shuffle(shuffle A, Undef, M0), A, M1) -> (shuffle A, Undef, M2)
2518 ;
2519 ; As a result, all the shuffle pairs in each function below should be
2520 ; combined into a single legal shuffle operation.
2521
2522 define <4 x float> @combine_undef_input_test16(<4 x float> %a) {
2523 ; ALL-LABEL: combine_undef_input_test16:
2524 ; ALL:       # BB#0:
2525 ; ALL-NEXT:    retq
2526   %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 4, i32 2, i32 3, i32 1>
2527   %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 0, i32 1, i32 5, i32 3>
2528   ret <4 x float> %2
2529 }
2530
2531 define <4 x float> @combine_undef_input_test17(<4 x float> %a) {
2532 ; SSE2-LABEL: combine_undef_input_test17:
2533 ; SSE2:       # BB#0:
2534 ; SSE2-NEXT:    movlhps {{.*#+}} xmm0 = xmm0[0,0]
2535 ; SSE2-NEXT:    retq
2536 ;
2537 ; SSSE3-LABEL: combine_undef_input_test17:
2538 ; SSSE3:       # BB#0:
2539 ; SSSE3-NEXT:    movddup {{.*#+}} xmm0 = xmm0[0,0]
2540 ; SSSE3-NEXT:    retq
2541 ;
2542 ; SSE41-LABEL: combine_undef_input_test17:
2543 ; SSE41:       # BB#0:
2544 ; SSE41-NEXT:    movddup {{.*#+}} xmm0 = xmm0[0,0]
2545 ; SSE41-NEXT:    retq
2546 ;
2547 ; AVX-LABEL: combine_undef_input_test17:
2548 ; AVX:       # BB#0:
2549 ; AVX-NEXT:    vmovddup {{.*#+}} xmm0 = xmm0[0,0]
2550 ; AVX-NEXT:    retq
2551   %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 6, i32 0, i32 1, i32 7>
2552   %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 5, i32 6, i32 0, i32 1>
2553   ret <4 x float> %2
2554 }
2555
2556 define <4 x float> @combine_undef_input_test18(<4 x float> %a) {
2557 ; SSE2-LABEL: combine_undef_input_test18:
2558 ; SSE2:       # BB#0:
2559 ; SSE2-NEXT:    movlhps {{.*#+}} xmm0 = xmm0[0,0]
2560 ; SSE2-NEXT:    retq
2561 ;
2562 ; SSSE3-LABEL: combine_undef_input_test18:
2563 ; SSSE3:       # BB#0:
2564 ; SSSE3-NEXT:    movddup {{.*#+}} xmm0 = xmm0[0,0]
2565 ; SSSE3-NEXT:    retq
2566 ;
2567 ; SSE41-LABEL: combine_undef_input_test18:
2568 ; SSE41:       # BB#0:
2569 ; SSE41-NEXT:    movddup {{.*#+}} xmm0 = xmm0[0,0]
2570 ; SSE41-NEXT:    retq
2571 ;
2572 ; AVX-LABEL: combine_undef_input_test18:
2573 ; AVX:       # BB#0:
2574 ; AVX-NEXT:    vmovddup {{.*#+}} xmm0 = xmm0[0,0]
2575 ; AVX-NEXT:    retq
2576   %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 5, i32 1, i32 7>
2577   %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 4, i32 6, i32 0, i32 5>
2578   ret <4 x float> %2
2579 }
2580
2581 define <4 x float> @combine_undef_input_test19(<4 x float> %a) {
2582 ; SSE-LABEL: combine_undef_input_test19:
2583 ; SSE:       # BB#0:
2584 ; SSE-NEXT:    movhlps {{.*#+}} xmm0 = xmm0[1,1]
2585 ; SSE-NEXT:    retq
2586 ;
2587 ; AVX-LABEL: combine_undef_input_test19:
2588 ; AVX:       # BB#0:
2589 ; AVX-NEXT:    vmovhlps {{.*#+}} xmm0 = xmm0[1,1]
2590 ; AVX-NEXT:    retq
2591   %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 2, i32 3, i32 5, i32 5>
2592   %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 2, i32 3, i32 4, i32 5>
2593   ret <4 x float> %2
2594 }
2595
2596 define <4 x float> @combine_undef_input_test20(<4 x float> %a) {
2597 ; ALL-LABEL: combine_undef_input_test20:
2598 ; ALL:       # BB#0:
2599 ; ALL-NEXT:    retq
2600   %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 4, i32 1, i32 3>
2601   %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 4, i32 6, i32 2, i32 3>
2602   ret <4 x float> %2
2603 }
2604
2605 ; These tests are designed to test the ability to combine away unnecessary
2606 ; operations feeding into a shuffle. The AVX cases are the important ones as
2607 ; they leverage operations which cannot be done naturally on the entire vector
2608 ; and thus are decomposed into multiple smaller operations.
2609
2610 define <8 x i32> @combine_unneeded_subvector1(<8 x i32> %a) {
2611 ; SSE-LABEL: combine_unneeded_subvector1:
2612 ; SSE:       # BB#0:
2613 ; SSE-NEXT:    paddd {{.*}}(%rip), %xmm1
2614 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[3,2,1,0]
2615 ; SSE-NEXT:    movdqa %xmm0, %xmm1
2616 ; SSE-NEXT:    retq
2617 ;
2618 ; AVX1-LABEL: combine_unneeded_subvector1:
2619 ; AVX1:       # BB#0:
2620 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
2621 ; AVX1-NEXT:    vpaddd {{.*}}(%rip), %xmm0, %xmm0
2622 ; AVX1-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[3,2,1,0]
2623 ; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm0, %ymm0
2624 ; AVX1-NEXT:    retq
2625 ;
2626 ; AVX2-LABEL: combine_unneeded_subvector1:
2627 ; AVX2:       # BB#0:
2628 ; AVX2-NEXT:    vpaddd {{.*}}(%rip), %ymm0, %ymm0
2629 ; AVX2-NEXT:    vmovdqa {{.*#+}} ymm1 = [7,6,5,4,7,6,5,4]
2630 ; AVX2-NEXT:    vpermd %ymm0, %ymm1, %ymm0
2631 ; AVX2-NEXT:    retq
2632   %b = add <8 x i32> %a, <i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8>
2633   %c = shufflevector <8 x i32> %b, <8 x i32> undef, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 7, i32 6, i32 5, i32 4>
2634   ret <8 x i32> %c
2635 }
2636
2637 define <8 x i32> @combine_unneeded_subvector2(<8 x i32> %a, <8 x i32> %b) {
2638 ; SSE-LABEL: combine_unneeded_subvector2:
2639 ; SSE:       # BB#0:
2640 ; SSE-NEXT:    paddd {{.*}}(%rip), %xmm1
2641 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[3,2,1,0]
2642 ; SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[3,2,1,0]
2643 ; SSE-NEXT:    retq
2644 ;
2645 ; AVX1-LABEL: combine_unneeded_subvector2:
2646 ; AVX1:       # BB#0:
2647 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
2648 ; AVX1-NEXT:    vpaddd {{.*}}(%rip), %xmm0, %xmm0
2649 ; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm0, %ymm0
2650 ; AVX1-NEXT:    vperm2f128 {{.*#+}} ymm0 = ymm1[2,3],ymm0[2,3]
2651 ; AVX1-NEXT:    vpermilps {{.*#+}} ymm0 = ymm0[3,2,1,0,7,6,5,4]
2652 ; AVX1-NEXT:    retq
2653 ;
2654 ; AVX2-LABEL: combine_unneeded_subvector2:
2655 ; AVX2:       # BB#0:
2656 ; AVX2-NEXT:    vpaddd {{.*}}(%rip), %ymm0, %ymm0
2657 ; AVX2-NEXT:    vperm2i128 {{.*#+}} ymm0 = ymm1[2,3],ymm0[2,3]
2658 ; AVX2-NEXT:    vpshufd {{.*#+}} ymm0 = ymm0[3,2,1,0,7,6,5,4]
2659 ; AVX2-NEXT:    retq
2660   %c = add <8 x i32> %a, <i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8>
2661   %d = shufflevector <8 x i32> %b, <8 x i32> %c, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 15, i32 14, i32 13, i32 12>
2662   ret <8 x i32> %d
2663 }
2664
2665 define <4 x float> @combine_insertps1(<4 x float> %a, <4 x float> %b) {
2666 ; SSE2-LABEL: combine_insertps1:
2667 ; SSE2:       # BB#0:
2668 ; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[1,0]
2669 ; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,2],xmm0[2,3]
2670 ; SSE2-NEXT:    movaps %xmm1, %xmm0
2671 ; SSE2-NEXT:    retq
2672 ;
2673 ; SSSE3-LABEL: combine_insertps1:
2674 ; SSSE3:       # BB#0:
2675 ; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[1,0]
2676 ; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,2],xmm0[2,3]
2677 ; SSSE3-NEXT:    movaps %xmm1, %xmm0
2678 ; SSSE3-NEXT:    retq
2679 ;
2680 ; SSE41-LABEL: combine_insertps1:
2681 ; SSE41:       # BB#0:
2682 ; SSE41-NEXT:    insertps {{.*#+}} xmm0 = xmm1[2],xmm0[1,2,3]
2683 ; SSE41-NEXT:    retq
2684 ;
2685 ; AVX-LABEL: combine_insertps1:
2686 ; AVX:       # BB#0:
2687 ; AVX-NEXT:    vinsertps {{.*#+}} xmm0 = xmm1[2],xmm0[1,2,3]
2688 ; AVX-NEXT:    retq
2689
2690   %c = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32><i32 0, i32 6, i32 2, i32 4>
2691   %d = shufflevector <4 x float> %a, <4 x float> %c, <4 x i32> <i32 5, i32 1, i32 6, i32 3>
2692   ret <4 x float> %d
2693 }
2694
2695 define <4 x float> @combine_insertps2(<4 x float> %a, <4 x float> %b) {
2696 ; SSE2-LABEL: combine_insertps2:
2697 ; SSE2:       # BB#0:
2698 ; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[0,0]
2699 ; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[2,3]
2700 ; SSE2-NEXT:    movaps %xmm1, %xmm0
2701 ; SSE2-NEXT:    retq
2702 ;
2703 ; SSSE3-LABEL: combine_insertps2:
2704 ; SSSE3:       # BB#0:
2705 ; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[0,0]
2706 ; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[2,3]
2707 ; SSSE3-NEXT:    movaps %xmm1, %xmm0
2708 ; SSSE3-NEXT:    retq
2709 ;
2710 ; SSE41-LABEL: combine_insertps2:
2711 ; SSE41:       # BB#0:
2712 ; SSE41-NEXT:    insertps {{.*#+}} xmm0 = xmm0[0],xmm1[2],xmm0[2,3]
2713 ; SSE41-NEXT:    retq
2714 ;
2715 ; AVX-LABEL: combine_insertps2:
2716 ; AVX:       # BB#0:
2717 ; AVX-NEXT:    vinsertps {{.*#+}} xmm0 = xmm0[0],xmm1[2],xmm0[2,3]
2718 ; AVX-NEXT:    retq
2719
2720   %c = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32><i32 0, i32 1, i32 6, i32 7>
2721   %d = shufflevector <4 x float> %a, <4 x float> %c, <4 x i32> <i32 4, i32 6, i32 2, i32 3>
2722   ret <4 x float> %d
2723 }
2724
2725 define <4 x float> @combine_insertps3(<4 x float> %a, <4 x float> %b) {
2726 ; SSE2-LABEL: combine_insertps3:
2727 ; SSE2:       # BB#0:
2728 ; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[3,0]
2729 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0,2]
2730 ; SSE2-NEXT:    retq
2731 ;
2732 ; SSSE3-LABEL: combine_insertps3:
2733 ; SSSE3:       # BB#0:
2734 ; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[3,0]
2735 ; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0,2]
2736 ; SSSE3-NEXT:    retq
2737 ;
2738 ; SSE41-LABEL: combine_insertps3:
2739 ; SSE41:       # BB#0:
2740 ; SSE41-NEXT:    insertps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0],xmm0[3]
2741 ; SSE41-NEXT:    retq
2742 ;
2743 ; AVX-LABEL: combine_insertps3:
2744 ; AVX:       # BB#0:
2745 ; AVX-NEXT:    vinsertps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0],xmm0[3]
2746 ; AVX-NEXT:    retq
2747
2748   %c = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32><i32 0, i32 4, i32 2, i32 5>
2749   %d = shufflevector <4 x float> %a, <4 x float> %c, <4 x i32><i32 4, i32 1, i32 5, i32 3>
2750   ret <4 x float> %d
2751 }
2752
2753 define <4 x float> @combine_insertps4(<4 x float> %a, <4 x float> %b) {
2754 ; SSE2-LABEL: combine_insertps4:
2755 ; SSE2:       # BB#0:
2756 ; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[2,0]
2757 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,0]
2758 ; SSE2-NEXT:    retq
2759 ;
2760 ; SSSE3-LABEL: combine_insertps4:
2761 ; SSSE3:       # BB#0:
2762 ; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[2,0]
2763 ; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,0]
2764 ; SSSE3-NEXT:    retq
2765 ;
2766 ; SSE41-LABEL: combine_insertps4:
2767 ; SSE41:       # BB#0:
2768 ; SSE41-NEXT:    insertps {{.*#+}} xmm0 = xmm0[0,1,2],xmm1[0]
2769 ; SSE41-NEXT:    retq
2770 ;
2771 ; AVX-LABEL: combine_insertps4:
2772 ; AVX:       # BB#0:
2773 ; AVX-NEXT:    vinsertps {{.*#+}} xmm0 = xmm0[0,1,2],xmm1[0]
2774 ; AVX-NEXT:    retq
2775
2776   %c = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32><i32 0, i32 4, i32 2, i32 5>
2777   %d = shufflevector <4 x float> %a, <4 x float> %c, <4 x i32><i32 4, i32 1, i32 6, i32 5>
2778   ret <4 x float> %d
2779 }
2780
2781 define <4 x float> @PR22377(<4 x float> %a, <4 x float> %b) {
2782 ; SSE-LABEL: PR22377:
2783 ; SSE:       # BB#0: # %entry
2784 ; SSE-NEXT:    movaps %xmm0, %xmm1
2785 ; SSE-NEXT:    shufps {{.*#+}} xmm1 = xmm1[1,3,1,3]
2786 ; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2,0,2]
2787 ; SSE-NEXT:    addps %xmm0, %xmm1
2788 ; SSE-NEXT:    unpcklps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
2789 ; SSE-NEXT:    retq
2790 ;
2791 ; AVX-LABEL: PR22377:
2792 ; AVX:       # BB#0: # %entry
2793 ; AVX-NEXT:    vpermilps {{.*#+}} xmm1 = xmm0[1,3,1,3]
2794 ; AVX-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[0,2,0,2]
2795 ; AVX-NEXT:    vaddps %xmm0, %xmm1, %xmm1
2796 ; AVX-NEXT:    vunpcklps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
2797 ; AVX-NEXT:    retq
2798 entry:
2799   %s1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 1, i32 3, i32 1, i32 3>
2800   %s2 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 2, i32 0, i32 2>
2801   %r2 = fadd <4 x float> %s1, %s2
2802   %s3 = shufflevector <4 x float> %s2, <4 x float> %r2, <4 x i32> <i32 0, i32 4, i32 1, i32 5>
2803   ret <4 x float> %s3
2804 }
2805
2806 define <4 x float> @PR22390(<4 x float> %a, <4 x float> %b) {
2807 ; SSE2-LABEL: PR22390:
2808 ; SSE2:       # BB#0: # %entry
2809 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,0,1,2]
2810 ; SSE2-NEXT:    movaps %xmm0, %xmm2
2811 ; SSE2-NEXT:    movss {{.*#+}} xmm2 = xmm1[0],xmm2[1,2,3]
2812 ; SSE2-NEXT:    addps %xmm0, %xmm2
2813 ; SSE2-NEXT:    movaps %xmm2, %xmm0
2814 ; SSE2-NEXT:    retq
2815 ;
2816 ; SSSE3-LABEL: PR22390:
2817 ; SSSE3:       # BB#0: # %entry
2818 ; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,0,1,2]
2819 ; SSSE3-NEXT:    movaps %xmm0, %xmm2
2820 ; SSSE3-NEXT:    movss {{.*#+}} xmm2 = xmm1[0],xmm2[1,2,3]
2821 ; SSSE3-NEXT:    addps %xmm0, %xmm2
2822 ; SSSE3-NEXT:    movaps %xmm2, %xmm0
2823 ; SSSE3-NEXT:    retq
2824 ;
2825 ; SSE41-LABEL: PR22390:
2826 ; SSE41:       # BB#0: # %entry
2827 ; SSE41-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,0,1,2]
2828 ; SSE41-NEXT:    blendps {{.*#+}} xmm1 = xmm1[0],xmm0[1,2,3]
2829 ; SSE41-NEXT:    addps %xmm1, %xmm0
2830 ; SSE41-NEXT:    retq
2831 ;
2832 ; AVX-LABEL: PR22390:
2833 ; AVX:       # BB#0: # %entry
2834 ; AVX-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[3,0,1,2]
2835 ; AVX-NEXT:    vblendps {{.*#+}} xmm1 = xmm1[0],xmm0[1,2,3]
2836 ; AVX-NEXT:    vaddps %xmm1, %xmm0, %xmm0
2837 ; AVX-NEXT:    retq
2838 entry:
2839   %s1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 3, i32 0, i32 1, i32 2>
2840   %s2 = shufflevector <4 x float> %s1, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 2, i32 3>
2841   %r2 = fadd <4 x float> %s1, %s2
2842   ret <4 x float> %r2
2843 }
2844
2845 define <8 x float> @PR22412(<8 x float> %a, <8 x float> %b) {
2846 ; SSE2-LABEL: PR22412:
2847 ; SSE2:       # BB#0: # %entry
2848 ; SSE2-NEXT:    movsd {{.*#+}} xmm2 = xmm0[0],xmm2[1]
2849 ; SSE2-NEXT:    movapd %xmm2, %xmm0
2850 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,0],xmm3[3,2]
2851 ; SSE2-NEXT:    shufps {{.*#+}} xmm3 = xmm3[1,0],xmm2[3,2]
2852 ; SSE2-NEXT:    movaps %xmm3, %xmm1
2853 ; SSE2-NEXT:    retq
2854 ;
2855 ; SSSE3-LABEL: PR22412:
2856 ; SSSE3:       # BB#0: # %entry
2857 ; SSSE3-NEXT:    movsd {{.*#+}} xmm2 = xmm0[0],xmm2[1]
2858 ; SSSE3-NEXT:    movapd %xmm2, %xmm0
2859 ; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,0],xmm3[3,2]
2860 ; SSSE3-NEXT:    shufps {{.*#+}} xmm3 = xmm3[1,0],xmm2[3,2]
2861 ; SSSE3-NEXT:    movaps %xmm3, %xmm1
2862 ; SSSE3-NEXT:    retq
2863 ;
2864 ; SSE41-LABEL: PR22412:
2865 ; SSE41:       # BB#0: # %entry
2866 ; SSE41-NEXT:    blendpd {{.*#+}} xmm0 = xmm0[0],xmm2[1]
2867 ; SSE41-NEXT:    movapd %xmm0, %xmm1
2868 ; SSE41-NEXT:    shufps {{.*#+}} xmm1 = xmm1[1,0],xmm3[3,2]
2869 ; SSE41-NEXT:    shufps {{.*#+}} xmm3 = xmm3[1,0],xmm0[3,2]
2870 ; SSE41-NEXT:    movaps %xmm1, %xmm0
2871 ; SSE41-NEXT:    movaps %xmm3, %xmm1
2872 ; SSE41-NEXT:    retq
2873 ;
2874 ; AVX1-LABEL: PR22412:
2875 ; AVX1:       # BB#0: # %entry
2876 ; AVX1-NEXT:    vblendpd {{.*#+}} ymm0 = ymm0[0],ymm1[1,2,3]
2877 ; AVX1-NEXT:    vperm2f128 {{.*#+}} ymm1 = ymm0[2,3,0,1]
2878 ; AVX1-NEXT:    vshufps {{.*#+}} ymm0 = ymm0[1,0],ymm1[3,2],ymm0[5,4],ymm1[7,6]
2879 ; AVX1-NEXT:    retq
2880 ;
2881 ; AVX2-LABEL: PR22412:
2882 ; AVX2:       # BB#0: # %entry
2883 ; AVX2-NEXT:    vblendpd {{.*#+}} ymm0 = ymm0[0],ymm1[1,2,3]
2884 ; AVX2-NEXT:    vmovaps {{.*#+}} ymm1 = [1,0,7,6,5,4,3,2]
2885 ; AVX2-NEXT:    vpermps %ymm0, %ymm1, %ymm0
2886 ; AVX2-NEXT:    retq
2887 entry:
2888   %s1 = shufflevector <8 x float> %a, <8 x float> %b, <8 x i32> <i32 0, i32 1, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
2889   %s2 = shufflevector <8 x float> %s1, <8 x float> undef, <8 x i32> <i32 1, i32 0, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2>
2890   ret <8 x float> %s2
2891 }