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