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