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