[SDAG] Now that we have a way to communicate the exact bit on sdiv use it to simplify...
[oota-llvm.git] / test / CodeGen / X86 / vector-sext.ll
1 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+sse2 | FileCheck %s --check-prefix=SSE --check-prefix=SSE2
2 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+ssse3 | FileCheck %s --check-prefix=SSE --check-prefix=SSSE3
3 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+sse4.1 | FileCheck %s --check-prefix=SSE --check-prefix=SSE41
4 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+avx | FileCheck %s --check-prefix=AVX --check-prefix=AVX1
5 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+avx2 | FileCheck %s --check-prefix=AVX --check-prefix=AVX2
6 ;
7 ; Just one 32-bit run to make sure we do reasonable things there.
8 ; RUN: llc < %s -mtriple=i686-unknown-unknown -mcpu=i686 -mattr=+sse4.1 | FileCheck %s --check-prefix=X32-SSE41
9
10 define <8 x i32> @sext_8i16_to_8i32(<8 x i16> %A) nounwind uwtable readnone ssp {
11 ; SSE2-LABEL: sext_8i16_to_8i32:
12 ; SSE2:       # BB#0: # %entry
13 ; SSE2-NEXT:    punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1],xmm2[2],xmm0[2],xmm2[3],xmm0[3]
14 ; SSE2-NEXT:    psrad $16, %xmm2
15 ; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
16 ; SSE2-NEXT:    punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
17 ; SSE2-NEXT:    psrad $16, %xmm1
18 ; SSE2-NEXT:    movdqa %xmm2, %xmm0
19 ; SSE2-NEXT:    retq
20 ;
21 ; SSSE3-LABEL: sext_8i16_to_8i32:
22 ; SSSE3:       # BB#0: # %entry
23 ; SSSE3-NEXT:    punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1],xmm2[2],xmm0[2],xmm2[3],xmm0[3]
24 ; SSSE3-NEXT:    psrad $16, %xmm2
25 ; SSSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
26 ; SSSE3-NEXT:    punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
27 ; SSSE3-NEXT:    psrad $16, %xmm1
28 ; SSSE3-NEXT:    movdqa %xmm2, %xmm0
29 ; SSSE3-NEXT:    retq
30 ;
31 ; SSE41-LABEL: sext_8i16_to_8i32:
32 ; SSE41:       # BB#0: # %entry
33 ; SSE41-NEXT:    pmovsxwd %xmm0, %xmm2
34 ; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
35 ; SSE41-NEXT:    pmovsxwd %xmm0, %xmm1
36 ; SSE41-NEXT:    movdqa %xmm2, %xmm0
37 ; SSE41-NEXT:    retq
38 ;
39 ; AVX1-LABEL: sext_8i16_to_8i32:
40 ; AVX1:       # BB#0: # %entry
41 ; AVX1-NEXT:    vpmovsxwd %xmm0, %xmm1
42 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
43 ; AVX1-NEXT:    vpmovsxwd %xmm0, %xmm0
44 ; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
45 ; AVX1-NEXT:    retq
46 ;
47 ; AVX2-LABEL: sext_8i16_to_8i32:
48 ; AVX2:       # BB#0: # %entry
49 ; AVX2-NEXT:    vpmovsxwd %xmm0, %ymm0
50 ; AVX2-NEXT:    retq
51 ;
52 ; X32-SSE41-LABEL: sext_8i16_to_8i32:
53 ; X32-SSE41:       # BB#0: # %entry
54 ; X32-SSE41-NEXT:    pmovsxwd %xmm0, %xmm2
55 ; X32-SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
56 ; X32-SSE41-NEXT:    pmovsxwd %xmm0, %xmm1
57 ; X32-SSE41-NEXT:    movdqa %xmm2, %xmm0
58 ; X32-SSE41-NEXT:    retl
59 entry:
60   %B = sext <8 x i16> %A to <8 x i32>
61   ret <8 x i32>%B
62 }
63
64 define <4 x i64> @sext_4i32_to_4i64(<4 x i32> %A) nounwind uwtable readnone ssp {
65 ; SSE2-LABEL: sext_4i32_to_4i64:
66 ; SSE2:       # BB#0: # %entry
67 ; SSE2-NEXT:    movdqa %xmm0, %xmm2
68 ; SSE2-NEXT:    psrad $31, %xmm2
69 ; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
70 ; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
71 ; SSE2-NEXT:    movdqa %xmm1, %xmm2
72 ; SSE2-NEXT:    psrad $31, %xmm2
73 ; SSE2-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
74 ; SSE2-NEXT:    retq
75 ;
76 ; SSSE3-LABEL: sext_4i32_to_4i64:
77 ; SSSE3:       # BB#0: # %entry
78 ; SSSE3-NEXT:    movdqa %xmm0, %xmm2
79 ; SSSE3-NEXT:    psrad $31, %xmm2
80 ; SSSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
81 ; SSSE3-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
82 ; SSSE3-NEXT:    movdqa %xmm1, %xmm2
83 ; SSSE3-NEXT:    psrad $31, %xmm2
84 ; SSSE3-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
85 ; SSSE3-NEXT:    retq
86 ;
87 ; SSE41-LABEL: sext_4i32_to_4i64:
88 ; SSE41:       # BB#0: # %entry
89 ; SSE41-NEXT:    pmovsxdq %xmm0, %xmm2
90 ; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
91 ; SSE41-NEXT:    pmovsxdq %xmm0, %xmm1
92 ; SSE41-NEXT:    movdqa %xmm2, %xmm0
93 ; SSE41-NEXT:    retq
94 ;
95 ; AVX1-LABEL: sext_4i32_to_4i64:
96 ; AVX1:       # BB#0: # %entry
97 ; AVX1-NEXT:    vpmovsxdq %xmm0, %xmm1
98 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
99 ; AVX1-NEXT:    vpmovsxdq %xmm0, %xmm0
100 ; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
101 ; AVX1-NEXT:    retq
102 ;
103 ; AVX2-LABEL: sext_4i32_to_4i64:
104 ; AVX2:       # BB#0: # %entry
105 ; AVX2-NEXT:    vpmovsxdq %xmm0, %ymm0
106 ; AVX2-NEXT:    retq
107 ;
108 ; X32-SSE41-LABEL: sext_4i32_to_4i64:
109 ; X32-SSE41:       # BB#0: # %entry
110 ; X32-SSE41-NEXT:    pmovsxdq %xmm0, %xmm2
111 ; X32-SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
112 ; X32-SSE41-NEXT:    pmovsxdq %xmm0, %xmm1
113 ; X32-SSE41-NEXT:    movdqa %xmm2, %xmm0
114 ; X32-SSE41-NEXT:    retl
115 entry:
116   %B = sext <4 x i32> %A to <4 x i64>
117   ret <4 x i64>%B
118 }
119
120 define <4 x i32> @load_sext_test1(<4 x i16> *%ptr) {
121 ; SSE2-LABEL: load_sext_test1:
122 ; SSE2:       # BB#0: # %entry
123 ; SSE2-NEXT:    movq (%rdi), %xmm0
124 ; SSE2-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
125 ; SSE2-NEXT:    psrad $16, %xmm0
126 ; SSE2-NEXT:    retq
127 ;
128 ; SSSE3-LABEL: load_sext_test1:
129 ; SSSE3:       # BB#0: # %entry
130 ; SSSE3-NEXT:    movq (%rdi), %xmm0
131 ; SSSE3-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
132 ; SSSE3-NEXT:    psrad $16, %xmm0
133 ; SSSE3-NEXT:    retq
134 ;
135 ; SSE41-LABEL: load_sext_test1:
136 ; SSE41:       # BB#0: # %entry
137 ; SSE41-NEXT:    pmovsxwd (%rdi), %xmm0
138 ; SSE41-NEXT:    retq
139 ;
140 ; AVX-LABEL: load_sext_test1:
141 ; AVX:       # BB#0: # %entry
142 ; AVX-NEXT:    vpmovsxwd (%rdi), %xmm0
143 ; AVX-NEXT:    retq
144 ;
145 ; X32-SSE41-LABEL: load_sext_test1:
146 ; X32-SSE41:       # BB#0: # %entry
147 ; X32-SSE41-NEXT:    movl {{[0-9]+}}(%esp), %eax
148 ; X32-SSE41-NEXT:    pmovsxwd (%eax), %xmm0
149 ; X32-SSE41-NEXT:    retl
150 entry:
151  %X = load <4 x i16>, <4 x i16>* %ptr
152  %Y = sext <4 x i16> %X to <4 x i32>
153  ret <4 x i32>%Y
154 }
155
156 define <4 x i32> @load_sext_test2(<4 x i8> *%ptr) {
157 ; SSE2-LABEL: load_sext_test2:
158 ; SSE2:       # BB#0: # %entry
159 ; SSE2-NEXT:    movd (%rdi), %xmm0
160 ; SSE2-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
161 ; SSE2-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
162 ; SSE2-NEXT:    psrad $24, %xmm0
163 ; SSE2-NEXT:    retq
164 ;
165 ; SSSE3-LABEL: load_sext_test2:
166 ; SSSE3:       # BB#0: # %entry
167 ; SSSE3-NEXT:    movd (%rdi), %xmm0
168 ; SSSE3-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
169 ; SSSE3-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
170 ; SSSE3-NEXT:    psrad $24, %xmm0
171 ; SSSE3-NEXT:    retq
172 ;
173 ; SSE41-LABEL: load_sext_test2:
174 ; SSE41:       # BB#0: # %entry
175 ; SSE41-NEXT:    pmovsxbd (%rdi), %xmm0
176 ; SSE41-NEXT:    retq
177 ;
178 ; AVX-LABEL: load_sext_test2:
179 ; AVX:       # BB#0: # %entry
180 ; AVX-NEXT:    vpmovsxbd (%rdi), %xmm0
181 ; AVX-NEXT:    retq
182 ;
183 ; X32-SSE41-LABEL: load_sext_test2:
184 ; X32-SSE41:       # BB#0: # %entry
185 ; X32-SSE41-NEXT:    movl {{[0-9]+}}(%esp), %eax
186 ; X32-SSE41-NEXT:    pmovsxbd (%eax), %xmm0
187 ; X32-SSE41-NEXT:    retl
188 entry:
189  %X = load <4 x i8>, <4 x i8>* %ptr
190  %Y = sext <4 x i8> %X to <4 x i32>
191  ret <4 x i32>%Y
192 }
193
194 define <2 x i64> @load_sext_test3(<2 x i8> *%ptr) {
195 ; SSE2-LABEL: load_sext_test3:
196 ; SSE2:       # BB#0: # %entry
197 ; SSE2-NEXT:    movzwl (%rdi), %eax
198 ; SSE2-NEXT:    movd %eax, %xmm0
199 ; SSE2-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
200 ; SSE2-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
201 ; SSE2-NEXT:    movdqa %xmm0, %xmm1
202 ; SSE2-NEXT:    psrad $31, %xmm1
203 ; SSE2-NEXT:    psrad $24, %xmm0
204 ; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
205 ; SSE2-NEXT:    retq
206 ;
207 ; SSSE3-LABEL: load_sext_test3:
208 ; SSSE3:       # BB#0: # %entry
209 ; SSSE3-NEXT:    movzwl (%rdi), %eax
210 ; SSSE3-NEXT:    movd %eax, %xmm0
211 ; SSSE3-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
212 ; SSSE3-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
213 ; SSSE3-NEXT:    movdqa %xmm0, %xmm1
214 ; SSSE3-NEXT:    psrad $31, %xmm1
215 ; SSSE3-NEXT:    psrad $24, %xmm0
216 ; SSSE3-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
217 ; SSSE3-NEXT:    retq
218 ;
219 ; SSE41-LABEL: load_sext_test3:
220 ; SSE41:       # BB#0: # %entry
221 ; SSE41-NEXT:    pmovsxbq (%rdi), %xmm0
222 ; SSE41-NEXT:    retq
223 ;
224 ; AVX-LABEL: load_sext_test3:
225 ; AVX:       # BB#0: # %entry
226 ; AVX-NEXT:    vpmovsxbq (%rdi), %xmm0
227 ; AVX-NEXT:    retq
228 ;
229 ; X32-SSE41-LABEL: load_sext_test3:
230 ; X32-SSE41:       # BB#0: # %entry
231 ; X32-SSE41-NEXT:    movl {{[0-9]+}}(%esp), %eax
232 ; X32-SSE41-NEXT:    pmovsxbq (%eax), %xmm0
233 ; X32-SSE41-NEXT:    retl
234 entry:
235  %X = load <2 x i8>, <2 x i8>* %ptr
236  %Y = sext <2 x i8> %X to <2 x i64>
237  ret <2 x i64>%Y
238 }
239
240 define <2 x i64> @load_sext_test4(<2 x i16> *%ptr) {
241 ; SSE2-LABEL: load_sext_test4:
242 ; SSE2:       # BB#0: # %entry
243 ; SSE2-NEXT:    movd (%rdi), %xmm0
244 ; SSE2-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
245 ; SSE2-NEXT:    movdqa %xmm0, %xmm1
246 ; SSE2-NEXT:    psrad $31, %xmm1
247 ; SSE2-NEXT:    psrad $16, %xmm0
248 ; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
249 ; SSE2-NEXT:    retq
250 ;
251 ; SSSE3-LABEL: load_sext_test4:
252 ; SSSE3:       # BB#0: # %entry
253 ; SSSE3-NEXT:    movd (%rdi), %xmm0
254 ; SSSE3-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
255 ; SSSE3-NEXT:    movdqa %xmm0, %xmm1
256 ; SSSE3-NEXT:    psrad $31, %xmm1
257 ; SSSE3-NEXT:    psrad $16, %xmm0
258 ; SSSE3-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
259 ; SSSE3-NEXT:    retq
260 ;
261 ; SSE41-LABEL: load_sext_test4:
262 ; SSE41:       # BB#0: # %entry
263 ; SSE41-NEXT:    pmovsxwq (%rdi), %xmm0
264 ; SSE41-NEXT:    retq
265 ;
266 ; AVX-LABEL: load_sext_test4:
267 ; AVX:       # BB#0: # %entry
268 ; AVX-NEXT:    vpmovsxwq (%rdi), %xmm0
269 ; AVX-NEXT:    retq
270 ;
271 ; X32-SSE41-LABEL: load_sext_test4:
272 ; X32-SSE41:       # BB#0: # %entry
273 ; X32-SSE41-NEXT:    movl {{[0-9]+}}(%esp), %eax
274 ; X32-SSE41-NEXT:    pmovsxwq (%eax), %xmm0
275 ; X32-SSE41-NEXT:    retl
276 entry:
277  %X = load <2 x i16>, <2 x i16>* %ptr
278  %Y = sext <2 x i16> %X to <2 x i64>
279  ret <2 x i64>%Y
280 }
281
282 define <2 x i64> @load_sext_test5(<2 x i32> *%ptr) {
283 ; SSE2-LABEL: load_sext_test5:
284 ; SSE2:       # BB#0: # %entry
285 ; SSE2-NEXT:    movq (%rdi), %xmm0
286 ; SSE2-NEXT:    movdqa %xmm0, %xmm1
287 ; SSE2-NEXT:    psrad $31, %xmm1
288 ; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
289 ; SSE2-NEXT:    retq
290 ;
291 ; SSSE3-LABEL: load_sext_test5:
292 ; SSSE3:       # BB#0: # %entry
293 ; SSSE3-NEXT:    movq (%rdi), %xmm0
294 ; SSSE3-NEXT:    movdqa %xmm0, %xmm1
295 ; SSSE3-NEXT:    psrad $31, %xmm1
296 ; SSSE3-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
297 ; SSSE3-NEXT:    retq
298 ;
299 ; SSE41-LABEL: load_sext_test5:
300 ; SSE41:       # BB#0: # %entry
301 ; SSE41-NEXT:    pmovsxdq (%rdi), %xmm0
302 ; SSE41-NEXT:    retq
303 ;
304 ; AVX-LABEL: load_sext_test5:
305 ; AVX:       # BB#0: # %entry
306 ; AVX-NEXT:    vpmovsxdq (%rdi), %xmm0
307 ; AVX-NEXT:    retq
308 ;
309 ; X32-SSE41-LABEL: load_sext_test5:
310 ; X32-SSE41:       # BB#0: # %entry
311 ; X32-SSE41-NEXT:    movl {{[0-9]+}}(%esp), %eax
312 ; X32-SSE41-NEXT:    pmovsxdq (%eax), %xmm0
313 ; X32-SSE41-NEXT:    retl
314 entry:
315  %X = load <2 x i32>, <2 x i32>* %ptr
316  %Y = sext <2 x i32> %X to <2 x i64>
317  ret <2 x i64>%Y
318 }
319
320 define <8 x i16> @load_sext_test6(<8 x i8> *%ptr) {
321 ; SSE2-LABEL: load_sext_test6:
322 ; SSE2:       # BB#0: # %entry
323 ; SSE2-NEXT:    movq (%rdi), %xmm0
324 ; SSE2-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
325 ; SSE2-NEXT:    psraw $8, %xmm0
326 ; SSE2-NEXT:    retq
327 ;
328 ; SSSE3-LABEL: load_sext_test6:
329 ; SSSE3:       # BB#0: # %entry
330 ; SSSE3-NEXT:    movq (%rdi), %xmm0
331 ; SSSE3-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
332 ; SSSE3-NEXT:    psraw $8, %xmm0
333 ; SSSE3-NEXT:    retq
334 ;
335 ; SSE41-LABEL: load_sext_test6:
336 ; SSE41:       # BB#0: # %entry
337 ; SSE41-NEXT:    pmovsxbw (%rdi), %xmm0
338 ; SSE41-NEXT:    retq
339 ;
340 ; AVX-LABEL: load_sext_test6:
341 ; AVX:       # BB#0: # %entry
342 ; AVX-NEXT:    vpmovsxbw (%rdi), %xmm0
343 ; AVX-NEXT:    retq
344 ;
345 ; X32-SSE41-LABEL: load_sext_test6:
346 ; X32-SSE41:       # BB#0: # %entry
347 ; X32-SSE41-NEXT:    movl {{[0-9]+}}(%esp), %eax
348 ; X32-SSE41-NEXT:    pmovsxbw (%eax), %xmm0
349 ; X32-SSE41-NEXT:    retl
350 entry:
351  %X = load <8 x i8>, <8 x i8>* %ptr
352  %Y = sext <8 x i8> %X to <8 x i16>
353  ret <8 x i16>%Y
354 }
355
356 define <4 x i64> @sext_4i1_to_4i64(<4 x i1> %mask) {
357 ; SSE2-LABEL: sext_4i1_to_4i64:
358 ; SSE2:       # BB#0:
359 ; SSE2-NEXT:    pslld $31, %xmm0
360 ; SSE2-NEXT:    psrad $31, %xmm0
361 ; SSE2-NEXT:    movdqa %xmm0, %xmm2
362 ; SSE2-NEXT:    psrad $31, %xmm2
363 ; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
364 ; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
365 ; SSE2-NEXT:    movdqa %xmm1, %xmm2
366 ; SSE2-NEXT:    psrad $31, %xmm2
367 ; SSE2-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
368 ; SSE2-NEXT:    retq
369 ;
370 ; SSSE3-LABEL: sext_4i1_to_4i64:
371 ; SSSE3:       # BB#0:
372 ; SSSE3-NEXT:    pslld $31, %xmm0
373 ; SSSE3-NEXT:    psrad $31, %xmm0
374 ; SSSE3-NEXT:    movdqa %xmm0, %xmm2
375 ; SSSE3-NEXT:    psrad $31, %xmm2
376 ; SSSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
377 ; SSSE3-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
378 ; SSSE3-NEXT:    movdqa %xmm1, %xmm2
379 ; SSSE3-NEXT:    psrad $31, %xmm2
380 ; SSSE3-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
381 ; SSSE3-NEXT:    retq
382 ;
383 ; SSE41-LABEL: sext_4i1_to_4i64:
384 ; SSE41:       # BB#0:
385 ; SSE41-NEXT:    pslld $31, %xmm0
386 ; SSE41-NEXT:    psrad $31, %xmm0
387 ; SSE41-NEXT:    pmovsxdq %xmm0, %xmm2
388 ; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
389 ; SSE41-NEXT:    pmovsxdq %xmm0, %xmm1
390 ; SSE41-NEXT:    movdqa %xmm2, %xmm0
391 ; SSE41-NEXT:    retq
392 ;
393 ; AVX1-LABEL: sext_4i1_to_4i64:
394 ; AVX1:       # BB#0:
395 ; AVX1-NEXT:    vpslld $31, %xmm0, %xmm0
396 ; AVX1-NEXT:    vpsrad $31, %xmm0, %xmm0
397 ; AVX1-NEXT:    vpmovsxdq %xmm0, %xmm1
398 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
399 ; AVX1-NEXT:    vpmovsxdq %xmm0, %xmm0
400 ; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
401 ; AVX1-NEXT:    retq
402 ;
403 ; AVX2-LABEL: sext_4i1_to_4i64:
404 ; AVX2:       # BB#0:
405 ; AVX2-NEXT:    vpslld $31, %xmm0, %xmm0
406 ; AVX2-NEXT:    vpsrad $31, %xmm0, %xmm0
407 ; AVX2-NEXT:    vpmovsxdq %xmm0, %ymm0
408 ; AVX2-NEXT:    retq
409 ;
410 ; X32-SSE41-LABEL: sext_4i1_to_4i64:
411 ; X32-SSE41:       # BB#0:
412 ; X32-SSE41-NEXT:    pslld $31, %xmm0
413 ; X32-SSE41-NEXT:    psrad $31, %xmm0
414 ; X32-SSE41-NEXT:    pmovsxdq %xmm0, %xmm2
415 ; X32-SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
416 ; X32-SSE41-NEXT:    pmovsxdq %xmm0, %xmm1
417 ; X32-SSE41-NEXT:    movdqa %xmm2, %xmm0
418 ; X32-SSE41-NEXT:    retl
419   %extmask = sext <4 x i1> %mask to <4 x i64>
420   ret <4 x i64> %extmask
421 }
422
423 define <16 x i16> @sext_16i8_to_16i16(<16 x i8> *%ptr) {
424 ; SSE2-LABEL: sext_16i8_to_16i16:
425 ; SSE2:       # BB#0: # %entry
426 ; SSE2-NEXT:    movq (%rdi), %xmm0
427 ; SSE2-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
428 ; SSE2-NEXT:    psraw $8, %xmm0
429 ; SSE2-NEXT:    movq 8(%rdi), %xmm1
430 ; SSE2-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
431 ; SSE2-NEXT:    psraw $8, %xmm1
432 ; SSE2-NEXT:    retq
433 ;
434 ; SSSE3-LABEL: sext_16i8_to_16i16:
435 ; SSSE3:       # BB#0: # %entry
436 ; SSSE3-NEXT:    movq (%rdi), %xmm0
437 ; SSSE3-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
438 ; SSSE3-NEXT:    psraw $8, %xmm0
439 ; SSSE3-NEXT:    movq 8(%rdi), %xmm1
440 ; SSSE3-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
441 ; SSSE3-NEXT:    psraw $8, %xmm1
442 ; SSSE3-NEXT:    retq
443 ;
444 ; SSE41-LABEL: sext_16i8_to_16i16:
445 ; SSE41:       # BB#0: # %entry
446 ; SSE41-NEXT:    pmovsxbw (%rdi), %xmm0
447 ; SSE41-NEXT:    pmovsxbw 8(%rdi), %xmm1
448 ; SSE41-NEXT:    retq
449 ;
450 ; AVX1-LABEL: sext_16i8_to_16i16:
451 ; AVX1:       # BB#0: # %entry
452 ; AVX1-NEXT:    vpmovsxbw (%rdi), %xmm0
453 ; AVX1-NEXT:    vpmovsxbw 8(%rdi), %xmm1
454 ; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
455 ; AVX1-NEXT:    retq
456 ;
457 ; AVX2-LABEL: sext_16i8_to_16i16:
458 ; AVX2:       # BB#0: # %entry
459 ; AVX2-NEXT:    vpmovsxbw (%rdi), %ymm0
460 ; AVX2-NEXT:    retq
461 ;
462 ; X32-SSE41-LABEL: sext_16i8_to_16i16:
463 ; X32-SSE41:       # BB#0: # %entry
464 ; X32-SSE41-NEXT:    movl {{[0-9]+}}(%esp), %eax
465 ; X32-SSE41-NEXT:    pmovsxbw (%eax), %xmm0
466 ; X32-SSE41-NEXT:    pmovsxbw 8(%eax), %xmm1
467 ; X32-SSE41-NEXT:    retl
468 entry:
469  %X = load <16 x i8>, <16 x i8>* %ptr
470  %Y = sext <16 x i8> %X to <16 x i16>
471  ret <16 x i16> %Y
472 }
473
474 define <4 x i64> @sext_4i8_to_4i64(<4 x i8> %mask) {
475 ; SSE2-LABEL: sext_4i8_to_4i64:
476 ; SSE2:       # BB#0:
477 ; SSE2-NEXT:    pslld $24, %xmm0
478 ; SSE2-NEXT:    psrad $24, %xmm0
479 ; SSE2-NEXT:    movdqa %xmm0, %xmm2
480 ; SSE2-NEXT:    psrad $31, %xmm2
481 ; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
482 ; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
483 ; SSE2-NEXT:    movdqa %xmm1, %xmm2
484 ; SSE2-NEXT:    psrad $31, %xmm2
485 ; SSE2-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
486 ; SSE2-NEXT:    retq
487 ;
488 ; SSSE3-LABEL: sext_4i8_to_4i64:
489 ; SSSE3:       # BB#0:
490 ; SSSE3-NEXT:    pslld $24, %xmm0
491 ; SSSE3-NEXT:    psrad $24, %xmm0
492 ; SSSE3-NEXT:    movdqa %xmm0, %xmm2
493 ; SSSE3-NEXT:    psrad $31, %xmm2
494 ; SSSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
495 ; SSSE3-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
496 ; SSSE3-NEXT:    movdqa %xmm1, %xmm2
497 ; SSSE3-NEXT:    psrad $31, %xmm2
498 ; SSSE3-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
499 ; SSSE3-NEXT:    retq
500 ;
501 ; SSE41-LABEL: sext_4i8_to_4i64:
502 ; SSE41:       # BB#0:
503 ; SSE41-NEXT:    pslld $24, %xmm0
504 ; SSE41-NEXT:    psrad $24, %xmm0
505 ; SSE41-NEXT:    pmovsxdq %xmm0, %xmm2
506 ; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
507 ; SSE41-NEXT:    pmovsxdq %xmm0, %xmm1
508 ; SSE41-NEXT:    movdqa %xmm2, %xmm0
509 ; SSE41-NEXT:    retq
510 ;
511 ; AVX1-LABEL: sext_4i8_to_4i64:
512 ; AVX1:       # BB#0:
513 ; AVX1-NEXT:    vpslld $24, %xmm0, %xmm0
514 ; AVX1-NEXT:    vpsrad $24, %xmm0, %xmm0
515 ; AVX1-NEXT:    vpmovsxdq %xmm0, %xmm1
516 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
517 ; AVX1-NEXT:    vpmovsxdq %xmm0, %xmm0
518 ; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
519 ; AVX1-NEXT:    retq
520 ;
521 ; AVX2-LABEL: sext_4i8_to_4i64:
522 ; AVX2:       # BB#0:
523 ; AVX2-NEXT:    vpslld $24, %xmm0, %xmm0
524 ; AVX2-NEXT:    vpsrad $24, %xmm0, %xmm0
525 ; AVX2-NEXT:    vpmovsxdq %xmm0, %ymm0
526 ; AVX2-NEXT:    retq
527 ;
528 ; X32-SSE41-LABEL: sext_4i8_to_4i64:
529 ; X32-SSE41:       # BB#0:
530 ; X32-SSE41-NEXT:    pslld $24, %xmm0
531 ; X32-SSE41-NEXT:    psrad $24, %xmm0
532 ; X32-SSE41-NEXT:    pmovsxdq %xmm0, %xmm2
533 ; X32-SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
534 ; X32-SSE41-NEXT:    pmovsxdq %xmm0, %xmm1
535 ; X32-SSE41-NEXT:    movdqa %xmm2, %xmm0
536 ; X32-SSE41-NEXT:    retl
537   %extmask = sext <4 x i8> %mask to <4 x i64>
538   ret <4 x i64> %extmask
539 }
540
541 define <4 x i64> @load_sext_4i8_to_4i64(<4 x i8> *%ptr) {
542 ; SSE2-LABEL: load_sext_4i8_to_4i64:
543 ; SSE2:       # BB#0: # %entry
544 ; SSE2-NEXT:    movsbq 1(%rdi), %rax
545 ; SSE2-NEXT:    movd %rax, %xmm1
546 ; SSE2-NEXT:    movsbq (%rdi), %rax
547 ; SSE2-NEXT:    movd %rax, %xmm0
548 ; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
549 ; SSE2-NEXT:    movsbq 3(%rdi), %rax
550 ; SSE2-NEXT:    movd %rax, %xmm2
551 ; SSE2-NEXT:    movsbq 2(%rdi), %rax
552 ; SSE2-NEXT:    movd %rax, %xmm1
553 ; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0]
554 ; SSE2-NEXT:    retq
555 ;
556 ; SSSE3-LABEL: load_sext_4i8_to_4i64:
557 ; SSSE3:       # BB#0: # %entry
558 ; SSSE3-NEXT:    movsbq 1(%rdi), %rax
559 ; SSSE3-NEXT:    movd %rax, %xmm1
560 ; SSSE3-NEXT:    movsbq (%rdi), %rax
561 ; SSSE3-NEXT:    movd %rax, %xmm0
562 ; SSSE3-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
563 ; SSSE3-NEXT:    movsbq 3(%rdi), %rax
564 ; SSSE3-NEXT:    movd %rax, %xmm2
565 ; SSSE3-NEXT:    movsbq 2(%rdi), %rax
566 ; SSSE3-NEXT:    movd %rax, %xmm1
567 ; SSSE3-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0]
568 ; SSSE3-NEXT:    retq
569 ;
570 ; SSE41-LABEL: load_sext_4i8_to_4i64:
571 ; SSE41:       # BB#0: # %entry
572 ; SSE41-NEXT:    pmovsxbq (%rdi), %xmm0
573 ; SSE41-NEXT:    pmovsxbq 2(%rdi), %xmm1
574 ; SSE41-NEXT:    retq
575 ;
576 ; AVX1-LABEL: load_sext_4i8_to_4i64:
577 ; AVX1:       # BB#0: # %entry
578 ; AVX1-NEXT:    vpmovsxbd (%rdi), %xmm0
579 ; AVX1-NEXT:    vpmovsxdq %xmm0, %xmm1
580 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
581 ; AVX1-NEXT:    vpmovsxdq %xmm0, %xmm0
582 ; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
583 ; AVX1-NEXT:    retq
584 ;
585 ; AVX2-LABEL: load_sext_4i8_to_4i64:
586 ; AVX2:       # BB#0: # %entry
587 ; AVX2-NEXT:    vpmovsxbq (%rdi), %ymm0
588 ; AVX2-NEXT:    retq
589 ;
590 ; X32-SSE41-LABEL: load_sext_4i8_to_4i64:
591 ; X32-SSE41:       # BB#0: # %entry
592 ; X32-SSE41-NEXT:    movl {{[0-9]+}}(%esp), %eax
593 ; X32-SSE41-NEXT:    pmovsxbq (%eax), %xmm0
594 ; X32-SSE41-NEXT:    pmovsxbq 2(%eax), %xmm1
595 ; X32-SSE41-NEXT:    retl
596 entry:
597  %X = load <4 x i8>, <4 x i8>* %ptr
598  %Y = sext <4 x i8> %X to <4 x i64>
599  ret <4 x i64>%Y
600 }
601
602 define <4 x i64> @load_sext_4i16_to_4i64(<4 x i16> *%ptr) {
603 ; SSE2-LABEL: load_sext_4i16_to_4i64:
604 ; SSE2:       # BB#0: # %entry
605 ; SSE2-NEXT:    movswq 2(%rdi), %rax
606 ; SSE2-NEXT:    movd %rax, %xmm1
607 ; SSE2-NEXT:    movswq (%rdi), %rax
608 ; SSE2-NEXT:    movd %rax, %xmm0
609 ; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
610 ; SSE2-NEXT:    movswq 6(%rdi), %rax
611 ; SSE2-NEXT:    movd %rax, %xmm2
612 ; SSE2-NEXT:    movswq 4(%rdi), %rax
613 ; SSE2-NEXT:    movd %rax, %xmm1
614 ; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0]
615 ; SSE2-NEXT:    retq
616 ;
617 ; SSSE3-LABEL: load_sext_4i16_to_4i64:
618 ; SSSE3:       # BB#0: # %entry
619 ; SSSE3-NEXT:    movswq 2(%rdi), %rax
620 ; SSSE3-NEXT:    movd %rax, %xmm1
621 ; SSSE3-NEXT:    movswq (%rdi), %rax
622 ; SSSE3-NEXT:    movd %rax, %xmm0
623 ; SSSE3-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
624 ; SSSE3-NEXT:    movswq 6(%rdi), %rax
625 ; SSSE3-NEXT:    movd %rax, %xmm2
626 ; SSSE3-NEXT:    movswq 4(%rdi), %rax
627 ; SSSE3-NEXT:    movd %rax, %xmm1
628 ; SSSE3-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0]
629 ; SSSE3-NEXT:    retq
630 ;
631 ; SSE41-LABEL: load_sext_4i16_to_4i64:
632 ; SSE41:       # BB#0: # %entry
633 ; SSE41-NEXT:    pmovsxwq (%rdi), %xmm0
634 ; SSE41-NEXT:    pmovsxwq 4(%rdi), %xmm1
635 ; SSE41-NEXT:    retq
636 ;
637 ; AVX1-LABEL: load_sext_4i16_to_4i64:
638 ; AVX1:       # BB#0: # %entry
639 ; AVX1-NEXT:    vpmovsxwd (%rdi), %xmm0
640 ; AVX1-NEXT:    vpmovsxdq %xmm0, %xmm1
641 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
642 ; AVX1-NEXT:    vpmovsxdq %xmm0, %xmm0
643 ; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
644 ; AVX1-NEXT:    retq
645 ;
646 ; AVX2-LABEL: load_sext_4i16_to_4i64:
647 ; AVX2:       # BB#0: # %entry
648 ; AVX2-NEXT:    vpmovsxwq (%rdi), %ymm0
649 ; AVX2-NEXT:    retq
650 ;
651 ; X32-SSE41-LABEL: load_sext_4i16_to_4i64:
652 ; X32-SSE41:       # BB#0: # %entry
653 ; X32-SSE41-NEXT:    movl {{[0-9]+}}(%esp), %eax
654 ; X32-SSE41-NEXT:    pmovsxwq (%eax), %xmm0
655 ; X32-SSE41-NEXT:    pmovsxwq 4(%eax), %xmm1
656 ; X32-SSE41-NEXT:    retl
657 entry:
658  %X = load <4 x i16>, <4 x i16>* %ptr
659  %Y = sext <4 x i16> %X to <4 x i64>
660  ret <4 x i64>%Y
661 }