[x86] Add the dispatch skeleton to the new vector shuffle lowering for
[oota-llvm.git] / test / CodeGen / X86 / combine-vec-shuffle-3.ll
1 ; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 | FileCheck %s
2
3 define <4 x float> @test1(<4 x float> %a, <4 x float> %b) {
4   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
5   %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
6   ret <4 x float> %2
7 }
8 ; CHECK-LABEL: test1
9 ; Mask: [0,1,2,3]
10 ; CHECK: movaps
11 ; CHECK: ret
12
13 define <4 x float> @test2(<4 x float> %a, <4 x float> %b) {
14   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
15   %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 6, i32 3>
16   ret <4 x float> %2
17 }
18 ; CHECK-LABEL: test2
19 ; Mask: [0,5,6,7]
20 ; CHECK: movss
21 ; CHECK: ret
22
23 define <4 x float> @test3(<4 x float> %a, <4 x float> %b) {
24   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 1, i32 7>
25   %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 2, i32 4, i32 1>
26   ret <4 x float> %2
27 }
28 ; CHECK-LABEL: test3
29 ; Mask: [0,1,4,5]
30 ; CHECK: movlhps
31 ; CHECK: ret
32
33 define <4 x float> @test4(<4 x float> %a, <4 x float> %b) {
34   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 2, i32 3, i32 5, i32 5>
35   %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 6, i32 7, i32 0, i32 1>
36   ret <4 x float> %2
37 }
38 ; CHECK-LABEL: test4
39 ; Mask: [6,7,2,3]
40 ; CHECK: movhlps
41 ; CHECK-NEXT: ret
42
43 define <4 x float> @test5(<4 x float> %a, <4 x float> %b) {
44   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
45   %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 2, i32 7>
46   ret <4 x float> %2
47 }
48 ; CHECK-LABEL: test5
49 ; Mask: [4,1,6,7]
50 ; CHECK: blendps $13
51 ; CHECK: ret
52
53
54 define <4 x i32> @test6(<4 x i32> %a, <4 x i32> %b) {
55   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
56   %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
57   ret <4 x i32> %2
58 }
59 ; CHECK-LABEL: test6
60 ; Mask: [4,5,6,7]
61 ; CHECK: movaps
62 ; CHECK: ret
63
64 define <4 x i32> @test7(<4 x i32> %a, <4 x i32> %b) {
65   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
66   %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 0, i32 1, i32 6, i32 3>
67   ret <4 x i32> %2
68 }
69 ; CHECK-LABEL: test7
70 ; Mask: [0,5,6,7]
71 ; CHECK: movss
72 ; CHECK: ret
73
74 define <4 x i32> @test8(<4 x i32> %a, <4 x i32> %b) {
75   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 5, i32 1, i32 7>
76   %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 0, i32 2, i32 4, i32 1>
77   ret <4 x i32> %2
78 }
79 ; CHECK-LABEL: test8
80 ; Mask: [0,1,4,5]
81 ; CHECK: movlhps
82 ; CHECK: ret
83
84 define <4 x i32> @test9(<4 x i32> %a, <4 x i32> %b) {
85   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 2, i32 3, i32 5, i32 5>
86   %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 6, i32 7, i32 0, i32 1>
87   ret <4 x i32> %2
88 }
89 ; CHECK-LABEL: test9
90 ; Mask: [6,7,2,3]
91 ; CHECK: movhlps
92 ; CHECK-NEXT: ret
93
94 define <4 x i32> @test10(<4 x i32> %a, <4 x i32> %b) {
95   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
96   %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 0, i32 1, i32 2, i32 7>
97   ret <4 x i32> %2
98 }
99 ; CHECK-LABEL: test10
100 ; Mask: [4,1,6,7]
101 ; CHECK: blendps
102 ; CHECK: ret
103
104 define <4 x float> @test11(<4 x float> %a, <4 x float> %b) {
105   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
106   %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
107   ret <4 x float> %2
108 }
109 ; CHECK-LABEL: test11
110 ; Mask: [0,1,2,3]
111 ; CHECK-NOT: movaps
112 ; CHECK-NOT: blendps
113 ; CHECK: ret
114
115 define <4 x float> @test12(<4 x float> %a, <4 x float> %b) {
116   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 6, i32 7>
117   %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 4, i32 1, i32 2, i32 3>
118   ret <4 x float> %2
119 }
120 ; CHECK-LABEL: test12
121 ; Mask: [0,5,6,7]
122 ; CHECK: movss
123 ; CHECK: ret
124
125 define <4 x float> @test13(<4 x float> %a, <4 x float> %b) {
126   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
127   %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 4, i32 5, i32 2, i32 3>
128   ret <4 x float> %2
129 }
130 ; CHECK-LABEL: test13
131 ; Mask: [0,1,4,5]
132 ; CHECK: movlhps
133 ; CHECK: ret
134
135 define <4 x float> @test14(<4 x float> %a, <4 x float> %b) {
136   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 6, i32 7, i32 5, i32 5>
137   %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 6, i32 7, i32 0, i32 1>
138   ret <4 x float> %2
139 }
140 ; CHECK-LABEL: test14
141 ; Mask: [6,7,2,3]
142 ; CHECK: movhlps
143 ; CHECK: ret
144
145 define <4 x float> @test15(<4 x float> %a, <4 x float> %b) {
146   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 7>
147   %2 = shufflevector <4 x float> %1, <4 x float> %a, <4 x i32> <i32 0, i32 5, i32 2, i32 3>
148   ret <4 x float> %2
149 }
150 ; CHECK-LABEL: test15
151 ; Mask: [4,1,6,7]
152 ; CHECK: blendps $13
153 ; CHECK: ret
154
155 define <4 x i32> @test16(<4 x i32> %a, <4 x i32> %b) {
156   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
157   %2 = shufflevector <4 x i32> %1, <4 x i32> %a, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
158   ret <4 x i32> %2
159 }
160 ; CHECK-LABEL: test16
161 ; Mask: [0,1,2,3]
162 ; CHECK-NOT: movaps
163 ; CHECK-NOT: blendps
164 ; CHECK: ret
165
166 define <4 x i32> @test17(<4 x i32> %a, <4 x i32> %b) {
167   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 5, i32 6, i32 7>
168   %2 = shufflevector <4 x i32> %1, <4 x i32> %a, <4 x i32> <i32 4, i32 1, i32 2, i32 3>
169   ret <4 x i32> %2
170 }
171 ; CHECK-LABEL: test17
172 ; Mask: [0,5,6,7]
173 ; CHECK: movss
174 ; CHECK: ret
175
176 define <4 x i32> @test18(<4 x i32> %a, <4 x i32> %b) {
177   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
178   %2 = shufflevector <4 x i32> %1, <4 x i32> %a, <4 x i32> <i32 4, i32 5, i32 2, i32 3>
179   ret <4 x i32> %2
180 }
181 ; CHECK-LABEL: test18
182 ; Mask: [0,1,4,5]
183 ; CHECK: movlhps
184 ; CHECK: ret
185
186 define <4 x i32> @test19(<4 x i32> %a, <4 x i32> %b) {
187   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 6, i32 7, i32 5, i32 5>
188   %2 = shufflevector <4 x i32> %1, <4 x i32> %a, <4 x i32> <i32 6, i32 7, i32 0, i32 1>
189   ret <4 x i32> %2
190 }
191 ; CHECK-LABEL: test19
192 ; Mask: [6,7,2,3]
193 ; CHECK: movhlps
194 ; CHECK: ret
195
196 define <4 x i32> @test20(<4 x i32> %a, <4 x i32> %b) {
197   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 7>
198   %2 = shufflevector <4 x i32> %1, <4 x i32> %a, <4 x i32> <i32 0, i32 5, i32 2, i32 3>
199   ret <4 x i32> %2
200 }
201 ; CHECK-LABEL: test20
202 ; Mask: [4,1,6,7]
203 ; CHECK: blendps $13
204 ; CHECK: ret
205
206 ; Check some negative cases.
207 define <4 x float> @test1b(<4 x float> %a, <4 x float> %b) {
208   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
209   %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 0>
210   ret <4 x float> %2
211 }
212 ; CHECK-LABEL: test1b
213 ; CHECK: shufps
214 ; CHECK: shufps
215 ; CHECK: ret
216
217 define <4 x float> @test2b(<4 x float> %a, <4 x float> %b) {
218   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
219   %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 0, i32 5>
220   ret <4 x float> %2
221 }
222 ; CHECK-LABEL: test2b
223 ; CHECK: shufps
224 ; CHECK: pshufd
225 ; CHECK: ret
226
227 define <4 x float> @test3b(<4 x float> %a, <4 x float> %b) {
228   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 0, i32 6, i32 3>
229   %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 0, i32 7, i32 2, i32 7>
230   ret <4 x float> %2
231 }
232 ; CHECK-LABEL: test3b
233 ; CHECK: shufps
234 ; CHECK: shufps
235 ; CHECK: ret
236
237 define <4 x float> @test4b(<4 x float> %a, <4 x float> %b) {
238   %1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
239   %2 = shufflevector <4 x float> %1, <4 x float> %b, <4 x i32> <i32 5, i32 5, i32 2, i32 7>
240   ret <4 x float> %2
241 }
242 ; CHECK-LABEL: test4b
243 ; CHECK: shufps
244 ; CHECK: shufps
245 ; CHECK: ret
246
247
248 ; Verify that we correctly fold shuffles even when we use illegal vector types.
249 define <4 x i8> @test1c(<4 x i8>* %a, <4 x i8>* %b) {
250   %A = load <4 x i8>* %a
251   %B = load <4 x i8>* %b
252   %1 = shufflevector <4 x i8> %A, <4 x i8> %B, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
253   %2 = shufflevector <4 x i8> %1, <4 x i8> %B, <4 x i32> <i32 0, i32 1, i32 6, i32 3>
254   ret <4 x i8> %2
255 }
256 ; CHECK-LABEL: test1c
257 ; Mask: [0,5,6,7]
258 ; CHECK: movss
259 ; CHECK-NEXT: ret
260
261 define <4 x i8> @test2c(<4 x i8>* %a, <4 x i8>* %b) {
262   %A = load <4 x i8>* %a
263   %B = load <4 x i8>* %b
264   %1 = shufflevector <4 x i8> %A, <4 x i8> %B, <4 x i32> <i32 0, i32 5, i32 1, i32 5>
265   %2 = shufflevector <4 x i8> %1, <4 x i8> %B, <4 x i32> <i32 0, i32 2, i32 4, i32 1>
266   ret <4 x i8> %2
267 }
268 ; CHECK-LABEL: test2c
269 ; Mask: [0,1,4,5]
270 ; CHECK: movlhps
271 ; CHECK-NEXT: ret
272
273 define <4 x i8> @test3c(<4 x i8>* %a, <4 x i8>* %b) {
274   %A = load <4 x i8>* %a
275   %B = load <4 x i8>* %b
276   %1 = shufflevector <4 x i8> %A, <4 x i8> %B, <4 x i32> <i32 2, i32 3, i32 5, i32 5>
277   %2 = shufflevector <4 x i8> %1, <4 x i8> %B, <4 x i32> <i32 6, i32 7, i32 0, i32 1>
278   ret <4 x i8> %2
279 }
280 ; CHECK-LABEL: test3c
281 ; Mask: [6,7,2,3]
282 ; CHECK: movhlps
283 ; CHECK-NEXT: ret
284
285 define <4 x i8> @test4c(<4 x i8>* %a, <4 x i8>* %b) {
286   %A = load <4 x i8>* %a
287   %B = load <4 x i8>* %b
288   %1 = shufflevector <4 x i8> %A, <4 x i8> %B, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
289   %2 = shufflevector <4 x i8> %1, <4 x i8> %B, <4 x i32> <i32 0, i32 1, i32 2, i32 7>
290   ret <4 x i8> %2
291 }
292 ; CHECK-LABEL: test4c
293 ; Mask: [4,1,6,7]
294 ; CHECK: blendps $13
295 ; CHECK: ret
296
297 ; The following test cases are generated from this C++ code
298
299 ;__m128 blend_01(__m128 a, __m128 b)
300 ;{
301 ;  __m128 s = a;
302 ;  s = _mm_blend_ps( s, b, 1<<0 );
303 ;  s = _mm_blend_ps( s, b, 1<<1 );
304 ;  return s;
305 ;}
306 ;
307 ;__m128 blend_02(__m128 a, __m128 b)
308 ;{
309 ;  __m128 s = a;
310 ;  s = _mm_blend_ps( s, b, 1<<0 );
311 ;  s = _mm_blend_ps( s, b, 1<<2 );
312 ;  return s;
313 ;}
314 ;
315 ;__m128 blend_123(__m128 a, __m128 b)
316 ;{
317 ;  __m128 s = a;
318 ;  s = _mm_blend_ps( s, b, 1<<1 );
319 ;  s = _mm_blend_ps( s, b, 1<<2 );
320 ;  s = _mm_blend_ps( s, b, 1<<3 );
321 ;  return s;
322 ;}
323
324 ; Ideally, we should collapse the following shuffles into a single one.
325
326 define <4 x float> @blend_01(<4 x float> %a, <4 x float> %b) {
327   %shuffle = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 undef, i32 2, i32 3>
328   %shuffle6 = shufflevector <4 x float> %shuffle, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 3>
329   ret <4 x float> %shuffle6
330 }
331 ; CHECK-LABEL: blend_01
332 ; CHECK: movsd
333 ; CHECK-NEXT: ret
334
335 define <4 x float> @blend_02(<4 x float> %a, <4 x float> %b) {
336   %shuffle = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 4, i32 1, i32 undef, i32 3>
337   %shuffle6 = shufflevector <4 x float> %shuffle, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 6, i32 3>
338   ret <4 x float> %shuffle6
339 }
340 ; CHECK-LABEL: blend_02
341 ; CHECK: blendps $5
342 ; CHECK-NEXT: ret
343
344 define <4 x float> @blend_123(<4 x float> %a, <4 x float> %b) {
345   %shuffle = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 undef, i32 undef>
346   %shuffle6 = shufflevector <4 x float> %shuffle, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 6, i32 undef>
347   %shuffle12 = shufflevector <4 x float> %shuffle6, <4 x float> %b, <4 x i32> <i32 0, i32 1, i32 2, i32 7>
348   ret <4 x float> %shuffle12
349 }
350 ; CHECK-LABEL: blend_123
351 ; CHECK: movss
352 ; CHECK: ret
353
354 define <4 x i32> @test_movhl_1(<4 x i32> %a, <4 x i32> %b) {
355   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 2, i32 7, i32 5, i32 3>
356   %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 6, i32 1, i32 0, i32 3>
357   ret <4 x i32> %2
358 }
359 ; CHECK-LABEL: test_movhl_1
360 ; CHECK: movhlps
361 ; CHECK-NEXT: ret
362
363 define <4 x i32> @test_movhl_2(<4 x i32> %a, <4 x i32> %b) {
364   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 2, i32 0, i32 3, i32 6>
365   %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 3, i32 7, i32 0, i32 2>
366   ret <4 x i32> %2
367 }
368 ; CHECK-LABEL: test_movhl_2
369 ; CHECK: movhlps
370 ; CHECK-NEXT: ret
371
372 define <4 x i32> @test_movhl_3(<4 x i32> %a, <4 x i32> %b) {
373   %1 = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 7, i32 6, i32 3, i32 2>
374   %2 = shufflevector <4 x i32> %1, <4 x i32> %b, <4 x i32> <i32 6, i32 0, i32 3, i32 2>
375   ret <4 x i32> %2
376 }
377 ; CHECK-LABEL: test_movhl_3
378 ; CHECK: movhlps
379 ; CHECK-NEXT: ret
380