1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefix=SSE --check-prefix=SSE2
3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+ssse3 | FileCheck %s --check-prefix=SSE --check-prefix=SSSE3
4; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.1 | FileCheck %s --check-prefix=SSE --check-prefix=SSE41
5; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefix=AVX --check-prefix=AVX1
6; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefixes=AVX,AVX2,AVX2-SLOW
7; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2,+fast-variable-shuffle | FileCheck %s --check-prefixes=AVX,AVX2,AVX2-FAST
8; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512f | FileCheck %s --check-prefix=AVX512 --check-prefix=AVX512F
9; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512vl,+fast-variable-shuffle | FileCheck %s --check-prefixes=AVX512,AVX512VL
10; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512bw,+fast-variable-shuffle | FileCheck %s --check-prefixes=AVX512,AVX512BW
11; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512bw,+avx512vl,+fast-variable-shuffle | FileCheck %s --check-prefixes=AVX512,AVX512BWVL
12
13define <8 x i32> @trunc8i64_8i32(<8 x i64> %a) {
14; SSE-LABEL: trunc8i64_8i32:
15; SSE:       # %bb.0: # %entry
16; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
17; SSE-NEXT:    shufps {{.*#+}} xmm2 = xmm2[0,2],xmm3[0,2]
18; SSE-NEXT:    movaps %xmm2, %xmm1
19; SSE-NEXT:    retq
20;
21; AVX1-LABEL: trunc8i64_8i32:
22; AVX1:       # %bb.0: # %entry
23; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
24; AVX1-NEXT:    vshufps {{.*#+}} xmm1 = xmm1[0,2],xmm2[0,2]
25; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
26; AVX1-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm2[0,2]
27; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
28; AVX1-NEXT:    retq
29;
30; AVX2-SLOW-LABEL: trunc8i64_8i32:
31; AVX2-SLOW:       # %bb.0: # %entry
32; AVX2-SLOW-NEXT:    vpermilps {{.*#+}} ymm0 = ymm0[0,2,2,3,4,6,6,7]
33; AVX2-SLOW-NEXT:    vpermpd {{.*#+}} ymm0 = ymm0[0,2,2,3]
34; AVX2-SLOW-NEXT:    vpermilps {{.*#+}} ymm1 = ymm1[0,2,2,3,4,6,6,7]
35; AVX2-SLOW-NEXT:    vpermpd {{.*#+}} ymm1 = ymm1[0,2,2,3]
36; AVX2-SLOW-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
37; AVX2-SLOW-NEXT:    retq
38;
39; AVX2-FAST-LABEL: trunc8i64_8i32:
40; AVX2-FAST:       # %bb.0: # %entry
41; AVX2-FAST-NEXT:    vmovaps {{.*#+}} ymm2 = [0,2,4,6,4,6,6,7]
42; AVX2-FAST-NEXT:    vpermps %ymm0, %ymm2, %ymm0
43; AVX2-FAST-NEXT:    vpermps %ymm1, %ymm2, %ymm1
44; AVX2-FAST-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
45; AVX2-FAST-NEXT:    retq
46;
47; AVX512-LABEL: trunc8i64_8i32:
48; AVX512:       # %bb.0: # %entry
49; AVX512-NEXT:    vpmovqd %zmm0, %ymm0
50; AVX512-NEXT:    retq
51entry:
52  %0 = trunc <8 x i64> %a to <8 x i32>
53  ret <8 x i32> %0
54}
55
56define <8 x i32> @trunc8i64_8i32_ashr(<8 x i64> %a) {
57; SSE-LABEL: trunc8i64_8i32_ashr:
58; SSE:       # %bb.0: # %entry
59; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,3],xmm1[1,3]
60; SSE-NEXT:    shufps {{.*#+}} xmm2 = xmm2[1,3],xmm3[1,3]
61; SSE-NEXT:    movaps %xmm2, %xmm1
62; SSE-NEXT:    retq
63;
64; AVX1-LABEL: trunc8i64_8i32_ashr:
65; AVX1:       # %bb.0: # %entry
66; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
67; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
68; AVX1-NEXT:    vshufps {{.*#+}} xmm1 = xmm1[1,3],xmm3[1,3]
69; AVX1-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[1,3],xmm2[1,3]
70; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
71; AVX1-NEXT:    retq
72;
73; AVX2-SLOW-LABEL: trunc8i64_8i32_ashr:
74; AVX2-SLOW:       # %bb.0: # %entry
75; AVX2-SLOW-NEXT:    vpermilps {{.*#+}} ymm0 = ymm0[1,3,2,3,5,7,6,7]
76; AVX2-SLOW-NEXT:    vpermpd {{.*#+}} ymm0 = ymm0[0,2,2,3]
77; AVX2-SLOW-NEXT:    vpermilps {{.*#+}} ymm1 = ymm1[1,3,2,3,5,7,6,7]
78; AVX2-SLOW-NEXT:    vpermpd {{.*#+}} ymm1 = ymm1[0,2,2,3]
79; AVX2-SLOW-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
80; AVX2-SLOW-NEXT:    retq
81;
82; AVX2-FAST-LABEL: trunc8i64_8i32_ashr:
83; AVX2-FAST:       # %bb.0: # %entry
84; AVX2-FAST-NEXT:    vmovaps {{.*#+}} ymm2 = [1,3,5,7,5,7,6,7]
85; AVX2-FAST-NEXT:    vpermps %ymm0, %ymm2, %ymm0
86; AVX2-FAST-NEXT:    vpermps %ymm1, %ymm2, %ymm1
87; AVX2-FAST-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
88; AVX2-FAST-NEXT:    retq
89;
90; AVX512-LABEL: trunc8i64_8i32_ashr:
91; AVX512:       # %bb.0: # %entry
92; AVX512-NEXT:    vpsraq $32, %zmm0, %zmm0
93; AVX512-NEXT:    vpmovqd %zmm0, %ymm0
94; AVX512-NEXT:    retq
95entry:
96  %0 = ashr <8 x i64> %a, <i64 32, i64 32, i64 32, i64 32, i64 32, i64 32, i64 32, i64 32>
97  %1 = trunc <8 x i64> %0 to <8 x i32>
98  ret <8 x i32> %1
99}
100
101define <8 x i32> @trunc8i64_8i32_lshr(<8 x i64> %a) {
102; SSE-LABEL: trunc8i64_8i32_lshr:
103; SSE:       # %bb.0: # %entry
104; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,3],xmm1[1,3]
105; SSE-NEXT:    shufps {{.*#+}} xmm2 = xmm2[1,3],xmm3[1,3]
106; SSE-NEXT:    movaps %xmm2, %xmm1
107; SSE-NEXT:    retq
108;
109; AVX1-LABEL: trunc8i64_8i32_lshr:
110; AVX1:       # %bb.0: # %entry
111; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
112; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
113; AVX1-NEXT:    vshufps {{.*#+}} xmm1 = xmm1[1,3],xmm3[1,3]
114; AVX1-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[1,3],xmm2[1,3]
115; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
116; AVX1-NEXT:    retq
117;
118; AVX2-SLOW-LABEL: trunc8i64_8i32_lshr:
119; AVX2-SLOW:       # %bb.0: # %entry
120; AVX2-SLOW-NEXT:    vpsrlq $32, %ymm1, %ymm1
121; AVX2-SLOW-NEXT:    vpsrlq $32, %ymm0, %ymm0
122; AVX2-SLOW-NEXT:    vpshufd {{.*#+}} ymm0 = ymm0[0,2,2,3,4,6,6,7]
123; AVX2-SLOW-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
124; AVX2-SLOW-NEXT:    vpshufd {{.*#+}} ymm1 = ymm1[0,2,2,3,4,6,6,7]
125; AVX2-SLOW-NEXT:    vpermq {{.*#+}} ymm1 = ymm1[0,2,2,3]
126; AVX2-SLOW-NEXT:    vinserti128 $1, %xmm1, %ymm0, %ymm0
127; AVX2-SLOW-NEXT:    retq
128;
129; AVX2-FAST-LABEL: trunc8i64_8i32_lshr:
130; AVX2-FAST:       # %bb.0: # %entry
131; AVX2-FAST-NEXT:    vpsrlq $32, %ymm1, %ymm1
132; AVX2-FAST-NEXT:    vpsrlq $32, %ymm0, %ymm0
133; AVX2-FAST-NEXT:    vmovdqa {{.*#+}} ymm2 = [0,2,4,6,4,6,6,7]
134; AVX2-FAST-NEXT:    vpermd %ymm0, %ymm2, %ymm0
135; AVX2-FAST-NEXT:    vpermd %ymm1, %ymm2, %ymm1
136; AVX2-FAST-NEXT:    vinserti128 $1, %xmm1, %ymm0, %ymm0
137; AVX2-FAST-NEXT:    retq
138;
139; AVX512-LABEL: trunc8i64_8i32_lshr:
140; AVX512:       # %bb.0: # %entry
141; AVX512-NEXT:    vpsrlq $32, %zmm0, %zmm0
142; AVX512-NEXT:    vpmovqd %zmm0, %ymm0
143; AVX512-NEXT:    retq
144entry:
145  %0 = lshr <8 x i64> %a, <i64 32, i64 32, i64 32, i64 32, i64 32, i64 32, i64 32, i64 32>
146  %1 = trunc <8 x i64> %0 to <8 x i32>
147  ret <8 x i32> %1
148}
149
150define <8 x i16> @trunc8i64_8i16(<8 x i64> %a) {
151; SSE2-LABEL: trunc8i64_8i16:
152; SSE2:       # %bb.0: # %entry
153; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
154; SSE2-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,2,2,3,4,5,6,7]
155; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
156; SSE2-NEXT:    pshuflw {{.*#+}} xmm4 = xmm0[0,2,2,3,4,5,6,7]
157; SSE2-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
158; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[0,2,2,3]
159; SSE2-NEXT:    pshuflw {{.*#+}} xmm1 = xmm0[0,1,0,2,4,5,6,7]
160; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3]
161; SSE2-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,1,0,2,4,5,6,7]
162; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
163; SSE2-NEXT:    movsd {{.*#+}} xmm0 = xmm4[0],xmm0[1]
164; SSE2-NEXT:    retq
165;
166; SSSE3-LABEL: trunc8i64_8i16:
167; SSSE3:       # %bb.0: # %entry
168; SSSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
169; SSSE3-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,2,2,3,4,5,6,7]
170; SSSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
171; SSSE3-NEXT:    pshuflw {{.*#+}} xmm4 = xmm0[0,2,2,3,4,5,6,7]
172; SSSE3-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
173; SSSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[0,2,2,3]
174; SSSE3-NEXT:    pshuflw {{.*#+}} xmm1 = xmm0[0,1,0,2,4,5,6,7]
175; SSSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3]
176; SSSE3-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,1,0,2,4,5,6,7]
177; SSSE3-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
178; SSSE3-NEXT:    movsd {{.*#+}} xmm0 = xmm4[0],xmm0[1]
179; SSSE3-NEXT:    retq
180;
181; SSE41-LABEL: trunc8i64_8i16:
182; SSE41:       # %bb.0: # %entry
183; SSE41-NEXT:    pxor %xmm4, %xmm4
184; SSE41-NEXT:    pblendw {{.*#+}} xmm3 = xmm3[0],xmm4[1,2,3],xmm3[4],xmm4[5,6,7]
185; SSE41-NEXT:    pblendw {{.*#+}} xmm2 = xmm2[0],xmm4[1,2,3],xmm2[4],xmm4[5,6,7]
186; SSE41-NEXT:    packusdw %xmm3, %xmm2
187; SSE41-NEXT:    pblendw {{.*#+}} xmm1 = xmm1[0],xmm4[1,2,3],xmm1[4],xmm4[5,6,7]
188; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0],xmm4[1,2,3],xmm0[4],xmm4[5,6,7]
189; SSE41-NEXT:    packusdw %xmm1, %xmm0
190; SSE41-NEXT:    packusdw %xmm2, %xmm0
191; SSE41-NEXT:    retq
192;
193; AVX1-LABEL: trunc8i64_8i16:
194; AVX1:       # %bb.0: # %entry
195; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
196; AVX1-NEXT:    vpxor %xmm3, %xmm3, %xmm3
197; AVX1-NEXT:    vpblendw {{.*#+}} xmm2 = xmm2[0],xmm3[1,2,3],xmm2[4],xmm3[5,6,7]
198; AVX1-NEXT:    vpblendw {{.*#+}} xmm1 = xmm1[0],xmm3[1,2,3],xmm1[4],xmm3[5,6,7]
199; AVX1-NEXT:    vpackusdw %xmm2, %xmm1, %xmm1
200; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
201; AVX1-NEXT:    vpblendw {{.*#+}} xmm2 = xmm2[0],xmm3[1,2,3],xmm2[4],xmm3[5,6,7]
202; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0],xmm3[1,2,3],xmm0[4],xmm3[5,6,7]
203; AVX1-NEXT:    vpackusdw %xmm2, %xmm0, %xmm0
204; AVX1-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
205; AVX1-NEXT:    vzeroupper
206; AVX1-NEXT:    retq
207;
208; AVX2-SLOW-LABEL: trunc8i64_8i16:
209; AVX2-SLOW:       # %bb.0: # %entry
210; AVX2-SLOW-NEXT:    vpshufd {{.*#+}} ymm0 = ymm0[0,2,2,3,4,6,6,7]
211; AVX2-SLOW-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
212; AVX2-SLOW-NEXT:    vpshufd {{.*#+}} ymm1 = ymm1[0,2,2,3,4,6,6,7]
213; AVX2-SLOW-NEXT:    vpermq {{.*#+}} ymm1 = ymm1[0,2,2,3]
214; AVX2-SLOW-NEXT:    vinserti128 $1, %xmm1, %ymm0, %ymm0
215; AVX2-SLOW-NEXT:    vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15,16,17,20,21,24,25,28,29,24,25,28,29,28,29,30,31]
216; AVX2-SLOW-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
217; AVX2-SLOW-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
218; AVX2-SLOW-NEXT:    vzeroupper
219; AVX2-SLOW-NEXT:    retq
220;
221; AVX2-FAST-LABEL: trunc8i64_8i16:
222; AVX2-FAST:       # %bb.0: # %entry
223; AVX2-FAST-NEXT:    vmovdqa {{.*#+}} ymm2 = [0,2,4,6,4,6,6,7]
224; AVX2-FAST-NEXT:    vpermd %ymm0, %ymm2, %ymm0
225; AVX2-FAST-NEXT:    vpermd %ymm1, %ymm2, %ymm1
226; AVX2-FAST-NEXT:    vinserti128 $1, %xmm1, %ymm0, %ymm0
227; AVX2-FAST-NEXT:    vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15,16,17,20,21,24,25,28,29,24,25,28,29,28,29,30,31]
228; AVX2-FAST-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
229; AVX2-FAST-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
230; AVX2-FAST-NEXT:    vzeroupper
231; AVX2-FAST-NEXT:    retq
232;
233; AVX512-LABEL: trunc8i64_8i16:
234; AVX512:       # %bb.0: # %entry
235; AVX512-NEXT:    vpmovqw %zmm0, %xmm0
236; AVX512-NEXT:    vzeroupper
237; AVX512-NEXT:    retq
238entry:
239  %0 = trunc <8 x i64> %a to <8 x i16>
240  ret <8 x i16> %0
241}
242
243define void @trunc8i64_8i8(<8 x i64> %a) {
244; SSE2-LABEL: trunc8i64_8i8:
245; SSE2:       # %bb.0: # %entry
246; SSE2-NEXT:    movdqa {{.*#+}} xmm4 = [255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0]
247; SSE2-NEXT:    pand %xmm4, %xmm3
248; SSE2-NEXT:    pand %xmm4, %xmm2
249; SSE2-NEXT:    packuswb %xmm3, %xmm2
250; SSE2-NEXT:    pand %xmm4, %xmm1
251; SSE2-NEXT:    pand %xmm4, %xmm0
252; SSE2-NEXT:    packuswb %xmm1, %xmm0
253; SSE2-NEXT:    packuswb %xmm2, %xmm0
254; SSE2-NEXT:    packuswb %xmm0, %xmm0
255; SSE2-NEXT:    movq %xmm0, (%rax)
256; SSE2-NEXT:    retq
257;
258; SSSE3-LABEL: trunc8i64_8i8:
259; SSSE3:       # %bb.0: # %entry
260; SSSE3-NEXT:    movdqa {{.*#+}} xmm4 = [255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0]
261; SSSE3-NEXT:    pand %xmm4, %xmm3
262; SSSE3-NEXT:    pand %xmm4, %xmm2
263; SSSE3-NEXT:    packuswb %xmm3, %xmm2
264; SSSE3-NEXT:    pand %xmm4, %xmm1
265; SSSE3-NEXT:    pand %xmm4, %xmm0
266; SSSE3-NEXT:    packuswb %xmm1, %xmm0
267; SSSE3-NEXT:    packuswb %xmm2, %xmm0
268; SSSE3-NEXT:    packuswb %xmm0, %xmm0
269; SSSE3-NEXT:    movq %xmm0, (%rax)
270; SSSE3-NEXT:    retq
271;
272; SSE41-LABEL: trunc8i64_8i8:
273; SSE41:       # %bb.0: # %entry
274; SSE41-NEXT:    movdqa {{.*#+}} xmm4 = [255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0]
275; SSE41-NEXT:    pand %xmm4, %xmm3
276; SSE41-NEXT:    pand %xmm4, %xmm2
277; SSE41-NEXT:    packusdw %xmm3, %xmm2
278; SSE41-NEXT:    pand %xmm4, %xmm1
279; SSE41-NEXT:    pand %xmm4, %xmm0
280; SSE41-NEXT:    packusdw %xmm1, %xmm0
281; SSE41-NEXT:    packusdw %xmm2, %xmm0
282; SSE41-NEXT:    packuswb %xmm0, %xmm0
283; SSE41-NEXT:    movq %xmm0, (%rax)
284; SSE41-NEXT:    retq
285;
286; AVX1-LABEL: trunc8i64_8i8:
287; AVX1:       # %bb.0: # %entry
288; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
289; AVX1-NEXT:    vmovddup {{.*#+}} xmm3 = [1.2598673968951787E-321,1.2598673968951787E-321]
290; AVX1-NEXT:    # xmm3 = mem[0,0]
291; AVX1-NEXT:    vandpd %xmm3, %xmm2, %xmm2
292; AVX1-NEXT:    vandpd %xmm3, %xmm1, %xmm1
293; AVX1-NEXT:    vpackusdw %xmm2, %xmm1, %xmm1
294; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
295; AVX1-NEXT:    vandpd %xmm3, %xmm2, %xmm2
296; AVX1-NEXT:    vandpd %xmm3, %xmm0, %xmm0
297; AVX1-NEXT:    vpackusdw %xmm2, %xmm0, %xmm0
298; AVX1-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
299; AVX1-NEXT:    vpackuswb %xmm0, %xmm0, %xmm0
300; AVX1-NEXT:    vmovq %xmm0, (%rax)
301; AVX1-NEXT:    vzeroupper
302; AVX1-NEXT:    retq
303;
304; AVX2-SLOW-LABEL: trunc8i64_8i8:
305; AVX2-SLOW:       # %bb.0: # %entry
306; AVX2-SLOW-NEXT:    vpshufd {{.*#+}} ymm0 = ymm0[0,2,2,3,4,6,6,7]
307; AVX2-SLOW-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
308; AVX2-SLOW-NEXT:    vpshufd {{.*#+}} ymm1 = ymm1[0,2,2,3,4,6,6,7]
309; AVX2-SLOW-NEXT:    vpermq {{.*#+}} ymm1 = ymm1[0,2,2,3]
310; AVX2-SLOW-NEXT:    vmovdqa {{.*#+}} xmm2 = <0,4,8,12,u,u,u,u,u,u,u,u,u,u,u,u>
311; AVX2-SLOW-NEXT:    vpshufb %xmm2, %xmm1, %xmm1
312; AVX2-SLOW-NEXT:    vpshufb %xmm2, %xmm0, %xmm0
313; AVX2-SLOW-NEXT:    vpunpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
314; AVX2-SLOW-NEXT:    vmovq %xmm0, (%rax)
315; AVX2-SLOW-NEXT:    vzeroupper
316; AVX2-SLOW-NEXT:    retq
317;
318; AVX2-FAST-LABEL: trunc8i64_8i8:
319; AVX2-FAST:       # %bb.0: # %entry
320; AVX2-FAST-NEXT:    vmovdqa {{.*#+}} ymm2 = [0,2,4,6,4,6,6,7]
321; AVX2-FAST-NEXT:    vpermd %ymm0, %ymm2, %ymm0
322; AVX2-FAST-NEXT:    vpermd %ymm1, %ymm2, %ymm1
323; AVX2-FAST-NEXT:    vmovdqa {{.*#+}} xmm2 = <0,4,8,12,u,u,u,u,u,u,u,u,u,u,u,u>
324; AVX2-FAST-NEXT:    vpshufb %xmm2, %xmm1, %xmm1
325; AVX2-FAST-NEXT:    vpshufb %xmm2, %xmm0, %xmm0
326; AVX2-FAST-NEXT:    vpunpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
327; AVX2-FAST-NEXT:    vmovq %xmm0, (%rax)
328; AVX2-FAST-NEXT:    vzeroupper
329; AVX2-FAST-NEXT:    retq
330;
331; AVX512-LABEL: trunc8i64_8i8:
332; AVX512:       # %bb.0: # %entry
333; AVX512-NEXT:    vpmovqb %zmm0, (%rax)
334; AVX512-NEXT:    vzeroupper
335; AVX512-NEXT:    retq
336entry:
337  %0 = trunc <8 x i64> %a to <8 x i8>
338  store <8 x i8> %0, <8 x i8>* undef, align 4
339  ret void
340}
341
342define <8 x i16> @trunc8i32_8i16(<8 x i32> %a) {
343; SSE2-LABEL: trunc8i32_8i16:
344; SSE2:       # %bb.0: # %entry
345; SSE2-NEXT:    pslld $16, %xmm1
346; SSE2-NEXT:    psrad $16, %xmm1
347; SSE2-NEXT:    pslld $16, %xmm0
348; SSE2-NEXT:    psrad $16, %xmm0
349; SSE2-NEXT:    packssdw %xmm1, %xmm0
350; SSE2-NEXT:    retq
351;
352; SSSE3-LABEL: trunc8i32_8i16:
353; SSSE3:       # %bb.0: # %entry
354; SSSE3-NEXT:    movdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
355; SSSE3-NEXT:    pshufb %xmm2, %xmm1
356; SSSE3-NEXT:    pshufb %xmm2, %xmm0
357; SSSE3-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
358; SSSE3-NEXT:    retq
359;
360; SSE41-LABEL: trunc8i32_8i16:
361; SSE41:       # %bb.0: # %entry
362; SSE41-NEXT:    movdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
363; SSE41-NEXT:    pshufb %xmm2, %xmm1
364; SSE41-NEXT:    pshufb %xmm2, %xmm0
365; SSE41-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
366; SSE41-NEXT:    retq
367;
368; AVX1-LABEL: trunc8i32_8i16:
369; AVX1:       # %bb.0: # %entry
370; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
371; AVX1-NEXT:    vmovdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
372; AVX1-NEXT:    vpshufb %xmm2, %xmm1, %xmm1
373; AVX1-NEXT:    vpshufb %xmm2, %xmm0, %xmm0
374; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
375; AVX1-NEXT:    vzeroupper
376; AVX1-NEXT:    retq
377;
378; AVX2-LABEL: trunc8i32_8i16:
379; AVX2:       # %bb.0: # %entry
380; AVX2-NEXT:    vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15,16,17,20,21,24,25,28,29,24,25,28,29,28,29,30,31]
381; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
382; AVX2-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
383; AVX2-NEXT:    vzeroupper
384; AVX2-NEXT:    retq
385;
386; AVX512F-LABEL: trunc8i32_8i16:
387; AVX512F:       # %bb.0: # %entry
388; AVX512F-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
389; AVX512F-NEXT:    vpmovdw %zmm0, %ymm0
390; AVX512F-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
391; AVX512F-NEXT:    vzeroupper
392; AVX512F-NEXT:    retq
393;
394; AVX512VL-LABEL: trunc8i32_8i16:
395; AVX512VL:       # %bb.0: # %entry
396; AVX512VL-NEXT:    vpmovdw %ymm0, %xmm0
397; AVX512VL-NEXT:    vzeroupper
398; AVX512VL-NEXT:    retq
399;
400; AVX512BW-LABEL: trunc8i32_8i16:
401; AVX512BW:       # %bb.0: # %entry
402; AVX512BW-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
403; AVX512BW-NEXT:    vpmovdw %zmm0, %ymm0
404; AVX512BW-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
405; AVX512BW-NEXT:    vzeroupper
406; AVX512BW-NEXT:    retq
407;
408; AVX512BWVL-LABEL: trunc8i32_8i16:
409; AVX512BWVL:       # %bb.0: # %entry
410; AVX512BWVL-NEXT:    vpmovdw %ymm0, %xmm0
411; AVX512BWVL-NEXT:    vzeroupper
412; AVX512BWVL-NEXT:    retq
413entry:
414  %0 = trunc <8 x i32> %a to <8 x i16>
415  ret <8 x i16> %0
416}
417
418define <8 x i16> @trunc8i32_8i16_ashr(<8 x i32> %a) {
419; SSE-LABEL: trunc8i32_8i16_ashr:
420; SSE:       # %bb.0: # %entry
421; SSE-NEXT:    psrad $16, %xmm1
422; SSE-NEXT:    psrad $16, %xmm0
423; SSE-NEXT:    packssdw %xmm1, %xmm0
424; SSE-NEXT:    retq
425;
426; AVX1-LABEL: trunc8i32_8i16_ashr:
427; AVX1:       # %bb.0: # %entry
428; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
429; AVX1-NEXT:    vpsrad $16, %xmm1, %xmm1
430; AVX1-NEXT:    vpsrad $16, %xmm0, %xmm0
431; AVX1-NEXT:    vpackssdw %xmm1, %xmm0, %xmm0
432; AVX1-NEXT:    vzeroupper
433; AVX1-NEXT:    retq
434;
435; AVX2-LABEL: trunc8i32_8i16_ashr:
436; AVX2:       # %bb.0: # %entry
437; AVX2-NEXT:    vpsrad $16, %ymm0, %ymm0
438; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
439; AVX2-NEXT:    vpackssdw %xmm1, %xmm0, %xmm0
440; AVX2-NEXT:    vzeroupper
441; AVX2-NEXT:    retq
442;
443; AVX512F-LABEL: trunc8i32_8i16_ashr:
444; AVX512F:       # %bb.0: # %entry
445; AVX512F-NEXT:    vpsrad $16, %ymm0, %ymm0
446; AVX512F-NEXT:    vpmovdw %zmm0, %ymm0
447; AVX512F-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
448; AVX512F-NEXT:    vzeroupper
449; AVX512F-NEXT:    retq
450;
451; AVX512VL-LABEL: trunc8i32_8i16_ashr:
452; AVX512VL:       # %bb.0: # %entry
453; AVX512VL-NEXT:    vpsrad $16, %ymm0, %ymm0
454; AVX512VL-NEXT:    vpmovdw %ymm0, %xmm0
455; AVX512VL-NEXT:    vzeroupper
456; AVX512VL-NEXT:    retq
457;
458; AVX512BW-LABEL: trunc8i32_8i16_ashr:
459; AVX512BW:       # %bb.0: # %entry
460; AVX512BW-NEXT:    vpsrad $16, %ymm0, %ymm0
461; AVX512BW-NEXT:    vpmovdw %zmm0, %ymm0
462; AVX512BW-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
463; AVX512BW-NEXT:    vzeroupper
464; AVX512BW-NEXT:    retq
465;
466; AVX512BWVL-LABEL: trunc8i32_8i16_ashr:
467; AVX512BWVL:       # %bb.0: # %entry
468; AVX512BWVL-NEXT:    vpsrad $16, %ymm0, %ymm0
469; AVX512BWVL-NEXT:    vpmovdw %ymm0, %xmm0
470; AVX512BWVL-NEXT:    vzeroupper
471; AVX512BWVL-NEXT:    retq
472entry:
473  %0 = ashr <8 x i32> %a, <i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16>
474  %1 = trunc <8 x i32> %0 to <8 x i16>
475  ret <8 x i16> %1
476}
477
478define <8 x i16> @trunc8i32_8i16_lshr(<8 x i32> %a) {
479; SSE2-LABEL: trunc8i32_8i16_lshr:
480; SSE2:       # %bb.0: # %entry
481; SSE2-NEXT:    psrld $16, %xmm0
482; SSE2-NEXT:    psrld $16, %xmm1
483; SSE2-NEXT:    pslld $16, %xmm1
484; SSE2-NEXT:    psrad $16, %xmm1
485; SSE2-NEXT:    pslld $16, %xmm0
486; SSE2-NEXT:    psrad $16, %xmm0
487; SSE2-NEXT:    packssdw %xmm1, %xmm0
488; SSE2-NEXT:    retq
489;
490; SSSE3-LABEL: trunc8i32_8i16_lshr:
491; SSSE3:       # %bb.0: # %entry
492; SSSE3-NEXT:    movdqa {{.*#+}} xmm2 = [2,3,6,7,10,11,14,15,10,11,14,15,14,15,255,255]
493; SSSE3-NEXT:    pshufb %xmm2, %xmm1
494; SSSE3-NEXT:    pshufb %xmm2, %xmm0
495; SSSE3-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
496; SSSE3-NEXT:    retq
497;
498; SSE41-LABEL: trunc8i32_8i16_lshr:
499; SSE41:       # %bb.0: # %entry
500; SSE41-NEXT:    psrld $16, %xmm1
501; SSE41-NEXT:    psrld $16, %xmm0
502; SSE41-NEXT:    packusdw %xmm1, %xmm0
503; SSE41-NEXT:    retq
504;
505; AVX1-LABEL: trunc8i32_8i16_lshr:
506; AVX1:       # %bb.0: # %entry
507; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
508; AVX1-NEXT:    vpsrld $16, %xmm1, %xmm1
509; AVX1-NEXT:    vpsrld $16, %xmm0, %xmm0
510; AVX1-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
511; AVX1-NEXT:    vzeroupper
512; AVX1-NEXT:    retq
513;
514; AVX2-LABEL: trunc8i32_8i16_lshr:
515; AVX2:       # %bb.0: # %entry
516; AVX2-NEXT:    vpsrld $16, %ymm0, %ymm0
517; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
518; AVX2-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
519; AVX2-NEXT:    vzeroupper
520; AVX2-NEXT:    retq
521;
522; AVX512F-LABEL: trunc8i32_8i16_lshr:
523; AVX512F:       # %bb.0: # %entry
524; AVX512F-NEXT:    vpsrld $16, %ymm0, %ymm0
525; AVX512F-NEXT:    vpmovdw %zmm0, %ymm0
526; AVX512F-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
527; AVX512F-NEXT:    vzeroupper
528; AVX512F-NEXT:    retq
529;
530; AVX512VL-LABEL: trunc8i32_8i16_lshr:
531; AVX512VL:       # %bb.0: # %entry
532; AVX512VL-NEXT:    vpsrld $16, %ymm0, %ymm0
533; AVX512VL-NEXT:    vpmovdw %ymm0, %xmm0
534; AVX512VL-NEXT:    vzeroupper
535; AVX512VL-NEXT:    retq
536;
537; AVX512BW-LABEL: trunc8i32_8i16_lshr:
538; AVX512BW:       # %bb.0: # %entry
539; AVX512BW-NEXT:    vpsrld $16, %ymm0, %ymm0
540; AVX512BW-NEXT:    vpmovdw %zmm0, %ymm0
541; AVX512BW-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
542; AVX512BW-NEXT:    vzeroupper
543; AVX512BW-NEXT:    retq
544;
545; AVX512BWVL-LABEL: trunc8i32_8i16_lshr:
546; AVX512BWVL:       # %bb.0: # %entry
547; AVX512BWVL-NEXT:    vpsrld $16, %ymm0, %ymm0
548; AVX512BWVL-NEXT:    vpmovdw %ymm0, %xmm0
549; AVX512BWVL-NEXT:    vzeroupper
550; AVX512BWVL-NEXT:    retq
551entry:
552  %0 = lshr <8 x i32> %a, <i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16>
553  %1 = trunc <8 x i32> %0 to <8 x i16>
554  ret <8 x i16> %1
555}
556
557define void @trunc8i32_8i8(<8 x i32> %a) {
558; SSE2-LABEL: trunc8i32_8i8:
559; SSE2:       # %bb.0: # %entry
560; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0]
561; SSE2-NEXT:    pand %xmm2, %xmm1
562; SSE2-NEXT:    pand %xmm2, %xmm0
563; SSE2-NEXT:    packuswb %xmm1, %xmm0
564; SSE2-NEXT:    packuswb %xmm0, %xmm0
565; SSE2-NEXT:    movq %xmm0, (%rax)
566; SSE2-NEXT:    retq
567;
568; SSSE3-LABEL: trunc8i32_8i8:
569; SSSE3:       # %bb.0: # %entry
570; SSSE3-NEXT:    movdqa {{.*#+}} xmm2 = <0,4,8,12,u,u,u,u,u,u,u,u,u,u,u,u>
571; SSSE3-NEXT:    pshufb %xmm2, %xmm1
572; SSSE3-NEXT:    pshufb %xmm2, %xmm0
573; SSSE3-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
574; SSSE3-NEXT:    movq %xmm0, (%rax)
575; SSSE3-NEXT:    retq
576;
577; SSE41-LABEL: trunc8i32_8i8:
578; SSE41:       # %bb.0: # %entry
579; SSE41-NEXT:    movdqa {{.*#+}} xmm2 = <0,4,8,12,u,u,u,u,u,u,u,u,u,u,u,u>
580; SSE41-NEXT:    pshufb %xmm2, %xmm1
581; SSE41-NEXT:    pshufb %xmm2, %xmm0
582; SSE41-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
583; SSE41-NEXT:    movq %xmm0, (%rax)
584; SSE41-NEXT:    retq
585;
586; AVX1-LABEL: trunc8i32_8i8:
587; AVX1:       # %bb.0: # %entry
588; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
589; AVX1-NEXT:    vmovdqa {{.*#+}} xmm2 = <0,4,8,12,u,u,u,u,u,u,u,u,u,u,u,u>
590; AVX1-NEXT:    vpshufb %xmm2, %xmm1, %xmm1
591; AVX1-NEXT:    vpshufb %xmm2, %xmm0, %xmm0
592; AVX1-NEXT:    vpunpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
593; AVX1-NEXT:    vmovq %xmm0, (%rax)
594; AVX1-NEXT:    vzeroupper
595; AVX1-NEXT:    retq
596;
597; AVX2-LABEL: trunc8i32_8i8:
598; AVX2:       # %bb.0: # %entry
599; AVX2-NEXT:    vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15,16,17,20,21,24,25,28,29,24,25,28,29,28,29,30,31]
600; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
601; AVX2-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u]
602; AVX2-NEXT:    vmovq %xmm0, (%rax)
603; AVX2-NEXT:    vzeroupper
604; AVX2-NEXT:    retq
605;
606; AVX512F-LABEL: trunc8i32_8i8:
607; AVX512F:       # %bb.0: # %entry
608; AVX512F-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
609; AVX512F-NEXT:    vpmovdw %zmm0, %ymm0
610; AVX512F-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u]
611; AVX512F-NEXT:    vmovq %xmm0, (%rax)
612; AVX512F-NEXT:    vzeroupper
613; AVX512F-NEXT:    retq
614;
615; AVX512VL-LABEL: trunc8i32_8i8:
616; AVX512VL:       # %bb.0: # %entry
617; AVX512VL-NEXT:    vpmovdb %ymm0, (%rax)
618; AVX512VL-NEXT:    vzeroupper
619; AVX512VL-NEXT:    retq
620;
621; AVX512BW-LABEL: trunc8i32_8i8:
622; AVX512BW:       # %bb.0: # %entry
623; AVX512BW-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
624; AVX512BW-NEXT:    vpmovdw %zmm0, %ymm0
625; AVX512BW-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u]
626; AVX512BW-NEXT:    vmovq %xmm0, (%rax)
627; AVX512BW-NEXT:    vzeroupper
628; AVX512BW-NEXT:    retq
629;
630; AVX512BWVL-LABEL: trunc8i32_8i8:
631; AVX512BWVL:       # %bb.0: # %entry
632; AVX512BWVL-NEXT:    vpmovdb %ymm0, (%rax)
633; AVX512BWVL-NEXT:    vzeroupper
634; AVX512BWVL-NEXT:    retq
635entry:
636  %0 = trunc <8 x i32> %a to <8 x i8>
637  store <8 x i8> %0, <8 x i8>* undef, align 4
638  ret void
639}
640
641define void @trunc16i32_16i16(<16 x i32> %a) {
642; SSE2-LABEL: trunc16i32_16i16:
643; SSE2:       # %bb.0: # %entry
644; SSE2-NEXT:    pslld $16, %xmm1
645; SSE2-NEXT:    psrad $16, %xmm1
646; SSE2-NEXT:    pslld $16, %xmm0
647; SSE2-NEXT:    psrad $16, %xmm0
648; SSE2-NEXT:    packssdw %xmm1, %xmm0
649; SSE2-NEXT:    pslld $16, %xmm3
650; SSE2-NEXT:    psrad $16, %xmm3
651; SSE2-NEXT:    pslld $16, %xmm2
652; SSE2-NEXT:    psrad $16, %xmm2
653; SSE2-NEXT:    packssdw %xmm3, %xmm2
654; SSE2-NEXT:    movdqu %xmm2, (%rax)
655; SSE2-NEXT:    movdqu %xmm0, (%rax)
656; SSE2-NEXT:    retq
657;
658; SSSE3-LABEL: trunc16i32_16i16:
659; SSSE3:       # %bb.0: # %entry
660; SSSE3-NEXT:    pslld $16, %xmm1
661; SSSE3-NEXT:    psrad $16, %xmm1
662; SSSE3-NEXT:    pslld $16, %xmm0
663; SSSE3-NEXT:    psrad $16, %xmm0
664; SSSE3-NEXT:    packssdw %xmm1, %xmm0
665; SSSE3-NEXT:    pslld $16, %xmm3
666; SSSE3-NEXT:    psrad $16, %xmm3
667; SSSE3-NEXT:    pslld $16, %xmm2
668; SSSE3-NEXT:    psrad $16, %xmm2
669; SSSE3-NEXT:    packssdw %xmm3, %xmm2
670; SSSE3-NEXT:    movdqu %xmm2, (%rax)
671; SSSE3-NEXT:    movdqu %xmm0, (%rax)
672; SSSE3-NEXT:    retq
673;
674; SSE41-LABEL: trunc16i32_16i16:
675; SSE41:       # %bb.0: # %entry
676; SSE41-NEXT:    pxor %xmm4, %xmm4
677; SSE41-NEXT:    pblendw {{.*#+}} xmm1 = xmm1[0],xmm4[1],xmm1[2],xmm4[3],xmm1[4],xmm4[5],xmm1[6],xmm4[7]
678; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0],xmm4[1],xmm0[2],xmm4[3],xmm0[4],xmm4[5],xmm0[6],xmm4[7]
679; SSE41-NEXT:    packusdw %xmm1, %xmm0
680; SSE41-NEXT:    pblendw {{.*#+}} xmm3 = xmm3[0],xmm4[1],xmm3[2],xmm4[3],xmm3[4],xmm4[5],xmm3[6],xmm4[7]
681; SSE41-NEXT:    pblendw {{.*#+}} xmm2 = xmm2[0],xmm4[1],xmm2[2],xmm4[3],xmm2[4],xmm4[5],xmm2[6],xmm4[7]
682; SSE41-NEXT:    packusdw %xmm3, %xmm2
683; SSE41-NEXT:    movdqu %xmm2, (%rax)
684; SSE41-NEXT:    movdqu %xmm0, (%rax)
685; SSE41-NEXT:    retq
686;
687; AVX1-LABEL: trunc16i32_16i16:
688; AVX1:       # %bb.0: # %entry
689; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
690; AVX1-NEXT:    vpxor %xmm3, %xmm3, %xmm3
691; AVX1-NEXT:    vpblendw {{.*#+}} xmm2 = xmm2[0],xmm3[1],xmm2[2],xmm3[3],xmm2[4],xmm3[5],xmm2[6],xmm3[7]
692; AVX1-NEXT:    vpblendw {{.*#+}} xmm1 = xmm1[0],xmm3[1],xmm1[2],xmm3[3],xmm1[4],xmm3[5],xmm1[6],xmm3[7]
693; AVX1-NEXT:    vpackusdw %xmm2, %xmm1, %xmm1
694; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
695; AVX1-NEXT:    vpblendw {{.*#+}} xmm2 = xmm2[0],xmm3[1],xmm2[2],xmm3[3],xmm2[4],xmm3[5],xmm2[6],xmm3[7]
696; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0],xmm3[1],xmm0[2],xmm3[3],xmm0[4],xmm3[5],xmm0[6],xmm3[7]
697; AVX1-NEXT:    vpackusdw %xmm2, %xmm0, %xmm0
698; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
699; AVX1-NEXT:    vmovups %ymm0, (%rax)
700; AVX1-NEXT:    vzeroupper
701; AVX1-NEXT:    retq
702;
703; AVX2-LABEL: trunc16i32_16i16:
704; AVX2:       # %bb.0: # %entry
705; AVX2-NEXT:    vmovdqa {{.*#+}} ymm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15,16,17,20,21,24,25,28,29,24,25,28,29,28,29,30,31]
706; AVX2-NEXT:    vpshufb %ymm2, %ymm0, %ymm0
707; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
708; AVX2-NEXT:    vpshufb %ymm2, %ymm1, %ymm1
709; AVX2-NEXT:    vpermq {{.*#+}} ymm1 = ymm1[0,2,2,3]
710; AVX2-NEXT:    vinserti128 $1, %xmm1, %ymm0, %ymm0
711; AVX2-NEXT:    vmovdqu %ymm0, (%rax)
712; AVX2-NEXT:    vzeroupper
713; AVX2-NEXT:    retq
714;
715; AVX512-LABEL: trunc16i32_16i16:
716; AVX512:       # %bb.0: # %entry
717; AVX512-NEXT:    vpmovdw %zmm0, (%rax)
718; AVX512-NEXT:    vzeroupper
719; AVX512-NEXT:    retq
720entry:
721  %0 = trunc <16 x i32> %a to <16 x i16>
722  store <16 x i16> %0, <16 x i16>* undef, align 4
723  ret void
724}
725
726define void @trunc16i32_16i16_ashr(<16 x i32> %a) {
727; SSE-LABEL: trunc16i32_16i16_ashr:
728; SSE:       # %bb.0: # %entry
729; SSE-NEXT:    psrad $16, %xmm3
730; SSE-NEXT:    psrad $16, %xmm2
731; SSE-NEXT:    packssdw %xmm3, %xmm2
732; SSE-NEXT:    psrad $16, %xmm1
733; SSE-NEXT:    psrad $16, %xmm0
734; SSE-NEXT:    packssdw %xmm1, %xmm0
735; SSE-NEXT:    movdqu %xmm2, (%rax)
736; SSE-NEXT:    movdqu %xmm0, (%rax)
737; SSE-NEXT:    retq
738;
739; AVX1-LABEL: trunc16i32_16i16_ashr:
740; AVX1:       # %bb.0: # %entry
741; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
742; AVX1-NEXT:    vpsrad $16, %xmm2, %xmm2
743; AVX1-NEXT:    vpsrad $16, %xmm0, %xmm0
744; AVX1-NEXT:    vpackssdw %xmm2, %xmm0, %xmm0
745; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
746; AVX1-NEXT:    vpsrad $16, %xmm2, %xmm2
747; AVX1-NEXT:    vpsrad $16, %xmm1, %xmm1
748; AVX1-NEXT:    vpackssdw %xmm2, %xmm1, %xmm1
749; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
750; AVX1-NEXT:    vmovups %ymm0, (%rax)
751; AVX1-NEXT:    vzeroupper
752; AVX1-NEXT:    retq
753;
754; AVX2-LABEL: trunc16i32_16i16_ashr:
755; AVX2:       # %bb.0: # %entry
756; AVX2-NEXT:    vpsrad $16, %ymm1, %ymm1
757; AVX2-NEXT:    vpsrad $16, %ymm0, %ymm0
758; AVX2-NEXT:    vpackssdw %ymm1, %ymm0, %ymm0
759; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3]
760; AVX2-NEXT:    vmovdqu %ymm0, (%rax)
761; AVX2-NEXT:    vzeroupper
762; AVX2-NEXT:    retq
763;
764; AVX512-LABEL: trunc16i32_16i16_ashr:
765; AVX512:       # %bb.0: # %entry
766; AVX512-NEXT:    vpsrld $16, %zmm0, %zmm0
767; AVX512-NEXT:    vpmovdw %zmm0, (%rax)
768; AVX512-NEXT:    vzeroupper
769; AVX512-NEXT:    retq
770entry:
771  %0 = ashr <16 x i32> %a, <i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16>
772  %1 = trunc <16 x i32> %0 to <16 x i16>
773  store <16 x i16> %1, <16 x i16>* undef, align 4
774  ret void
775}
776
777define void @trunc16i32_16i16_lshr(<16 x i32> %a) {
778; SSE2-LABEL: trunc16i32_16i16_lshr:
779; SSE2:       # %bb.0: # %entry
780; SSE2-NEXT:    psrld $16, %xmm2
781; SSE2-NEXT:    psrld $16, %xmm3
782; SSE2-NEXT:    psrld $16, %xmm0
783; SSE2-NEXT:    psrld $16, %xmm1
784; SSE2-NEXT:    pslld $16, %xmm1
785; SSE2-NEXT:    psrad $16, %xmm1
786; SSE2-NEXT:    pslld $16, %xmm0
787; SSE2-NEXT:    psrad $16, %xmm0
788; SSE2-NEXT:    packssdw %xmm1, %xmm0
789; SSE2-NEXT:    pslld $16, %xmm3
790; SSE2-NEXT:    psrad $16, %xmm3
791; SSE2-NEXT:    pslld $16, %xmm2
792; SSE2-NEXT:    psrad $16, %xmm2
793; SSE2-NEXT:    packssdw %xmm3, %xmm2
794; SSE2-NEXT:    movdqu %xmm2, (%rax)
795; SSE2-NEXT:    movdqu %xmm0, (%rax)
796; SSE2-NEXT:    retq
797;
798; SSSE3-LABEL: trunc16i32_16i16_lshr:
799; SSSE3:       # %bb.0: # %entry
800; SSSE3-NEXT:    psrld $16, %xmm2
801; SSSE3-NEXT:    psrld $16, %xmm3
802; SSSE3-NEXT:    psrld $16, %xmm0
803; SSSE3-NEXT:    psrld $16, %xmm1
804; SSSE3-NEXT:    pslld $16, %xmm1
805; SSSE3-NEXT:    psrad $16, %xmm1
806; SSSE3-NEXT:    pslld $16, %xmm0
807; SSSE3-NEXT:    psrad $16, %xmm0
808; SSSE3-NEXT:    packssdw %xmm1, %xmm0
809; SSSE3-NEXT:    pslld $16, %xmm3
810; SSSE3-NEXT:    psrad $16, %xmm3
811; SSSE3-NEXT:    pslld $16, %xmm2
812; SSSE3-NEXT:    psrad $16, %xmm2
813; SSSE3-NEXT:    packssdw %xmm3, %xmm2
814; SSSE3-NEXT:    movdqu %xmm2, (%rax)
815; SSSE3-NEXT:    movdqu %xmm0, (%rax)
816; SSSE3-NEXT:    retq
817;
818; SSE41-LABEL: trunc16i32_16i16_lshr:
819; SSE41:       # %bb.0: # %entry
820; SSE41-NEXT:    psrld $16, %xmm3
821; SSE41-NEXT:    psrld $16, %xmm2
822; SSE41-NEXT:    packusdw %xmm3, %xmm2
823; SSE41-NEXT:    psrld $16, %xmm1
824; SSE41-NEXT:    psrld $16, %xmm0
825; SSE41-NEXT:    packusdw %xmm1, %xmm0
826; SSE41-NEXT:    movdqu %xmm2, (%rax)
827; SSE41-NEXT:    movdqu %xmm0, (%rax)
828; SSE41-NEXT:    retq
829;
830; AVX1-LABEL: trunc16i32_16i16_lshr:
831; AVX1:       # %bb.0: # %entry
832; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
833; AVX1-NEXT:    vpsrld $16, %xmm2, %xmm2
834; AVX1-NEXT:    vpsrld $16, %xmm0, %xmm0
835; AVX1-NEXT:    vpackusdw %xmm2, %xmm0, %xmm0
836; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
837; AVX1-NEXT:    vpsrld $16, %xmm2, %xmm2
838; AVX1-NEXT:    vpsrld $16, %xmm1, %xmm1
839; AVX1-NEXT:    vpackusdw %xmm2, %xmm1, %xmm1
840; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
841; AVX1-NEXT:    vmovups %ymm0, (%rax)
842; AVX1-NEXT:    vzeroupper
843; AVX1-NEXT:    retq
844;
845; AVX2-LABEL: trunc16i32_16i16_lshr:
846; AVX2:       # %bb.0: # %entry
847; AVX2-NEXT:    vpsrld $16, %ymm1, %ymm1
848; AVX2-NEXT:    vpsrld $16, %ymm0, %ymm0
849; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
850; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3]
851; AVX2-NEXT:    vmovdqu %ymm0, (%rax)
852; AVX2-NEXT:    vzeroupper
853; AVX2-NEXT:    retq
854;
855; AVX512-LABEL: trunc16i32_16i16_lshr:
856; AVX512:       # %bb.0: # %entry
857; AVX512-NEXT:    vpsrld $16, %zmm0, %zmm0
858; AVX512-NEXT:    vpmovdw %zmm0, (%rax)
859; AVX512-NEXT:    vzeroupper
860; AVX512-NEXT:    retq
861entry:
862  %0 = lshr <16 x i32> %a, <i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16>
863  %1 = trunc <16 x i32> %0 to <16 x i16>
864  store <16 x i16> %1, <16 x i16>* undef, align 4
865  ret void
866}
867
868define void @trunc16i32_16i8(<16 x i32> %a) {
869; SSE2-LABEL: trunc16i32_16i8:
870; SSE2:       # %bb.0: # %entry
871; SSE2-NEXT:    movdqa {{.*#+}} xmm4 = [255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0]
872; SSE2-NEXT:    pand %xmm4, %xmm3
873; SSE2-NEXT:    pand %xmm4, %xmm2
874; SSE2-NEXT:    packuswb %xmm3, %xmm2
875; SSE2-NEXT:    pand %xmm4, %xmm1
876; SSE2-NEXT:    pand %xmm4, %xmm0
877; SSE2-NEXT:    packuswb %xmm1, %xmm0
878; SSE2-NEXT:    packuswb %xmm2, %xmm0
879; SSE2-NEXT:    movdqu %xmm0, (%rax)
880; SSE2-NEXT:    retq
881;
882; SSSE3-LABEL: trunc16i32_16i8:
883; SSSE3:       # %bb.0: # %entry
884; SSSE3-NEXT:    movdqa {{.*#+}} xmm4 = [255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0]
885; SSSE3-NEXT:    pand %xmm4, %xmm3
886; SSSE3-NEXT:    pand %xmm4, %xmm2
887; SSSE3-NEXT:    packuswb %xmm3, %xmm2
888; SSSE3-NEXT:    pand %xmm4, %xmm1
889; SSSE3-NEXT:    pand %xmm4, %xmm0
890; SSSE3-NEXT:    packuswb %xmm1, %xmm0
891; SSSE3-NEXT:    packuswb %xmm2, %xmm0
892; SSSE3-NEXT:    movdqu %xmm0, (%rax)
893; SSSE3-NEXT:    retq
894;
895; SSE41-LABEL: trunc16i32_16i8:
896; SSE41:       # %bb.0: # %entry
897; SSE41-NEXT:    movdqa {{.*#+}} xmm4 = [255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0]
898; SSE41-NEXT:    pand %xmm4, %xmm3
899; SSE41-NEXT:    pand %xmm4, %xmm2
900; SSE41-NEXT:    packusdw %xmm3, %xmm2
901; SSE41-NEXT:    pand %xmm4, %xmm1
902; SSE41-NEXT:    pand %xmm4, %xmm0
903; SSE41-NEXT:    packusdw %xmm1, %xmm0
904; SSE41-NEXT:    packuswb %xmm2, %xmm0
905; SSE41-NEXT:    movdqu %xmm0, (%rax)
906; SSE41-NEXT:    retq
907;
908; AVX1-LABEL: trunc16i32_16i8:
909; AVX1:       # %bb.0: # %entry
910; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
911; AVX1-NEXT:    vbroadcastss {{.*#+}} xmm3 = [3.57331108E-43,3.57331108E-43,3.57331108E-43,3.57331108E-43]
912; AVX1-NEXT:    vandps %xmm3, %xmm2, %xmm2
913; AVX1-NEXT:    vandps %xmm3, %xmm1, %xmm1
914; AVX1-NEXT:    vpackusdw %xmm2, %xmm1, %xmm1
915; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
916; AVX1-NEXT:    vandps %xmm3, %xmm2, %xmm2
917; AVX1-NEXT:    vandps %xmm3, %xmm0, %xmm0
918; AVX1-NEXT:    vpackusdw %xmm2, %xmm0, %xmm0
919; AVX1-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
920; AVX1-NEXT:    vmovdqu %xmm0, (%rax)
921; AVX1-NEXT:    vzeroupper
922; AVX1-NEXT:    retq
923;
924; AVX2-LABEL: trunc16i32_16i8:
925; AVX2:       # %bb.0: # %entry
926; AVX2-NEXT:    vmovdqa {{.*#+}} ymm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15,16,17,20,21,24,25,28,29,24,25,28,29,28,29,30,31]
927; AVX2-NEXT:    vpshufb %ymm2, %ymm1, %ymm1
928; AVX2-NEXT:    vpermq {{.*#+}} ymm1 = ymm1[0,2,2,3]
929; AVX2-NEXT:    vmovdqa {{.*#+}} xmm3 = [255,255,255,255,255,255,255,255]
930; AVX2-NEXT:    vpand %xmm3, %xmm1, %xmm1
931; AVX2-NEXT:    vpshufb %ymm2, %ymm0, %ymm0
932; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
933; AVX2-NEXT:    vpand %xmm3, %xmm0, %xmm0
934; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
935; AVX2-NEXT:    vmovdqu %xmm0, (%rax)
936; AVX2-NEXT:    vzeroupper
937; AVX2-NEXT:    retq
938;
939; AVX512-LABEL: trunc16i32_16i8:
940; AVX512:       # %bb.0: # %entry
941; AVX512-NEXT:    vpmovdb %zmm0, (%rax)
942; AVX512-NEXT:    vzeroupper
943; AVX512-NEXT:    retq
944entry:
945  %0 = trunc <16 x i32> %a to <16 x i8>
946  store <16 x i8> %0, <16 x i8>* undef, align 4
947  ret void
948}
949
950define void @trunc16i32_16i8_ashr(<16 x i32> %a) {
951; SSE-LABEL: trunc16i32_16i8_ashr:
952; SSE:       # %bb.0: # %entry
953; SSE-NEXT:    psrad $24, %xmm1
954; SSE-NEXT:    psrad $24, %xmm0
955; SSE-NEXT:    packssdw %xmm1, %xmm0
956; SSE-NEXT:    psrad $24, %xmm3
957; SSE-NEXT:    psrad $24, %xmm2
958; SSE-NEXT:    packssdw %xmm3, %xmm2
959; SSE-NEXT:    packsswb %xmm2, %xmm0
960; SSE-NEXT:    movdqu %xmm0, (%rax)
961; SSE-NEXT:    retq
962;
963; AVX1-LABEL: trunc16i32_16i8_ashr:
964; AVX1:       # %bb.0: # %entry
965; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
966; AVX1-NEXT:    vpsrad $24, %xmm2, %xmm2
967; AVX1-NEXT:    vpsrad $24, %xmm0, %xmm0
968; AVX1-NEXT:    vpackssdw %xmm2, %xmm0, %xmm0
969; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
970; AVX1-NEXT:    vpsrad $24, %xmm2, %xmm2
971; AVX1-NEXT:    vpsrad $24, %xmm1, %xmm1
972; AVX1-NEXT:    vpackssdw %xmm2, %xmm1, %xmm1
973; AVX1-NEXT:    vpacksswb %xmm1, %xmm0, %xmm0
974; AVX1-NEXT:    vmovdqu %xmm0, (%rax)
975; AVX1-NEXT:    vzeroupper
976; AVX1-NEXT:    retq
977;
978; AVX2-LABEL: trunc16i32_16i8_ashr:
979; AVX2:       # %bb.0: # %entry
980; AVX2-NEXT:    vpsrad $24, %ymm1, %ymm1
981; AVX2-NEXT:    vpsrad $24, %ymm0, %ymm0
982; AVX2-NEXT:    vpackssdw %ymm1, %ymm0, %ymm0
983; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3]
984; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
985; AVX2-NEXT:    vpacksswb %xmm1, %xmm0, %xmm0
986; AVX2-NEXT:    vmovdqu %xmm0, (%rax)
987; AVX2-NEXT:    vzeroupper
988; AVX2-NEXT:    retq
989;
990; AVX512-LABEL: trunc16i32_16i8_ashr:
991; AVX512:       # %bb.0: # %entry
992; AVX512-NEXT:    vpsrld $24, %zmm0, %zmm0
993; AVX512-NEXT:    vpmovdb %zmm0, (%rax)
994; AVX512-NEXT:    vzeroupper
995; AVX512-NEXT:    retq
996entry:
997  %0 = ashr <16 x i32> %a, <i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24>
998  %1 = trunc <16 x i32> %0 to <16 x i8>
999  store <16 x i8> %1, <16 x i8>* undef, align 4
1000  ret void
1001}
1002
1003define void @trunc16i32_16i8_lshr(<16 x i32> %a) {
1004; SSE2-LABEL: trunc16i32_16i8_lshr:
1005; SSE2:       # %bb.0: # %entry
1006; SSE2-NEXT:    psrld $24, %xmm1
1007; SSE2-NEXT:    psrld $24, %xmm0
1008; SSE2-NEXT:    packuswb %xmm1, %xmm0
1009; SSE2-NEXT:    psrld $24, %xmm3
1010; SSE2-NEXT:    psrld $24, %xmm2
1011; SSE2-NEXT:    packuswb %xmm3, %xmm2
1012; SSE2-NEXT:    packuswb %xmm2, %xmm0
1013; SSE2-NEXT:    movdqu %xmm0, (%rax)
1014; SSE2-NEXT:    retq
1015;
1016; SSSE3-LABEL: trunc16i32_16i8_lshr:
1017; SSSE3:       # %bb.0: # %entry
1018; SSSE3-NEXT:    psrld $24, %xmm1
1019; SSSE3-NEXT:    psrld $24, %xmm0
1020; SSSE3-NEXT:    packuswb %xmm1, %xmm0
1021; SSSE3-NEXT:    psrld $24, %xmm3
1022; SSSE3-NEXT:    psrld $24, %xmm2
1023; SSSE3-NEXT:    packuswb %xmm3, %xmm2
1024; SSSE3-NEXT:    packuswb %xmm2, %xmm0
1025; SSSE3-NEXT:    movdqu %xmm0, (%rax)
1026; SSSE3-NEXT:    retq
1027;
1028; SSE41-LABEL: trunc16i32_16i8_lshr:
1029; SSE41:       # %bb.0: # %entry
1030; SSE41-NEXT:    psrld $24, %xmm1
1031; SSE41-NEXT:    psrld $24, %xmm0
1032; SSE41-NEXT:    packusdw %xmm1, %xmm0
1033; SSE41-NEXT:    psrld $24, %xmm3
1034; SSE41-NEXT:    psrld $24, %xmm2
1035; SSE41-NEXT:    packusdw %xmm3, %xmm2
1036; SSE41-NEXT:    packuswb %xmm2, %xmm0
1037; SSE41-NEXT:    movdqu %xmm0, (%rax)
1038; SSE41-NEXT:    retq
1039;
1040; AVX1-LABEL: trunc16i32_16i8_lshr:
1041; AVX1:       # %bb.0: # %entry
1042; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
1043; AVX1-NEXT:    vpsrld $24, %xmm2, %xmm2
1044; AVX1-NEXT:    vpsrld $24, %xmm0, %xmm0
1045; AVX1-NEXT:    vpackusdw %xmm2, %xmm0, %xmm0
1046; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
1047; AVX1-NEXT:    vpsrld $24, %xmm2, %xmm2
1048; AVX1-NEXT:    vpsrld $24, %xmm1, %xmm1
1049; AVX1-NEXT:    vpackusdw %xmm2, %xmm1, %xmm1
1050; AVX1-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
1051; AVX1-NEXT:    vmovdqu %xmm0, (%rax)
1052; AVX1-NEXT:    vzeroupper
1053; AVX1-NEXT:    retq
1054;
1055; AVX2-LABEL: trunc16i32_16i8_lshr:
1056; AVX2:       # %bb.0: # %entry
1057; AVX2-NEXT:    vpsrld $24, %ymm1, %ymm1
1058; AVX2-NEXT:    vpsrld $24, %ymm0, %ymm0
1059; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
1060; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3]
1061; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
1062; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
1063; AVX2-NEXT:    vmovdqu %xmm0, (%rax)
1064; AVX2-NEXT:    vzeroupper
1065; AVX2-NEXT:    retq
1066;
1067; AVX512-LABEL: trunc16i32_16i8_lshr:
1068; AVX512:       # %bb.0: # %entry
1069; AVX512-NEXT:    vpsrld $24, %zmm0, %zmm0
1070; AVX512-NEXT:    vpmovdb %zmm0, (%rax)
1071; AVX512-NEXT:    vzeroupper
1072; AVX512-NEXT:    retq
1073entry:
1074  %0 = lshr <16 x i32> %a, <i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24>
1075  %1 = trunc <16 x i32> %0 to <16 x i8>
1076  store <16 x i8> %1, <16 x i8>* undef, align 4
1077  ret void
1078}
1079
1080;PR25684
1081define void @trunc16i16_16i8(<16 x i16> %a) {
1082; SSE2-LABEL: trunc16i16_16i8:
1083; SSE2:       # %bb.0: # %entry
1084; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [255,255,255,255,255,255,255,255]
1085; SSE2-NEXT:    pand %xmm2, %xmm1
1086; SSE2-NEXT:    pand %xmm2, %xmm0
1087; SSE2-NEXT:    packuswb %xmm1, %xmm0
1088; SSE2-NEXT:    movdqu %xmm0, (%rax)
1089; SSE2-NEXT:    retq
1090;
1091; SSSE3-LABEL: trunc16i16_16i8:
1092; SSSE3:       # %bb.0: # %entry
1093; SSSE3-NEXT:    movdqa {{.*#+}} xmm2 = <0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u>
1094; SSSE3-NEXT:    pshufb %xmm2, %xmm1
1095; SSSE3-NEXT:    pshufb %xmm2, %xmm0
1096; SSSE3-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1097; SSSE3-NEXT:    movdqu %xmm0, (%rax)
1098; SSSE3-NEXT:    retq
1099;
1100; SSE41-LABEL: trunc16i16_16i8:
1101; SSE41:       # %bb.0: # %entry
1102; SSE41-NEXT:    movdqa {{.*#+}} xmm2 = <0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u>
1103; SSE41-NEXT:    pshufb %xmm2, %xmm1
1104; SSE41-NEXT:    pshufb %xmm2, %xmm0
1105; SSE41-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1106; SSE41-NEXT:    movdqu %xmm0, (%rax)
1107; SSE41-NEXT:    retq
1108;
1109; AVX1-LABEL: trunc16i16_16i8:
1110; AVX1:       # %bb.0: # %entry
1111; AVX1-NEXT:    vandps {{.*}}(%rip), %ymm0, %ymm0
1112; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
1113; AVX1-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
1114; AVX1-NEXT:    vmovdqu %xmm0, (%rax)
1115; AVX1-NEXT:    vzeroupper
1116; AVX1-NEXT:    retq
1117;
1118; AVX2-LABEL: trunc16i16_16i8:
1119; AVX2:       # %bb.0: # %entry
1120; AVX2-NEXT:    vpand {{.*}}(%rip), %ymm0, %ymm0
1121; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
1122; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
1123; AVX2-NEXT:    vmovdqu %xmm0, (%rax)
1124; AVX2-NEXT:    vzeroupper
1125; AVX2-NEXT:    retq
1126;
1127; AVX512F-LABEL: trunc16i16_16i8:
1128; AVX512F:       # %bb.0: # %entry
1129; AVX512F-NEXT:    vpmovzxwd {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero
1130; AVX512F-NEXT:    vpmovdb %zmm0, (%rax)
1131; AVX512F-NEXT:    vzeroupper
1132; AVX512F-NEXT:    retq
1133;
1134; AVX512VL-LABEL: trunc16i16_16i8:
1135; AVX512VL:       # %bb.0: # %entry
1136; AVX512VL-NEXT:    vpmovzxwd {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero
1137; AVX512VL-NEXT:    vpmovdb %zmm0, (%rax)
1138; AVX512VL-NEXT:    vzeroupper
1139; AVX512VL-NEXT:    retq
1140;
1141; AVX512BW-LABEL: trunc16i16_16i8:
1142; AVX512BW:       # %bb.0: # %entry
1143; AVX512BW-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
1144; AVX512BW-NEXT:    vpmovwb %zmm0, %ymm0
1145; AVX512BW-NEXT:    vmovdqu %xmm0, (%rax)
1146; AVX512BW-NEXT:    vzeroupper
1147; AVX512BW-NEXT:    retq
1148;
1149; AVX512BWVL-LABEL: trunc16i16_16i8:
1150; AVX512BWVL:       # %bb.0: # %entry
1151; AVX512BWVL-NEXT:    vpmovwb %ymm0, (%rax)
1152; AVX512BWVL-NEXT:    vzeroupper
1153; AVX512BWVL-NEXT:    retq
1154entry:
1155  %0 = trunc <16 x i16> %a to <16 x i8>
1156  store <16 x i8> %0, <16 x i8>* undef, align 4
1157  ret void
1158}
1159
1160define void @trunc16i16_16i8_ashr(<16 x i16> %a) {
1161; SSE-LABEL: trunc16i16_16i8_ashr:
1162; SSE:       # %bb.0: # %entry
1163; SSE-NEXT:    psraw $8, %xmm1
1164; SSE-NEXT:    psraw $8, %xmm0
1165; SSE-NEXT:    packsswb %xmm1, %xmm0
1166; SSE-NEXT:    movdqu %xmm0, (%rax)
1167; SSE-NEXT:    retq
1168;
1169; AVX1-LABEL: trunc16i16_16i8_ashr:
1170; AVX1:       # %bb.0: # %entry
1171; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
1172; AVX1-NEXT:    vpsraw $8, %xmm1, %xmm1
1173; AVX1-NEXT:    vpsraw $8, %xmm0, %xmm0
1174; AVX1-NEXT:    vpacksswb %xmm1, %xmm0, %xmm0
1175; AVX1-NEXT:    vmovdqu %xmm0, (%rax)
1176; AVX1-NEXT:    vzeroupper
1177; AVX1-NEXT:    retq
1178;
1179; AVX2-LABEL: trunc16i16_16i8_ashr:
1180; AVX2:       # %bb.0: # %entry
1181; AVX2-NEXT:    vpsraw $8, %ymm0, %ymm0
1182; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
1183; AVX2-NEXT:    vpacksswb %xmm1, %xmm0, %xmm0
1184; AVX2-NEXT:    vmovdqu %xmm0, (%rax)
1185; AVX2-NEXT:    vzeroupper
1186; AVX2-NEXT:    retq
1187;
1188; AVX512F-LABEL: trunc16i16_16i8_ashr:
1189; AVX512F:       # %bb.0: # %entry
1190; AVX512F-NEXT:    vpsraw $8, %ymm0, %ymm0
1191; AVX512F-NEXT:    vpmovzxwd {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero
1192; AVX512F-NEXT:    vpmovdb %zmm0, (%rax)
1193; AVX512F-NEXT:    vzeroupper
1194; AVX512F-NEXT:    retq
1195;
1196; AVX512VL-LABEL: trunc16i16_16i8_ashr:
1197; AVX512VL:       # %bb.0: # %entry
1198; AVX512VL-NEXT:    vpsraw $8, %ymm0, %ymm0
1199; AVX512VL-NEXT:    vpmovzxwd {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero
1200; AVX512VL-NEXT:    vpmovdb %zmm0, (%rax)
1201; AVX512VL-NEXT:    vzeroupper
1202; AVX512VL-NEXT:    retq
1203;
1204; AVX512BW-LABEL: trunc16i16_16i8_ashr:
1205; AVX512BW:       # %bb.0: # %entry
1206; AVX512BW-NEXT:    vpsraw $8, %ymm0, %ymm0
1207; AVX512BW-NEXT:    vpmovwb %zmm0, %ymm0
1208; AVX512BW-NEXT:    vmovdqu %xmm0, (%rax)
1209; AVX512BW-NEXT:    vzeroupper
1210; AVX512BW-NEXT:    retq
1211;
1212; AVX512BWVL-LABEL: trunc16i16_16i8_ashr:
1213; AVX512BWVL:       # %bb.0: # %entry
1214; AVX512BWVL-NEXT:    vpsrlw $8, %ymm0, %ymm0
1215; AVX512BWVL-NEXT:    vpmovwb %ymm0, (%rax)
1216; AVX512BWVL-NEXT:    vzeroupper
1217; AVX512BWVL-NEXT:    retq
1218entry:
1219  %0 = ashr <16 x i16> %a, <i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8>
1220  %1 = trunc <16 x i16> %0 to <16 x i8>
1221  store <16 x i8> %1, <16 x i8>* undef, align 4
1222  ret void
1223}
1224
1225define void @trunc16i16_16i8_lshr(<16 x i16> %a) {
1226; SSE-LABEL: trunc16i16_16i8_lshr:
1227; SSE:       # %bb.0: # %entry
1228; SSE-NEXT:    psrlw $8, %xmm1
1229; SSE-NEXT:    psrlw $8, %xmm0
1230; SSE-NEXT:    packuswb %xmm1, %xmm0
1231; SSE-NEXT:    movdqu %xmm0, (%rax)
1232; SSE-NEXT:    retq
1233;
1234; AVX1-LABEL: trunc16i16_16i8_lshr:
1235; AVX1:       # %bb.0: # %entry
1236; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
1237; AVX1-NEXT:    vpsrlw $8, %xmm1, %xmm1
1238; AVX1-NEXT:    vpsrlw $8, %xmm0, %xmm0
1239; AVX1-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
1240; AVX1-NEXT:    vmovdqu %xmm0, (%rax)
1241; AVX1-NEXT:    vzeroupper
1242; AVX1-NEXT:    retq
1243;
1244; AVX2-LABEL: trunc16i16_16i8_lshr:
1245; AVX2:       # %bb.0: # %entry
1246; AVX2-NEXT:    vpsrlw $8, %ymm0, %ymm0
1247; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
1248; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
1249; AVX2-NEXT:    vmovdqu %xmm0, (%rax)
1250; AVX2-NEXT:    vzeroupper
1251; AVX2-NEXT:    retq
1252;
1253; AVX512F-LABEL: trunc16i16_16i8_lshr:
1254; AVX512F:       # %bb.0: # %entry
1255; AVX512F-NEXT:    vpsrlw $8, %ymm0, %ymm0
1256; AVX512F-NEXT:    vpmovzxwd {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero
1257; AVX512F-NEXT:    vpmovdb %zmm0, (%rax)
1258; AVX512F-NEXT:    vzeroupper
1259; AVX512F-NEXT:    retq
1260;
1261; AVX512VL-LABEL: trunc16i16_16i8_lshr:
1262; AVX512VL:       # %bb.0: # %entry
1263; AVX512VL-NEXT:    vpsrlw $8, %ymm0, %ymm0
1264; AVX512VL-NEXT:    vpmovzxwd {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero
1265; AVX512VL-NEXT:    vpmovdb %zmm0, (%rax)
1266; AVX512VL-NEXT:    vzeroupper
1267; AVX512VL-NEXT:    retq
1268;
1269; AVX512BW-LABEL: trunc16i16_16i8_lshr:
1270; AVX512BW:       # %bb.0: # %entry
1271; AVX512BW-NEXT:    vpsrlw $8, %ymm0, %ymm0
1272; AVX512BW-NEXT:    vpmovwb %zmm0, %ymm0
1273; AVX512BW-NEXT:    vmovdqu %xmm0, (%rax)
1274; AVX512BW-NEXT:    vzeroupper
1275; AVX512BW-NEXT:    retq
1276;
1277; AVX512BWVL-LABEL: trunc16i16_16i8_lshr:
1278; AVX512BWVL:       # %bb.0: # %entry
1279; AVX512BWVL-NEXT:    vpsrlw $8, %ymm0, %ymm0
1280; AVX512BWVL-NEXT:    vpmovwb %ymm0, (%rax)
1281; AVX512BWVL-NEXT:    vzeroupper
1282; AVX512BWVL-NEXT:    retq
1283entry:
1284  %0 = lshr <16 x i16> %a, <i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8>
1285  %1 = trunc <16 x i16> %0 to <16 x i8>
1286  store <16 x i8> %1, <16 x i8>* undef, align 4
1287  ret void
1288}
1289
1290define void @trunc32i16_32i8(<32 x i16> %a) {
1291; SSE2-LABEL: trunc32i16_32i8:
1292; SSE2:       # %bb.0: # %entry
1293; SSE2-NEXT:    movdqa {{.*#+}} xmm4 = [255,255,255,255,255,255,255,255]
1294; SSE2-NEXT:    pand %xmm4, %xmm1
1295; SSE2-NEXT:    pand %xmm4, %xmm0
1296; SSE2-NEXT:    packuswb %xmm1, %xmm0
1297; SSE2-NEXT:    pand %xmm4, %xmm3
1298; SSE2-NEXT:    pand %xmm4, %xmm2
1299; SSE2-NEXT:    packuswb %xmm3, %xmm2
1300; SSE2-NEXT:    movdqu %xmm2, (%rax)
1301; SSE2-NEXT:    movdqu %xmm0, (%rax)
1302; SSE2-NEXT:    retq
1303;
1304; SSSE3-LABEL: trunc32i16_32i8:
1305; SSSE3:       # %bb.0: # %entry
1306; SSSE3-NEXT:    movdqa {{.*#+}} xmm4 = <0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u>
1307; SSSE3-NEXT:    pshufb %xmm4, %xmm1
1308; SSSE3-NEXT:    pshufb %xmm4, %xmm0
1309; SSSE3-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1310; SSSE3-NEXT:    pshufb %xmm4, %xmm3
1311; SSSE3-NEXT:    pshufb %xmm4, %xmm2
1312; SSSE3-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm3[0]
1313; SSSE3-NEXT:    movdqu %xmm2, (%rax)
1314; SSSE3-NEXT:    movdqu %xmm0, (%rax)
1315; SSSE3-NEXT:    retq
1316;
1317; SSE41-LABEL: trunc32i16_32i8:
1318; SSE41:       # %bb.0: # %entry
1319; SSE41-NEXT:    movdqa {{.*#+}} xmm4 = <0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u>
1320; SSE41-NEXT:    pshufb %xmm4, %xmm1
1321; SSE41-NEXT:    pshufb %xmm4, %xmm0
1322; SSE41-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1323; SSE41-NEXT:    pshufb %xmm4, %xmm3
1324; SSE41-NEXT:    pshufb %xmm4, %xmm2
1325; SSE41-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm3[0]
1326; SSE41-NEXT:    movdqu %xmm2, (%rax)
1327; SSE41-NEXT:    movdqu %xmm0, (%rax)
1328; SSE41-NEXT:    retq
1329;
1330; AVX1-LABEL: trunc32i16_32i8:
1331; AVX1:       # %bb.0: # %entry
1332; AVX1-NEXT:    vmovaps {{.*#+}} ymm2 = [255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255]
1333; AVX1-NEXT:    vandps %ymm2, %ymm1, %ymm1
1334; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
1335; AVX1-NEXT:    vpackuswb %xmm3, %xmm1, %xmm1
1336; AVX1-NEXT:    vandps %ymm2, %ymm0, %ymm0
1337; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
1338; AVX1-NEXT:    vpackuswb %xmm2, %xmm0, %xmm0
1339; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
1340; AVX1-NEXT:    vmovups %ymm0, (%rax)
1341; AVX1-NEXT:    vzeroupper
1342; AVX1-NEXT:    retq
1343;
1344; AVX2-LABEL: trunc32i16_32i8:
1345; AVX2:       # %bb.0: # %entry
1346; AVX2-NEXT:    vmovdqa {{.*#+}} ymm2 = [255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255]
1347; AVX2-NEXT:    vpand %ymm2, %ymm1, %ymm1
1348; AVX2-NEXT:    vextracti128 $1, %ymm1, %xmm3
1349; AVX2-NEXT:    vpackuswb %xmm3, %xmm1, %xmm1
1350; AVX2-NEXT:    vpand %ymm2, %ymm0, %ymm0
1351; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm2
1352; AVX2-NEXT:    vpackuswb %xmm2, %xmm0, %xmm0
1353; AVX2-NEXT:    vinserti128 $1, %xmm1, %ymm0, %ymm0
1354; AVX2-NEXT:    vmovdqu %ymm0, (%rax)
1355; AVX2-NEXT:    vzeroupper
1356; AVX2-NEXT:    retq
1357;
1358; AVX512F-LABEL: trunc32i16_32i8:
1359; AVX512F:       # %bb.0: # %entry
1360; AVX512F-NEXT:    vpmovzxwd {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero
1361; AVX512F-NEXT:    vpmovdb %zmm0, %xmm0
1362; AVX512F-NEXT:    vpmovzxwd {{.*#+}} zmm1 = ymm1[0],zero,ymm1[1],zero,ymm1[2],zero,ymm1[3],zero,ymm1[4],zero,ymm1[5],zero,ymm1[6],zero,ymm1[7],zero,ymm1[8],zero,ymm1[9],zero,ymm1[10],zero,ymm1[11],zero,ymm1[12],zero,ymm1[13],zero,ymm1[14],zero,ymm1[15],zero
1363; AVX512F-NEXT:    vpmovdb %zmm1, %xmm1
1364; AVX512F-NEXT:    vinserti128 $1, %xmm1, %ymm0, %ymm0
1365; AVX512F-NEXT:    vmovdqu %ymm0, (%rax)
1366; AVX512F-NEXT:    vzeroupper
1367; AVX512F-NEXT:    retq
1368;
1369; AVX512VL-LABEL: trunc32i16_32i8:
1370; AVX512VL:       # %bb.0: # %entry
1371; AVX512VL-NEXT:    vpmovzxwd {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero
1372; AVX512VL-NEXT:    vpmovdb %zmm0, %xmm0
1373; AVX512VL-NEXT:    vpmovzxwd {{.*#+}} zmm1 = ymm1[0],zero,ymm1[1],zero,ymm1[2],zero,ymm1[3],zero,ymm1[4],zero,ymm1[5],zero,ymm1[6],zero,ymm1[7],zero,ymm1[8],zero,ymm1[9],zero,ymm1[10],zero,ymm1[11],zero,ymm1[12],zero,ymm1[13],zero,ymm1[14],zero,ymm1[15],zero
1374; AVX512VL-NEXT:    vpmovdb %zmm1, %xmm1
1375; AVX512VL-NEXT:    vinserti128 $1, %xmm1, %ymm0, %ymm0
1376; AVX512VL-NEXT:    vmovdqu %ymm0, (%rax)
1377; AVX512VL-NEXT:    vzeroupper
1378; AVX512VL-NEXT:    retq
1379;
1380; AVX512BW-LABEL: trunc32i16_32i8:
1381; AVX512BW:       # %bb.0: # %entry
1382; AVX512BW-NEXT:    vpmovwb %zmm0, (%rax)
1383; AVX512BW-NEXT:    vzeroupper
1384; AVX512BW-NEXT:    retq
1385;
1386; AVX512BWVL-LABEL: trunc32i16_32i8:
1387; AVX512BWVL:       # %bb.0: # %entry
1388; AVX512BWVL-NEXT:    vpmovwb %zmm0, (%rax)
1389; AVX512BWVL-NEXT:    vzeroupper
1390; AVX512BWVL-NEXT:    retq
1391entry:
1392  %0 = trunc <32 x i16> %a to <32 x i8>
1393  store <32 x i8> %0, <32 x i8>* undef, align 4
1394  ret void
1395}
1396
1397define <8 x i32> @trunc2x4i64_8i32(<4 x i64> %a, <4 x i64> %b) {
1398; SSE-LABEL: trunc2x4i64_8i32:
1399; SSE:       # %bb.0: # %entry
1400; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
1401; SSE-NEXT:    shufps {{.*#+}} xmm2 = xmm2[0,2],xmm3[0,2]
1402; SSE-NEXT:    movaps %xmm2, %xmm1
1403; SSE-NEXT:    retq
1404;
1405; AVX1-LABEL: trunc2x4i64_8i32:
1406; AVX1:       # %bb.0: # %entry
1407; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
1408; AVX1-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm2[0,2]
1409; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
1410; AVX1-NEXT:    vshufps {{.*#+}} xmm1 = xmm1[0,2],xmm2[0,2]
1411; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
1412; AVX1-NEXT:    retq
1413;
1414; AVX2-SLOW-LABEL: trunc2x4i64_8i32:
1415; AVX2-SLOW:       # %bb.0: # %entry
1416; AVX2-SLOW-NEXT:    vpermilps {{.*#+}} ymm0 = ymm0[0,2,2,3,4,6,6,7]
1417; AVX2-SLOW-NEXT:    vpermpd {{.*#+}} ymm0 = ymm0[0,2,2,3]
1418; AVX2-SLOW-NEXT:    vpermilps {{.*#+}} ymm1 = ymm1[0,2,2,3,4,6,6,7]
1419; AVX2-SLOW-NEXT:    vpermpd {{.*#+}} ymm1 = ymm1[0,2,2,3]
1420; AVX2-SLOW-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
1421; AVX2-SLOW-NEXT:    retq
1422;
1423; AVX2-FAST-LABEL: trunc2x4i64_8i32:
1424; AVX2-FAST:       # %bb.0: # %entry
1425; AVX2-FAST-NEXT:    vmovaps {{.*#+}} ymm2 = [0,2,4,6,4,6,6,7]
1426; AVX2-FAST-NEXT:    vpermps %ymm0, %ymm2, %ymm0
1427; AVX2-FAST-NEXT:    vpermps %ymm1, %ymm2, %ymm1
1428; AVX2-FAST-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
1429; AVX2-FAST-NEXT:    retq
1430;
1431; AVX512F-LABEL: trunc2x4i64_8i32:
1432; AVX512F:       # %bb.0: # %entry
1433; AVX512F-NEXT:    # kill: def $ymm1 killed $ymm1 def $zmm1
1434; AVX512F-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
1435; AVX512F-NEXT:    vpmovqd %zmm0, %ymm0
1436; AVX512F-NEXT:    vpmovqd %zmm1, %ymm1
1437; AVX512F-NEXT:    vinserti128 $1, %xmm1, %ymm0, %ymm0
1438; AVX512F-NEXT:    retq
1439;
1440; AVX512VL-LABEL: trunc2x4i64_8i32:
1441; AVX512VL:       # %bb.0: # %entry
1442; AVX512VL-NEXT:    vpmovqd %ymm0, %xmm0
1443; AVX512VL-NEXT:    vpmovqd %ymm1, %xmm1
1444; AVX512VL-NEXT:    vinserti128 $1, %xmm1, %ymm0, %ymm0
1445; AVX512VL-NEXT:    retq
1446;
1447; AVX512BW-LABEL: trunc2x4i64_8i32:
1448; AVX512BW:       # %bb.0: # %entry
1449; AVX512BW-NEXT:    # kill: def $ymm1 killed $ymm1 def $zmm1
1450; AVX512BW-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
1451; AVX512BW-NEXT:    vpmovqd %zmm0, %ymm0
1452; AVX512BW-NEXT:    vpmovqd %zmm1, %ymm1
1453; AVX512BW-NEXT:    vinserti128 $1, %xmm1, %ymm0, %ymm0
1454; AVX512BW-NEXT:    retq
1455;
1456; AVX512BWVL-LABEL: trunc2x4i64_8i32:
1457; AVX512BWVL:       # %bb.0: # %entry
1458; AVX512BWVL-NEXT:    vpmovqd %ymm0, %xmm0
1459; AVX512BWVL-NEXT:    vpmovqd %ymm1, %xmm1
1460; AVX512BWVL-NEXT:    vinserti128 $1, %xmm1, %ymm0, %ymm0
1461; AVX512BWVL-NEXT:    retq
1462entry:
1463  %0 = trunc <4 x i64> %a to <4 x i32>
1464  %1 = trunc <4 x i64> %b to <4 x i32>
1465  %2 = shufflevector <4 x i32> %0, <4 x i32> %1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
1466  ret <8 x i32> %2
1467}
1468
1469define <8 x i16> @trunc2x4i64_8i16(<4 x i64> %a, <4 x i64> %b) {
1470; SSE2-LABEL: trunc2x4i64_8i16:
1471; SSE2:       # %bb.0: # %entry
1472; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
1473; SSE2-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,2,2,3,4,5,6,7]
1474; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
1475; SSE2-NEXT:    pshuflw {{.*#+}} xmm4 = xmm0[0,2,2,3,4,5,6,7]
1476; SSE2-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
1477; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[0,2,2,3]
1478; SSE2-NEXT:    pshuflw {{.*#+}} xmm1 = xmm0[0,1,0,2,4,5,6,7]
1479; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3]
1480; SSE2-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,1,0,2,4,5,6,7]
1481; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
1482; SSE2-NEXT:    movsd {{.*#+}} xmm0 = xmm4[0],xmm0[1]
1483; SSE2-NEXT:    retq
1484;
1485; SSSE3-LABEL: trunc2x4i64_8i16:
1486; SSSE3:       # %bb.0: # %entry
1487; SSSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
1488; SSSE3-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,2,2,3,4,5,6,7]
1489; SSSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
1490; SSSE3-NEXT:    pshuflw {{.*#+}} xmm4 = xmm0[0,2,2,3,4,5,6,7]
1491; SSSE3-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
1492; SSSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[0,2,2,3]
1493; SSSE3-NEXT:    pshuflw {{.*#+}} xmm1 = xmm0[0,1,0,2,4,5,6,7]
1494; SSSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3]
1495; SSSE3-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,1,0,2,4,5,6,7]
1496; SSSE3-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
1497; SSSE3-NEXT:    movsd {{.*#+}} xmm0 = xmm4[0],xmm0[1]
1498; SSSE3-NEXT:    retq
1499;
1500; SSE41-LABEL: trunc2x4i64_8i16:
1501; SSE41:       # %bb.0: # %entry
1502; SSE41-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[0,2,2,3]
1503; SSE41-NEXT:    pshuflw {{.*#+}} xmm3 = xmm3[0,1,0,2,4,5,6,7]
1504; SSE41-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[0,2,2,3]
1505; SSE41-NEXT:    pshuflw {{.*#+}} xmm2 = xmm2[0,1,0,2,4,5,6,7]
1506; SSE41-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm3[0],xmm2[1],xmm3[1]
1507; SSE41-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
1508; SSE41-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,2,2,3,4,5,6,7]
1509; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
1510; SSE41-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,2,2,3,4,5,6,7]
1511; SSE41-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
1512; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm2[4,5,6,7]
1513; SSE41-NEXT:    retq
1514;
1515; AVX1-LABEL: trunc2x4i64_8i16:
1516; AVX1:       # %bb.0: # %entry
1517; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
1518; AVX1-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm2[0,2]
1519; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
1520; AVX1-NEXT:    vshufps {{.*#+}} xmm1 = xmm1[0,2],xmm2[0,2]
1521; AVX1-NEXT:    vmovdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
1522; AVX1-NEXT:    vpshufb %xmm2, %xmm1, %xmm1
1523; AVX1-NEXT:    vpshufb %xmm2, %xmm0, %xmm0
1524; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1525; AVX1-NEXT:    vzeroupper
1526; AVX1-NEXT:    retq
1527;
1528; AVX2-SLOW-LABEL: trunc2x4i64_8i16:
1529; AVX2-SLOW:       # %bb.0: # %entry
1530; AVX2-SLOW-NEXT:    vpshufd {{.*#+}} ymm0 = ymm0[0,2,2,3,4,6,6,7]
1531; AVX2-SLOW-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
1532; AVX2-SLOW-NEXT:    vpshufd {{.*#+}} ymm1 = ymm1[0,2,2,3,4,6,6,7]
1533; AVX2-SLOW-NEXT:    vpermq {{.*#+}} ymm1 = ymm1[0,2,2,3]
1534; AVX2-SLOW-NEXT:    vmovdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
1535; AVX2-SLOW-NEXT:    vpshufb %xmm2, %xmm1, %xmm1
1536; AVX2-SLOW-NEXT:    vpshufb %xmm2, %xmm0, %xmm0
1537; AVX2-SLOW-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1538; AVX2-SLOW-NEXT:    vzeroupper
1539; AVX2-SLOW-NEXT:    retq
1540;
1541; AVX2-FAST-LABEL: trunc2x4i64_8i16:
1542; AVX2-FAST:       # %bb.0: # %entry
1543; AVX2-FAST-NEXT:    vmovdqa {{.*#+}} ymm2 = [0,2,4,6,4,6,6,7]
1544; AVX2-FAST-NEXT:    vpermd %ymm0, %ymm2, %ymm0
1545; AVX2-FAST-NEXT:    vpermd %ymm1, %ymm2, %ymm1
1546; AVX2-FAST-NEXT:    vmovdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
1547; AVX2-FAST-NEXT:    vpshufb %xmm2, %xmm1, %xmm1
1548; AVX2-FAST-NEXT:    vpshufb %xmm2, %xmm0, %xmm0
1549; AVX2-FAST-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1550; AVX2-FAST-NEXT:    vzeroupper
1551; AVX2-FAST-NEXT:    retq
1552;
1553; AVX512F-LABEL: trunc2x4i64_8i16:
1554; AVX512F:       # %bb.0: # %entry
1555; AVX512F-NEXT:    # kill: def $ymm1 killed $ymm1 def $zmm1
1556; AVX512F-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
1557; AVX512F-NEXT:    vpmovqd %zmm0, %ymm0
1558; AVX512F-NEXT:    vpmovqd %zmm1, %ymm1
1559; AVX512F-NEXT:    vmovdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
1560; AVX512F-NEXT:    vpshufb %xmm2, %xmm1, %xmm1
1561; AVX512F-NEXT:    vpshufb %xmm2, %xmm0, %xmm0
1562; AVX512F-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1563; AVX512F-NEXT:    vzeroupper
1564; AVX512F-NEXT:    retq
1565;
1566; AVX512VL-LABEL: trunc2x4i64_8i16:
1567; AVX512VL:       # %bb.0: # %entry
1568; AVX512VL-NEXT:    vpmovqd %ymm0, %xmm0
1569; AVX512VL-NEXT:    vpmovqd %ymm1, %xmm1
1570; AVX512VL-NEXT:    vmovdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
1571; AVX512VL-NEXT:    vpshufb %xmm2, %xmm1, %xmm1
1572; AVX512VL-NEXT:    vpshufb %xmm2, %xmm0, %xmm0
1573; AVX512VL-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1574; AVX512VL-NEXT:    vzeroupper
1575; AVX512VL-NEXT:    retq
1576;
1577; AVX512BW-LABEL: trunc2x4i64_8i16:
1578; AVX512BW:       # %bb.0: # %entry
1579; AVX512BW-NEXT:    # kill: def $ymm1 killed $ymm1 def $zmm1
1580; AVX512BW-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
1581; AVX512BW-NEXT:    vpmovqd %zmm0, %ymm0
1582; AVX512BW-NEXT:    vpmovqd %zmm1, %ymm1
1583; AVX512BW-NEXT:    vmovdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
1584; AVX512BW-NEXT:    vpshufb %xmm2, %xmm1, %xmm1
1585; AVX512BW-NEXT:    vpshufb %xmm2, %xmm0, %xmm0
1586; AVX512BW-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1587; AVX512BW-NEXT:    vzeroupper
1588; AVX512BW-NEXT:    retq
1589;
1590; AVX512BWVL-LABEL: trunc2x4i64_8i16:
1591; AVX512BWVL:       # %bb.0: # %entry
1592; AVX512BWVL-NEXT:    vpmovqd %ymm0, %xmm0
1593; AVX512BWVL-NEXT:    vpmovqd %ymm1, %xmm1
1594; AVX512BWVL-NEXT:    vmovdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
1595; AVX512BWVL-NEXT:    vpshufb %xmm2, %xmm1, %xmm1
1596; AVX512BWVL-NEXT:    vpshufb %xmm2, %xmm0, %xmm0
1597; AVX512BWVL-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1598; AVX512BWVL-NEXT:    vzeroupper
1599; AVX512BWVL-NEXT:    retq
1600entry:
1601  %0 = trunc <4 x i64> %a to <4 x i16>
1602  %1 = trunc <4 x i64> %b to <4 x i16>
1603  %2 = shufflevector <4 x i16> %0, <4 x i16> %1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
1604  ret <8 x i16> %2
1605}
1606
1607define <4 x i32> @trunc2x2i64_4i32(<2 x i64> %a, <2 x i64> %b) {
1608; SSE-LABEL: trunc2x2i64_4i32:
1609; SSE:       # %bb.0: # %entry
1610; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
1611; SSE-NEXT:    retq
1612;
1613; AVX-LABEL: trunc2x2i64_4i32:
1614; AVX:       # %bb.0: # %entry
1615; AVX-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
1616; AVX-NEXT:    retq
1617;
1618; AVX512-LABEL: trunc2x2i64_4i32:
1619; AVX512:       # %bb.0: # %entry
1620; AVX512-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
1621; AVX512-NEXT:    retq
1622entry:
1623  %0 = trunc <2 x i64> %a to <2 x i32>
1624  %1 = trunc <2 x i64> %b to <2 x i32>
1625  %2 = shufflevector <2 x i32> %0, <2 x i32> %1, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
1626  ret <4 x i32> %2
1627}
1628
1629define i64 @trunc2i64_i64(<2 x i64> %inval) {
1630; SSE-LABEL: trunc2i64_i64:
1631; SSE:       # %bb.0: # %entry
1632; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
1633; SSE-NEXT:    movq %xmm0, %rax
1634; SSE-NEXT:    retq
1635;
1636; AVX-LABEL: trunc2i64_i64:
1637; AVX:       # %bb.0: # %entry
1638; AVX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
1639; AVX-NEXT:    vmovq %xmm0, %rax
1640; AVX-NEXT:    retq
1641;
1642; AVX512-LABEL: trunc2i64_i64:
1643; AVX512:       # %bb.0: # %entry
1644; AVX512-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
1645; AVX512-NEXT:    vmovq %xmm0, %rax
1646; AVX512-NEXT:    retq
1647entry:
1648  %0 = trunc <2 x i64> %inval to <2 x i32>
1649  %1 = bitcast <2 x i32> %0 to i64
1650  ret i64 %1
1651}
1652
1653define <8 x i16> @trunc2x4i32_8i16(<4 x i32> %a, <4 x i32> %b) {
1654; SSE2-LABEL: trunc2x4i32_8i16:
1655; SSE2:       # %bb.0: # %entry
1656; SSE2-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,2,2,3,4,5,6,7]
1657; SSE2-NEXT:    pshufhw {{.*#+}} xmm1 = xmm1[0,1,2,3,4,6,6,7]
1658; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
1659; SSE2-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,2,2,3,4,5,6,7]
1660; SSE2-NEXT:    pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,4,6,6,7]
1661; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
1662; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1663; SSE2-NEXT:    retq
1664;
1665; SSSE3-LABEL: trunc2x4i32_8i16:
1666; SSSE3:       # %bb.0: # %entry
1667; SSSE3-NEXT:    movdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
1668; SSSE3-NEXT:    pshufb %xmm2, %xmm1
1669; SSSE3-NEXT:    pshufb %xmm2, %xmm0
1670; SSSE3-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1671; SSSE3-NEXT:    retq
1672;
1673; SSE41-LABEL: trunc2x4i32_8i16:
1674; SSE41:       # %bb.0: # %entry
1675; SSE41-NEXT:    movdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
1676; SSE41-NEXT:    pshufb %xmm2, %xmm1
1677; SSE41-NEXT:    pshufb %xmm2, %xmm0
1678; SSE41-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1679; SSE41-NEXT:    retq
1680;
1681; AVX-LABEL: trunc2x4i32_8i16:
1682; AVX:       # %bb.0: # %entry
1683; AVX-NEXT:    vmovdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
1684; AVX-NEXT:    vpshufb %xmm2, %xmm1, %xmm1
1685; AVX-NEXT:    vpshufb %xmm2, %xmm0, %xmm0
1686; AVX-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1687; AVX-NEXT:    retq
1688;
1689; AVX512-LABEL: trunc2x4i32_8i16:
1690; AVX512:       # %bb.0: # %entry
1691; AVX512-NEXT:    vmovdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
1692; AVX512-NEXT:    vpshufb %xmm2, %xmm1, %xmm1
1693; AVX512-NEXT:    vpshufb %xmm2, %xmm0, %xmm0
1694; AVX512-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1695; AVX512-NEXT:    retq
1696entry:
1697  %0 = trunc <4 x i32> %a to <4 x i16>
1698  %1 = trunc <4 x i32> %b to <4 x i16>
1699  %2 = shufflevector <4 x i16> %0, <4 x i16> %1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
1700  ret <8 x i16> %2
1701}
1702
1703; PR15524 http://llvm.org/bugs/show_bug.cgi?id=15524
1704define i64 @trunc4i32_i64(<4 x i32> %inval) {
1705; SSE2-LABEL: trunc4i32_i64:
1706; SSE2:       # %bb.0: # %entry
1707; SSE2-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,2,2,3,4,5,6,7]
1708; SSE2-NEXT:    pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,4,6,6,7]
1709; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
1710; SSE2-NEXT:    movq %xmm0, %rax
1711; SSE2-NEXT:    retq
1712;
1713; SSSE3-LABEL: trunc4i32_i64:
1714; SSSE3:       # %bb.0: # %entry
1715; SSSE3-NEXT:    pshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
1716; SSSE3-NEXT:    movq %xmm0, %rax
1717; SSSE3-NEXT:    retq
1718;
1719; SSE41-LABEL: trunc4i32_i64:
1720; SSE41:       # %bb.0: # %entry
1721; SSE41-NEXT:    pshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
1722; SSE41-NEXT:    movq %xmm0, %rax
1723; SSE41-NEXT:    retq
1724;
1725; AVX-LABEL: trunc4i32_i64:
1726; AVX:       # %bb.0: # %entry
1727; AVX-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
1728; AVX-NEXT:    vmovq %xmm0, %rax
1729; AVX-NEXT:    retq
1730;
1731; AVX512-LABEL: trunc4i32_i64:
1732; AVX512:       # %bb.0: # %entry
1733; AVX512-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
1734; AVX512-NEXT:    vmovq %xmm0, %rax
1735; AVX512-NEXT:    retq
1736entry:
1737  %0 = trunc <4 x i32> %inval to <4 x i16>
1738  %1 = bitcast <4 x i16> %0 to i64
1739  ret i64 %1
1740}
1741
1742define <16 x i8> @trunc2x8i16_16i8(<8 x i16> %a, <8 x i16> %b) {
1743; SSE2-LABEL: trunc2x8i16_16i8:
1744; SSE2:       # %bb.0: # %entry
1745; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [255,255,255,255,255,255,255,255]
1746; SSE2-NEXT:    pand %xmm2, %xmm1
1747; SSE2-NEXT:    pand %xmm2, %xmm0
1748; SSE2-NEXT:    packuswb %xmm1, %xmm0
1749; SSE2-NEXT:    retq
1750;
1751; SSSE3-LABEL: trunc2x8i16_16i8:
1752; SSSE3:       # %bb.0: # %entry
1753; SSSE3-NEXT:    movdqa {{.*#+}} xmm2 = <0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u>
1754; SSSE3-NEXT:    pshufb %xmm2, %xmm1
1755; SSSE3-NEXT:    pshufb %xmm2, %xmm0
1756; SSSE3-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1757; SSSE3-NEXT:    retq
1758;
1759; SSE41-LABEL: trunc2x8i16_16i8:
1760; SSE41:       # %bb.0: # %entry
1761; SSE41-NEXT:    movdqa {{.*#+}} xmm2 = <0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u>
1762; SSE41-NEXT:    pshufb %xmm2, %xmm1
1763; SSE41-NEXT:    pshufb %xmm2, %xmm0
1764; SSE41-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1765; SSE41-NEXT:    retq
1766;
1767; AVX-LABEL: trunc2x8i16_16i8:
1768; AVX:       # %bb.0: # %entry
1769; AVX-NEXT:    vmovdqa {{.*#+}} xmm2 = <0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u>
1770; AVX-NEXT:    vpshufb %xmm2, %xmm1, %xmm1
1771; AVX-NEXT:    vpshufb %xmm2, %xmm0, %xmm0
1772; AVX-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1773; AVX-NEXT:    retq
1774;
1775; AVX512-LABEL: trunc2x8i16_16i8:
1776; AVX512:       # %bb.0: # %entry
1777; AVX512-NEXT:    vmovdqa {{.*#+}} xmm2 = <0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u>
1778; AVX512-NEXT:    vpshufb %xmm2, %xmm1, %xmm1
1779; AVX512-NEXT:    vpshufb %xmm2, %xmm0, %xmm0
1780; AVX512-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1781; AVX512-NEXT:    retq
1782entry:
1783  %0 = trunc <8 x i16> %a to <8 x i8>
1784  %1 = trunc <8 x i16> %b to <8 x i8>
1785  %2 = shufflevector <8 x i8> %0, <8 x i8> %1, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
1786  ret <16 x i8> %2
1787}
1788
1789; PR15524 http://llvm.org/bugs/show_bug.cgi?id=15524
1790define i64 @trunc8i16_i64(<8 x i16> %inval) {
1791; SSE2-LABEL: trunc8i16_i64:
1792; SSE2:       # %bb.0: # %entry
1793; SSE2-NEXT:    pand {{.*}}(%rip), %xmm0
1794; SSE2-NEXT:    packuswb %xmm0, %xmm0
1795; SSE2-NEXT:    movq %xmm0, %rax
1796; SSE2-NEXT:    retq
1797;
1798; SSSE3-LABEL: trunc8i16_i64:
1799; SSSE3:       # %bb.0: # %entry
1800; SSSE3-NEXT:    pshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u]
1801; SSSE3-NEXT:    movq %xmm0, %rax
1802; SSSE3-NEXT:    retq
1803;
1804; SSE41-LABEL: trunc8i16_i64:
1805; SSE41:       # %bb.0: # %entry
1806; SSE41-NEXT:    pshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u]
1807; SSE41-NEXT:    movq %xmm0, %rax
1808; SSE41-NEXT:    retq
1809;
1810; AVX-LABEL: trunc8i16_i64:
1811; AVX:       # %bb.0: # %entry
1812; AVX-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u]
1813; AVX-NEXT:    vmovq %xmm0, %rax
1814; AVX-NEXT:    retq
1815;
1816; AVX512-LABEL: trunc8i16_i64:
1817; AVX512:       # %bb.0: # %entry
1818; AVX512-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u]
1819; AVX512-NEXT:    vmovq %xmm0, %rax
1820; AVX512-NEXT:    retq
1821entry:
1822  %0 = trunc <8 x i16> %inval to <8 x i8>
1823  %1 = bitcast <8 x i8> %0 to i64
1824  ret i64 %1
1825}
1826
1827define <16 x i8> @trunc16i64_16i8_const() {
1828; SSE-LABEL: trunc16i64_16i8_const:
1829; SSE:       # %bb.0: # %entry
1830; SSE-NEXT:    xorps %xmm0, %xmm0
1831; SSE-NEXT:    retq
1832;
1833; AVX-LABEL: trunc16i64_16i8_const:
1834; AVX:       # %bb.0: # %entry
1835; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
1836; AVX-NEXT:    retq
1837;
1838; AVX512-LABEL: trunc16i64_16i8_const:
1839; AVX512:       # %bb.0: # %entry
1840; AVX512-NEXT:    vxorps %xmm0, %xmm0, %xmm0
1841; AVX512-NEXT:    retq
1842
1843entry:
1844  %0 = trunc <16 x i64> zeroinitializer to <16 x i8>
1845  %1 = shufflevector <16 x i8> %0, <16 x i8> %0, <16 x i32> <i32 28, i32 30, i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 undef, i32 14, i32 16, i32 18, i32 20, i32 22, i32 24, i32 26>
1846  ret <16 x i8> %1
1847}
1848
1849define <8 x i16> @PR32160(<8 x i32> %x) {
1850; SSE-LABEL: PR32160:
1851; SSE:       # %bb.0:
1852; SSE-NEXT:    pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,4,4,6,7]
1853; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,2,2,2]
1854; SSE-NEXT:    retq
1855;
1856; AVX1-LABEL: PR32160:
1857; AVX1:       # %bb.0:
1858; AVX1-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9]
1859; AVX1-NEXT:    vzeroupper
1860; AVX1-NEXT:    retq
1861;
1862; AVX2-SLOW-LABEL: PR32160:
1863; AVX2-SLOW:       # %bb.0:
1864; AVX2-SLOW-NEXT:    vpunpckhwd {{.*#+}} xmm0 = xmm0[4,4,5,5,6,6,7,7]
1865; AVX2-SLOW-NEXT:    vpbroadcastd %xmm0, %xmm0
1866; AVX2-SLOW-NEXT:    vzeroupper
1867; AVX2-SLOW-NEXT:    retq
1868;
1869; AVX2-FAST-LABEL: PR32160:
1870; AVX2-FAST:       # %bb.0:
1871; AVX2-FAST-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9]
1872; AVX2-FAST-NEXT:    vzeroupper
1873; AVX2-FAST-NEXT:    retq
1874;
1875; AVX512F-LABEL: PR32160:
1876; AVX512F:       # %bb.0:
1877; AVX512F-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
1878; AVX512F-NEXT:    vpmovdw %zmm0, %ymm0
1879; AVX512F-NEXT:    vpshuflw {{.*#+}} xmm0 = xmm0[2,2,2,3,4,5,6,7]
1880; AVX512F-NEXT:    vpbroadcastd %xmm0, %xmm0
1881; AVX512F-NEXT:    vzeroupper
1882; AVX512F-NEXT:    retq
1883;
1884; AVX512VL-LABEL: PR32160:
1885; AVX512VL:       # %bb.0:
1886; AVX512VL-NEXT:    vpmovdw %ymm0, %xmm0
1887; AVX512VL-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5]
1888; AVX512VL-NEXT:    vzeroupper
1889; AVX512VL-NEXT:    retq
1890;
1891; AVX512BW-LABEL: PR32160:
1892; AVX512BW:       # %bb.0:
1893; AVX512BW-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
1894; AVX512BW-NEXT:    vpmovdw %zmm0, %ymm0
1895; AVX512BW-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5]
1896; AVX512BW-NEXT:    vzeroupper
1897; AVX512BW-NEXT:    retq
1898;
1899; AVX512BWVL-LABEL: PR32160:
1900; AVX512BWVL:       # %bb.0:
1901; AVX512BWVL-NEXT:    vpmovdw %ymm0, %xmm0
1902; AVX512BWVL-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5]
1903; AVX512BWVL-NEXT:    vzeroupper
1904; AVX512BWVL-NEXT:    retq
1905  %shuf = trunc <8 x i32> %x to <8 x i16>
1906  %trunc = shufflevector <8 x i16> %shuf, <8 x i16> undef, <8 x i32> <i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2>
1907  ret <8 x i16> %trunc
1908}
1909
1910define void @PR34773(i16* %a0, i8* %a1) {
1911; SSE-LABEL: PR34773:
1912; SSE:       # %bb.0:
1913; SSE-NEXT:    movdqu (%rdi), %xmm0
1914; SSE-NEXT:    movdqu 16(%rdi), %xmm1
1915; SSE-NEXT:    movdqu 32(%rdi), %xmm2
1916; SSE-NEXT:    movdqu 48(%rdi), %xmm3
1917; SSE-NEXT:    psrlw $8, %xmm1
1918; SSE-NEXT:    psrlw $8, %xmm0
1919; SSE-NEXT:    packuswb %xmm1, %xmm0
1920; SSE-NEXT:    psrlw $8, %xmm3
1921; SSE-NEXT:    psrlw $8, %xmm2
1922; SSE-NEXT:    packuswb %xmm3, %xmm2
1923; SSE-NEXT:    movdqu %xmm0, (%rsi)
1924; SSE-NEXT:    movdqu %xmm2, 16(%rsi)
1925; SSE-NEXT:    retq
1926;
1927; AVX1-LABEL: PR34773:
1928; AVX1:       # %bb.0:
1929; AVX1-NEXT:    vmovdqu (%rdi), %xmm0
1930; AVX1-NEXT:    vmovdqu 16(%rdi), %xmm1
1931; AVX1-NEXT:    vmovdqu 32(%rdi), %xmm2
1932; AVX1-NEXT:    vmovdqu 48(%rdi), %xmm3
1933; AVX1-NEXT:    vpsrlw $8, %xmm1, %xmm1
1934; AVX1-NEXT:    vpsrlw $8, %xmm0, %xmm0
1935; AVX1-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
1936; AVX1-NEXT:    vpsrlw $8, %xmm3, %xmm1
1937; AVX1-NEXT:    vpsrlw $8, %xmm2, %xmm2
1938; AVX1-NEXT:    vpackuswb %xmm1, %xmm2, %xmm1
1939; AVX1-NEXT:    vmovdqu %xmm0, (%rsi)
1940; AVX1-NEXT:    vmovdqu %xmm1, 16(%rsi)
1941; AVX1-NEXT:    retq
1942;
1943; AVX2-LABEL: PR34773:
1944; AVX2:       # %bb.0:
1945; AVX2-NEXT:    vmovdqu (%rdi), %ymm0
1946; AVX2-NEXT:    vmovdqu 32(%rdi), %ymm1
1947; AVX2-NEXT:    vpsrlw $8, %ymm0, %ymm0
1948; AVX2-NEXT:    vpsrlw $8, %ymm1, %ymm1
1949; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm2
1950; AVX2-NEXT:    vpackuswb %xmm2, %xmm0, %xmm0
1951; AVX2-NEXT:    vextracti128 $1, %ymm1, %xmm2
1952; AVX2-NEXT:    vpackuswb %xmm2, %xmm1, %xmm1
1953; AVX2-NEXT:    vmovdqu %xmm0, (%rsi)
1954; AVX2-NEXT:    vmovdqu %xmm1, 16(%rsi)
1955; AVX2-NEXT:    vzeroupper
1956; AVX2-NEXT:    retq
1957;
1958; AVX512F-LABEL: PR34773:
1959; AVX512F:       # %bb.0:
1960; AVX512F-NEXT:    vmovdqu (%rdi), %ymm0
1961; AVX512F-NEXT:    vmovdqu 32(%rdi), %ymm1
1962; AVX512F-NEXT:    vpsrlw $8, %ymm0, %ymm0
1963; AVX512F-NEXT:    vpsrlw $8, %ymm1, %ymm1
1964; AVX512F-NEXT:    vpmovzxwd {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero
1965; AVX512F-NEXT:    vpmovdb %zmm0, (%rsi)
1966; AVX512F-NEXT:    vpmovzxwd {{.*#+}} zmm0 = ymm1[0],zero,ymm1[1],zero,ymm1[2],zero,ymm1[3],zero,ymm1[4],zero,ymm1[5],zero,ymm1[6],zero,ymm1[7],zero,ymm1[8],zero,ymm1[9],zero,ymm1[10],zero,ymm1[11],zero,ymm1[12],zero,ymm1[13],zero,ymm1[14],zero,ymm1[15],zero
1967; AVX512F-NEXT:    vpmovdb %zmm0, 16(%rsi)
1968; AVX512F-NEXT:    vzeroupper
1969; AVX512F-NEXT:    retq
1970;
1971; AVX512VL-LABEL: PR34773:
1972; AVX512VL:       # %bb.0:
1973; AVX512VL-NEXT:    vmovdqu (%rdi), %ymm0
1974; AVX512VL-NEXT:    vmovdqu 32(%rdi), %ymm1
1975; AVX512VL-NEXT:    vpsrlw $8, %ymm0, %ymm0
1976; AVX512VL-NEXT:    vpsrlw $8, %ymm1, %ymm1
1977; AVX512VL-NEXT:    vpmovzxwd {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero
1978; AVX512VL-NEXT:    vpmovdb %zmm0, (%rsi)
1979; AVX512VL-NEXT:    vpmovzxwd {{.*#+}} zmm0 = ymm1[0],zero,ymm1[1],zero,ymm1[2],zero,ymm1[3],zero,ymm1[4],zero,ymm1[5],zero,ymm1[6],zero,ymm1[7],zero,ymm1[8],zero,ymm1[9],zero,ymm1[10],zero,ymm1[11],zero,ymm1[12],zero,ymm1[13],zero,ymm1[14],zero,ymm1[15],zero
1980; AVX512VL-NEXT:    vpmovdb %zmm0, 16(%rsi)
1981; AVX512VL-NEXT:    vzeroupper
1982; AVX512VL-NEXT:    retq
1983;
1984; AVX512BW-LABEL: PR34773:
1985; AVX512BW:       # %bb.0:
1986; AVX512BW-NEXT:    vmovdqu (%rdi), %ymm0
1987; AVX512BW-NEXT:    vmovdqu 32(%rdi), %ymm1
1988; AVX512BW-NEXT:    vpsrlw $8, %ymm0, %ymm0
1989; AVX512BW-NEXT:    vpsrlw $8, %ymm1, %ymm1
1990; AVX512BW-NEXT:    vpmovwb %zmm0, %ymm0
1991; AVX512BW-NEXT:    vpmovwb %zmm1, %ymm1
1992; AVX512BW-NEXT:    vmovdqu %xmm0, (%rsi)
1993; AVX512BW-NEXT:    vmovdqu %xmm1, 16(%rsi)
1994; AVX512BW-NEXT:    vzeroupper
1995; AVX512BW-NEXT:    retq
1996;
1997; AVX512BWVL-LABEL: PR34773:
1998; AVX512BWVL:       # %bb.0:
1999; AVX512BWVL-NEXT:    vpsrlw $8, (%rdi), %ymm0
2000; AVX512BWVL-NEXT:    vpsrlw $8, 32(%rdi), %ymm1
2001; AVX512BWVL-NEXT:    vpmovwb %ymm0, (%rsi)
2002; AVX512BWVL-NEXT:    vpmovwb %ymm1, 16(%rsi)
2003; AVX512BWVL-NEXT:    vzeroupper
2004; AVX512BWVL-NEXT:    retq
2005  %1  = getelementptr i16, i16* %a0, i64 16
2006  %2  = getelementptr i8, i8* %a1, i64 16
2007  %3  = bitcast i16* %a0 to <16 x i16>*
2008  %4  = bitcast i16* %1 to <16 x i16>*
2009  %5  = bitcast i8* %a1 to <16 x i8>*
2010  %6  = bitcast i8* %2 to <16 x i8>*
2011  %7  = load <16 x i16>, <16 x i16>* %3, align 2
2012  %8  = load <16 x i16>, <16 x i16>* %4, align 2
2013  %9  = lshr <16 x i16> %7, <i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8>
2014  %10 = lshr <16 x i16> %8, <i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8>
2015  %11 = trunc <16 x i16> %9  to <16 x i8>
2016  %12 = trunc <16 x i16> %10 to <16 x i8>
2017  store <16 x i8> %11, <16 x i8>* %5, align 1
2018  store <16 x i8> %12, <16 x i8>* %6, align 1
2019  ret void
2020}
2021