1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mcpu=x86-64 -mattr=+sse2 | FileCheck %s --check-prefix=ALL --check-prefix=SSE --check-prefix=SSE2
3; RUN: llc < %s -mcpu=x86-64 -mattr=+ssse3 | FileCheck %s --check-prefix=ALL --check-prefix=SSE --check-prefix=SSSE3
4; RUN: llc < %s -mcpu=x86-64 -mattr=+sse4.1 | FileCheck %s --check-prefix=ALL --check-prefix=SSE --check-prefix=SSE41
5; RUN: llc < %s -mcpu=x86-64 -mattr=+avx | FileCheck %s --check-prefix=ALL --check-prefix=AVX --check-prefix=AVX1
6; RUN: llc < %s -mcpu=x86-64 -mattr=+avx2 | FileCheck %s --check-prefixes=ALL,AVX,AVX2,AVX2-SLOW
7; RUN: llc < %s -mcpu=x86-64 -mattr=+avx2,+fast-variable-shuffle | FileCheck %s --check-prefixes=ALL,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; ALL-LABEL: combine_pshufd1:
22; ALL:       # %bb.0: # %entry
23; ALL-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; ALL-LABEL: combine_pshufd2:
32; ALL:       # %bb.0: # %entry
33; ALL-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; ALL-LABEL: combine_pshufd3:
45; ALL:       # %bb.0: # %entry
46; ALL-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; ALL-LABEL: combine_pshuflw1:
117; ALL:       # %bb.0: # %entry
118; ALL-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; ALL-LABEL: combine_pshuflw2:
127; ALL:       # %bb.0: # %entry
128; ALL-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:    vpbroadcastq %xmm0, %xmm0
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; ALL-LABEL: combine_nested_undef_test13:
815; ALL:       # %bb.0:
816; ALL-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; AVX1-LABEL: combine_nested_undef_test15:
868; AVX1:       # %bb.0:
869; AVX1-NEXT:    vpermilps {{.*#+}} xmm1 = xmm1[0,0,1,1]
870; AVX1-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[3,1,0,1]
871; AVX1-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2,3]
872; AVX1-NEXT:    retq
873;
874; AVX2-LABEL: combine_nested_undef_test15:
875; AVX2:       # %bb.0:
876; AVX2-NEXT:    vbroadcastss %xmm1, %xmm1
877; AVX2-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[3,1,0,1]
878; AVX2-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2,3]
879; AVX2-NEXT:    retq
880  %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 4, i32 3, i32 1>
881  %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 1, i32 0, i32 3>
882  ret <4 x i32> %2
883}
884
885define <4 x i32> @combine_nested_undef_test16(<4 x i32> %A, <4 x i32> %B) {
886; SSE2-LABEL: combine_nested_undef_test16:
887; SSE2:       # %bb.0:
888; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[1,3,2,3]
889; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,0,2,3]
890; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
891; SSE2-NEXT:    retq
892;
893; SSSE3-LABEL: combine_nested_undef_test16:
894; SSSE3:       # %bb.0:
895; SSSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[1,3,2,3]
896; SSSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,0,2,3]
897; SSSE3-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
898; SSSE3-NEXT:    retq
899;
900; SSE41-LABEL: combine_nested_undef_test16:
901; SSE41:       # %bb.0:
902; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
903; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7]
904; SSE41-NEXT:    retq
905;
906; AVX-LABEL: combine_nested_undef_test16:
907; AVX:       # %bb.0:
908; AVX-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[2,3,0,1]
909; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
910; AVX-NEXT:    retq
911  %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
912  %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 1, i32 0, i32 3>
913  ret <4 x i32> %2
914}
915
916define <4 x i32> @combine_nested_undef_test17(<4 x i32> %A, <4 x i32> %B) {
917; SSE2-LABEL: combine_nested_undef_test17:
918; SSE2:       # %bb.0:
919; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[1,0]
920; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,1],xmm1[0,2]
921; SSE2-NEXT:    retq
922;
923; SSSE3-LABEL: combine_nested_undef_test17:
924; SSSE3:       # %bb.0:
925; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[1,0]
926; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,1],xmm1[0,2]
927; SSSE3-NEXT:    retq
928;
929; SSE41-LABEL: combine_nested_undef_test17:
930; SSE41:       # %bb.0:
931; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3,4,5,6,7]
932; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[3,1,0,1]
933; SSE41-NEXT:    retq
934;
935; AVX-LABEL: combine_nested_undef_test17:
936; AVX:       # %bb.0:
937; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]
938; AVX-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[3,1,0,1]
939; AVX-NEXT:    retq
940  %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 1, i32 3, i32 1>
941  %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 1, i32 0, i32 3>
942  ret <4 x i32> %2
943}
944
945define <4 x i32> @combine_nested_undef_test18(<4 x i32> %A, <4 x i32> %B) {
946; SSE-LABEL: combine_nested_undef_test18:
947; SSE:       # %bb.0:
948; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,0,3]
949; SSE-NEXT:    retq
950;
951; AVX-LABEL: combine_nested_undef_test18:
952; AVX:       # %bb.0:
953; AVX-NEXT:    vpermilps {{.*#+}} xmm0 = xmm1[1,1,0,3]
954; AVX-NEXT:    retq
955  %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 5, i32 2, i32 7>
956  %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 1, i32 1, i32 0, i32 3>
957  ret <4 x i32> %2
958}
959
960define <4 x i32> @combine_nested_undef_test19(<4 x i32> %A, <4 x i32> %B) {
961; SSE2-LABEL: combine_nested_undef_test19:
962; SSE2:       # %bb.0:
963; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
964; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[3,0,0,0]
965; SSE2-NEXT:    retq
966;
967; SSSE3-LABEL: combine_nested_undef_test19:
968; SSSE3:       # %bb.0:
969; SSSE3-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
970; SSSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[3,0,0,0]
971; SSSE3-NEXT:    retq
972;
973; SSE41-LABEL: combine_nested_undef_test19:
974; SSE41:       # %bb.0:
975; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5,6,7]
976; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,0,0,0]
977; SSE41-NEXT:    retq
978;
979; AVX-LABEL: combine_nested_undef_test19:
980; AVX:       # %bb.0:
981; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2,3]
982; AVX-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[1,0,0,0]
983; AVX-NEXT:    retq
984  %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 4, i32 5, i32 6>
985  %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 0, i32 0, i32 0>
986  ret <4 x i32> %2
987}
988
989define <4 x i32> @combine_nested_undef_test20(<4 x i32> %A, <4 x i32> %B) {
990; SSE2-LABEL: combine_nested_undef_test20:
991; SSE2:       # %bb.0:
992; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[2,3]
993; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,2,3,1]
994; SSE2-NEXT:    movaps %xmm1, %xmm0
995; SSE2-NEXT:    retq
996;
997; SSSE3-LABEL: combine_nested_undef_test20:
998; SSSE3:       # %bb.0:
999; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[2,3]
1000; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,2,3,1]
1001; SSSE3-NEXT:    movaps %xmm1, %xmm0
1002; SSSE3-NEXT:    retq
1003;
1004; SSE41-LABEL: combine_nested_undef_test20:
1005; SSE41:       # %bb.0:
1006; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm1[0,1,2,3],xmm0[4,5,6,7]
1007; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,3,0]
1008; SSE41-NEXT:    retq
1009;
1010; AVX-LABEL: combine_nested_undef_test20:
1011; AVX:       # %bb.0:
1012; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3]
1013; AVX-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[0,2,3,0]
1014; AVX-NEXT:    retq
1015  %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 3, i32 2, i32 4, i32 4>
1016  %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 1, i32 0, i32 3>
1017  ret <4 x i32> %2
1018}
1019
1020define <4 x i32> @combine_nested_undef_test21(<4 x i32> %A, <4 x i32> %B) {
1021; SSE2-LABEL: combine_nested_undef_test21:
1022; SSE2:       # %bb.0:
1023; SSE2-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
1024; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[0,3,0,3]
1025; SSE2-NEXT:    retq
1026;
1027; SSSE3-LABEL: combine_nested_undef_test21:
1028; SSSE3:       # %bb.0:
1029; SSSE3-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
1030; SSSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[0,3,0,3]
1031; SSSE3-NEXT:    retq
1032;
1033; SSE41-LABEL: combine_nested_undef_test21:
1034; SSE41:       # %bb.0:
1035; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3],xmm1[4,5,6,7]
1036; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1]
1037; SSE41-NEXT:    retq
1038;
1039; AVX1-LABEL: combine_nested_undef_test21:
1040; AVX1:       # %bb.0:
1041; AVX1-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3]
1042; AVX1-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[0,1,0,1]
1043; AVX1-NEXT:    retq
1044;
1045; AVX2-LABEL: combine_nested_undef_test21:
1046; AVX2:       # %bb.0:
1047; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3]
1048; AVX2-NEXT:    vpbroadcastq %xmm0, %xmm0
1049; AVX2-NEXT:    retq
1050  %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 1, i32 3, i32 1>
1051  %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 1, i32 0, i32 3>
1052  ret <4 x i32> %2
1053}
1054
1055
1056; Test that we correctly combine shuffles according to rule
1057;  shuffle(shuffle(x, y), undef) -> shuffle(y, undef)
1058
1059define <4 x i32> @combine_nested_undef_test22(<4 x i32> %A, <4 x i32> %B) {
1060; SSE-LABEL: combine_nested_undef_test22:
1061; SSE:       # %bb.0:
1062; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,1,3]
1063; SSE-NEXT:    retq
1064;
1065; AVX-LABEL: combine_nested_undef_test22:
1066; AVX:       # %bb.0:
1067; AVX-NEXT:    vpermilps {{.*#+}} xmm0 = xmm1[1,1,1,3]
1068; AVX-NEXT:    retq
1069  %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 5, i32 2, i32 7>
1070  %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 3>
1071  ret <4 x i32> %2
1072}
1073
1074define <4 x i32> @combine_nested_undef_test23(<4 x i32> %A, <4 x i32> %B) {
1075; SSE-LABEL: combine_nested_undef_test23:
1076; SSE:       # %bb.0:
1077; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[0,1,0,3]
1078; SSE-NEXT:    retq
1079;
1080; AVX-LABEL: combine_nested_undef_test23:
1081; AVX:       # %bb.0:
1082; AVX-NEXT:    vpermilps {{.*#+}} xmm0 = xmm1[0,1,0,3]
1083; AVX-NEXT:    retq
1084  %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 5, i32 2, i32 7>
1085  %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 1, i32 0, i32 3>
1086  ret <4 x i32> %2
1087}
1088
1089define <4 x i32> @combine_nested_undef_test24(<4 x i32> %A, <4 x i32> %B) {
1090; SSE-LABEL: combine_nested_undef_test24:
1091; SSE:       # %bb.0:
1092; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[0,3,2,3]
1093; SSE-NEXT:    retq
1094;
1095; AVX-LABEL: combine_nested_undef_test24:
1096; AVX:       # %bb.0:
1097; AVX-NEXT:    vpermilps {{.*#+}} xmm0 = xmm1[0,3,2,3]
1098; AVX-NEXT:    retq
1099  %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 1, i32 6, i32 7>
1100  %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 3, i32 2, i32 4>
1101  ret <4 x i32> %2
1102}
1103
1104define <4 x i32> @combine_nested_undef_test25(<4 x i32> %A, <4 x i32> %B) {
1105; SSE-LABEL: combine_nested_undef_test25:
1106; SSE:       # %bb.0:
1107; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1]
1108; SSE-NEXT:    retq
1109;
1110; AVX1-LABEL: combine_nested_undef_test25:
1111; AVX1:       # %bb.0:
1112; AVX1-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[0,1,0,1]
1113; AVX1-NEXT:    retq
1114;
1115; AVX2-LABEL: combine_nested_undef_test25:
1116; AVX2:       # %bb.0:
1117; AVX2-NEXT:    vpbroadcastq %xmm0, %xmm0
1118; AVX2-NEXT:    retq
1119  %1 = shufflevector <4 x i32> %B, <4 x i32> %A, <4 x i32> <i32 1, i32 5, i32 2, i32 4>
1120  %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 3, i32 1, i32 3, i32 1>
1121  ret <4 x i32> %2
1122}
1123
1124define <4 x i32> @combine_nested_undef_test26(<4 x i32> %A, <4 x i32> %B) {
1125; SSE-LABEL: combine_nested_undef_test26:
1126; SSE:       # %bb.0:
1127; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3]
1128; SSE-NEXT:    retq
1129;
1130; AVX-LABEL: combine_nested_undef_test26:
1131; AVX:       # %bb.0:
1132; AVX-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[2,3,2,3]
1133; AVX-NEXT:    retq
1134  %1 = shufflevector <4 x i32> %B, <4 x i32> %A, <4 x i32> <i32 1, i32 2, i32 6, i32 7>
1135  %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 3, i32 2, i32 3>
1136  ret <4 x i32> %2
1137}
1138
1139define <4 x i32> @combine_nested_undef_test27(<4 x i32> %A, <4 x i32> %B) {
1140; SSE-LABEL: combine_nested_undef_test27:
1141; SSE:       # %bb.0:
1142; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1]
1143; SSE-NEXT:    retq
1144;
1145; AVX1-LABEL: combine_nested_undef_test27:
1146; AVX1:       # %bb.0:
1147; AVX1-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[0,1,0,1]
1148; AVX1-NEXT:    retq
1149;
1150; AVX2-LABEL: combine_nested_undef_test27:
1151; AVX2:       # %bb.0:
1152; AVX2-NEXT:    vpbroadcastq %xmm0, %xmm0
1153; AVX2-NEXT:    retq
1154  %1 = shufflevector <4 x i32> %B, <4 x i32> %A, <4 x i32> <i32 2, i32 1, i32 5, i32 4>
1155  %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 3, i32 2, i32 3, i32 2>
1156  ret <4 x i32> %2
1157}
1158
1159define <4 x i32> @combine_nested_undef_test28(<4 x i32> %A, <4 x i32> %B) {
1160; SSE-LABEL: combine_nested_undef_test28:
1161; SSE:       # %bb.0:
1162; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,1,1,0]
1163; SSE-NEXT:    retq
1164;
1165; AVX-LABEL: combine_nested_undef_test28:
1166; AVX:       # %bb.0:
1167; AVX-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[0,1,1,0]
1168; AVX-NEXT:    retq
1169  %1 = shufflevector <4 x i32> %B, <4 x i32> %A, <4 x i32> <i32 1, i32 2, i32 4, i32 5>
1170  %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 3, i32 3, i32 2>
1171  ret <4 x i32> %2
1172}
1173
1174define <4 x float> @combine_test1(<4 x float> %a, <4 x float> %b) {
1175; SSE-LABEL: combine_test1:
1176; SSE:       # %bb.0:
1177; SSE-NEXT:    movaps %xmm1, %xmm0
1178; SSE-NEXT:    retq
1179;
1180; AVX-LABEL: combine_test1:
1181; AVX:       # %bb.0:
1182; AVX-NEXT:    vmovaps %xmm1, %xmm0
1183; AVX-NEXT:    retq
1184  %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
1185  %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
1186  ret <4 x float> %2
1187}
1188
1189define <4 x float> @combine_test2(<4 x float> %a, <4 x float> %b) {
1190; SSE2-LABEL: combine_test2:
1191; SSE2:       # %bb.0:
1192; SSE2-NEXT:    movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]
1193; SSE2-NEXT:    movaps %xmm1, %xmm0
1194; SSE2-NEXT:    retq
1195;
1196; SSSE3-LABEL: combine_test2:
1197; SSSE3:       # %bb.0:
1198; SSSE3-NEXT:    movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]
1199; SSSE3-NEXT:    movaps %xmm1, %xmm0
1200; SSSE3-NEXT:    retq
1201;
1202; SSE41-LABEL: combine_test2:
1203; SSE41:       # %bb.0:
1204; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]
1205; SSE41-NEXT:    retq
1206;
1207; AVX-LABEL: combine_test2:
1208; AVX:       # %bb.0:
1209; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]
1210; AVX-NEXT:    retq
1211  %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
1212  %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 6, i32 3>
1213  ret <4 x float> %2
1214}
1215
1216define <4 x float> @combine_test3(<4 x float> %a, <4 x float> %b) {
1217; SSE-LABEL: combine_test3:
1218; SSE:       # %bb.0:
1219; SSE-NEXT:    movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1220; SSE-NEXT:    retq
1221;
1222; AVX-LABEL: combine_test3:
1223; AVX:       # %bb.0:
1224; AVX-NEXT:    vmovlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1225; AVX-NEXT:    retq
1226  %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 1, i32 7>
1227  %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 2, i32 4, i32 1>
1228  ret <4 x float> %2
1229}
1230
1231define <4 x float> @combine_test4(<4 x float> %a, <4 x float> %b) {
1232; SSE-LABEL: combine_test4:
1233; SSE:       # %bb.0:
1234; SSE-NEXT:    movhlps {{.*#+}} xmm0 = xmm1[1],xmm0[1]
1235; SSE-NEXT:    retq
1236;
1237; AVX-LABEL: combine_test4:
1238; AVX:       # %bb.0:
1239; AVX-NEXT:    vunpckhpd {{.*#+}} xmm0 = xmm1[1],xmm0[1]
1240; AVX-NEXT:    retq
1241  %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 2, i32 3, i32 5, i32 5>
1242  %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 6, i32 7, i32 0, i32 1>
1243  ret <4 x float> %2
1244}
1245
1246define <4 x float> @combine_test5(<4 x float> %a, <4 x float> %b) {
1247; SSE2-LABEL: combine_test5:
1248; SSE2:       # %bb.0:
1249; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0]
1250; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3]
1251; SSE2-NEXT:    retq
1252;
1253; SSSE3-LABEL: combine_test5:
1254; SSSE3:       # %bb.0:
1255; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0]
1256; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3]
1257; SSSE3-NEXT:    retq
1258;
1259; SSE41-LABEL: combine_test5:
1260; SSE41:       # %bb.0:
1261; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3]
1262; SSE41-NEXT:    retq
1263;
1264; AVX-LABEL: combine_test5:
1265; AVX:       # %bb.0:
1266; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3]
1267; AVX-NEXT:    retq
1268  %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
1269  %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 2, i32 7>
1270  ret <4 x float> %2
1271}
1272
1273define <4 x i32> @combine_test6(<4 x i32> %a, <4 x i32> %b) {
1274; SSE-LABEL: combine_test6:
1275; SSE:       # %bb.0:
1276; SSE-NEXT:    movaps %xmm1, %xmm0
1277; SSE-NEXT:    retq
1278;
1279; AVX-LABEL: combine_test6:
1280; AVX:       # %bb.0:
1281; AVX-NEXT:    vmovaps %xmm1, %xmm0
1282; AVX-NEXT:    retq
1283  %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
1284  %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
1285  ret <4 x i32> %2
1286}
1287
1288define <4 x i32> @combine_test7(<4 x i32> %a, <4 x i32> %b) {
1289; SSE2-LABEL: combine_test7:
1290; SSE2:       # %bb.0:
1291; SSE2-NEXT:    movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]
1292; SSE2-NEXT:    movaps %xmm1, %xmm0
1293; SSE2-NEXT:    retq
1294;
1295; SSSE3-LABEL: combine_test7:
1296; SSSE3:       # %bb.0:
1297; SSSE3-NEXT:    movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]
1298; SSSE3-NEXT:    movaps %xmm1, %xmm0
1299; SSSE3-NEXT:    retq
1300;
1301; SSE41-LABEL: combine_test7:
1302; SSE41:       # %bb.0:
1303; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]
1304; SSE41-NEXT:    retq
1305;
1306; AVX-LABEL: combine_test7:
1307; AVX:       # %bb.0:
1308; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]
1309; AVX-NEXT:    retq
1310  %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
1311  %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 0, i32 1, i32 6, i32 3>
1312  ret <4 x i32> %2
1313}
1314
1315define <4 x i32> @combine_test8(<4 x i32> %a, <4 x i32> %b) {
1316; SSE-LABEL: combine_test8:
1317; SSE:       # %bb.0:
1318; SSE-NEXT:    movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1319; SSE-NEXT:    retq
1320;
1321; AVX-LABEL: combine_test8:
1322; AVX:       # %bb.0:
1323; AVX-NEXT:    vmovlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1324; AVX-NEXT:    retq
1325  %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 5, i32 1, i32 7>
1326  %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 0, i32 2, i32 4, i32 1>
1327  ret <4 x i32> %2
1328}
1329
1330define <4 x i32> @combine_test9(<4 x i32> %a, <4 x i32> %b) {
1331; SSE-LABEL: combine_test9:
1332; SSE:       # %bb.0:
1333; SSE-NEXT:    unpckhpd {{.*#+}} xmm1 = xmm1[1],xmm0[1]
1334; SSE-NEXT:    movaps %xmm1, %xmm0
1335; SSE-NEXT:    retq
1336;
1337; AVX-LABEL: combine_test9:
1338; AVX:       # %bb.0:
1339; AVX-NEXT:    vunpckhpd {{.*#+}} xmm0 = xmm1[1],xmm0[1]
1340; AVX-NEXT:    retq
1341  %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 2, i32 3, i32 5, i32 5>
1342  %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 6, i32 7, i32 0, i32 1>
1343  ret <4 x i32> %2
1344}
1345
1346define <4 x i32> @combine_test10(<4 x i32> %a, <4 x i32> %b) {
1347; SSE2-LABEL: combine_test10:
1348; SSE2:       # %bb.0:
1349; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0]
1350; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3]
1351; SSE2-NEXT:    retq
1352;
1353; SSSE3-LABEL: combine_test10:
1354; SSSE3:       # %bb.0:
1355; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0]
1356; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3]
1357; SSSE3-NEXT:    retq
1358;
1359; SSE41-LABEL: combine_test10:
1360; SSE41:       # %bb.0:
1361; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3]
1362; SSE41-NEXT:    retq
1363;
1364; AVX-LABEL: combine_test10:
1365; AVX:       # %bb.0:
1366; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3]
1367; AVX-NEXT:    retq
1368  %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
1369  %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 0, i32 1, i32 2, i32 7>
1370  ret <4 x i32> %2
1371}
1372
1373define <4 x float> @combine_test11(<4 x float> %a, <4 x float> %b) {
1374; ALL-LABEL: combine_test11:
1375; ALL:       # %bb.0:
1376; ALL-NEXT:    retq
1377  %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
1378  %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
1379  ret <4 x float> %2
1380}
1381
1382define <4 x float> @combine_test12(<4 x float> %a, <4 x float> %b) {
1383; SSE2-LABEL: combine_test12:
1384; SSE2:       # %bb.0:
1385; SSE2-NEXT:    movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]
1386; SSE2-NEXT:    movaps %xmm1, %xmm0
1387; SSE2-NEXT:    retq
1388;
1389; SSSE3-LABEL: combine_test12:
1390; SSSE3:       # %bb.0:
1391; SSSE3-NEXT:    movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]
1392; SSSE3-NEXT:    movaps %xmm1, %xmm0
1393; SSSE3-NEXT:    retq
1394;
1395; SSE41-LABEL: combine_test12:
1396; SSE41:       # %bb.0:
1397; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]
1398; SSE41-NEXT:    retq
1399;
1400; AVX-LABEL: combine_test12:
1401; AVX:       # %bb.0:
1402; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]
1403; AVX-NEXT:    retq
1404  %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 6, i32 7>
1405  %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 4, i32 1, i32 2, i32 3>
1406  ret <4 x float> %2
1407}
1408
1409define <4 x float> @combine_test13(<4 x float> %a, <4 x float> %b) {
1410; SSE-LABEL: combine_test13:
1411; SSE:       # %bb.0:
1412; SSE-NEXT:    movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1413; SSE-NEXT:    retq
1414;
1415; AVX-LABEL: combine_test13:
1416; AVX:       # %bb.0:
1417; AVX-NEXT:    vmovlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1418; AVX-NEXT:    retq
1419  %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
1420  %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 4, i32 5, i32 2, i32 3>
1421  ret <4 x float> %2
1422}
1423
1424define <4 x float> @combine_test14(<4 x float> %a, <4 x float> %b) {
1425; SSE-LABEL: combine_test14:
1426; SSE:       # %bb.0:
1427; SSE-NEXT:    unpckhpd {{.*#+}} xmm0 = xmm0[1],xmm1[1]
1428; SSE-NEXT:    retq
1429;
1430; AVX-LABEL: combine_test14:
1431; AVX:       # %bb.0:
1432; AVX-NEXT:    vunpckhpd {{.*#+}} xmm0 = xmm0[1],xmm1[1]
1433; AVX-NEXT:    retq
1434  %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 6, i32 7, i32 5, i32 5>
1435  %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 6, i32 7, i32 0, i32 1>
1436  ret <4 x float> %2
1437}
1438
1439define <4 x float> @combine_test15(<4 x float> %a, <4 x float> %b) {
1440; SSE2-LABEL: combine_test15:
1441; SSE2:       # %bb.0:
1442; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0]
1443; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3]
1444; SSE2-NEXT:    retq
1445;
1446; SSSE3-LABEL: combine_test15:
1447; SSSE3:       # %bb.0:
1448; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0]
1449; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3]
1450; SSSE3-NEXT:    retq
1451;
1452; SSE41-LABEL: combine_test15:
1453; SSE41:       # %bb.0:
1454; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3]
1455; SSE41-NEXT:    retq
1456;
1457; AVX-LABEL: combine_test15:
1458; AVX:       # %bb.0:
1459; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3]
1460; AVX-NEXT:    retq
1461  %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 7>
1462  %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 0, i32 5, i32 2, i32 3>
1463  ret <4 x float> %2
1464}
1465
1466define <4 x i32> @combine_test16(<4 x i32> %a, <4 x i32> %b) {
1467; ALL-LABEL: combine_test16:
1468; ALL:       # %bb.0:
1469; ALL-NEXT:    retq
1470  %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
1471  %2 = shufflevector <4 x i32> %1, <4 x i32> %a, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
1472  ret <4 x i32> %2
1473}
1474
1475define <4 x i32> @combine_test17(<4 x i32> %a, <4 x i32> %b) {
1476; SSE2-LABEL: combine_test17:
1477; SSE2:       # %bb.0:
1478; SSE2-NEXT:    movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]
1479; SSE2-NEXT:    movaps %xmm1, %xmm0
1480; SSE2-NEXT:    retq
1481;
1482; SSSE3-LABEL: combine_test17:
1483; SSSE3:       # %bb.0:
1484; SSSE3-NEXT:    movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]
1485; SSSE3-NEXT:    movaps %xmm1, %xmm0
1486; SSSE3-NEXT:    retq
1487;
1488; SSE41-LABEL: combine_test17:
1489; SSE41:       # %bb.0:
1490; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]
1491; SSE41-NEXT:    retq
1492;
1493; AVX-LABEL: combine_test17:
1494; AVX:       # %bb.0:
1495; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]
1496; AVX-NEXT:    retq
1497  %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 5, i32 6, i32 7>
1498  %2 = shufflevector <4 x i32> %1, <4 x i32> %a, <4 x i32> <i32 4, i32 1, i32 2, i32 3>
1499  ret <4 x i32> %2
1500}
1501
1502define <4 x i32> @combine_test18(<4 x i32> %a, <4 x i32> %b) {
1503; SSE-LABEL: combine_test18:
1504; SSE:       # %bb.0:
1505; SSE-NEXT:    movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1506; SSE-NEXT:    retq
1507;
1508; AVX-LABEL: combine_test18:
1509; AVX:       # %bb.0:
1510; AVX-NEXT:    vmovlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1511; AVX-NEXT:    retq
1512  %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
1513  %2 = shufflevector <4 x i32> %1, <4 x i32> %a, <4 x i32> <i32 4, i32 5, i32 2, i32 3>
1514  ret <4 x i32> %2
1515}
1516
1517define <4 x i32> @combine_test19(<4 x i32> %a, <4 x i32> %b) {
1518; SSE-LABEL: combine_test19:
1519; SSE:       # %bb.0:
1520; SSE-NEXT:    unpckhpd {{.*#+}} xmm0 = xmm0[1],xmm1[1]
1521; SSE-NEXT:    retq
1522;
1523; AVX-LABEL: combine_test19:
1524; AVX:       # %bb.0:
1525; AVX-NEXT:    vunpckhpd {{.*#+}} xmm0 = xmm0[1],xmm1[1]
1526; AVX-NEXT:    retq
1527  %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 6, i32 7, i32 5, i32 5>
1528  %2 = shufflevector <4 x i32> %1, <4 x i32> %a, <4 x i32> <i32 6, i32 7, i32 0, i32 1>
1529  ret <4 x i32> %2
1530}
1531
1532define <4 x i32> @combine_test20(<4 x i32> %a, <4 x i32> %b) {
1533; SSE2-LABEL: combine_test20:
1534; SSE2:       # %bb.0:
1535; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0]
1536; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3]
1537; SSE2-NEXT:    retq
1538;
1539; SSSE3-LABEL: combine_test20:
1540; SSSE3:       # %bb.0:
1541; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0]
1542; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3]
1543; SSSE3-NEXT:    retq
1544;
1545; SSE41-LABEL: combine_test20:
1546; SSE41:       # %bb.0:
1547; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3]
1548; SSE41-NEXT:    retq
1549;
1550; AVX-LABEL: combine_test20:
1551; AVX:       # %bb.0:
1552; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3]
1553; AVX-NEXT:    retq
1554  %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 7>
1555  %2 = shufflevector <4 x i32> %1, <4 x i32> %a, <4 x i32> <i32 0, i32 5, i32 2, i32 3>
1556  ret <4 x i32> %2
1557}
1558
1559define <4 x i32> @combine_test21(<8 x i32> %a, <4 x i32>* %ptr) {
1560; SSE-LABEL: combine_test21:
1561; SSE:       # %bb.0:
1562; SSE-NEXT:    movaps %xmm0, %xmm2
1563; SSE-NEXT:    movlhps {{.*#+}} xmm2 = xmm2[0],xmm1[0]
1564; SSE-NEXT:    unpckhpd {{.*#+}} xmm0 = xmm0[1],xmm1[1]
1565; SSE-NEXT:    movaps %xmm2, (%rdi)
1566; SSE-NEXT:    retq
1567;
1568; AVX-LABEL: combine_test21:
1569; AVX:       # %bb.0:
1570; AVX-NEXT:    vextractf128 $1, %ymm0, %xmm1
1571; AVX-NEXT:    vmovlhps {{.*#+}} xmm2 = xmm0[0],xmm1[0]
1572; AVX-NEXT:    vunpckhpd {{.*#+}} xmm0 = xmm0[1],xmm1[1]
1573; AVX-NEXT:    vmovaps %xmm2, (%rdi)
1574; AVX-NEXT:    vzeroupper
1575; AVX-NEXT:    retq
1576  %1 = shufflevector <8 x i32> %a, <8 x i32> %a, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
1577  %2 = shufflevector <8 x i32> %a, <8 x i32> %a, <4 x i32> <i32 2, i32 3, i32 6, i32 7>
1578  store <4 x i32> %1, <4 x i32>* %ptr, align 16
1579  ret <4 x i32> %2
1580}
1581
1582define <8 x float> @combine_test22(<2 x float>* %a, <2 x float>* %b) {
1583; SSE-LABEL: combine_test22:
1584; SSE:       # %bb.0:
1585; SSE-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
1586; SSE-NEXT:    movhpd {{.*#+}} xmm0 = xmm0[0],mem[0]
1587; SSE-NEXT:    retq
1588;
1589; AVX-LABEL: combine_test22:
1590; AVX:       # %bb.0:
1591; AVX-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
1592; AVX-NEXT:    vmovhpd {{.*#+}} xmm0 = xmm0[0],mem[0]
1593; AVX-NEXT:    retq
1594; Current AVX2 lowering of this is still awful, not adding a test case.
1595  %1 = load <2 x float>, <2 x float>* %a, align 8
1596  %2 = load <2 x float>, <2 x float>* %b, align 8
1597  %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>
1598  ret <8 x float> %3
1599}
1600
1601; PR22359
1602define void @combine_test23(<8 x float> %v, <2 x float>* %ptr) {
1603; SSE-LABEL: combine_test23:
1604; SSE:       # %bb.0:
1605; SSE-NEXT:    movups %xmm0, (%rdi)
1606; SSE-NEXT:    retq
1607;
1608; AVX-LABEL: combine_test23:
1609; AVX:       # %bb.0:
1610; AVX-NEXT:    vmovups %xmm0, (%rdi)
1611; AVX-NEXT:    vzeroupper
1612; AVX-NEXT:    retq
1613  %idx2 = getelementptr inbounds <2 x float>, <2 x float>* %ptr, i64 1
1614  %shuffle0 = shufflevector <8 x float> %v, <8 x float> undef, <2 x i32> <i32 0, i32 1>
1615  %shuffle1 = shufflevector <8 x float> %v, <8 x float> undef, <2 x i32> <i32 2, i32 3>
1616  store <2 x float> %shuffle0, <2 x float>* %ptr, align 8
1617  store <2 x float> %shuffle1, <2 x float>* %idx2, align 8
1618  ret void
1619}
1620
1621; Check some negative cases.
1622; FIXME: Do any of these really make sense? Are they redundant with the above tests?
1623
1624define <4 x float> @combine_test1b(<4 x float> %a, <4 x float> %b) {
1625; SSE-LABEL: combine_test1b:
1626; SSE:       # %bb.0:
1627; SSE-NEXT:    movaps %xmm1, %xmm0
1628; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,0]
1629; SSE-NEXT:    retq
1630;
1631; AVX-LABEL: combine_test1b:
1632; AVX:       # %bb.0:
1633; AVX-NEXT:    vpermilps {{.*#+}} xmm0 = xmm1[0,1,2,0]
1634; AVX-NEXT:    retq
1635  %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
1636  %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 0>
1637  ret <4 x float> %2
1638}
1639
1640define <4 x float> @combine_test2b(<4 x float> %a, <4 x float> %b) {
1641; SSE2-LABEL: combine_test2b:
1642; SSE2:       # %bb.0:
1643; SSE2-NEXT:    movaps %xmm1, %xmm0
1644; SSE2-NEXT:    movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1645; SSE2-NEXT:    retq
1646;
1647; SSSE3-LABEL: combine_test2b:
1648; SSSE3:       # %bb.0:
1649; SSSE3-NEXT:    movddup {{.*#+}} xmm0 = xmm1[0,0]
1650; SSSE3-NEXT:    retq
1651;
1652; SSE41-LABEL: combine_test2b:
1653; SSE41:       # %bb.0:
1654; SSE41-NEXT:    movddup {{.*#+}} xmm0 = xmm1[0,0]
1655; SSE41-NEXT:    retq
1656;
1657; AVX-LABEL: combine_test2b:
1658; AVX:       # %bb.0:
1659; AVX-NEXT:    vmovddup {{.*#+}} xmm0 = xmm1[0,0]
1660; AVX-NEXT:    retq
1661  %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
1662  %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 0, i32 5>
1663  ret <4 x float> %2
1664}
1665
1666define <4 x float> @combine_test3b(<4 x float> %a, <4 x float> %b) {
1667; SSE2-LABEL: combine_test3b:
1668; SSE2:       # %bb.0:
1669; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,0],xmm1[3,0]
1670; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[2,3]
1671; SSE2-NEXT:    retq
1672;
1673; SSSE3-LABEL: combine_test3b:
1674; SSSE3:       # %bb.0:
1675; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,0],xmm1[3,0]
1676; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[2,3]
1677; SSSE3-NEXT:    retq
1678;
1679; SSE41-LABEL: combine_test3b:
1680; SSE41:       # %bb.0:
1681; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]
1682; SSE41-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,3,2,3]
1683; SSE41-NEXT:    retq
1684;
1685; AVX-LABEL: combine_test3b:
1686; AVX:       # %bb.0:
1687; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]
1688; AVX-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[0,3,2,3]
1689; AVX-NEXT:    retq
1690  %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 0, i32 6, i32 3>
1691  %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 7, i32 2, i32 7>
1692  ret <4 x float> %2
1693}
1694
1695define <4 x float> @combine_test4b(<4 x float> %a, <4 x float> %b) {
1696; SSE-LABEL: combine_test4b:
1697; SSE:       # %bb.0:
1698; SSE-NEXT:    movaps %xmm1, %xmm0
1699; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1],xmm1[2,3]
1700; SSE-NEXT:    retq
1701;
1702; AVX-LABEL: combine_test4b:
1703; AVX:       # %bb.0:
1704; AVX-NEXT:    vpermilps {{.*#+}} xmm0 = xmm1[1,1,2,3]
1705; AVX-NEXT:    retq
1706  %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
1707  %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 5, i32 5, i32 2, i32 7>
1708  ret <4 x float> %2
1709}
1710
1711
1712; Verify that we correctly fold shuffles even when we use illegal vector types.
1713
1714define <4 x i8> @combine_test1c(<4 x i8>* %a, <4 x i8>* %b) {
1715; SSE2-LABEL: combine_test1c:
1716; SSE2:       # %bb.0:
1717; SSE2-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
1718; SSE2-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
1719; SSE2-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
1720; SSE2-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
1721; SSE2-NEXT:    movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]
1722; SSE2-NEXT:    retq
1723;
1724; SSSE3-LABEL: combine_test1c:
1725; SSSE3:       # %bb.0:
1726; SSSE3-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
1727; SSSE3-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
1728; SSSE3-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
1729; SSSE3-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
1730; SSSE3-NEXT:    movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]
1731; SSSE3-NEXT:    retq
1732;
1733; SSE41-LABEL: combine_test1c:
1734; SSE41:       # %bb.0:
1735; SSE41-NEXT:    pmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1736; SSE41-NEXT:    pmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1737; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3,4,5,6,7]
1738; SSE41-NEXT:    retq
1739;
1740; AVX1-LABEL: combine_test1c:
1741; AVX1:       # %bb.0:
1742; AVX1-NEXT:    vpmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1743; AVX1-NEXT:    vpmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1744; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3,4,5,6,7]
1745; AVX1-NEXT:    retq
1746;
1747; AVX2-LABEL: combine_test1c:
1748; AVX2:       # %bb.0:
1749; AVX2-NEXT:    vpmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1750; AVX2-NEXT:    vpmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1751; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]
1752; AVX2-NEXT:    retq
1753  %A = load <4 x i8>, <4 x i8>* %a
1754  %B = load <4 x i8>, <4 x i8>* %b
1755  %1 = shufflevector <4 x i8> %A, <4 x i8> %B, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
1756  %2 = shufflevector <4 x i8> %1, <4 x i8> %B, <4 x i32> <i32 0, i32 1, i32 6, i32 3>
1757  ret <4 x i8> %2
1758}
1759
1760define <4 x i8> @combine_test2c(<4 x i8>* %a, <4 x i8>* %b) {
1761; SSE2-LABEL: combine_test2c:
1762; SSE2:       # %bb.0:
1763; SSE2-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
1764; SSE2-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
1765; SSE2-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
1766; SSE2-NEXT:    movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
1767; SSE2-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7]
1768; SSE2-NEXT:    punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
1769; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1770; SSE2-NEXT:    retq
1771;
1772; SSSE3-LABEL: combine_test2c:
1773; SSSE3:       # %bb.0:
1774; SSSE3-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
1775; SSSE3-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
1776; SSSE3-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
1777; SSSE3-NEXT:    movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
1778; SSSE3-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7]
1779; SSSE3-NEXT:    punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
1780; SSSE3-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1781; SSSE3-NEXT:    retq
1782;
1783; SSE41-LABEL: combine_test2c:
1784; SSE41:       # %bb.0:
1785; SSE41-NEXT:    pmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1786; SSE41-NEXT:    pmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1787; SSE41-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1788; SSE41-NEXT:    retq
1789;
1790; AVX-LABEL: combine_test2c:
1791; AVX:       # %bb.0:
1792; AVX-NEXT:    vpmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1793; AVX-NEXT:    vpmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1794; AVX-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1795; AVX-NEXT:    retq
1796  %A = load <4 x i8>, <4 x i8>* %a
1797  %B = load <4 x i8>, <4 x i8>* %b
1798  %1 = shufflevector <4 x i8> %A, <4 x i8> %B, <4 x i32> <i32 0, i32 5, i32 1, i32 5>
1799  %2 = shufflevector <4 x i8> %1, <4 x i8> %B, <4 x i32> <i32 0, i32 2, i32 4, i32 1>
1800  ret <4 x i8> %2
1801}
1802
1803define <4 x i8> @combine_test3c(<4 x i8>* %a, <4 x i8>* %b) {
1804; SSE2-LABEL: combine_test3c:
1805; SSE2:       # %bb.0:
1806; SSE2-NEXT:    movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
1807; SSE2-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7]
1808; SSE2-NEXT:    punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
1809; SSE2-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
1810; SSE2-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
1811; SSE2-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
1812; SSE2-NEXT:    punpckhqdq {{.*#+}} xmm0 = xmm0[1],xmm1[1]
1813; SSE2-NEXT:    retq
1814;
1815; SSSE3-LABEL: combine_test3c:
1816; SSSE3:       # %bb.0:
1817; SSSE3-NEXT:    movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
1818; SSSE3-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7]
1819; SSSE3-NEXT:    punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
1820; SSSE3-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
1821; SSSE3-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
1822; SSSE3-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
1823; SSSE3-NEXT:    punpckhqdq {{.*#+}} xmm0 = xmm0[1],xmm1[1]
1824; SSSE3-NEXT:    retq
1825;
1826; SSE41-LABEL: combine_test3c:
1827; SSE41:       # %bb.0:
1828; SSE41-NEXT:    pmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1829; SSE41-NEXT:    pmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1830; SSE41-NEXT:    punpckhqdq {{.*#+}} xmm0 = xmm0[1],xmm1[1]
1831; SSE41-NEXT:    retq
1832;
1833; AVX-LABEL: combine_test3c:
1834; AVX:       # %bb.0:
1835; AVX-NEXT:    vpmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1836; AVX-NEXT:    vpmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1837; AVX-NEXT:    vpunpckhqdq {{.*#+}} xmm0 = xmm1[1],xmm0[1]
1838; AVX-NEXT:    retq
1839  %A = load <4 x i8>, <4 x i8>* %a
1840  %B = load <4 x i8>, <4 x i8>* %b
1841  %1 = shufflevector <4 x i8> %A, <4 x i8> %B, <4 x i32> <i32 2, i32 3, i32 5, i32 5>
1842  %2 = shufflevector <4 x i8> %1, <4 x i8> %B, <4 x i32> <i32 6, i32 7, i32 0, i32 1>
1843  ret <4 x i8> %2
1844}
1845
1846define <4 x i8> @combine_test4c(<4 x i8>* %a, <4 x i8>* %b) {
1847; SSE2-LABEL: combine_test4c:
1848; SSE2:       # %bb.0:
1849; SSE2-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
1850; SSE2-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
1851; SSE2-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
1852; SSE2-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
1853; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0]
1854; SSE2-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7]
1855; SSE2-NEXT:    punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
1856; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3]
1857; SSE2-NEXT:    retq
1858;
1859; SSSE3-LABEL: combine_test4c:
1860; SSSE3:       # %bb.0:
1861; SSSE3-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
1862; SSSE3-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
1863; SSSE3-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
1864; SSSE3-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
1865; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,0]
1866; SSSE3-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7]
1867; SSSE3-NEXT:    punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
1868; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3]
1869; SSSE3-NEXT:    retq
1870;
1871; SSE41-LABEL: combine_test4c:
1872; SSE41:       # %bb.0:
1873; SSE41-NEXT:    pmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1874; SSE41-NEXT:    pmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1875; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5,6,7]
1876; SSE41-NEXT:    retq
1877;
1878; AVX1-LABEL: combine_test4c:
1879; AVX1:       # %bb.0:
1880; AVX1-NEXT:    vpmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1881; AVX1-NEXT:    vpmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1882; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3],xmm1[4,5,6,7]
1883; AVX1-NEXT:    retq
1884;
1885; AVX2-LABEL: combine_test4c:
1886; AVX2:       # %bb.0:
1887; AVX2-NEXT:    vpmovzxbd {{.*#+}} xmm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1888; AVX2-NEXT:    vpmovzxbd {{.*#+}} xmm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
1889; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2,3]
1890; AVX2-NEXT:    retq
1891  %A = load <4 x i8>, <4 x i8>* %a
1892  %B = load <4 x i8>, <4 x i8>* %b
1893  %1 = shufflevector <4 x i8> %A, <4 x i8> %B, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
1894  %2 = shufflevector <4 x i8> %1, <4 x i8> %B, <4 x i32> <i32 0, i32 1, i32 2, i32 7>
1895  ret <4 x i8> %2
1896}
1897
1898
1899; The following test cases are generated from this C++ code
1900;
1901;__m128 blend_01(__m128 a, __m128 b)
1902;{
1903;  __m128 s = a;
1904;  s = _mm_blend_ps( s, b, 1<<0 );
1905;  s = _mm_blend_ps( s, b, 1<<1 );
1906;  return s;
1907;}
1908;
1909;__m128 blend_02(__m128 a, __m128 b)
1910;{
1911;  __m128 s = a;
1912;  s = _mm_blend_ps( s, b, 1<<0 );
1913;  s = _mm_blend_ps( s, b, 1<<2 );
1914;  return s;
1915;}
1916;
1917;__m128 blend_123(__m128 a, __m128 b)
1918;{
1919;  __m128 s = a;
1920;  s = _mm_blend_ps( s, b, 1<<1 );
1921;  s = _mm_blend_ps( s, b, 1<<2 );
1922;  s = _mm_blend_ps( s, b, 1<<3 );
1923;  return s;
1924;}
1925
1926; Ideally, we should collapse the following shuffles into a single one.
1927
1928define <4 x float> @combine_blend_01(<4 x float> %a, <4 x float> %b) {
1929; SSE2-LABEL: combine_blend_01:
1930; SSE2:       # %bb.0:
1931; SSE2-NEXT:    movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]
1932; SSE2-NEXT:    retq
1933;
1934; SSSE3-LABEL: combine_blend_01:
1935; SSSE3:       # %bb.0:
1936; SSSE3-NEXT:    movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]
1937; SSSE3-NEXT:    retq
1938;
1939; SSE41-LABEL: combine_blend_01:
1940; SSE41:       # %bb.0:
1941; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3]
1942; SSE41-NEXT:    retq
1943;
1944; AVX-LABEL: combine_blend_01:
1945; AVX:       # %bb.0:
1946; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3]
1947; AVX-NEXT:    retq
1948  %shuffle = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 undef, i32 2, i32 3>
1949  %shuffle6 = shufflevector <4 x float> %shuffle, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 3>
1950  ret <4 x float> %shuffle6
1951}
1952
1953define <4 x float> @combine_blend_02(<4 x float> %a, <4 x float> %b) {
1954; SSE2-LABEL: combine_blend_02:
1955; SSE2:       # %bb.0:
1956; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,2],xmm0[1,3]
1957; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,2,1,3]
1958; SSE2-NEXT:    movaps %xmm1, %xmm0
1959; SSE2-NEXT:    retq
1960;
1961; SSSE3-LABEL: combine_blend_02:
1962; SSSE3:       # %bb.0:
1963; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,2],xmm0[1,3]
1964; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,2,1,3]
1965; SSSE3-NEXT:    movaps %xmm1, %xmm0
1966; SSSE3-NEXT:    retq
1967;
1968; SSE41-LABEL: combine_blend_02:
1969; SSE41:       # %bb.0:
1970; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2],xmm0[3]
1971; SSE41-NEXT:    retq
1972;
1973; AVX-LABEL: combine_blend_02:
1974; AVX:       # %bb.0:
1975; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0],xmm0[1],xmm1[2],xmm0[3]
1976; AVX-NEXT:    retq
1977  %shuffle = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 undef, i32 3>
1978  %shuffle6 = shufflevector <4 x float> %shuffle, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 6, i32 3>
1979  ret <4 x float> %shuffle6
1980}
1981
1982define <4 x float> @combine_blend_123(<4 x float> %a, <4 x float> %b) {
1983; SSE2-LABEL: combine_blend_123:
1984; SSE2:       # %bb.0:
1985; SSE2-NEXT:    movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]
1986; SSE2-NEXT:    movaps %xmm1, %xmm0
1987; SSE2-NEXT:    retq
1988;
1989; SSSE3-LABEL: combine_blend_123:
1990; SSSE3:       # %bb.0:
1991; SSSE3-NEXT:    movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]
1992; SSSE3-NEXT:    movaps %xmm1, %xmm0
1993; SSSE3-NEXT:    retq
1994;
1995; SSE41-LABEL: combine_blend_123:
1996; SSE41:       # %bb.0:
1997; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]
1998; SSE41-NEXT:    retq
1999;
2000; AVX-LABEL: combine_blend_123:
2001; AVX:       # %bb.0:
2002; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]
2003; AVX-NEXT:    retq
2004  %shuffle = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 undef, i32 undef>
2005  %shuffle6 = shufflevector <4 x float> %shuffle, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 6, i32 undef>
2006  %shuffle12 = shufflevector <4 x float> %shuffle6, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 2, i32 7>
2007  ret <4 x float> %shuffle12
2008}
2009
2010define <4 x i32> @combine_test_movhl_1(<4 x i32> %a, <4 x i32> %b) {
2011; SSE-LABEL: combine_test_movhl_1:
2012; SSE:       # %bb.0:
2013; SSE-NEXT:    unpckhpd {{.*#+}} xmm1 = xmm1[1],xmm0[1]
2014; SSE-NEXT:    movaps %xmm1, %xmm0
2015; SSE-NEXT:    retq
2016;
2017; AVX-LABEL: combine_test_movhl_1:
2018; AVX:       # %bb.0:
2019; AVX-NEXT:    vunpckhpd {{.*#+}} xmm0 = xmm1[1],xmm0[1]
2020; AVX-NEXT:    retq
2021  %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 2, i32 7, i32 5, i32 3>
2022  %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 6, i32 1, i32 0, i32 3>
2023  ret <4 x i32> %2
2024}
2025
2026define <4 x i32> @combine_test_movhl_2(<4 x i32> %a, <4 x i32> %b) {
2027; SSE-LABEL: combine_test_movhl_2:
2028; SSE:       # %bb.0:
2029; SSE-NEXT:    unpckhpd {{.*#+}} xmm1 = xmm1[1],xmm0[1]
2030; SSE-NEXT:    movaps %xmm1, %xmm0
2031; SSE-NEXT:    retq
2032;
2033; AVX-LABEL: combine_test_movhl_2:
2034; AVX:       # %bb.0:
2035; AVX-NEXT:    vunpckhpd {{.*#+}} xmm0 = xmm1[1],xmm0[1]
2036; AVX-NEXT:    retq
2037  %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 2, i32 0, i32 3, i32 6>
2038  %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 3, i32 7, i32 0, i32 2>
2039  ret <4 x i32> %2
2040}
2041
2042define <4 x i32> @combine_test_movhl_3(<4 x i32> %a, <4 x i32> %b) {
2043; SSE-LABEL: combine_test_movhl_3:
2044; SSE:       # %bb.0:
2045; SSE-NEXT:    unpckhpd {{.*#+}} xmm1 = xmm1[1],xmm0[1]
2046; SSE-NEXT:    movaps %xmm1, %xmm0
2047; SSE-NEXT:    retq
2048;
2049; AVX-LABEL: combine_test_movhl_3:
2050; AVX:       # %bb.0:
2051; AVX-NEXT:    vunpckhpd {{.*#+}} xmm0 = xmm1[1],xmm0[1]
2052; AVX-NEXT:    retq
2053  %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 7, i32 6, i32 3, i32 2>
2054  %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 6, i32 0, i32 3, i32 2>
2055  ret <4 x i32> %2
2056}
2057
2058
2059; Verify that we fold shuffles according to rule:
2060;  (shuffle(shuffle A, Undef, M0), B, M1) -> (shuffle A, B, M2)
2061
2062define <4 x float> @combine_undef_input_test1(<4 x float> %a, <4 x float> %b) {
2063; SSE2-LABEL: combine_undef_input_test1:
2064; SSE2:       # %bb.0:
2065; SSE2-NEXT:    movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]
2066; SSE2-NEXT:    retq
2067;
2068; SSSE3-LABEL: combine_undef_input_test1:
2069; SSSE3:       # %bb.0:
2070; SSSE3-NEXT:    movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]
2071; SSSE3-NEXT:    retq
2072;
2073; SSE41-LABEL: combine_undef_input_test1:
2074; SSE41:       # %bb.0:
2075; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3]
2076; SSE41-NEXT:    retq
2077;
2078; AVX-LABEL: combine_undef_input_test1:
2079; AVX:       # %bb.0:
2080; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3]
2081; AVX-NEXT:    retq
2082  %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 4, i32 2, i32 3, i32 1>
2083  %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 4, i32 5, i32 1, i32 2>
2084  ret <4 x float> %2
2085}
2086
2087define <4 x float> @combine_undef_input_test2(<4 x float> %a, <4 x float> %b) {
2088; SSE-LABEL: combine_undef_input_test2:
2089; SSE:       # %bb.0:
2090; SSE-NEXT:    movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]
2091; SSE-NEXT:    retq
2092;
2093; AVX-LABEL: combine_undef_input_test2:
2094; AVX:       # %bb.0:
2095; AVX-NEXT:    vmovlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]
2096; AVX-NEXT:    retq
2097  %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 6, i32 0, i32 1, i32 7>
2098  %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 1, i32 2, i32 4, i32 5>
2099  ret <4 x float> %2
2100}
2101
2102define <4 x float> @combine_undef_input_test3(<4 x float> %a, <4 x float> %b) {
2103; SSE-LABEL: combine_undef_input_test3:
2104; SSE:       # %bb.0:
2105; SSE-NEXT:    movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]
2106; SSE-NEXT:    retq
2107;
2108; AVX-LABEL: combine_undef_input_test3:
2109; AVX:       # %bb.0:
2110; AVX-NEXT:    vmovlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]
2111; AVX-NEXT:    retq
2112  %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 5, i32 1, i32 7>
2113  %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 2, i32 4, i32 1>
2114  ret <4 x float> %2
2115}
2116
2117define <4 x float> @combine_undef_input_test4(<4 x float> %a, <4 x float> %b) {
2118; SSE-LABEL: combine_undef_input_test4:
2119; SSE:       # %bb.0:
2120; SSE-NEXT:    movhlps {{.*#+}} xmm0 = xmm1[1],xmm0[1]
2121; SSE-NEXT:    retq
2122;
2123; AVX-LABEL: combine_undef_input_test4:
2124; AVX:       # %bb.0:
2125; AVX-NEXT:    vunpckhpd {{.*#+}} xmm0 = xmm1[1],xmm0[1]
2126; AVX-NEXT:    retq
2127  %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 2, i32 3, i32 5, i32 5>
2128  %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 6, i32 7, i32 0, i32 1>
2129  ret <4 x float> %2
2130}
2131
2132define <4 x float> @combine_undef_input_test5(<4 x float> %a, <4 x float> %b) {
2133; SSE2-LABEL: combine_undef_input_test5:
2134; SSE2:       # %bb.0:
2135; SSE2-NEXT:    movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1]
2136; SSE2-NEXT:    movapd %xmm1, %xmm0
2137; SSE2-NEXT:    retq
2138;
2139; SSSE3-LABEL: combine_undef_input_test5:
2140; SSSE3:       # %bb.0:
2141; SSSE3-NEXT:    movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1]
2142; SSSE3-NEXT:    movapd %xmm1, %xmm0
2143; SSSE3-NEXT:    retq
2144;
2145; SSE41-LABEL: combine_undef_input_test5:
2146; SSE41:       # %bb.0:
2147; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]
2148; SSE41-NEXT:    retq
2149;
2150; AVX-LABEL: combine_undef_input_test5:
2151; AVX:       # %bb.0:
2152; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]
2153; AVX-NEXT:    retq
2154  %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 4, i32 1, i32 3>
2155  %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 2, i32 6, i32 7>
2156  ret <4 x float> %2
2157}
2158
2159
2160; Verify that we fold shuffles according to rule:
2161;  (shuffle(shuffle A, Undef, M0), A, M1) -> (shuffle A, Undef, M2)
2162
2163define <4 x float> @combine_undef_input_test6(<4 x float> %a) {
2164; ALL-LABEL: combine_undef_input_test6:
2165; ALL:       # %bb.0:
2166; ALL-NEXT:    retq
2167  %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 4, i32 2, i32 3, i32 1>
2168  %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 4, i32 5, i32 1, i32 2>
2169  ret <4 x float> %2
2170}
2171
2172define <4 x float> @combine_undef_input_test7(<4 x float> %a) {
2173; SSE2-LABEL: combine_undef_input_test7:
2174; SSE2:       # %bb.0:
2175; SSE2-NEXT:    movlhps {{.*#+}} xmm0 = xmm0[0,0]
2176; SSE2-NEXT:    retq
2177;
2178; SSSE3-LABEL: combine_undef_input_test7:
2179; SSSE3:       # %bb.0:
2180; SSSE3-NEXT:    movddup {{.*#+}} xmm0 = xmm0[0,0]
2181; SSSE3-NEXT:    retq
2182;
2183; SSE41-LABEL: combine_undef_input_test7:
2184; SSE41:       # %bb.0:
2185; SSE41-NEXT:    movddup {{.*#+}} xmm0 = xmm0[0,0]
2186; SSE41-NEXT:    retq
2187;
2188; AVX-LABEL: combine_undef_input_test7:
2189; AVX:       # %bb.0:
2190; AVX-NEXT:    vmovddup {{.*#+}} xmm0 = xmm0[0,0]
2191; AVX-NEXT:    retq
2192  %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 6, i32 0, i32 1, i32 7>
2193  %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 1, i32 2, i32 4, i32 5>
2194  ret <4 x float> %2
2195}
2196
2197define <4 x float> @combine_undef_input_test8(<4 x float> %a) {
2198; SSE2-LABEL: combine_undef_input_test8:
2199; SSE2:       # %bb.0:
2200; SSE2-NEXT:    movlhps {{.*#+}} xmm0 = xmm0[0,0]
2201; SSE2-NEXT:    retq
2202;
2203; SSSE3-LABEL: combine_undef_input_test8:
2204; SSSE3:       # %bb.0:
2205; SSSE3-NEXT:    movddup {{.*#+}} xmm0 = xmm0[0,0]
2206; SSSE3-NEXT:    retq
2207;
2208; SSE41-LABEL: combine_undef_input_test8:
2209; SSE41:       # %bb.0:
2210; SSE41-NEXT:    movddup {{.*#+}} xmm0 = xmm0[0,0]
2211; SSE41-NEXT:    retq
2212;
2213; AVX-LABEL: combine_undef_input_test8:
2214; AVX:       # %bb.0:
2215; AVX-NEXT:    vmovddup {{.*#+}} xmm0 = xmm0[0,0]
2216; AVX-NEXT:    retq
2217  %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 5, i32 1, i32 7>
2218  %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 0, i32 2, i32 4, i32 1>
2219  ret <4 x float> %2
2220}
2221
2222define <4 x float> @combine_undef_input_test9(<4 x float> %a) {
2223; SSE-LABEL: combine_undef_input_test9:
2224; SSE:       # %bb.0:
2225; SSE-NEXT:    movhlps {{.*#+}} xmm0 = xmm0[1,1]
2226; SSE-NEXT:    retq
2227;
2228; AVX-LABEL: combine_undef_input_test9:
2229; AVX:       # %bb.0:
2230; AVX-NEXT:    vpermilpd {{.*#+}} xmm0 = xmm0[1,1]
2231; AVX-NEXT:    retq
2232  %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 2, i32 3, i32 5, i32 5>
2233  %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 6, i32 7, i32 0, i32 1>
2234  ret <4 x float> %2
2235}
2236
2237define <4 x float> @combine_undef_input_test10(<4 x float> %a) {
2238; ALL-LABEL: combine_undef_input_test10:
2239; ALL:       # %bb.0:
2240; ALL-NEXT:    retq
2241  %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 4, i32 1, i32 3>
2242  %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 0, i32 2, i32 6, i32 7>
2243  ret <4 x float> %2
2244}
2245
2246define <4 x float> @combine_undef_input_test11(<4 x float> %a, <4 x float> %b) {
2247; SSE2-LABEL: combine_undef_input_test11:
2248; SSE2:       # %bb.0:
2249; SSE2-NEXT:    movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]
2250; SSE2-NEXT:    retq
2251;
2252; SSSE3-LABEL: combine_undef_input_test11:
2253; SSSE3:       # %bb.0:
2254; SSSE3-NEXT:    movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]
2255; SSSE3-NEXT:    retq
2256;
2257; SSE41-LABEL: combine_undef_input_test11:
2258; SSE41:       # %bb.0:
2259; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3]
2260; SSE41-NEXT:    retq
2261;
2262; AVX-LABEL: combine_undef_input_test11:
2263; AVX:       # %bb.0:
2264; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm1[0,1],xmm0[2,3]
2265; AVX-NEXT:    retq
2266  %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 4, i32 2, i32 3, i32 1>
2267  %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 0, i32 1, i32 5, i32 6>
2268  ret <4 x float> %2
2269}
2270
2271define <4 x float> @combine_undef_input_test12(<4 x float> %a, <4 x float> %b) {
2272; SSE-LABEL: combine_undef_input_test12:
2273; SSE:       # %bb.0:
2274; SSE-NEXT:    movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]
2275; SSE-NEXT:    retq
2276;
2277; AVX-LABEL: combine_undef_input_test12:
2278; AVX:       # %bb.0:
2279; AVX-NEXT:    vmovlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]
2280; AVX-NEXT:    retq
2281  %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 6, i32 0, i32 1, i32 7>
2282  %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 5, i32 6, i32 0, i32 1>
2283  ret <4 x float> %2
2284}
2285
2286define <4 x float> @combine_undef_input_test13(<4 x float> %a, <4 x float> %b) {
2287; SSE-LABEL: combine_undef_input_test13:
2288; SSE:       # %bb.0:
2289; SSE-NEXT:    movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]
2290; SSE-NEXT:    retq
2291;
2292; AVX-LABEL: combine_undef_input_test13:
2293; AVX:       # %bb.0:
2294; AVX-NEXT:    vmovlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]
2295; AVX-NEXT:    retq
2296  %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 5, i32 1, i32 7>
2297  %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 4, i32 5, i32 0, i32 5>
2298  ret <4 x float> %2
2299}
2300
2301define <4 x float> @combine_undef_input_test14(<4 x float> %a, <4 x float> %b) {
2302; SSE-LABEL: combine_undef_input_test14:
2303; SSE:       # %bb.0:
2304; SSE-NEXT:    movhlps {{.*#+}} xmm0 = xmm1[1],xmm0[1]
2305; SSE-NEXT:    retq
2306;
2307; AVX-LABEL: combine_undef_input_test14:
2308; AVX:       # %bb.0:
2309; AVX-NEXT:    vunpckhpd {{.*#+}} xmm0 = xmm1[1],xmm0[1]
2310; AVX-NEXT:    retq
2311  %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 2, i32 3, i32 5, i32 5>
2312  %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 2, i32 3, i32 4, i32 5>
2313  ret <4 x float> %2
2314}
2315
2316define <4 x float> @combine_undef_input_test15(<4 x float> %a, <4 x float> %b) {
2317; SSE2-LABEL: combine_undef_input_test15:
2318; SSE2:       # %bb.0:
2319; SSE2-NEXT:    movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1]
2320; SSE2-NEXT:    movapd %xmm1, %xmm0
2321; SSE2-NEXT:    retq
2322;
2323; SSSE3-LABEL: combine_undef_input_test15:
2324; SSSE3:       # %bb.0:
2325; SSSE3-NEXT:    movsd {{.*#+}} xmm1 = xmm0[0],xmm1[1]
2326; SSSE3-NEXT:    movapd %xmm1, %xmm0
2327; SSSE3-NEXT:    retq
2328;
2329; SSE41-LABEL: combine_undef_input_test15:
2330; SSE41:       # %bb.0:
2331; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]
2332; SSE41-NEXT:    retq
2333;
2334; AVX-LABEL: combine_undef_input_test15:
2335; AVX:       # %bb.0:
2336; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3]
2337; AVX-NEXT:    retq
2338  %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 4, i32 1, i32 3>
2339  %2 = shufflevector <4 x float> %b, <4 x float> %1, <4 x i32> <i32 4, i32 6, i32 2, i32 3>
2340  ret <4 x float> %2
2341}
2342
2343
2344; Verify that shuffles are canonicalized according to rules:
2345;  shuffle(B, shuffle(A, Undef)) -> shuffle(shuffle(A, Undef), B)
2346;
2347; This allows to trigger the following combine rule:
2348;  (shuffle(shuffle A, Undef, M0), A, M1) -> (shuffle A, Undef, M2)
2349;
2350; As a result, all the shuffle pairs in each function below should be
2351; combined into a single legal shuffle operation.
2352
2353define <4 x float> @combine_undef_input_test16(<4 x float> %a) {
2354; ALL-LABEL: combine_undef_input_test16:
2355; ALL:       # %bb.0:
2356; ALL-NEXT:    retq
2357  %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 4, i32 2, i32 3, i32 1>
2358  %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 0, i32 1, i32 5, i32 3>
2359  ret <4 x float> %2
2360}
2361
2362define <4 x float> @combine_undef_input_test17(<4 x float> %a) {
2363; SSE2-LABEL: combine_undef_input_test17:
2364; SSE2:       # %bb.0:
2365; SSE2-NEXT:    movlhps {{.*#+}} xmm0 = xmm0[0,0]
2366; SSE2-NEXT:    retq
2367;
2368; SSSE3-LABEL: combine_undef_input_test17:
2369; SSSE3:       # %bb.0:
2370; SSSE3-NEXT:    movddup {{.*#+}} xmm0 = xmm0[0,0]
2371; SSSE3-NEXT:    retq
2372;
2373; SSE41-LABEL: combine_undef_input_test17:
2374; SSE41:       # %bb.0:
2375; SSE41-NEXT:    movddup {{.*#+}} xmm0 = xmm0[0,0]
2376; SSE41-NEXT:    retq
2377;
2378; AVX-LABEL: combine_undef_input_test17:
2379; AVX:       # %bb.0:
2380; AVX-NEXT:    vmovddup {{.*#+}} xmm0 = xmm0[0,0]
2381; AVX-NEXT:    retq
2382  %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 6, i32 0, i32 1, i32 7>
2383  %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 5, i32 6, i32 0, i32 1>
2384  ret <4 x float> %2
2385}
2386
2387define <4 x float> @combine_undef_input_test18(<4 x float> %a) {
2388; SSE2-LABEL: combine_undef_input_test18:
2389; SSE2:       # %bb.0:
2390; SSE2-NEXT:    movlhps {{.*#+}} xmm0 = xmm0[0,0]
2391; SSE2-NEXT:    retq
2392;
2393; SSSE3-LABEL: combine_undef_input_test18:
2394; SSSE3:       # %bb.0:
2395; SSSE3-NEXT:    movddup {{.*#+}} xmm0 = xmm0[0,0]
2396; SSSE3-NEXT:    retq
2397;
2398; SSE41-LABEL: combine_undef_input_test18:
2399; SSE41:       # %bb.0:
2400; SSE41-NEXT:    movddup {{.*#+}} xmm0 = xmm0[0,0]
2401; SSE41-NEXT:    retq
2402;
2403; AVX-LABEL: combine_undef_input_test18:
2404; AVX:       # %bb.0:
2405; AVX-NEXT:    vmovddup {{.*#+}} xmm0 = xmm0[0,0]
2406; AVX-NEXT:    retq
2407  %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 5, i32 1, i32 7>
2408  %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 4, i32 6, i32 0, i32 5>
2409  ret <4 x float> %2
2410}
2411
2412define <4 x float> @combine_undef_input_test19(<4 x float> %a) {
2413; SSE-LABEL: combine_undef_input_test19:
2414; SSE:       # %bb.0:
2415; SSE-NEXT:    movhlps {{.*#+}} xmm0 = xmm0[1,1]
2416; SSE-NEXT:    retq
2417;
2418; AVX-LABEL: combine_undef_input_test19:
2419; AVX:       # %bb.0:
2420; AVX-NEXT:    vpermilpd {{.*#+}} xmm0 = xmm0[1,1]
2421; AVX-NEXT:    retq
2422  %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 2, i32 3, i32 5, i32 5>
2423  %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 2, i32 3, i32 4, i32 5>
2424  ret <4 x float> %2
2425}
2426
2427define <4 x float> @combine_undef_input_test20(<4 x float> %a) {
2428; ALL-LABEL: combine_undef_input_test20:
2429; ALL:       # %bb.0:
2430; ALL-NEXT:    retq
2431  %1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 4, i32 1, i32 3>
2432  %2 = shufflevector <4 x float> %a, <4 x float> %1, <4 x i32> <i32 4, i32 6, i32 2, i32 3>
2433  ret <4 x float> %2
2434}
2435
2436; These tests are designed to test the ability to combine away unnecessary
2437; operations feeding into a shuffle. The AVX cases are the important ones as
2438; they leverage operations which cannot be done naturally on the entire vector
2439; and thus are decomposed into multiple smaller operations.
2440
2441define <8 x i32> @combine_unneeded_subvector1(<8 x i32> %a) {
2442; SSE-LABEL: combine_unneeded_subvector1:
2443; SSE:       # %bb.0:
2444; SSE-NEXT:    paddd {{.*}}(%rip), %xmm1
2445; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[3,2,1,0]
2446; SSE-NEXT:    movdqa %xmm0, %xmm1
2447; SSE-NEXT:    retq
2448;
2449; AVX1-LABEL: combine_unneeded_subvector1:
2450; AVX1:       # %bb.0:
2451; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
2452; AVX1-NEXT:    vpaddd {{.*}}(%rip), %xmm0, %xmm0
2453; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm0, %ymm0
2454; AVX1-NEXT:    vpermilps {{.*#+}} ymm0 = ymm0[3,2,1,0,7,6,5,4]
2455; AVX1-NEXT:    vperm2f128 {{.*#+}} ymm0 = ymm0[2,3,2,3]
2456; AVX1-NEXT:    retq
2457;
2458; AVX2-SLOW-LABEL: combine_unneeded_subvector1:
2459; AVX2-SLOW:       # %bb.0:
2460; AVX2-SLOW-NEXT:    vpaddd {{.*}}(%rip), %ymm0, %ymm0
2461; AVX2-SLOW-NEXT:    vpshufd {{.*#+}} ymm0 = ymm0[3,2,1,0,7,6,5,4]
2462; AVX2-SLOW-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[2,3,2,3]
2463; AVX2-SLOW-NEXT:    retq
2464;
2465; AVX2-FAST-LABEL: combine_unneeded_subvector1:
2466; AVX2-FAST:       # %bb.0:
2467; AVX2-FAST-NEXT:    vpaddd {{.*}}(%rip), %ymm0, %ymm0
2468; AVX2-FAST-NEXT:    vmovdqa {{.*#+}} ymm1 = [7,6,5,4,7,6,5,4]
2469; AVX2-FAST-NEXT:    vpermd %ymm0, %ymm1, %ymm0
2470; AVX2-FAST-NEXT:    retq
2471  %b = add <8 x i32> %a, <i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8>
2472  %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>
2473  ret <8 x i32> %c
2474}
2475
2476define <8 x i32> @combine_unneeded_subvector2(<8 x i32> %a, <8 x i32> %b) {
2477; SSE-LABEL: combine_unneeded_subvector2:
2478; SSE:       # %bb.0:
2479; SSE-NEXT:    paddd {{.*}}(%rip), %xmm1
2480; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[3,2,1,0]
2481; SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[3,2,1,0]
2482; SSE-NEXT:    retq
2483;
2484; AVX1-LABEL: combine_unneeded_subvector2:
2485; AVX1:       # %bb.0:
2486; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
2487; AVX1-NEXT:    vpaddd {{.*}}(%rip), %xmm0, %xmm0
2488; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm0, %ymm0
2489; AVX1-NEXT:    vperm2f128 {{.*#+}} ymm0 = ymm1[2,3],ymm0[2,3]
2490; AVX1-NEXT:    vpermilps {{.*#+}} ymm0 = ymm0[3,2,1,0,7,6,5,4]
2491; AVX1-NEXT:    retq
2492;
2493; AVX2-LABEL: combine_unneeded_subvector2:
2494; AVX2:       # %bb.0:
2495; AVX2-NEXT:    vpaddd {{.*}}(%rip), %ymm0, %ymm0
2496; AVX2-NEXT:    vperm2i128 {{.*#+}} ymm0 = ymm1[2,3],ymm0[2,3]
2497; AVX2-NEXT:    vpshufd {{.*#+}} ymm0 = ymm0[3,2,1,0,7,6,5,4]
2498; AVX2-NEXT:    retq
2499  %c = add <8 x i32> %a, <i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8>
2500  %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>
2501  ret <8 x i32> %d
2502}
2503
2504define <4 x float> @combine_insertps1(<4 x float> %a, <4 x float> %b) {
2505; SSE2-LABEL: combine_insertps1:
2506; SSE2:       # %bb.0:
2507; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[1,0]
2508; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,2],xmm0[2,3]
2509; SSE2-NEXT:    movaps %xmm1, %xmm0
2510; SSE2-NEXT:    retq
2511;
2512; SSSE3-LABEL: combine_insertps1:
2513; SSSE3:       # %bb.0:
2514; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[1,0]
2515; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,2],xmm0[2,3]
2516; SSSE3-NEXT:    movaps %xmm1, %xmm0
2517; SSSE3-NEXT:    retq
2518;
2519; SSE41-LABEL: combine_insertps1:
2520; SSE41:       # %bb.0:
2521; SSE41-NEXT:    insertps {{.*#+}} xmm0 = xmm1[2],xmm0[1,2,3]
2522; SSE41-NEXT:    retq
2523;
2524; AVX-LABEL: combine_insertps1:
2525; AVX:       # %bb.0:
2526; AVX-NEXT:    vinsertps {{.*#+}} xmm0 = xmm1[2],xmm0[1,2,3]
2527; AVX-NEXT:    retq
2528
2529  %c = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32><i32 0, i32 6, i32 2, i32 4>
2530  %d = shufflevector <4 x float> %a, <4 x float> %c, <4 x i32> <i32 5, i32 1, i32 6, i32 3>
2531  ret <4 x float> %d
2532}
2533
2534define <4 x float> @combine_insertps2(<4 x float> %a, <4 x float> %b) {
2535; SSE2-LABEL: combine_insertps2:
2536; SSE2:       # %bb.0:
2537; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[0,0]
2538; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[2,3]
2539; SSE2-NEXT:    movaps %xmm1, %xmm0
2540; SSE2-NEXT:    retq
2541;
2542; SSSE3-LABEL: combine_insertps2:
2543; SSSE3:       # %bb.0:
2544; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[0,0]
2545; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[2,3]
2546; SSSE3-NEXT:    movaps %xmm1, %xmm0
2547; SSSE3-NEXT:    retq
2548;
2549; SSE41-LABEL: combine_insertps2:
2550; SSE41:       # %bb.0:
2551; SSE41-NEXT:    insertps {{.*#+}} xmm0 = xmm0[0],xmm1[2],xmm0[2,3]
2552; SSE41-NEXT:    retq
2553;
2554; AVX-LABEL: combine_insertps2:
2555; AVX:       # %bb.0:
2556; AVX-NEXT:    vinsertps {{.*#+}} xmm0 = xmm0[0],xmm1[2],xmm0[2,3]
2557; AVX-NEXT:    retq
2558
2559  %c = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32><i32 0, i32 1, i32 6, i32 7>
2560  %d = shufflevector <4 x float> %a, <4 x float> %c, <4 x i32> <i32 4, i32 6, i32 2, i32 3>
2561  ret <4 x float> %d
2562}
2563
2564define <4 x float> @combine_insertps3(<4 x float> %a, <4 x float> %b) {
2565; SSE2-LABEL: combine_insertps3:
2566; SSE2:       # %bb.0:
2567; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[3,0]
2568; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0,2]
2569; SSE2-NEXT:    retq
2570;
2571; SSSE3-LABEL: combine_insertps3:
2572; SSSE3:       # %bb.0:
2573; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[3,0]
2574; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0,2]
2575; SSSE3-NEXT:    retq
2576;
2577; SSE41-LABEL: combine_insertps3:
2578; SSE41:       # %bb.0:
2579; SSE41-NEXT:    insertps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0],xmm0[3]
2580; SSE41-NEXT:    retq
2581;
2582; AVX-LABEL: combine_insertps3:
2583; AVX:       # %bb.0:
2584; AVX-NEXT:    vinsertps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0],xmm0[3]
2585; AVX-NEXT:    retq
2586
2587  %c = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32><i32 0, i32 4, i32 2, i32 5>
2588  %d = shufflevector <4 x float> %a, <4 x float> %c, <4 x i32><i32 4, i32 1, i32 5, i32 3>
2589  ret <4 x float> %d
2590}
2591
2592define <4 x float> @combine_insertps4(<4 x float> %a, <4 x float> %b) {
2593; SSE2-LABEL: combine_insertps4:
2594; SSE2:       # %bb.0:
2595; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[2,0]
2596; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,0]
2597; SSE2-NEXT:    retq
2598;
2599; SSSE3-LABEL: combine_insertps4:
2600; SSSE3:       # %bb.0:
2601; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[2,0]
2602; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,0]
2603; SSSE3-NEXT:    retq
2604;
2605; SSE41-LABEL: combine_insertps4:
2606; SSE41:       # %bb.0:
2607; SSE41-NEXT:    insertps {{.*#+}} xmm0 = xmm0[0,1,2],xmm1[0]
2608; SSE41-NEXT:    retq
2609;
2610; AVX-LABEL: combine_insertps4:
2611; AVX:       # %bb.0:
2612; AVX-NEXT:    vinsertps {{.*#+}} xmm0 = xmm0[0,1,2],xmm1[0]
2613; AVX-NEXT:    retq
2614
2615  %c = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32><i32 0, i32 4, i32 2, i32 5>
2616  %d = shufflevector <4 x float> %a, <4 x float> %c, <4 x i32><i32 4, i32 1, i32 6, i32 5>
2617  ret <4 x float> %d
2618}
2619
2620define void @combine_scalar_load_with_blend_with_zero(double* %a0, <4 x float>* %a1) {
2621; SSE-LABEL: combine_scalar_load_with_blend_with_zero:
2622; SSE:       # %bb.0:
2623; SSE-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
2624; SSE-NEXT:    movaps %xmm0, (%rsi)
2625; SSE-NEXT:    retq
2626;
2627; AVX-LABEL: combine_scalar_load_with_blend_with_zero:
2628; AVX:       # %bb.0:
2629; AVX-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
2630; AVX-NEXT:    vmovaps %xmm0, (%rsi)
2631; AVX-NEXT:    retq
2632  %1 = load double, double* %a0, align 8
2633  %2 = insertelement <2 x double> undef, double %1, i32 0
2634  %3 = insertelement <2 x double> %2, double 0.000000e+00, i32 1
2635  %4 = bitcast <2 x double> %3 to <4 x float>
2636  %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>
2637  store <4 x float> %5, <4 x float>* %a1, align 16
2638  ret void
2639}
2640
2641; PR30371
2642define <4 x float> @combine_constant_insertion_v4f32(float %f) {
2643; SSE2-LABEL: combine_constant_insertion_v4f32:
2644; SSE2:       # %bb.0:
2645; SSE2-NEXT:    movaps {{.*#+}} xmm1 = <u,4.0E+0,5.0E+0,3.0E+0>
2646; SSE2-NEXT:    movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]
2647; SSE2-NEXT:    movaps %xmm1, %xmm0
2648; SSE2-NEXT:    retq
2649;
2650; SSSE3-LABEL: combine_constant_insertion_v4f32:
2651; SSSE3:       # %bb.0:
2652; SSSE3-NEXT:    movaps {{.*#+}} xmm1 = <u,4.0E+0,5.0E+0,3.0E+0>
2653; SSSE3-NEXT:    movss {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]
2654; SSSE3-NEXT:    movaps %xmm1, %xmm0
2655; SSSE3-NEXT:    retq
2656;
2657; SSE41-LABEL: combine_constant_insertion_v4f32:
2658; SSE41:       # %bb.0:
2659; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm0[0],mem[1,2,3]
2660; SSE41-NEXT:    retq
2661;
2662; AVX-LABEL: combine_constant_insertion_v4f32:
2663; AVX:       # %bb.0:
2664; AVX-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0],mem[1,2,3]
2665; AVX-NEXT:    retq
2666  %a0 = insertelement <4 x float> undef, float %f, i32 0
2667  %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>
2668  ret <4 x float> %ret
2669}
2670
2671define <4 x i32> @combine_constant_insertion_v4i32(i32 %f) {
2672; SSE2-LABEL: combine_constant_insertion_v4i32:
2673; SSE2:       # %bb.0:
2674; SSE2-NEXT:    movd %edi, %xmm1
2675; SSE2-NEXT:    movaps {{.*#+}} xmm0 = <u,4,5,30>
2676; SSE2-NEXT:    movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]
2677; SSE2-NEXT:    retq
2678;
2679; SSSE3-LABEL: combine_constant_insertion_v4i32:
2680; SSSE3:       # %bb.0:
2681; SSSE3-NEXT:    movd %edi, %xmm1
2682; SSSE3-NEXT:    movaps {{.*#+}} xmm0 = <u,4,5,30>
2683; SSSE3-NEXT:    movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]
2684; SSSE3-NEXT:    retq
2685;
2686; SSE41-LABEL: combine_constant_insertion_v4i32:
2687; SSE41:       # %bb.0:
2688; SSE41-NEXT:    movdqa {{.*#+}} xmm0 = <u,4,5,30>
2689; SSE41-NEXT:    pinsrd $0, %edi, %xmm0
2690; SSE41-NEXT:    retq
2691;
2692; AVX-LABEL: combine_constant_insertion_v4i32:
2693; AVX:       # %bb.0:
2694; AVX-NEXT:    vmovdqa {{.*#+}} xmm0 = <u,4,5,30>
2695; AVX-NEXT:    vpinsrd $0, %edi, %xmm0, %xmm0
2696; AVX-NEXT:    retq
2697  %a0 = insertelement <4 x i32> undef, i32 %f, i32 0
2698  %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>
2699  ret <4 x i32> %ret
2700}
2701
2702define <4 x float> @PR22377(<4 x float> %a, <4 x float> %b) {
2703; SSE-LABEL: PR22377:
2704; SSE:       # %bb.0: # %entry
2705; SSE-NEXT:    movaps %xmm0, %xmm1
2706; SSE-NEXT:    shufps {{.*#+}} xmm1 = xmm1[1,3],xmm0[2,3]
2707; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2,0,2]
2708; SSE-NEXT:    addps %xmm0, %xmm1
2709; SSE-NEXT:    unpcklps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
2710; SSE-NEXT:    retq
2711;
2712; AVX-LABEL: PR22377:
2713; AVX:       # %bb.0: # %entry
2714; AVX-NEXT:    vpermilps {{.*#+}} xmm1 = xmm0[1,3,2,3]
2715; AVX-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[0,2,0,2]
2716; AVX-NEXT:    vaddps %xmm0, %xmm1, %xmm1
2717; AVX-NEXT:    vunpcklps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
2718; AVX-NEXT:    retq
2719entry:
2720  %s1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 1, i32 3, i32 1, i32 3>
2721  %s2 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 0, i32 2, i32 0, i32 2>
2722  %r2 = fadd <4 x float> %s1, %s2
2723  %s3 = shufflevector <4 x float> %s2, <4 x float> %r2, <4 x i32> <i32 0, i32 4, i32 1, i32 5>
2724  ret <4 x float> %s3
2725}
2726
2727define <4 x float> @PR22390(<4 x float> %a, <4 x float> %b) {
2728; SSE2-LABEL: PR22390:
2729; SSE2:       # %bb.0: # %entry
2730; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,0,1,2]
2731; SSE2-NEXT:    movaps %xmm0, %xmm2
2732; SSE2-NEXT:    movss {{.*#+}} xmm2 = xmm1[0],xmm2[1,2,3]
2733; SSE2-NEXT:    addps %xmm0, %xmm2
2734; SSE2-NEXT:    movaps %xmm2, %xmm0
2735; SSE2-NEXT:    retq
2736;
2737; SSSE3-LABEL: PR22390:
2738; SSSE3:       # %bb.0: # %entry
2739; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,0,1,2]
2740; SSSE3-NEXT:    movaps %xmm0, %xmm2
2741; SSSE3-NEXT:    movss {{.*#+}} xmm2 = xmm1[0],xmm2[1,2,3]
2742; SSSE3-NEXT:    addps %xmm0, %xmm2
2743; SSSE3-NEXT:    movaps %xmm2, %xmm0
2744; SSSE3-NEXT:    retq
2745;
2746; SSE41-LABEL: PR22390:
2747; SSE41:       # %bb.0: # %entry
2748; SSE41-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,0,1,2]
2749; SSE41-NEXT:    blendps {{.*#+}} xmm1 = xmm1[0],xmm0[1,2,3]
2750; SSE41-NEXT:    addps %xmm1, %xmm0
2751; SSE41-NEXT:    retq
2752;
2753; AVX-LABEL: PR22390:
2754; AVX:       # %bb.0: # %entry
2755; AVX-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[3,0,1,2]
2756; AVX-NEXT:    vblendps {{.*#+}} xmm1 = xmm1[0],xmm0[1,2,3]
2757; AVX-NEXT:    vaddps %xmm1, %xmm0, %xmm0
2758; AVX-NEXT:    retq
2759entry:
2760  %s1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 3, i32 0, i32 1, i32 2>
2761  %s2 = shufflevector <4 x float> %s1, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 2, i32 3>
2762  %r2 = fadd <4 x float> %s1, %s2
2763  ret <4 x float> %r2
2764}
2765
2766define <8 x float> @PR22412(<8 x float> %a, <8 x float> %b) {
2767; SSE-LABEL: PR22412:
2768; SSE:       # %bb.0: # %entry
2769; SSE-NEXT:    movaps %xmm3, %xmm1
2770; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,0],xmm3[3,2]
2771; SSE-NEXT:    shufps {{.*#+}} xmm1 = xmm1[1,0],xmm2[3,2]
2772; SSE-NEXT:    retq
2773;
2774; AVX1-LABEL: PR22412:
2775; AVX1:       # %bb.0: # %entry
2776; AVX1-NEXT:    vperm2f128 {{.*#+}} ymm2 = ymm1[2,3,0,1]
2777; AVX1-NEXT:    vblendps {{.*#+}} ymm0 = ymm0[0,1,2,3],ymm1[4,5,6,7]
2778; AVX1-NEXT:    vshufps {{.*#+}} ymm0 = ymm0[1,0],ymm2[3,2],ymm0[5,4],ymm2[7,6]
2779; AVX1-NEXT:    retq
2780;
2781; AVX2-LABEL: PR22412:
2782; AVX2:       # %bb.0: # %entry
2783; AVX2-NEXT:    vblendps {{.*#+}} ymm0 = ymm0[0,1,2,3],ymm1[4,5,6,7]
2784; AVX2-NEXT:    vpermpd {{.*#+}} ymm1 = ymm1[2,3,0,1]
2785; AVX2-NEXT:    vshufps {{.*#+}} ymm0 = ymm0[1,0],ymm1[3,2],ymm0[5,4],ymm1[7,6]
2786; AVX2-NEXT:    retq
2787entry:
2788  %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>
2789  %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>
2790  ret <8 x float> %s2
2791}
2792
2793define <4 x float> @PR30264(<4 x float> %x) {
2794; SSE2-LABEL: PR30264:
2795; SSE2:       # %bb.0:
2796; SSE2-NEXT:    xorps %xmm1, %xmm1
2797; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[1,0],xmm0[0,0]
2798; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[2,0],mem[2,3]
2799; SSE2-NEXT:    movaps %xmm1, %xmm0
2800; SSE2-NEXT:    retq
2801;
2802; SSSE3-LABEL: PR30264:
2803; SSSE3:       # %bb.0:
2804; SSSE3-NEXT:    xorps %xmm1, %xmm1
2805; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[1,0],xmm0[0,0]
2806; SSSE3-NEXT:    shufps {{.*#+}} xmm1 = xmm1[2,0],mem[2,3]
2807; SSSE3-NEXT:    movaps %xmm1, %xmm0
2808; SSSE3-NEXT:    retq
2809;
2810; SSE41-LABEL: PR30264:
2811; SSE41:       # %bb.0:
2812; SSE41-NEXT:    movaps {{.*#+}} xmm1 = <u,u,4.0E+0,1.0E+0>
2813; SSE41-NEXT:    insertps {{.*#+}} xmm1 = xmm0[0],zero,xmm1[2,3]
2814; SSE41-NEXT:    movaps %xmm1, %xmm0
2815; SSE41-NEXT:    retq
2816;
2817; AVX-LABEL: PR30264:
2818; AVX:       # %bb.0:
2819; AVX-NEXT:    vmovaps {{.*#+}} xmm1 = <u,u,4.0E+0,1.0E+0>
2820; AVX-NEXT:    vinsertps {{.*#+}} xmm0 = xmm0[0],zero,xmm1[2,3]
2821; AVX-NEXT:    retq
2822  %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>
2823  %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>
2824  ret <4 x float> %shuf2
2825}
2826
2827define <8 x i16> @PR39549(<16 x i8> %x) {
2828; SSE-LABEL: PR39549:
2829; SSE:       # %bb.0:
2830; SSE-NEXT:    punpckhbw {{.*#+}} xmm0 = xmm0[8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15]
2831; SSE-NEXT:    psraw $8, %xmm0
2832; SSE-NEXT:    retq
2833;
2834; AVX-LABEL: PR39549:
2835; AVX:       # %bb.0:
2836; AVX-NEXT:    vpunpckhbw {{.*#+}} xmm0 = xmm0[8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15]
2837; AVX-NEXT:    vpsraw $8, %xmm0, %xmm0
2838; AVX-NEXT:    retq
2839  %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>
2840  %b = bitcast <16 x i8> %a to <8 x i16>
2841  %c = shl <8 x i16> %b, <i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8>
2842  %d = ashr <8 x i16> %c, <i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8>
2843  ret <8 x i16> %d
2844}
2845