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