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