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