[x86] Teach the new vector shuffle lowering to use BLENDPS and BLENDPD.
[oota-llvm.git] / test / CodeGen / X86 / vector-shuffle-128-v2.ll
1 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -x86-experimental-vector-shuffle-lowering | FileCheck %s --check-prefix=ALL --check-prefix=SSE2
2 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+sse3 -x86-experimental-vector-shuffle-lowering | FileCheck %s --check-prefix=ALL --check-prefix=SSE3
3 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+sse4.1 -x86-experimental-vector-shuffle-lowering | FileCheck %s --check-prefix=ALL --check-prefix=SSE41
4
5 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
6 target triple = "x86_64-unknown-unknown"
7
8 define <2 x i64> @shuffle_v2i64_00(<2 x i64> %a, <2 x i64> %b) {
9 ; ALL-LABEL: @shuffle_v2i64_00
10 ; ALL:         pshufd {{.*}} # xmm0 = xmm0[0,1,0,1]
11 ; ALL-NEXT:    retq
12   %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 0, i32 0>
13   ret <2 x i64> %shuffle
14 }
15 define <2 x i64> @shuffle_v2i64_10(<2 x i64> %a, <2 x i64> %b) {
16 ; ALL-LABEL: @shuffle_v2i64_10
17 ; ALL:         pshufd {{.*}} # xmm0 = xmm0[2,3,0,1]
18 ; ALL-NEXT:    retq
19   %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 1, i32 0>
20   ret <2 x i64> %shuffle
21 }
22 define <2 x i64> @shuffle_v2i64_11(<2 x i64> %a, <2 x i64> %b) {
23 ; ALL-LABEL: @shuffle_v2i64_11
24 ; ALL:         pshufd {{.*}} # xmm0 = xmm0[2,3,2,3]
25 ; ALL-NEXT:    retq
26   %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 1, i32 1>
27   ret <2 x i64> %shuffle
28 }
29 define <2 x i64> @shuffle_v2i64_22(<2 x i64> %a, <2 x i64> %b) {
30 ; ALL-LABEL: @shuffle_v2i64_22
31 ; ALL:         pshufd {{.*}} # xmm0 = xmm1[0,1,0,1]
32 ; ALL-NEXT:    retq
33   %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 2, i32 2>
34   ret <2 x i64> %shuffle
35 }
36 define <2 x i64> @shuffle_v2i64_32(<2 x i64> %a, <2 x i64> %b) {
37 ; ALL-LABEL: @shuffle_v2i64_32
38 ; ALL:         pshufd {{.*}} # xmm0 = xmm1[2,3,0,1]
39 ; ALL-NEXT:    retq
40   %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 3, i32 2>
41   ret <2 x i64> %shuffle
42 }
43 define <2 x i64> @shuffle_v2i64_33(<2 x i64> %a, <2 x i64> %b) {
44 ; ALL-LABEL: @shuffle_v2i64_33
45 ; ALL:         pshufd {{.*}} # xmm0 = xmm1[2,3,2,3]
46 ; ALL-NEXT:    retq
47   %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 3, i32 3>
48   ret <2 x i64> %shuffle
49 }
50
51 define <2 x double> @shuffle_v2f64_00(<2 x double> %a, <2 x double> %b) {
52 ; SSE2-LABEL: @shuffle_v2f64_00
53 ; SSE2:         movlhps {{.*}} # xmm0 = xmm0[0,0]
54 ; SSE2-NEXT:    retq
55 ;
56 ; SSE3-LABEL: @shuffle_v2f64_00
57 ; SSE3:         unpcklpd {{.*}} # xmm0 = xmm0[0,0]
58 ; SSE3-NEXT:    retq
59 ;
60 ; SSE41-LABEL: @shuffle_v2f64_00
61 ; SSE41:         unpcklpd {{.*}} # xmm0 = xmm0[0,0]
62 ; SSE41-NEXT:    retq
63   %shuffle = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 0, i32 0>
64   ret <2 x double> %shuffle
65 }
66 define <2 x double> @shuffle_v2f64_10(<2 x double> %a, <2 x double> %b) {
67 ; ALL-LABEL: @shuffle_v2f64_10
68 ; ALL:         shufpd {{.*}} # xmm0 = xmm0[1,0]
69 ; ALL-NEXT:    retq
70   %shuffle = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 1, i32 0>
71   ret <2 x double> %shuffle
72 }
73 define <2 x double> @shuffle_v2f64_11(<2 x double> %a, <2 x double> %b) {
74 ; ALL-LABEL: @shuffle_v2f64_11
75 ; ALL:         movhlps {{.*}} # xmm0 = xmm0[1,1]
76 ; ALL-NEXT:    retq
77   %shuffle = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 1, i32 1>
78   ret <2 x double> %shuffle
79 }
80 define <2 x double> @shuffle_v2f64_22(<2 x double> %a, <2 x double> %b) {
81 ; SSE2-LABEL: @shuffle_v2f64_22
82 ; SSE2:         movlhps {{.*}} # xmm1 = xmm1[0,0]
83 ; SSE2-NEXT:    movaps %xmm1, %xmm0
84 ; SSE2-NEXT:    retq
85 ;
86 ; SSE3-LABEL: @shuffle_v2f64_22
87 ; SSE3:         unpcklpd {{.*}} # xmm1 = xmm1[0,0]
88 ; SSE3-NEXT:    movapd %xmm1, %xmm0
89 ; SSE3-NEXT:    retq
90 ;
91 ; SSE41-LABEL: @shuffle_v2f64_22
92 ; SSE41:         unpcklpd {{.*}} # xmm1 = xmm1[0,0]
93 ; SSE41-NEXT:    movapd %xmm1, %xmm0
94 ; SSE41-NEXT:    retq
95   %shuffle = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 2, i32 2>
96   ret <2 x double> %shuffle
97 }
98 define <2 x double> @shuffle_v2f64_32(<2 x double> %a, <2 x double> %b) {
99 ; ALL-LABEL: @shuffle_v2f64_32
100 ; ALL:         pshufd {{.*}} # xmm0 = xmm1[2,3,0,1]
101 ; ALL-NEXT:    retq
102   %shuffle = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 3, i32 2>
103   ret <2 x double> %shuffle
104 }
105 define <2 x double> @shuffle_v2f64_33(<2 x double> %a, <2 x double> %b) {
106 ; ALL-LABEL: @shuffle_v2f64_33
107 ; ALL:         movhlps {{.*}} # xmm1 = xmm1[1,1]
108 ; ALL-NEXT:    movaps %xmm1, %xmm0
109 ; ALL-NEXT:    retq
110   %shuffle = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 3, i32 3>
111   ret <2 x double> %shuffle
112 }
113 define <2 x double> @shuffle_v2f64_03(<2 x double> %a, <2 x double> %b) {
114 ; SSE2-LABEL: @shuffle_v2f64_03
115 ; SSE2:         shufpd {{.*}} # xmm0 = xmm0[0],xmm1[1]
116 ; SSE2-NEXT:    retq
117 ;
118 ; SSE3-LABEL: @shuffle_v2f64_03
119 ; SSE3:         shufpd {{.*}} # xmm0 = xmm0[0],xmm1[1]
120 ; SSE3-NEXT:    retq
121 ;
122 ; SSE41-LABEL: @shuffle_v2f64_03
123 ; SSE41:         blendpd {{.*}} # xmm0 = xmm0[0],xmm1[1]
124 ; SSE41-NEXT:    retq
125   %shuffle = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 0, i32 3>
126   ret <2 x double> %shuffle
127 }
128 define <2 x double> @shuffle_v2f64_21(<2 x double> %a, <2 x double> %b) {
129 ; SSE2-LABEL: @shuffle_v2f64_21
130 ; SSE2:         shufpd {{.*}} # xmm1 = xmm1[0],xmm0[1]
131 ; SSE2-NEXT:    movapd %xmm1, %xmm0
132 ; SSE2-NEXT:    retq
133 ;
134 ; SSE3-LABEL: @shuffle_v2f64_21
135 ; SSE3:         shufpd {{.*}} # xmm1 = xmm1[0],xmm0[1]
136 ; SSE3-NEXT:    movapd %xmm1, %xmm0
137 ; SSE3-NEXT:    retq
138 ;
139 ; SSE41-LABEL: @shuffle_v2f64_21
140 ; SSE41:         blendpd {{.*}} # xmm1 = xmm1[0],xmm0[1]
141 ; SSE41-NEXT:    movapd %xmm1, %xmm0
142 ; SSE41-NEXT:    retq
143   %shuffle = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 2, i32 1>
144   ret <2 x double> %shuffle
145 }
146
147
148 define <2 x i64> @shuffle_v2i64_02(<2 x i64> %a, <2 x i64> %b) {
149 ; ALL-LABEL: @shuffle_v2i64_02
150 ; ALL:         punpcklqdq {{.*}} # xmm0 = xmm0[0],xmm1[0]
151 ; ALL-NEXT:    retq
152   %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 0, i32 2>
153   ret <2 x i64> %shuffle
154 }
155 define <2 x i64> @shuffle_v2i64_02_copy(<2 x i64> %nonce, <2 x i64> %a, <2 x i64> %b) {
156 ; ALL-LABEL: @shuffle_v2i64_02_copy
157 ; ALL:         punpcklqdq {{.*}} # xmm1 = xmm1[0],xmm2[0]
158 ; ALL-NEXT:    movdqa %xmm1, %xmm0
159 ; ALL-NEXT:    retq
160   %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 0, i32 2>
161   ret <2 x i64> %shuffle
162 }
163 define <2 x i64> @shuffle_v2i64_03(<2 x i64> %a, <2 x i64> %b) {
164 ; SSE2-LABEL: @shuffle_v2i64_03
165 ; SSE2:         shufpd {{.*}} # xmm0 = xmm0[0],xmm1[1]
166 ; SSE2-NEXT:    retq
167 ;
168 ; SSE3-LABEL: @shuffle_v2i64_03
169 ; SSE3:         shufpd {{.*}} # xmm0 = xmm0[0],xmm1[1]
170 ; SSE3-NEXT:    retq
171 ;
172 ; SSE41-LABEL: @shuffle_v2i64_03
173 ; SSE41:         blendpd {{.*}} # xmm0 = xmm0[0],xmm1[1]
174 ; SSE41-NEXT:    retq
175   %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 0, i32 3>
176   ret <2 x i64> %shuffle
177 }
178 define <2 x i64> @shuffle_v2i64_03_copy(<2 x i64> %nonce, <2 x i64> %a, <2 x i64> %b) {
179 ; SSE2-LABEL: @shuffle_v2i64_03_copy
180 ; SSE2:         shufpd {{.*}} # xmm1 = xmm1[0],xmm2[1]
181 ; SSE2-NEXT:    movapd %xmm1, %xmm0
182 ; SSE2-NEXT:    retq
183 ;
184 ; SSE3-LABEL: @shuffle_v2i64_03_copy
185 ; SSE3:         shufpd {{.*}} # xmm1 = xmm1[0],xmm2[1]
186 ; SSE3-NEXT:    movapd %xmm1, %xmm0
187 ; SSE3-NEXT:    retq
188 ;
189 ; SSE41-LABEL: @shuffle_v2i64_03_copy
190 ; SSE41:         blendpd {{.*}} # xmm1 = xmm1[0],xmm2[1]
191 ; SSE41-NEXT:    movapd %xmm1, %xmm0
192 ; SSE41-NEXT:    retq
193   %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 0, i32 3>
194   ret <2 x i64> %shuffle
195 }
196 define <2 x i64> @shuffle_v2i64_12(<2 x i64> %a, <2 x i64> %b) {
197 ; ALL-LABEL: @shuffle_v2i64_12
198 ; ALL:         shufpd {{.*}} # xmm0 = xmm0[1],xmm1[0]
199 ; ALL-NEXT:    retq
200   %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 1, i32 2>
201   ret <2 x i64> %shuffle
202 }
203 define <2 x i64> @shuffle_v2i64_12_copy(<2 x i64> %nonce, <2 x i64> %a, <2 x i64> %b) {
204 ; ALL-LABEL: @shuffle_v2i64_12_copy
205 ; ALL:         shufpd {{.*}} # xmm1 = xmm1[1],xmm2[0]
206 ; ALL-NEXT:    movapd %xmm1, %xmm0
207 ; ALL-NEXT:    retq
208   %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 1, i32 2>
209   ret <2 x i64> %shuffle
210 }
211 define <2 x i64> @shuffle_v2i64_13(<2 x i64> %a, <2 x i64> %b) {
212 ; ALL-LABEL: @shuffle_v2i64_13
213 ; ALL:         punpckhqdq {{.*}} # xmm0 = xmm0[1],xmm1[1]
214 ; ALL-NEXT:    retq
215   %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 1, i32 3>
216   ret <2 x i64> %shuffle
217 }
218 define <2 x i64> @shuffle_v2i64_13_copy(<2 x i64> %nonce, <2 x i64> %a, <2 x i64> %b) {
219 ; ALL-LABEL: @shuffle_v2i64_13_copy
220 ; ALL:         punpckhqdq {{.*}} # xmm1 = xmm1[1],xmm2[1]
221 ; ALL-NEXT:    movdqa %xmm1, %xmm0
222 ; ALL-NEXT:    retq
223   %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 1, i32 3>
224   ret <2 x i64> %shuffle
225 }
226 define <2 x i64> @shuffle_v2i64_20(<2 x i64> %a, <2 x i64> %b) {
227 ; ALL-LABEL: @shuffle_v2i64_20
228 ; ALL:         punpcklqdq {{.*}} # xmm1 = xmm1[0],xmm0[0]
229 ; ALL-NEXT:    movdqa %xmm1, %xmm0
230 ; ALL-NEXT:    retq
231   %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 2, i32 0>
232   ret <2 x i64> %shuffle
233 }
234 define <2 x i64> @shuffle_v2i64_20_copy(<2 x i64> %nonce, <2 x i64> %a, <2 x i64> %b) {
235 ; ALL-LABEL: @shuffle_v2i64_20_copy
236 ; ALL:         punpcklqdq {{.*}} # xmm2 = xmm2[0],xmm1[0]
237 ; ALL-NEXT:    movdqa %xmm2, %xmm0
238 ; ALL-NEXT:    retq
239   %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 2, i32 0>
240   ret <2 x i64> %shuffle
241 }
242 define <2 x i64> @shuffle_v2i64_21(<2 x i64> %a, <2 x i64> %b) {
243 ; SSE2-LABEL: @shuffle_v2i64_21
244 ; SSE2:         shufpd {{.*}} # xmm1 = xmm1[0],xmm0[1]
245 ; SSE2-NEXT:    movapd %xmm1, %xmm0
246 ; SSE2-NEXT:    retq
247 ;
248 ; SSE3-LABEL: @shuffle_v2i64_21
249 ; SSE3:         shufpd {{.*}} # xmm1 = xmm1[0],xmm0[1]
250 ; SSE3-NEXT:    movapd %xmm1, %xmm0
251 ; SSE3-NEXT:    retq
252 ;
253 ; SSE41-LABEL: @shuffle_v2i64_21
254 ; SSE41:         blendpd {{.*}} # xmm1 = xmm1[0],xmm0[1]
255 ; SSE41-NEXT:    movapd %xmm1, %xmm0
256 ; SSE41-NEXT:    retq
257   %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 2, i32 1>
258   ret <2 x i64> %shuffle
259 }
260 define <2 x i64> @shuffle_v2i64_21_copy(<2 x i64> %nonce, <2 x i64> %a, <2 x i64> %b) {
261 ; SSE2-LABEL: @shuffle_v2i64_21_copy
262 ; SSE2:         shufpd {{.*}} # xmm2 = xmm2[0],xmm1[1]
263 ; SSE2-NEXT:    movapd %xmm2, %xmm0
264 ; SSE2-NEXT:    retq
265 ;
266 ; SSE3-LABEL: @shuffle_v2i64_21_copy
267 ; SSE3:         shufpd {{.*}} # xmm2 = xmm2[0],xmm1[1]
268 ; SSE3-NEXT:    movapd %xmm2, %xmm0
269 ; SSE3-NEXT:    retq
270 ;
271 ; SSE41-LABEL: @shuffle_v2i64_21_copy
272 ; SSE41:         blendpd {{.*}} # xmm2 = xmm2[0],xmm1[1]
273 ; SSE41-NEXT:    movapd %xmm2, %xmm0
274 ; SSE41-NEXT:    retq
275   %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 2, i32 1>
276   ret <2 x i64> %shuffle
277 }
278 define <2 x i64> @shuffle_v2i64_30(<2 x i64> %a, <2 x i64> %b) {
279 ; ALL-LABEL: @shuffle_v2i64_30
280 ; ALL:         shufpd {{.*}} # xmm1 = xmm1[1],xmm0[0]
281 ; ALL-NEXT:    movapd %xmm1, %xmm0
282 ; ALL-NEXT:    retq
283   %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 3, i32 0>
284   ret <2 x i64> %shuffle
285 }
286 define <2 x i64> @shuffle_v2i64_30_copy(<2 x i64> %nonce, <2 x i64> %a, <2 x i64> %b) {
287 ; ALL-LABEL: @shuffle_v2i64_30_copy
288 ; ALL:         shufpd {{.*}} # xmm2 = xmm2[1],xmm1[0]
289 ; ALL-NEXT:    movapd %xmm2, %xmm0
290 ; ALL-NEXT:    retq
291   %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 3, i32 0>
292   ret <2 x i64> %shuffle
293 }
294 define <2 x i64> @shuffle_v2i64_31(<2 x i64> %a, <2 x i64> %b) {
295 ; ALL-LABEL: @shuffle_v2i64_31
296 ; ALL:         punpckhqdq {{.*}} # xmm1 = xmm1[1],xmm0[1]
297 ; ALL-NEXT:    movdqa %xmm1, %xmm0
298 ; ALL-NEXT:    retq
299   %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 3, i32 1>
300   ret <2 x i64> %shuffle
301 }
302 define <2 x i64> @shuffle_v2i64_31_copy(<2 x i64> %nonce, <2 x i64> %a, <2 x i64> %b) {
303 ; ALL-LABEL: @shuffle_v2i64_31_copy
304 ; ALL:         punpckhqdq {{.*}} # xmm2 = xmm2[1],xmm1[1]
305 ; ALL-NEXT:    movdqa %xmm2, %xmm0
306 ; ALL-NEXT:    retq
307   %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 3, i32 1>
308   ret <2 x i64> %shuffle
309 }
310
311
312 define <2 x double> @insert_dup_reg_v2f64(double %a) {
313 ; SSE2-LABEL: @insert_dup_reg_v2f64
314 ; SSE2:         movlhps {{.*}} # xmm0 = xmm0[0,0]
315 ; SSE2-NEXT:    retq
316 ;
317 ; FIXME: This should match movddup as well!
318 ; SSE3-LABEL: @insert_dup_reg_v2f64
319 ; SSE3:         unpcklpd {{.*}} # xmm0 = xmm0[0,0]
320 ; SSE3-NEXT:    retq
321 ;
322 ; FIXME: This should match movddup as well!
323 ; SSE41-LABEL: @insert_dup_reg_v2f64
324 ; SSE41:         unpcklpd {{.*}} # xmm0 = xmm0[0,0]
325 ; SSE41-NEXT:    retq
326   %v = insertelement <2 x double> undef, double %a, i32 0
327   %shuffle = shufflevector <2 x double> %v, <2 x double> undef, <2 x i32> <i32 0, i32 0>
328   ret <2 x double> %shuffle
329 }
330 define <2 x double> @insert_dup_mem_v2f64(double* %ptr) {
331 ; SSE2-LABEL: @insert_dup_mem_v2f64
332 ; SSE2:         movsd {{.*}}, %xmm0
333 ; SSE2-NEXT:    movlhps {{.*}} # xmm0 = xmm0[0,0]
334 ; SSE2-NEXT:    retq
335 ;
336 ; SSE3-LABEL: @insert_dup_mem_v2f64
337 ; SSE3:         movddup {{.*}}, %xmm0
338 ; SSE3-NEXT:    retq
339 ;
340 ; SSE41-LABEL: @insert_dup_mem_v2f64
341 ; SSE41:         movddup {{.*}}, %xmm0
342 ; SSE41-NEXT:    retq
343   %a = load double* %ptr
344   %v = insertelement <2 x double> undef, double %a, i32 0
345   %shuffle = shufflevector <2 x double> %v, <2 x double> undef, <2 x i32> <i32 0, i32 0>
346   ret <2 x double> %shuffle
347 }