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
5 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
6 target triple = "x86_64-unknown-unknown"
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]
12 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 0, i32 0>
13 ret <2 x i64> %shuffle
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]
19 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 1, i32 0>
20 ret <2 x i64> %shuffle
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]
26 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 1, i32 1>
27 ret <2 x i64> %shuffle
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]
33 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 2, i32 2>
34 ret <2 x i64> %shuffle
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]
40 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 3, i32 2>
41 ret <2 x i64> %shuffle
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]
47 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 3, i32 3>
48 ret <2 x i64> %shuffle
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]
56 ; SSE3-LABEL: @shuffle_v2f64_00
57 ; SSE3: unpcklpd {{.*}} # xmm0 = xmm0[0,0]
60 ; SSE41-LABEL: @shuffle_v2f64_00
61 ; SSE41: unpcklpd {{.*}} # xmm0 = xmm0[0,0]
63 %shuffle = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 0, i32 0>
64 ret <2 x double> %shuffle
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]
70 %shuffle = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 1, i32 0>
71 ret <2 x double> %shuffle
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]
77 %shuffle = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 1, i32 1>
78 ret <2 x double> %shuffle
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
86 ; SSE3-LABEL: @shuffle_v2f64_22
87 ; SSE3: unpcklpd {{.*}} # xmm1 = xmm1[0,0]
88 ; SSE3-NEXT: movapd %xmm1, %xmm0
91 ; SSE41-LABEL: @shuffle_v2f64_22
92 ; SSE41: unpcklpd {{.*}} # xmm1 = xmm1[0,0]
93 ; SSE41-NEXT: movapd %xmm1, %xmm0
95 %shuffle = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 2, i32 2>
96 ret <2 x double> %shuffle
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]
102 %shuffle = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 3, i32 2>
103 ret <2 x double> %shuffle
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
110 %shuffle = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 3, i32 3>
111 ret <2 x double> %shuffle
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]
118 ; SSE3-LABEL: @shuffle_v2f64_03
119 ; SSE3: shufpd {{.*}} # xmm0 = xmm0[0],xmm1[1]
122 ; SSE41-LABEL: @shuffle_v2f64_03
123 ; SSE41: blendpd {{.*}} # xmm0 = xmm0[0],xmm1[1]
125 %shuffle = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 0, i32 3>
126 ret <2 x double> %shuffle
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
134 ; SSE3-LABEL: @shuffle_v2f64_21
135 ; SSE3: shufpd {{.*}} # xmm1 = xmm1[0],xmm0[1]
136 ; SSE3-NEXT: movapd %xmm1, %xmm0
139 ; SSE41-LABEL: @shuffle_v2f64_21
140 ; SSE41: blendpd {{.*}} # xmm1 = xmm1[0],xmm0[1]
141 ; SSE41-NEXT: movapd %xmm1, %xmm0
143 %shuffle = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 2, i32 1>
144 ret <2 x double> %shuffle
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]
152 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 0, i32 2>
153 ret <2 x i64> %shuffle
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
160 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 0, i32 2>
161 ret <2 x i64> %shuffle
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]
168 ; SSE3-LABEL: @shuffle_v2i64_03
169 ; SSE3: shufpd {{.*}} # xmm0 = xmm0[0],xmm1[1]
172 ; SSE41-LABEL: @shuffle_v2i64_03
173 ; SSE41: blendpd {{.*}} # xmm0 = xmm0[0],xmm1[1]
175 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 0, i32 3>
176 ret <2 x i64> %shuffle
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
184 ; SSE3-LABEL: @shuffle_v2i64_03_copy
185 ; SSE3: shufpd {{.*}} # xmm1 = xmm1[0],xmm2[1]
186 ; SSE3-NEXT: movapd %xmm1, %xmm0
189 ; SSE41-LABEL: @shuffle_v2i64_03_copy
190 ; SSE41: blendpd {{.*}} # xmm1 = xmm1[0],xmm2[1]
191 ; SSE41-NEXT: movapd %xmm1, %xmm0
193 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 0, i32 3>
194 ret <2 x i64> %shuffle
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]
200 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 1, i32 2>
201 ret <2 x i64> %shuffle
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
208 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 1, i32 2>
209 ret <2 x i64> %shuffle
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]
215 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 1, i32 3>
216 ret <2 x i64> %shuffle
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
223 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 1, i32 3>
224 ret <2 x i64> %shuffle
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
231 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 2, i32 0>
232 ret <2 x i64> %shuffle
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
239 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 2, i32 0>
240 ret <2 x i64> %shuffle
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
248 ; SSE3-LABEL: @shuffle_v2i64_21
249 ; SSE3: shufpd {{.*}} # xmm1 = xmm1[0],xmm0[1]
250 ; SSE3-NEXT: movapd %xmm1, %xmm0
253 ; SSE41-LABEL: @shuffle_v2i64_21
254 ; SSE41: blendpd {{.*}} # xmm1 = xmm1[0],xmm0[1]
255 ; SSE41-NEXT: movapd %xmm1, %xmm0
257 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 2, i32 1>
258 ret <2 x i64> %shuffle
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
266 ; SSE3-LABEL: @shuffle_v2i64_21_copy
267 ; SSE3: shufpd {{.*}} # xmm2 = xmm2[0],xmm1[1]
268 ; SSE3-NEXT: movapd %xmm2, %xmm0
271 ; SSE41-LABEL: @shuffle_v2i64_21_copy
272 ; SSE41: blendpd {{.*}} # xmm2 = xmm2[0],xmm1[1]
273 ; SSE41-NEXT: movapd %xmm2, %xmm0
275 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 2, i32 1>
276 ret <2 x i64> %shuffle
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
283 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 3, i32 0>
284 ret <2 x i64> %shuffle
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
291 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 3, i32 0>
292 ret <2 x i64> %shuffle
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
299 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 3, i32 1>
300 ret <2 x i64> %shuffle
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
307 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 3, i32 1>
308 ret <2 x i64> %shuffle
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]
317 ; FIXME: This should match movddup as well!
318 ; SSE3-LABEL: @insert_dup_reg_v2f64
319 ; SSE3: unpcklpd {{.*}} # xmm0 = xmm0[0,0]
322 ; FIXME: This should match movddup as well!
323 ; SSE41-LABEL: @insert_dup_reg_v2f64
324 ; SSE41: unpcklpd {{.*}} # xmm0 = xmm0[0,0]
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
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]
336 ; SSE3-LABEL: @insert_dup_mem_v2f64
337 ; SSE3: movddup {{.*}}, %xmm0
340 ; SSE41-LABEL: @insert_dup_mem_v2f64
341 ; SSE41: movddup {{.*}}, %xmm0
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