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