833a057b9a33623734e472afabef90712abb01e2
[oota-llvm.git] / test / CodeGen / X86 / avx512-trunc.ll
1 ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mattr=+avx512f | FileCheck %s --check-prefix=ALL --check-prefix=KNL
2 ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mattr=+avx512f -mattr=+avx512vl -mattr=+avx512bw -mattr=+avx512dq | FileCheck %s --check-prefix=ALL --check-prefix=SKX
3
4  attributes #0 = { nounwind }
5
6 define <16 x i8> @trunc_16x32_to_16x8(<16 x i32> %i) #0 {
7 ; ALL-LABEL: trunc_16x32_to_16x8:
8 ; ALL:       ## BB#0:
9 ; ALL-NEXT:    vpmovdb %zmm0, %xmm0
10 ; ALL-NEXT:    retq
11   %x = trunc <16 x i32> %i to <16 x i8>
12   ret <16 x i8> %x
13 }
14
15 define <8 x i16> @trunc_8x64_to_8x16(<8 x i64> %i) #0 {
16 ; ALL-LABEL: trunc_8x64_to_8x16:
17 ; ALL:       ## BB#0:
18 ; ALL-NEXT:    vpmovqw %zmm0, %xmm0
19 ; ALL-NEXT:    retq
20   %x = trunc <8 x i64> %i to <8 x i16>
21   ret <8 x i16> %x
22 }
23
24 define <16 x i16> @trunc_v16i32_to_v16i16(<16 x i32> %x) #0 {
25 ; ALL-LABEL: trunc_v16i32_to_v16i16:
26 ; ALL:       ## BB#0:
27 ; ALL-NEXT:    vpmovdw %zmm0, %ymm0
28 ; ALL-NEXT:    retq
29   %1 = trunc <16 x i32> %x to <16 x i16>
30   ret <16 x i16> %1
31 }
32
33 define <8 x i8> @trunc_qb_512(<8 x i64> %i) #0 {
34 ; ALL-LABEL: trunc_qb_512:
35 ; ALL:       ## BB#0:
36 ; ALL-NEXT:    vpmovqw %zmm0, %xmm0
37 ; ALL-NEXT:    retq
38   %x = trunc <8 x i64> %i to <8 x i8>
39   ret <8 x i8> %x
40 }
41
42 define void @trunc_qb_512_mem(<8 x i64> %i, <8 x i8>* %res) #0 {
43 ; ALL-LABEL: trunc_qb_512_mem:
44 ; ALL:       ## BB#0:
45 ; ALL-NEXT:    vpmovqb %zmm0, (%rdi)
46 ; ALL-NEXT:    retq
47     %x = trunc <8 x i64> %i to <8 x i8>
48     store <8 x i8> %x, <8 x i8>* %res
49     ret void
50 }
51
52 define <4 x i8> @trunc_qb_256(<4 x i64> %i) #0 {
53 ; KNL-LABEL: trunc_qb_256:
54 ; KNL:       ## BB#0:
55 ; KNL-NEXT:    vpmovqd %zmm0, %ymm0
56 ; KNL-NEXT:    retq
57 ;
58 ; SKX-LABEL: trunc_qb_256:
59 ; SKX:       ## BB#0:
60 ; SKX-NEXT:    vpmovqd %ymm0, %xmm0
61 ; SKX-NEXT:    retq
62   %x = trunc <4 x i64> %i to <4 x i8>
63   ret <4 x i8> %x
64 }
65
66 define void @trunc_qb_256_mem(<4 x i64> %i, <4 x i8>* %res) #0 {
67 ; KNL-LABEL: trunc_qb_256_mem:
68 ; KNL:       ## BB#0:
69 ; KNL-NEXT:    vpmovqd %zmm0, %ymm0
70 ; KNL-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[0,4,8,12,u,u,u,u,u,u,u,u,u,u,u,u]
71 ; KNL-NEXT:    vmovd %xmm0, (%rdi)
72 ; KNL-NEXT:    retq
73 ;
74 ; SKX-LABEL: trunc_qb_256_mem:
75 ; SKX:       ## BB#0:
76 ; SKX-NEXT:    vpmovqb %ymm0, (%rdi)
77 ; SKX-NEXT:    retq
78     %x = trunc <4 x i64> %i to <4 x i8>
79     store <4 x i8> %x, <4 x i8>* %res
80     ret void
81 }
82
83 define <2 x i8> @trunc_qb_128(<2 x i64> %i) #0 {
84 ; ALL-LABEL: trunc_qb_128:
85 ; ALL:       ## BB#0:
86 ; ALL-NEXT:    retq
87   %x = trunc <2 x i64> %i to <2 x i8>
88   ret <2 x i8> %x
89 }
90
91 define void @trunc_qb_128_mem(<2 x i64> %i, <2 x i8>* %res) #0 {
92 ; KNL-LABEL: trunc_qb_128_mem:
93 ; KNL:       ## BB#0:
94 ; KNL-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[0,8,u,u,u,u,u,u,u,u,u,u,u,u,u,u]
95 ; KNL-NEXT:    vmovd %xmm0, %eax
96 ; KNL-NEXT:    movw %ax, (%rdi)
97 ; KNL-NEXT:    retq
98 ;
99 ; SKX-LABEL: trunc_qb_128_mem:
100 ; SKX:       ## BB#0:
101 ; SKX-NEXT:    vpmovqb %xmm0, (%rdi)
102 ; SKX-NEXT:    retq
103     %x = trunc <2 x i64> %i to <2 x i8>
104     store <2 x i8> %x, <2 x i8>* %res
105     ret void
106 }
107
108 define <8 x i16> @trunc_qw_512(<8 x i64> %i) #0 {
109 ; ALL-LABEL: trunc_qw_512:
110 ; ALL:       ## BB#0:
111 ; ALL-NEXT:    vpmovqw %zmm0, %xmm0
112 ; ALL-NEXT:    retq
113   %x = trunc <8 x i64> %i to <8 x i16>
114   ret <8 x i16> %x
115 }
116
117 define void @trunc_qw_512_mem(<8 x i64> %i, <8 x i16>* %res) #0 {
118 ; ALL-LABEL: trunc_qw_512_mem:
119 ; ALL:       ## BB#0:
120 ; ALL-NEXT:    vpmovqw %zmm0, (%rdi)
121 ; ALL-NEXT:    retq
122     %x = trunc <8 x i64> %i to <8 x i16>
123     store <8 x i16> %x, <8 x i16>* %res
124     ret void
125 }
126
127 define <4 x i16> @trunc_qw_256(<4 x i64> %i) #0 {
128 ; KNL-LABEL: trunc_qw_256:
129 ; KNL:       ## BB#0:
130 ; KNL-NEXT:    vpmovqd %zmm0, %ymm0
131 ; KNL-NEXT:    retq
132 ;
133 ; SKX-LABEL: trunc_qw_256:
134 ; SKX:       ## BB#0:
135 ; SKX-NEXT:    vpmovqd %ymm0, %xmm0
136 ; SKX-NEXT:    retq
137   %x = trunc <4 x i64> %i to <4 x i16>
138   ret <4 x i16> %x
139 }
140
141 define void @trunc_qw_256_mem(<4 x i64> %i, <4 x i16>* %res) #0 {
142 ; KNL-LABEL: trunc_qw_256_mem:
143 ; KNL:       ## BB#0:
144 ; KNL-NEXT:    vpmovqd %zmm0, %ymm0
145 ; KNL-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
146 ; KNL-NEXT:    vmovq %xmm0, (%rdi)
147 ; KNL-NEXT:    retq
148 ;
149 ; SKX-LABEL: trunc_qw_256_mem:
150 ; SKX:       ## BB#0:
151 ; SKX-NEXT:    vpmovqw %ymm0, (%rdi)
152 ; SKX-NEXT:    retq
153     %x = trunc <4 x i64> %i to <4 x i16>
154     store <4 x i16> %x, <4 x i16>* %res
155     ret void
156 }
157
158 define <2 x i16> @trunc_qw_128(<2 x i64> %i) #0 {
159 ; ALL-LABEL: trunc_qw_128:
160 ; ALL:       ## BB#0:
161 ; ALL-NEXT:    retq
162   %x = trunc <2 x i64> %i to <2 x i16>
163   ret <2 x i16> %x
164 }
165
166 define void @trunc_qw_128_mem(<2 x i64> %i, <2 x i16>* %res) #0 {
167 ; KNL-LABEL: trunc_qw_128_mem:
168 ; KNL:       ## BB#0:
169 ; KNL-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
170 ; KNL-NEXT:    vpshuflw {{.*#+}} xmm0 = xmm0[0,2,2,3,4,5,6,7]
171 ; KNL-NEXT:    vmovd %xmm0, (%rdi)
172 ; KNL-NEXT:    retq
173 ;
174 ; SKX-LABEL: trunc_qw_128_mem:
175 ; SKX:       ## BB#0:
176 ; SKX-NEXT:    vpmovqw %xmm0, (%rdi)
177 ; SKX-NEXT:    retq
178     %x = trunc <2 x i64> %i to <2 x i16>
179     store <2 x i16> %x, <2 x i16>* %res
180     ret void
181 }
182
183 define <8 x i32> @trunc_qd_512(<8 x i64> %i) #0 {
184 ; ALL-LABEL: trunc_qd_512:
185 ; ALL:       ## BB#0:
186 ; ALL-NEXT:    vpmovqd %zmm0, %ymm0
187 ; ALL-NEXT:    retq
188   %x = trunc <8 x i64> %i to <8 x i32>
189   ret <8 x i32> %x
190 }
191
192 define void @trunc_qd_512_mem(<8 x i64> %i, <8 x i32>* %res) #0 {
193 ; ALL-LABEL: trunc_qd_512_mem:
194 ; ALL:       ## BB#0:
195 ; ALL-NEXT:    vpmovqd %zmm0, (%rdi)
196 ; ALL-NEXT:    retq
197     %x = trunc <8 x i64> %i to <8 x i32>
198     store <8 x i32> %x, <8 x i32>* %res
199     ret void
200 }
201
202 define <4 x i32> @trunc_qd_256(<4 x i64> %i) #0 {
203 ; KNL-LABEL: trunc_qd_256:
204 ; KNL:       ## BB#0:
205 ; KNL-NEXT:    vpmovqd %zmm0, %ymm0
206 ; KNL-NEXT:    retq
207 ;
208 ; SKX-LABEL: trunc_qd_256:
209 ; SKX:       ## BB#0:
210 ; SKX-NEXT:    vpmovqd %ymm0, %xmm0
211 ; SKX-NEXT:    retq
212   %x = trunc <4 x i64> %i to <4 x i32>
213   ret <4 x i32> %x
214 }
215
216 define void @trunc_qd_256_mem(<4 x i64> %i, <4 x i32>* %res) #0 {
217 ; KNL-LABEL: trunc_qd_256_mem:
218 ; KNL:       ## BB#0:
219 ; KNL-NEXT:    vpmovqd %zmm0, %ymm0
220 ; KNL-NEXT:    vmovaps %xmm0, (%rdi)
221 ; KNL-NEXT:    retq
222 ;
223 ; SKX-LABEL: trunc_qd_256_mem:
224 ; SKX:       ## BB#0:
225 ; SKX-NEXT:    vpmovqd %ymm0, (%rdi)
226 ; SKX-NEXT:    retq
227     %x = trunc <4 x i64> %i to <4 x i32>
228     store <4 x i32> %x, <4 x i32>* %res
229     ret void
230 }
231
232 define <2 x i32> @trunc_qd_128(<2 x i64> %i) #0 {
233 ; ALL-LABEL: trunc_qd_128:
234 ; ALL:       ## BB#0:
235 ; ALL-NEXT:    retq
236   %x = trunc <2 x i64> %i to <2 x i32>
237   ret <2 x i32> %x
238 }
239
240 define void @trunc_qd_128_mem(<2 x i64> %i, <2 x i32>* %res) #0 {
241 ; KNL-LABEL: trunc_qd_128_mem:
242 ; KNL:       ## BB#0:
243 ; KNL-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
244 ; KNL-NEXT:    vmovq %xmm0, (%rdi)
245 ; KNL-NEXT:    retq
246 ;
247 ; SKX-LABEL: trunc_qd_128_mem:
248 ; SKX:       ## BB#0:
249 ; SKX-NEXT:    vpmovqd %xmm0, (%rdi)
250 ; SKX-NEXT:    retq
251     %x = trunc <2 x i64> %i to <2 x i32>
252     store <2 x i32> %x, <2 x i32>* %res
253     ret void
254 }
255
256 define <16 x i8> @trunc_db_512(<16 x i32> %i) #0 {
257 ; ALL-LABEL: trunc_db_512:
258 ; ALL:       ## BB#0:
259 ; ALL-NEXT:    vpmovdb %zmm0, %xmm0
260 ; ALL-NEXT:    retq
261   %x = trunc <16 x i32> %i to <16 x i8>
262   ret <16 x i8> %x
263 }
264
265 define void @trunc_db_512_mem(<16 x i32> %i, <16 x i8>* %res) #0 {
266 ; ALL-LABEL: trunc_db_512_mem:
267 ; ALL:       ## BB#0:
268 ; ALL-NEXT:    vpmovdb %zmm0, (%rdi)
269 ; ALL-NEXT:    retq
270     %x = trunc <16 x i32> %i to <16 x i8>
271     store <16 x i8> %x, <16 x i8>* %res
272     ret void
273 }
274
275 define <8 x i8> @trunc_db_256(<8 x i32> %i) #0 {
276 ; KNL-LABEL: trunc_db_256:
277 ; KNL:       ## BB#0:
278 ; KNL-NEXT:    vpmovdw %zmm0, %ymm0
279 ; KNL-NEXT:    retq
280 ;
281 ; SKX-LABEL: trunc_db_256:
282 ; SKX:       ## BB#0:
283 ; SKX-NEXT:    vpmovdw %ymm0, %xmm0
284 ; SKX-NEXT:    retq
285   %x = trunc <8 x i32> %i to <8 x i8>
286   ret <8 x i8> %x
287 }
288
289 define void @trunc_db_256_mem(<8 x i32> %i, <8 x i8>* %res) #0 {
290 ; KNL-LABEL: trunc_db_256_mem:
291 ; KNL:       ## BB#0:
292 ; KNL-NEXT:    vpmovdw %zmm0, %ymm0
293 ; KNL-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u]
294 ; KNL-NEXT:    vmovq %xmm0, (%rdi)
295 ; KNL-NEXT:    retq
296 ;
297 ; SKX-LABEL: trunc_db_256_mem:
298 ; SKX:       ## BB#0:
299 ; SKX-NEXT:    vpmovdb %ymm0, (%rdi)
300 ; SKX-NEXT:    retq
301     %x = trunc <8 x i32> %i to <8 x i8>
302     store <8 x i8> %x, <8 x i8>* %res
303     ret void
304 }
305
306 define <4 x i8> @trunc_db_128(<4 x i32> %i) #0 {
307 ; ALL-LABEL: trunc_db_128:
308 ; ALL:       ## BB#0:
309 ; ALL-NEXT:    retq
310   %x = trunc <4 x i32> %i to <4 x i8>
311   ret <4 x i8> %x
312 }
313
314 define void @trunc_db_128_mem(<4 x i32> %i, <4 x i8>* %res) #0 {
315 ; KNL-LABEL: trunc_db_128_mem:
316 ; KNL:       ## BB#0:
317 ; KNL-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[0,4,8,12,u,u,u,u,u,u,u,u,u,u,u,u]
318 ; KNL-NEXT:    vmovd %xmm0, (%rdi)
319 ; KNL-NEXT:    retq
320 ;
321 ; SKX-LABEL: trunc_db_128_mem:
322 ; SKX:       ## BB#0:
323 ; SKX-NEXT:    vpmovdb %xmm0, (%rdi)
324 ; SKX-NEXT:    retq
325     %x = trunc <4 x i32> %i to <4 x i8>
326     store <4 x i8> %x, <4 x i8>* %res
327     ret void
328 }
329
330 define <16 x i16> @trunc_dw_512(<16 x i32> %i) #0 {
331 ; ALL-LABEL: trunc_dw_512:
332 ; ALL:       ## BB#0:
333 ; ALL-NEXT:    vpmovdw %zmm0, %ymm0
334 ; ALL-NEXT:    retq
335   %x = trunc <16 x i32> %i to <16 x i16>
336   ret <16 x i16> %x
337 }
338
339 define void @trunc_dw_512_mem(<16 x i32> %i, <16 x i16>* %res) #0 {
340 ; ALL-LABEL: trunc_dw_512_mem:
341 ; ALL:       ## BB#0:
342 ; ALL-NEXT:    vpmovdw %zmm0, (%rdi)
343 ; ALL-NEXT:    retq
344     %x = trunc <16 x i32> %i to <16 x i16>
345     store <16 x i16> %x, <16 x i16>* %res
346     ret void
347 }
348
349 define <8 x i16> @trunc_dw_256(<8 x i32> %i) #0 {
350 ; KNL-LABEL: trunc_dw_256:
351 ; KNL:       ## BB#0:
352 ; KNL-NEXT:    vpmovdw %zmm0, %ymm0
353 ; KNL-NEXT:    retq
354 ;
355 ; SKX-LABEL: trunc_dw_256:
356 ; SKX:       ## BB#0:
357 ; SKX-NEXT:    vpmovdw %ymm0, %xmm0
358 ; SKX-NEXT:    retq
359   %x = trunc <8 x i32> %i to <8 x i16>
360   ret <8 x i16> %x
361 }
362
363 define void @trunc_dw_256_mem(<8 x i32> %i, <8 x i16>* %res) #0 {
364 ; KNL-LABEL: trunc_dw_256_mem:
365 ; KNL:       ## BB#0:
366 ; KNL-NEXT:    vpmovdw %zmm0, %ymm0
367 ; KNL-NEXT:    vmovaps %xmm0, (%rdi)
368 ; KNL-NEXT:    retq
369 ;
370 ; SKX-LABEL: trunc_dw_256_mem:
371 ; SKX:       ## BB#0:
372 ; SKX-NEXT:    vpmovdw %ymm0, (%rdi)
373 ; SKX-NEXT:    retq
374     %x = trunc <8 x i32> %i to <8 x i16>
375     store <8 x i16> %x, <8 x i16>* %res
376     ret void
377 }
378
379 define void @trunc_dw_128_mem(<4 x i32> %i, <4 x i16>* %res) #0 {
380 ; KNL-LABEL: trunc_dw_128_mem:
381 ; KNL:       ## BB#0:
382 ; KNL-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
383 ; KNL-NEXT:    vmovq %xmm0, (%rdi)
384 ; KNL-NEXT:    retq
385 ;
386 ; SKX-LABEL: trunc_dw_128_mem:
387 ; SKX:       ## BB#0:
388 ; SKX-NEXT:    vpmovdw %xmm0, (%rdi)
389 ; SKX-NEXT:    retq
390     %x = trunc <4 x i32> %i to <4 x i16>
391     store <4 x i16> %x, <4 x i16>* %res
392     ret void
393 }
394
395 define <32 x i8> @trunc_wb_512(<32 x i16> %i) #0 {
396 ; KNL-LABEL: trunc_wb_512:
397 ; KNL:       ## BB#0:
398 ; KNL-NEXT:    vpmovsxwd %ymm0, %zmm0
399 ; KNL-NEXT:    vpmovdb %zmm0, %xmm0
400 ; KNL-NEXT:    vpmovsxwd %ymm1, %zmm1
401 ; KNL-NEXT:    vpmovdb %zmm1, %xmm1
402 ; KNL-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
403 ; KNL-NEXT:    retq
404 ;
405 ; SKX-LABEL: trunc_wb_512:
406 ; SKX:       ## BB#0:
407 ; SKX-NEXT:    vpmovwb %zmm0, %ymm0
408 ; SKX-NEXT:    retq
409   %x = trunc <32 x i16> %i to <32 x i8>
410   ret <32 x i8> %x
411 }
412
413 define void @trunc_wb_512_mem(<32 x i16> %i, <32 x i8>* %res) #0 {
414 ; KNL-LABEL: trunc_wb_512_mem:
415 ; KNL:       ## BB#0:
416 ; KNL-NEXT:    vpmovsxwd %ymm0, %zmm0
417 ; KNL-NEXT:    vpmovdb %zmm0, %xmm0
418 ; KNL-NEXT:    vpmovsxwd %ymm1, %zmm1
419 ; KNL-NEXT:    vpmovdb %zmm1, %xmm1
420 ; KNL-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
421 ; KNL-NEXT:    vmovaps %ymm0, (%rdi)
422 ; KNL-NEXT:    retq
423 ;
424 ; SKX-LABEL: trunc_wb_512_mem:
425 ; SKX:       ## BB#0:
426 ; SKX-NEXT:    vpmovwb %zmm0, (%rdi)
427 ; SKX-NEXT:    retq
428     %x = trunc <32 x i16> %i to <32 x i8>
429     store <32 x i8> %x, <32 x i8>* %res
430     ret void
431 }
432
433 define <16 x i8> @trunc_wb_256(<16 x i16> %i) #0 {
434 ; KNL-LABEL: trunc_wb_256:
435 ; KNL:       ## BB#0:
436 ; KNL-NEXT:    vpmovsxwd %ymm0, %zmm0
437 ; KNL-NEXT:    vpmovdb %zmm0, %xmm0
438 ; KNL-NEXT:    retq
439 ;
440 ; SKX-LABEL: trunc_wb_256:
441 ; SKX:       ## BB#0:
442 ; SKX-NEXT:    vpmovwb %ymm0, %xmm0
443 ; SKX-NEXT:    retq
444   %x = trunc <16 x i16> %i to <16 x i8>
445   ret <16 x i8> %x
446 }
447
448 define void @trunc_wb_256_mem(<16 x i16> %i, <16 x i8>* %res) #0 {
449 ; KNL-LABEL: trunc_wb_256_mem:
450 ; KNL:       ## BB#0:
451 ; KNL-NEXT:    vpmovsxwd %ymm0, %zmm0
452 ; KNL-NEXT:    vpmovdb %zmm0, %xmm0
453 ; KNL-NEXT:    vmovaps %xmm0, (%rdi)
454 ; KNL-NEXT:    retq
455 ;
456 ; SKX-LABEL: trunc_wb_256_mem:
457 ; SKX:       ## BB#0:
458 ; SKX-NEXT:    vpmovwb %ymm0, (%rdi)
459 ; SKX-NEXT:    retq
460     %x = trunc <16 x i16> %i to <16 x i8>
461     store <16 x i8> %x, <16 x i8>* %res
462     ret void
463 }
464
465 define <8 x i8> @trunc_wb_128(<8 x i16> %i) #0 {
466 ; ALL-LABEL: trunc_wb_128:
467 ; ALL:       ## BB#0:
468 ; ALL-NEXT:    retq
469   %x = trunc <8 x i16> %i to <8 x i8>
470   ret <8 x i8> %x
471 }
472
473 define void @trunc_wb_128_mem(<8 x i16> %i, <8 x i8>* %res) #0 {
474 ; KNL-LABEL: trunc_wb_128_mem:
475 ; KNL:       ## BB#0:
476 ; KNL-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u]
477 ; KNL-NEXT:    vmovq %xmm0, (%rdi)
478 ; KNL-NEXT:    retq
479 ;
480 ; SKX-LABEL: trunc_wb_128_mem:
481 ; SKX:       ## BB#0:
482 ; SKX-NEXT:    vpmovwb %xmm0, (%rdi)
483 ; SKX-NEXT:    retq
484     %x = trunc <8 x i16> %i to <8 x i8>
485     store <8 x i8> %x, <8 x i8>* %res
486     ret void
487 }