1 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -x86-experimental-vector-shuffle-lowering | FileCheck %s --check-prefix=CHECK-SSE2
2 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+sse3 -x86-experimental-vector-shuffle-lowering | FileCheck %s --check-prefix=CHECK-SSE3
4 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
5 target triple = "x86_64-unknown-unknown"
7 define <2 x i64> @shuffle_v2i64_00(<2 x i64> %a, <2 x i64> %b) {
8 ; CHECK-SSE2-LABEL: @shuffle_v2i64_00
9 ; CHECK-SSE2: pshufd {{.*}} # xmm0 = xmm0[0,1,0,1]
10 ; CHECK-SSE2-NEXT: retq
11 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 0, i32 0>
12 ret <2 x i64> %shuffle
14 define <2 x i64> @shuffle_v2i64_10(<2 x i64> %a, <2 x i64> %b) {
15 ; CHECK-SSE2-LABEL: @shuffle_v2i64_10
16 ; CHECK-SSE2: pshufd {{.*}} # xmm0 = xmm0[2,3,0,1]
17 ; CHECK-SSE2-NEXT: retq
18 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 1, i32 0>
19 ret <2 x i64> %shuffle
21 define <2 x i64> @shuffle_v2i64_11(<2 x i64> %a, <2 x i64> %b) {
22 ; CHECK-SSE2-LABEL: @shuffle_v2i64_11
23 ; CHECK-SSE2: pshufd {{.*}} # xmm0 = xmm0[2,3,2,3]
24 ; CHECK-SSE2-NEXT: retq
25 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 1, i32 1>
26 ret <2 x i64> %shuffle
28 define <2 x i64> @shuffle_v2i64_22(<2 x i64> %a, <2 x i64> %b) {
29 ; CHECK-SSE2-LABEL: @shuffle_v2i64_22
30 ; CHECK-SSE2: pshufd {{.*}} # xmm0 = xmm1[0,1,0,1]
31 ; CHECK-SSE2-NEXT: retq
32 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 2, i32 2>
33 ret <2 x i64> %shuffle
35 define <2 x i64> @shuffle_v2i64_32(<2 x i64> %a, <2 x i64> %b) {
36 ; CHECK-SSE2-LABEL: @shuffle_v2i64_32
37 ; CHECK-SSE2: pshufd {{.*}} # xmm0 = xmm1[2,3,0,1]
38 ; CHECK-SSE2-NEXT: retq
39 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 3, i32 2>
40 ret <2 x i64> %shuffle
42 define <2 x i64> @shuffle_v2i64_33(<2 x i64> %a, <2 x i64> %b) {
43 ; CHECK-SSE2-LABEL: @shuffle_v2i64_33
44 ; CHECK-SSE2: pshufd {{.*}} # xmm0 = xmm1[2,3,2,3]
45 ; CHECK-SSE2-NEXT: retq
46 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 3, i32 3>
47 ret <2 x i64> %shuffle
50 define <2 x double> @shuffle_v2f64_00(<2 x double> %a, <2 x double> %b) {
51 ; CHECK-SSE2-LABEL: @shuffle_v2f64_00
52 ; CHECK-SSE2: unpcklpd {{.*}} # xmm0 = xmm0[0,0]
53 ; CHECK-SSE2-NEXT: retq
54 %shuffle = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 0, i32 0>
55 ret <2 x double> %shuffle
57 define <2 x double> @shuffle_v2f64_10(<2 x double> %a, <2 x double> %b) {
58 ; CHECK-SSE2-LABEL: @shuffle_v2f64_10
59 ; CHECK-SSE2: shufpd {{.*}} # xmm0 = xmm0[1,0]
60 ; CHECK-SSE2-NEXT: retq
61 %shuffle = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 1, i32 0>
62 ret <2 x double> %shuffle
64 define <2 x double> @shuffle_v2f64_11(<2 x double> %a, <2 x double> %b) {
65 ; CHECK-SSE2-LABEL: @shuffle_v2f64_11
66 ; CHECK-SSE2: unpckhpd {{.*}} # xmm0 = xmm0[1,1]
67 ; CHECK-SSE2-NEXT: retq
68 %shuffle = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 1, i32 1>
69 ret <2 x double> %shuffle
71 define <2 x double> @shuffle_v2f64_22(<2 x double> %a, <2 x double> %b) {
72 ; CHECK-SSE2-LABEL: @shuffle_v2f64_22
73 ; CHECK-SSE2: unpcklpd {{.*}} # xmm1 = xmm1[0,0]
74 ; CHECK-SSE2-NEXT: movapd %xmm1, %xmm0
75 ; CHECK-SSE2-NEXT: retq
76 %shuffle = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 2, i32 2>
77 ret <2 x double> %shuffle
79 define <2 x double> @shuffle_v2f64_32(<2 x double> %a, <2 x double> %b) {
80 ; CHECK-SSE2-LABEL: @shuffle_v2f64_32
81 ; CHECK-SSE2: pshufd {{.*}} # xmm0 = xmm1[2,3,0,1]
82 ; CHECK-SSE2-NEXT: retq
83 %shuffle = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 3, i32 2>
84 ret <2 x double> %shuffle
86 define <2 x double> @shuffle_v2f64_33(<2 x double> %a, <2 x double> %b) {
87 ; CHECK-SSE2-LABEL: @shuffle_v2f64_33
88 ; CHECK-SSE2: unpckhpd {{.*}} # xmm1 = xmm1[1,1]
89 ; CHECK-SSE2-NEXT: movapd %xmm1, %xmm0
90 ; CHECK-SSE2-NEXT: retq
91 %shuffle = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 3, i32 3>
92 ret <2 x double> %shuffle
96 define <2 x i64> @shuffle_v2i64_02(<2 x i64> %a, <2 x i64> %b) {
97 ; CHECK-SSE2-LABEL: @shuffle_v2i64_02
98 ; CHECK-SSE2: punpcklqdq {{.*}} # xmm0 = xmm0[0],xmm1[0]
99 ; CHECK-SSE2-NEXT: retq
100 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 0, i32 2>
101 ret <2 x i64> %shuffle
103 define <2 x i64> @shuffle_v2i64_02_copy(<2 x i64> %nonce, <2 x i64> %a, <2 x i64> %b) {
104 ; CHECK-SSE2-LABEL: @shuffle_v2i64_02_copy
105 ; CHECK-SSE2: punpcklqdq {{.*}} # xmm1 = xmm1[0],xmm2[0]
106 ; CHECK-SSE2-NEXT: movdqa %xmm1, %xmm0
107 ; CHECK-SSE2-NEXT: retq
108 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 0, i32 2>
109 ret <2 x i64> %shuffle
111 define <2 x i64> @shuffle_v2i64_03(<2 x i64> %a, <2 x i64> %b) {
112 ; CHECK-SSE2-LABEL: @shuffle_v2i64_03
113 ; CHECK-SSE2: shufpd {{.*}} # xmm0 = xmm0[0],xmm1[1]
114 ; CHECK-SSE2-NEXT: retq
115 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 0, i32 3>
116 ret <2 x i64> %shuffle
118 define <2 x i64> @shuffle_v2i64_03_copy(<2 x i64> %nonce, <2 x i64> %a, <2 x i64> %b) {
119 ; CHECK-SSE2-LABEL: @shuffle_v2i64_03_copy
120 ; CHECK-SSE2: shufpd {{.*}} # xmm1 = xmm1[0],xmm2[1]
121 ; CHECK-SSE2-NEXT: movapd %xmm1, %xmm0
122 ; CHECK-SSE2-NEXT: retq
123 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 0, i32 3>
124 ret <2 x i64> %shuffle
126 define <2 x i64> @shuffle_v2i64_12(<2 x i64> %a, <2 x i64> %b) {
127 ; CHECK-SSE2-LABEL: @shuffle_v2i64_12
128 ; CHECK-SSE2: shufpd {{.*}} # xmm0 = xmm0[1],xmm1[0]
129 ; CHECK-SSE2-NEXT: retq
130 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 1, i32 2>
131 ret <2 x i64> %shuffle
133 define <2 x i64> @shuffle_v2i64_12_copy(<2 x i64> %nonce, <2 x i64> %a, <2 x i64> %b) {
134 ; CHECK-SSE2-LABEL: @shuffle_v2i64_12_copy
135 ; CHECK-SSE2: shufpd {{.*}} # xmm1 = xmm1[1],xmm2[0]
136 ; CHECK-SSE2-NEXT: movapd %xmm1, %xmm0
137 ; CHECK-SSE2-NEXT: retq
138 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 1, i32 2>
139 ret <2 x i64> %shuffle
141 define <2 x i64> @shuffle_v2i64_13(<2 x i64> %a, <2 x i64> %b) {
142 ; CHECK-SSE2-LABEL: @shuffle_v2i64_13
143 ; CHECK-SSE2: punpckhqdq {{.*}} # xmm0 = xmm0[1],xmm1[1]
144 ; CHECK-SSE2-NEXT: retq
145 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 1, i32 3>
146 ret <2 x i64> %shuffle
148 define <2 x i64> @shuffle_v2i64_13_copy(<2 x i64> %nonce, <2 x i64> %a, <2 x i64> %b) {
149 ; CHECK-SSE2-LABEL: @shuffle_v2i64_13_copy
150 ; CHECK-SSE2: punpckhqdq {{.*}} # xmm1 = xmm1[1],xmm2[1]
151 ; CHECK-SSE2-NEXT: movdqa %xmm1, %xmm0
152 ; CHECK-SSE2-NEXT: retq
153 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 1, i32 3>
154 ret <2 x i64> %shuffle
156 define <2 x i64> @shuffle_v2i64_20(<2 x i64> %a, <2 x i64> %b) {
157 ; CHECK-SSE2-LABEL: @shuffle_v2i64_20
158 ; CHECK-SSE2: punpcklqdq {{.*}} # xmm1 = xmm1[0],xmm0[0]
159 ; CHECK-SSE2-NEXT: movdqa %xmm1, %xmm0
160 ; CHECK-SSE2-NEXT: retq
161 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 2, i32 0>
162 ret <2 x i64> %shuffle
164 define <2 x i64> @shuffle_v2i64_20_copy(<2 x i64> %nonce, <2 x i64> %a, <2 x i64> %b) {
165 ; CHECK-SSE2-LABEL: @shuffle_v2i64_20_copy
166 ; CHECK-SSE2: punpcklqdq {{.*}} # xmm2 = xmm2[0],xmm1[0]
167 ; CHECK-SSE2-NEXT: movdqa %xmm2, %xmm0
168 ; CHECK-SSE2-NEXT: retq
169 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 2, i32 0>
170 ret <2 x i64> %shuffle
172 define <2 x i64> @shuffle_v2i64_21(<2 x i64> %a, <2 x i64> %b) {
173 ; CHECK-SSE2-LABEL: @shuffle_v2i64_21
174 ; CHECK-SSE2: shufpd {{.*}} # xmm1 = xmm1[0],xmm0[1]
175 ; CHECK-SSE2-NEXT: movapd %xmm1, %xmm0
176 ; CHECK-SSE2-NEXT: retq
177 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 2, i32 1>
178 ret <2 x i64> %shuffle
180 define <2 x i64> @shuffle_v2i64_21_copy(<2 x i64> %nonce, <2 x i64> %a, <2 x i64> %b) {
181 ; CHECK-SSE2-LABEL: @shuffle_v2i64_21_copy
182 ; CHECK-SSE2: shufpd {{.*}} # xmm2 = xmm2[0],xmm1[1]
183 ; CHECK-SSE2-NEXT: movapd %xmm2, %xmm0
184 ; CHECK-SSE2-NEXT: retq
185 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 2, i32 1>
186 ret <2 x i64> %shuffle
188 define <2 x i64> @shuffle_v2i64_30(<2 x i64> %a, <2 x i64> %b) {
189 ; CHECK-SSE2-LABEL: @shuffle_v2i64_30
190 ; CHECK-SSE2: shufpd {{.*}} # xmm1 = xmm1[1],xmm0[0]
191 ; CHECK-SSE2-NEXT: movapd %xmm1, %xmm0
192 ; CHECK-SSE2-NEXT: retq
193 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 3, i32 0>
194 ret <2 x i64> %shuffle
196 define <2 x i64> @shuffle_v2i64_30_copy(<2 x i64> %nonce, <2 x i64> %a, <2 x i64> %b) {
197 ; CHECK-SSE2-LABEL: @shuffle_v2i64_30_copy
198 ; CHECK-SSE2: shufpd {{.*}} # xmm2 = xmm2[1],xmm1[0]
199 ; CHECK-SSE2-NEXT: movapd %xmm2, %xmm0
200 ; CHECK-SSE2-NEXT: retq
201 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 3, i32 0>
202 ret <2 x i64> %shuffle
204 define <2 x i64> @shuffle_v2i64_31(<2 x i64> %a, <2 x i64> %b) {
205 ; CHECK-SSE2-LABEL: @shuffle_v2i64_31
206 ; CHECK-SSE2: punpckhqdq {{.*}} # xmm1 = xmm1[1],xmm0[1]
207 ; CHECK-SSE2-NEXT: movdqa %xmm1, %xmm0
208 ; CHECK-SSE2-NEXT: retq
209 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 3, i32 1>
210 ret <2 x i64> %shuffle
212 define <2 x i64> @shuffle_v2i64_31_copy(<2 x i64> %nonce, <2 x i64> %a, <2 x i64> %b) {
213 ; CHECK-SSE2-LABEL: @shuffle_v2i64_31_copy
214 ; CHECK-SSE2: punpckhqdq {{.*}} # xmm2 = xmm2[1],xmm1[1]
215 ; CHECK-SSE2-NEXT: movdqa %xmm2, %xmm0
216 ; CHECK-SSE2-NEXT: retq
217 %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 3, i32 1>
218 ret <2 x i64> %shuffle
222 define <2 x double> @insert_dup_reg_v2f64(double %a) {
223 ; CHECK-SSE2-LABEL: @insert_dup_reg_v2f64
224 ; CHECK-SSE2: unpcklpd {{.*}} # xmm0 = xmm0[0,0]
225 ; CHECK-SSE2-NEXT: retq
227 ; CHECK-SSE3-LABEL: @insert_dup_reg_v2f64
228 ; CHECK-SSE3: unpcklpd {{.*}} # xmm0 = xmm0[0,0]
229 ; CHECK-SSE3-NEXT: retq
230 %v = insertelement <2 x double> undef, double %a, i32 0
231 %shuffle = shufflevector <2 x double> %v, <2 x double> undef, <2 x i32> <i32 0, i32 0>
232 ret <2 x double> %shuffle
234 define <2 x double> @insert_dup_mem_v2f64(double* %ptr) {
235 ; CHECK-SSE2-LABEL: @insert_dup_mem_v2f64
236 ; CHECK-SSE2: movsd {{.*}}, %xmm0
237 ; CHECK-SSE2-NEXT: unpcklpd {{.*}} # xmm0 = xmm0[0,0]
238 ; CHECK-SSE2-NEXT: retq
240 ; CHECK-SSE3-LABEL: @insert_dup_mem_v2f64
241 ; CHECK-SSE3: movddup {{.*}}, %xmm0
242 ; CHECK-SSE3-NEXT: retq
243 %a = load double* %ptr
244 %v = insertelement <2 x double> undef, double %a, i32 0
245 %shuffle = shufflevector <2 x double> %v, <2 x double> undef, <2 x i32> <i32 0, i32 0>
246 ret <2 x double> %shuffle