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