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-prefixes=SSE
3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefixes=AVX,AVX1
4; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefixes=AVX,AVX2,AVX2-SLOW
5; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2,+fast-variable-shuffle | FileCheck %s --check-prefixes=AVX,AVX2,AVX2-FAST
6; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512f | FileCheck %s --check-prefixes=AVX,AVX512,AVX512F
7; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512bw,+fast-variable-shuffle | FileCheck %s --check-prefixes=AVX,AVX512,AVX512BW
8; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512dq,+fast-variable-shuffle | FileCheck %s --check-prefixes=AVX,AVX512,AVX512DQ
9
10;
11; add
12;
13
14define <4 x i32> @trunc_add_v4i64_v4i32(<4 x i64> %a0, <4 x i64> %a1) nounwind {
15; SSE-LABEL: trunc_add_v4i64_v4i32:
16; SSE:       # %bb.0:
17; SSE-NEXT:    paddq %xmm3, %xmm1
18; SSE-NEXT:    paddq %xmm2, %xmm0
19; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
20; SSE-NEXT:    retq
21;
22; AVX1-LABEL: trunc_add_v4i64_v4i32:
23; AVX1:       # %bb.0:
24; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
25; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
26; AVX1-NEXT:    vpaddq %xmm2, %xmm3, %xmm2
27; AVX1-NEXT:    vpaddq %xmm1, %xmm0, %xmm0
28; AVX1-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm2[0,2]
29; AVX1-NEXT:    vzeroupper
30; AVX1-NEXT:    retq
31;
32; AVX2-SLOW-LABEL: trunc_add_v4i64_v4i32:
33; AVX2-SLOW:       # %bb.0:
34; AVX2-SLOW-NEXT:    vpaddq %ymm1, %ymm0, %ymm0
35; AVX2-SLOW-NEXT:    vextracti128 $1, %ymm0, %xmm1
36; AVX2-SLOW-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
37; AVX2-SLOW-NEXT:    vzeroupper
38; AVX2-SLOW-NEXT:    retq
39;
40; AVX2-FAST-LABEL: trunc_add_v4i64_v4i32:
41; AVX2-FAST:       # %bb.0:
42; AVX2-FAST-NEXT:    vpaddq %ymm1, %ymm0, %ymm0
43; AVX2-FAST-NEXT:    vmovdqa {{.*#+}} ymm1 = <0,2,4,6,u,u,u,u>
44; AVX2-FAST-NEXT:    vpermd %ymm0, %ymm1, %ymm0
45; AVX2-FAST-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
46; AVX2-FAST-NEXT:    vzeroupper
47; AVX2-FAST-NEXT:    retq
48;
49; AVX512-LABEL: trunc_add_v4i64_v4i32:
50; AVX512:       # %bb.0:
51; AVX512-NEXT:    vpaddq %ymm1, %ymm0, %ymm0
52; AVX512-NEXT:    vpmovqd %zmm0, %ymm0
53; AVX512-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
54; AVX512-NEXT:    vzeroupper
55; AVX512-NEXT:    retq
56  %1 = add <4 x i64> %a0, %a1
57  %2 = trunc <4 x i64> %1 to <4 x i32>
58  ret <4 x i32> %2
59}
60
61define <8 x i16> @trunc_add_v8i64_v8i16(<8 x i64> %a0, <8 x i64> %a1) nounwind {
62; SSE-LABEL: trunc_add_v8i64_v8i16:
63; SSE:       # %bb.0:
64; SSE-NEXT:    paddq %xmm6, %xmm2
65; SSE-NEXT:    paddq %xmm7, %xmm3
66; SSE-NEXT:    paddq %xmm4, %xmm0
67; SSE-NEXT:    paddq %xmm5, %xmm1
68; SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
69; SSE-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,2,2,3,4,5,6,7]
70; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
71; SSE-NEXT:    pshuflw {{.*#+}} xmm4 = xmm0[0,2,2,3,4,5,6,7]
72; SSE-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
73; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[0,2,2,3]
74; SSE-NEXT:    pshuflw {{.*#+}} xmm1 = xmm0[0,1,0,2,4,5,6,7]
75; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3]
76; SSE-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,1,0,2,4,5,6,7]
77; SSE-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
78; SSE-NEXT:    movsd {{.*#+}} xmm0 = xmm4[0],xmm0[1]
79; SSE-NEXT:    retq
80;
81; AVX1-LABEL: trunc_add_v8i64_v8i16:
82; AVX1:       # %bb.0:
83; AVX1-NEXT:    vpaddq %xmm2, %xmm0, %xmm4
84; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm2
85; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
86; AVX1-NEXT:    vpaddq %xmm2, %xmm0, %xmm0
87; AVX1-NEXT:    vpaddq %xmm3, %xmm1, %xmm2
88; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm3
89; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm1
90; AVX1-NEXT:    vpaddq %xmm3, %xmm1, %xmm1
91; AVX1-NEXT:    vpxor %xmm3, %xmm3, %xmm3
92; AVX1-NEXT:    vpblendw {{.*#+}} xmm1 = xmm1[0],xmm3[1,2,3],xmm1[4],xmm3[5,6,7]
93; AVX1-NEXT:    vpblendw {{.*#+}} xmm2 = xmm2[0],xmm3[1,2,3],xmm2[4],xmm3[5,6,7]
94; AVX1-NEXT:    vpackusdw %xmm1, %xmm2, %xmm1
95; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0],xmm3[1,2,3],xmm0[4],xmm3[5,6,7]
96; AVX1-NEXT:    vpblendw {{.*#+}} xmm2 = xmm4[0],xmm3[1,2,3],xmm4[4],xmm3[5,6,7]
97; AVX1-NEXT:    vpackusdw %xmm0, %xmm2, %xmm0
98; AVX1-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
99; AVX1-NEXT:    vzeroupper
100; AVX1-NEXT:    retq
101;
102; AVX2-LABEL: trunc_add_v8i64_v8i16:
103; AVX2:       # %bb.0:
104; AVX2-NEXT:    vpaddq %ymm2, %ymm0, %ymm0
105; AVX2-NEXT:    vpaddq %ymm3, %ymm1, %ymm1
106; AVX2-NEXT:    vpxor %xmm2, %xmm2, %xmm2
107; AVX2-NEXT:    vpblendw {{.*#+}} ymm1 = ymm1[0],ymm2[1,2,3],ymm1[4],ymm2[5,6,7],ymm1[8],ymm2[9,10,11],ymm1[12],ymm2[13,14,15]
108; AVX2-NEXT:    vpblendw {{.*#+}} ymm0 = ymm0[0],ymm2[1,2,3],ymm0[4],ymm2[5,6,7],ymm0[8],ymm2[9,10,11],ymm0[12],ymm2[13,14,15]
109; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
110; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
111; AVX2-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
112; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
113; AVX2-NEXT:    vzeroupper
114; AVX2-NEXT:    retq
115;
116; AVX512-LABEL: trunc_add_v8i64_v8i16:
117; AVX512:       # %bb.0:
118; AVX512-NEXT:    vpaddq %zmm1, %zmm0, %zmm0
119; AVX512-NEXT:    vpmovqw %zmm0, %xmm0
120; AVX512-NEXT:    vzeroupper
121; AVX512-NEXT:    retq
122  %1 = add <8 x i64> %a0, %a1
123  %2 = trunc <8 x i64> %1 to <8 x i16>
124  ret <8 x i16> %2
125}
126
127define <8 x i16> @trunc_add_v8i32_v8i16(<8 x i32> %a0, <8 x i32> %a1) nounwind {
128; SSE-LABEL: trunc_add_v8i32_v8i16:
129; SSE:       # %bb.0:
130; SSE-NEXT:    paddd %xmm2, %xmm0
131; SSE-NEXT:    paddd %xmm3, %xmm1
132; SSE-NEXT:    pslld $16, %xmm1
133; SSE-NEXT:    psrad $16, %xmm1
134; SSE-NEXT:    pslld $16, %xmm0
135; SSE-NEXT:    psrad $16, %xmm0
136; SSE-NEXT:    packssdw %xmm1, %xmm0
137; SSE-NEXT:    retq
138;
139; AVX1-LABEL: trunc_add_v8i32_v8i16:
140; AVX1:       # %bb.0:
141; AVX1-NEXT:    vpaddd %xmm1, %xmm0, %xmm2
142; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm1
143; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
144; AVX1-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
145; AVX1-NEXT:    vmovdqa {{.*#+}} xmm1 = <0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u>
146; AVX1-NEXT:    vpshufb %xmm1, %xmm0, %xmm0
147; AVX1-NEXT:    vpshufb %xmm1, %xmm2, %xmm1
148; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0]
149; AVX1-NEXT:    vzeroupper
150; AVX1-NEXT:    retq
151;
152; AVX2-LABEL: trunc_add_v8i32_v8i16:
153; AVX2:       # %bb.0:
154; AVX2-NEXT:    vpaddd %ymm1, %ymm0, %ymm0
155; AVX2-NEXT:    vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u,16,17,20,21,24,25,28,29,u,u,u,u,u,u,u,u]
156; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
157; AVX2-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
158; AVX2-NEXT:    vzeroupper
159; AVX2-NEXT:    retq
160;
161; AVX512-LABEL: trunc_add_v8i32_v8i16:
162; AVX512:       # %bb.0:
163; AVX512-NEXT:    vpaddd %ymm1, %ymm0, %ymm0
164; AVX512-NEXT:    vpmovdw %zmm0, %ymm0
165; AVX512-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
166; AVX512-NEXT:    vzeroupper
167; AVX512-NEXT:    retq
168  %1 = add <8 x i32> %a0, %a1
169  %2 = trunc <8 x i32> %1 to <8 x i16>
170  ret <8 x i16> %2
171}
172
173define <16 x i8> @trunc_add_v16i64_v16i8(<16 x i64> %a0, <16 x i64> %a1) nounwind {
174; SSE-LABEL: trunc_add_v16i64_v16i8:
175; SSE:       # %bb.0:
176; SSE-NEXT:    paddq {{[0-9]+}}(%rsp), %xmm0
177; SSE-NEXT:    paddq {{[0-9]+}}(%rsp), %xmm1
178; SSE-NEXT:    paddq {{[0-9]+}}(%rsp), %xmm2
179; SSE-NEXT:    paddq {{[0-9]+}}(%rsp), %xmm3
180; SSE-NEXT:    paddq {{[0-9]+}}(%rsp), %xmm4
181; SSE-NEXT:    paddq {{[0-9]+}}(%rsp), %xmm5
182; SSE-NEXT:    paddq {{[0-9]+}}(%rsp), %xmm6
183; SSE-NEXT:    paddq {{[0-9]+}}(%rsp), %xmm7
184; SSE-NEXT:    movdqa {{.*#+}} xmm8 = [255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0]
185; SSE-NEXT:    pand %xmm8, %xmm7
186; SSE-NEXT:    pand %xmm8, %xmm6
187; SSE-NEXT:    packuswb %xmm7, %xmm6
188; SSE-NEXT:    pand %xmm8, %xmm5
189; SSE-NEXT:    pand %xmm8, %xmm4
190; SSE-NEXT:    packuswb %xmm5, %xmm4
191; SSE-NEXT:    packuswb %xmm6, %xmm4
192; SSE-NEXT:    pand %xmm8, %xmm3
193; SSE-NEXT:    pand %xmm8, %xmm2
194; SSE-NEXT:    packuswb %xmm3, %xmm2
195; SSE-NEXT:    pand %xmm8, %xmm1
196; SSE-NEXT:    pand %xmm8, %xmm0
197; SSE-NEXT:    packuswb %xmm1, %xmm0
198; SSE-NEXT:    packuswb %xmm2, %xmm0
199; SSE-NEXT:    packuswb %xmm4, %xmm0
200; SSE-NEXT:    retq
201;
202; AVX1-LABEL: trunc_add_v16i64_v16i8:
203; AVX1:       # %bb.0:
204; AVX1-NEXT:    vpaddq %xmm4, %xmm0, %xmm8
205; AVX1-NEXT:    vextractf128 $1, %ymm4, %xmm4
206; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
207; AVX1-NEXT:    vpaddq %xmm4, %xmm0, %xmm0
208; AVX1-NEXT:    vpaddq %xmm5, %xmm1, %xmm4
209; AVX1-NEXT:    vextractf128 $1, %ymm5, %xmm5
210; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm1
211; AVX1-NEXT:    vpaddq %xmm5, %xmm1, %xmm1
212; AVX1-NEXT:    vpaddq %xmm6, %xmm2, %xmm5
213; AVX1-NEXT:    vextractf128 $1, %ymm6, %xmm6
214; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm2
215; AVX1-NEXT:    vpaddq %xmm6, %xmm2, %xmm2
216; AVX1-NEXT:    vpaddq %xmm7, %xmm3, %xmm6
217; AVX1-NEXT:    vextractf128 $1, %ymm7, %xmm7
218; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm3
219; AVX1-NEXT:    vpaddq %xmm7, %xmm3, %xmm3
220; AVX1-NEXT:    vmovdqa {{.*#+}} xmm7 = [255,255]
221; AVX1-NEXT:    vpand %xmm7, %xmm3, %xmm3
222; AVX1-NEXT:    vpand %xmm7, %xmm6, %xmm6
223; AVX1-NEXT:    vpackusdw %xmm3, %xmm6, %xmm3
224; AVX1-NEXT:    vpand %xmm7, %xmm2, %xmm2
225; AVX1-NEXT:    vpand %xmm7, %xmm5, %xmm5
226; AVX1-NEXT:    vpackusdw %xmm2, %xmm5, %xmm2
227; AVX1-NEXT:    vpackusdw %xmm3, %xmm2, %xmm2
228; AVX1-NEXT:    vpand %xmm7, %xmm1, %xmm1
229; AVX1-NEXT:    vpand %xmm7, %xmm4, %xmm3
230; AVX1-NEXT:    vpackusdw %xmm1, %xmm3, %xmm1
231; AVX1-NEXT:    vpand %xmm7, %xmm0, %xmm0
232; AVX1-NEXT:    vpand %xmm7, %xmm8, %xmm3
233; AVX1-NEXT:    vpackusdw %xmm0, %xmm3, %xmm0
234; AVX1-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
235; AVX1-NEXT:    vpackuswb %xmm2, %xmm0, %xmm0
236; AVX1-NEXT:    vzeroupper
237; AVX1-NEXT:    retq
238;
239; AVX2-LABEL: trunc_add_v16i64_v16i8:
240; AVX2:       # %bb.0:
241; AVX2-NEXT:    vpaddq %ymm4, %ymm0, %ymm0
242; AVX2-NEXT:    vpaddq %ymm5, %ymm1, %ymm1
243; AVX2-NEXT:    vpaddq %ymm6, %ymm2, %ymm2
244; AVX2-NEXT:    vpaddq %ymm7, %ymm3, %ymm3
245; AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm4 = [255,255,255,255]
246; AVX2-NEXT:    vpand %ymm4, %ymm3, %ymm3
247; AVX2-NEXT:    vpand %ymm4, %ymm2, %ymm2
248; AVX2-NEXT:    vpackusdw %ymm3, %ymm2, %ymm2
249; AVX2-NEXT:    vpermq {{.*#+}} ymm2 = ymm2[0,2,1,3]
250; AVX2-NEXT:    vpand %ymm4, %ymm1, %ymm1
251; AVX2-NEXT:    vpand %ymm4, %ymm0, %ymm0
252; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
253; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3]
254; AVX2-NEXT:    vpackusdw %ymm2, %ymm0, %ymm0
255; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
256; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
257; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
258; AVX2-NEXT:    vzeroupper
259; AVX2-NEXT:    retq
260;
261; AVX512-LABEL: trunc_add_v16i64_v16i8:
262; AVX512:       # %bb.0:
263; AVX512-NEXT:    vpaddq %zmm2, %zmm0, %zmm0
264; AVX512-NEXT:    vpaddq %zmm3, %zmm1, %zmm1
265; AVX512-NEXT:    vpmovqb %zmm1, %xmm1
266; AVX512-NEXT:    vpmovqb %zmm0, %xmm0
267; AVX512-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
268; AVX512-NEXT:    vzeroupper
269; AVX512-NEXT:    retq
270  %1 = add <16 x i64> %a0, %a1
271  %2 = trunc <16 x i64> %1 to <16 x i8>
272  ret <16 x i8> %2
273}
274
275define <16 x i8> @trunc_add_v16i32_v16i8(<16 x i32> %a0, <16 x i32> %a1) nounwind {
276; SSE-LABEL: trunc_add_v16i32_v16i8:
277; SSE:       # %bb.0:
278; SSE-NEXT:    paddd %xmm4, %xmm0
279; SSE-NEXT:    paddd %xmm5, %xmm1
280; SSE-NEXT:    paddd %xmm6, %xmm2
281; SSE-NEXT:    paddd %xmm7, %xmm3
282; SSE-NEXT:    movdqa {{.*#+}} xmm4 = [255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0]
283; SSE-NEXT:    pand %xmm4, %xmm3
284; SSE-NEXT:    pand %xmm4, %xmm2
285; SSE-NEXT:    packuswb %xmm3, %xmm2
286; SSE-NEXT:    pand %xmm4, %xmm1
287; SSE-NEXT:    pand %xmm4, %xmm0
288; SSE-NEXT:    packuswb %xmm1, %xmm0
289; SSE-NEXT:    packuswb %xmm2, %xmm0
290; SSE-NEXT:    retq
291;
292; AVX1-LABEL: trunc_add_v16i32_v16i8:
293; AVX1:       # %bb.0:
294; AVX1-NEXT:    vpaddd %xmm2, %xmm0, %xmm4
295; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm2
296; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
297; AVX1-NEXT:    vpaddd %xmm2, %xmm0, %xmm0
298; AVX1-NEXT:    vpaddd %xmm3, %xmm1, %xmm2
299; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm3
300; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm1
301; AVX1-NEXT:    vpaddd %xmm3, %xmm1, %xmm1
302; AVX1-NEXT:    vmovdqa {{.*#+}} xmm3 = [255,255,255,255]
303; AVX1-NEXT:    vpand %xmm3, %xmm1, %xmm1
304; AVX1-NEXT:    vpand %xmm3, %xmm2, %xmm2
305; AVX1-NEXT:    vpackusdw %xmm1, %xmm2, %xmm1
306; AVX1-NEXT:    vpand %xmm3, %xmm0, %xmm0
307; AVX1-NEXT:    vpand %xmm3, %xmm4, %xmm2
308; AVX1-NEXT:    vpackusdw %xmm0, %xmm2, %xmm0
309; AVX1-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
310; AVX1-NEXT:    vzeroupper
311; AVX1-NEXT:    retq
312;
313; AVX2-LABEL: trunc_add_v16i32_v16i8:
314; AVX2:       # %bb.0:
315; AVX2-NEXT:    vpaddd %ymm2, %ymm0, %ymm0
316; AVX2-NEXT:    vpaddd %ymm3, %ymm1, %ymm1
317; AVX2-NEXT:    vpbroadcastd {{.*#+}} ymm2 = [255,255,255,255,255,255,255,255]
318; AVX2-NEXT:    vpand %ymm2, %ymm1, %ymm1
319; AVX2-NEXT:    vpand %ymm2, %ymm0, %ymm0
320; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
321; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
322; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
323; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
324; AVX2-NEXT:    vzeroupper
325; AVX2-NEXT:    retq
326;
327; AVX512-LABEL: trunc_add_v16i32_v16i8:
328; AVX512:       # %bb.0:
329; AVX512-NEXT:    vpaddd %zmm1, %zmm0, %zmm0
330; AVX512-NEXT:    vpmovdb %zmm0, %xmm0
331; AVX512-NEXT:    vzeroupper
332; AVX512-NEXT:    retq
333  %1 = add <16 x i32> %a0, %a1
334  %2 = trunc <16 x i32> %1 to <16 x i8>
335  ret <16 x i8> %2
336}
337
338define <16 x i8> @trunc_add_v16i16_v16i8(<16 x i16> %a0, <16 x i16> %a1) nounwind {
339; SSE-LABEL: trunc_add_v16i16_v16i8:
340; SSE:       # %bb.0:
341; SSE-NEXT:    paddw %xmm2, %xmm0
342; SSE-NEXT:    paddw %xmm3, %xmm1
343; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0]
344; SSE-NEXT:    pand %xmm2, %xmm1
345; SSE-NEXT:    pand %xmm2, %xmm0
346; SSE-NEXT:    packuswb %xmm1, %xmm0
347; SSE-NEXT:    retq
348;
349; AVX1-LABEL: trunc_add_v16i16_v16i8:
350; AVX1:       # %bb.0:
351; AVX1-NEXT:    vpaddw %xmm1, %xmm0, %xmm2
352; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm1
353; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
354; AVX1-NEXT:    vpaddw %xmm1, %xmm0, %xmm0
355; AVX1-NEXT:    vmovdqa {{.*#+}} xmm1 = [255,255,255,255,255,255,255,255]
356; AVX1-NEXT:    vpand %xmm1, %xmm0, %xmm0
357; AVX1-NEXT:    vpand %xmm1, %xmm2, %xmm1
358; AVX1-NEXT:    vpackuswb %xmm0, %xmm1, %xmm0
359; AVX1-NEXT:    vzeroupper
360; AVX1-NEXT:    retq
361;
362; AVX2-LABEL: trunc_add_v16i16_v16i8:
363; AVX2:       # %bb.0:
364; AVX2-NEXT:    vpaddw %ymm1, %ymm0, %ymm0
365; AVX2-NEXT:    vpand {{.*}}(%rip), %ymm0, %ymm0
366; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
367; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
368; AVX2-NEXT:    vzeroupper
369; AVX2-NEXT:    retq
370;
371; AVX512F-LABEL: trunc_add_v16i16_v16i8:
372; AVX512F:       # %bb.0:
373; AVX512F-NEXT:    vpaddw %ymm1, %ymm0, %ymm0
374; 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
375; AVX512F-NEXT:    vpmovdb %zmm0, %xmm0
376; AVX512F-NEXT:    vzeroupper
377; AVX512F-NEXT:    retq
378;
379; AVX512BW-LABEL: trunc_add_v16i16_v16i8:
380; AVX512BW:       # %bb.0:
381; AVX512BW-NEXT:    vpaddw %ymm1, %ymm0, %ymm0
382; AVX512BW-NEXT:    vpmovwb %zmm0, %ymm0
383; AVX512BW-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
384; AVX512BW-NEXT:    vzeroupper
385; AVX512BW-NEXT:    retq
386;
387; AVX512DQ-LABEL: trunc_add_v16i16_v16i8:
388; AVX512DQ:       # %bb.0:
389; AVX512DQ-NEXT:    vpaddw %ymm1, %ymm0, %ymm0
390; AVX512DQ-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
391; AVX512DQ-NEXT:    vpmovdb %zmm0, %xmm0
392; AVX512DQ-NEXT:    vzeroupper
393; AVX512DQ-NEXT:    retq
394  %1 = add <16 x i16> %a0, %a1
395  %2 = trunc <16 x i16> %1 to <16 x i8>
396  ret <16 x i8> %2
397}
398
399define <8 x i16> @trunc_add_v8i32_v8i16_sext_8i8(<16 x i8> %a0, <8 x i32> %a1) {
400; SSE-LABEL: trunc_add_v8i32_v8i16_sext_8i8:
401; SSE:       # %bb.0:
402; SSE-NEXT:    pslld $16, %xmm2
403; SSE-NEXT:    psrad $16, %xmm2
404; SSE-NEXT:    pslld $16, %xmm1
405; SSE-NEXT:    psrad $16, %xmm1
406; SSE-NEXT:    packssdw %xmm2, %xmm1
407; SSE-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
408; SSE-NEXT:    psraw $8, %xmm0
409; SSE-NEXT:    paddw %xmm1, %xmm0
410; SSE-NEXT:    retq
411;
412; AVX1-LABEL: trunc_add_v8i32_v8i16_sext_8i8:
413; AVX1:       # %bb.0:
414; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
415; AVX1-NEXT:    vmovdqa {{.*#+}} xmm3 = <0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u>
416; AVX1-NEXT:    vpshufb %xmm3, %xmm2, %xmm2
417; AVX1-NEXT:    vpshufb %xmm3, %xmm1, %xmm1
418; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0]
419; AVX1-NEXT:    vpmovsxbw %xmm0, %xmm0
420; AVX1-NEXT:    vpaddw %xmm1, %xmm0, %xmm0
421; AVX1-NEXT:    vzeroupper
422; AVX1-NEXT:    retq
423;
424; AVX2-LABEL: trunc_add_v8i32_v8i16_sext_8i8:
425; AVX2:       # %bb.0:
426; AVX2-NEXT:    vpmovsxbw %xmm0, %xmm0
427; AVX2-NEXT:    vpshufb {{.*#+}} ymm1 = ymm1[0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u,16,17,20,21,24,25,28,29,u,u,u,u,u,u,u,u]
428; AVX2-NEXT:    vpermq {{.*#+}} ymm1 = ymm1[0,2,2,3]
429; AVX2-NEXT:    vpaddw %xmm1, %xmm0, %xmm0
430; AVX2-NEXT:    vzeroupper
431; AVX2-NEXT:    retq
432;
433; AVX512-LABEL: trunc_add_v8i32_v8i16_sext_8i8:
434; AVX512:       # %bb.0:
435; AVX512-NEXT:    # kill: def $ymm1 killed $ymm1 def $zmm1
436; AVX512-NEXT:    vpmovdw %zmm1, %ymm1
437; AVX512-NEXT:    vpmovsxbw %xmm0, %xmm0
438; AVX512-NEXT:    vpaddw %xmm1, %xmm0, %xmm0
439; AVX512-NEXT:    vzeroupper
440; AVX512-NEXT:    retq
441  %1 = shufflevector <16 x i8> %a0, <16 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
442  %2 = sext <8 x i8> %1 to <8 x i32>
443  %3 = add <8 x i32> %2, %a1
444  %4 = trunc <8 x i32> %3 to <8 x i16>
445  ret <8 x i16> %4
446}
447
448;
449; add to constant
450;
451
452define <4 x i32> @trunc_add_const_v4i64_v4i32(<4 x i64> %a0) nounwind {
453; SSE-LABEL: trunc_add_const_v4i64_v4i32:
454; SSE:       # %bb.0:
455; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
456; SSE-NEXT:    paddd {{.*}}(%rip), %xmm0
457; SSE-NEXT:    retq
458;
459; AVX1-LABEL: trunc_add_const_v4i64_v4i32:
460; AVX1:       # %bb.0:
461; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
462; AVX1-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
463; AVX1-NEXT:    vpaddd {{.*}}(%rip), %xmm0, %xmm0
464; AVX1-NEXT:    vzeroupper
465; AVX1-NEXT:    retq
466;
467; AVX2-SLOW-LABEL: trunc_add_const_v4i64_v4i32:
468; AVX2-SLOW:       # %bb.0:
469; AVX2-SLOW-NEXT:    vextractf128 $1, %ymm0, %xmm1
470; AVX2-SLOW-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
471; AVX2-SLOW-NEXT:    vpaddd {{.*}}(%rip), %xmm0, %xmm0
472; AVX2-SLOW-NEXT:    vzeroupper
473; AVX2-SLOW-NEXT:    retq
474;
475; AVX2-FAST-LABEL: trunc_add_const_v4i64_v4i32:
476; AVX2-FAST:       # %bb.0:
477; AVX2-FAST-NEXT:    vmovdqa {{.*#+}} ymm1 = <0,2,4,6,u,u,u,u>
478; AVX2-FAST-NEXT:    vpermd %ymm0, %ymm1, %ymm0
479; AVX2-FAST-NEXT:    vpaddd {{.*}}(%rip), %xmm0, %xmm0
480; AVX2-FAST-NEXT:    vzeroupper
481; AVX2-FAST-NEXT:    retq
482;
483; AVX512-LABEL: trunc_add_const_v4i64_v4i32:
484; AVX512:       # %bb.0:
485; AVX512-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
486; AVX512-NEXT:    vpmovqd %zmm0, %ymm0
487; AVX512-NEXT:    vpaddd {{.*}}(%rip), %xmm0, %xmm0
488; AVX512-NEXT:    vzeroupper
489; AVX512-NEXT:    retq
490  %1 = add <4 x i64> %a0, <i64 0, i64 1, i64 2, i64 3>
491  %2 = trunc <4 x i64> %1 to <4 x i32>
492  ret <4 x i32> %2
493}
494
495define <8 x i16> @trunc_add_const_v8i64_v8i16(<8 x i64> %a0) nounwind {
496; SSE-LABEL: trunc_add_const_v8i64_v8i16:
497; SSE:       # %bb.0:
498; SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
499; SSE-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,2,2,3,4,5,6,7]
500; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
501; SSE-NEXT:    pshuflw {{.*#+}} xmm4 = xmm0[0,2,2,3,4,5,6,7]
502; SSE-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
503; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[0,2,2,3]
504; SSE-NEXT:    pshuflw {{.*#+}} xmm1 = xmm0[0,1,0,2,4,5,6,7]
505; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3]
506; SSE-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,1,0,2,4,5,6,7]
507; SSE-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
508; SSE-NEXT:    movsd {{.*#+}} xmm0 = xmm4[0],xmm0[1]
509; SSE-NEXT:    paddw {{.*}}(%rip), %xmm0
510; SSE-NEXT:    retq
511;
512; AVX1-LABEL: trunc_add_const_v8i64_v8i16:
513; AVX1:       # %bb.0:
514; AVX1-NEXT:    vmovaps {{.*#+}} ymm2 = [65535,65535,65535,65535]
515; AVX1-NEXT:    vandps %ymm2, %ymm1, %ymm1
516; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
517; AVX1-NEXT:    vpackusdw %xmm3, %xmm1, %xmm1
518; AVX1-NEXT:    vandps %ymm2, %ymm0, %ymm0
519; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
520; AVX1-NEXT:    vpackusdw %xmm2, %xmm0, %xmm0
521; AVX1-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
522; AVX1-NEXT:    vpaddw {{.*}}(%rip), %xmm0, %xmm0
523; AVX1-NEXT:    vzeroupper
524; AVX1-NEXT:    retq
525;
526; AVX2-LABEL: trunc_add_const_v8i64_v8i16:
527; AVX2:       # %bb.0:
528; AVX2-NEXT:    vpxor %xmm2, %xmm2, %xmm2
529; AVX2-NEXT:    vpblendw {{.*#+}} ymm1 = ymm1[0],ymm2[1,2,3],ymm1[4],ymm2[5,6,7],ymm1[8],ymm2[9,10,11],ymm1[12],ymm2[13,14,15]
530; AVX2-NEXT:    vpblendw {{.*#+}} ymm0 = ymm0[0],ymm2[1,2,3],ymm0[4],ymm2[5,6,7],ymm0[8],ymm2[9,10,11],ymm0[12],ymm2[13,14,15]
531; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
532; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
533; AVX2-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
534; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
535; AVX2-NEXT:    vpaddw {{.*}}(%rip), %xmm0, %xmm0
536; AVX2-NEXT:    vzeroupper
537; AVX2-NEXT:    retq
538;
539; AVX512-LABEL: trunc_add_const_v8i64_v8i16:
540; AVX512:       # %bb.0:
541; AVX512-NEXT:    vpmovqw %zmm0, %xmm0
542; AVX512-NEXT:    vpaddw {{.*}}(%rip), %xmm0, %xmm0
543; AVX512-NEXT:    vzeroupper
544; AVX512-NEXT:    retq
545  %1 = add <8 x i64> %a0, <i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7>
546  %2 = trunc <8 x i64> %1 to <8 x i16>
547  ret <8 x i16> %2
548}
549
550define <8 x i16> @trunc_add_const_v8i32_v8i16(<8 x i32> %a0) nounwind {
551; SSE-LABEL: trunc_add_const_v8i32_v8i16:
552; SSE:       # %bb.0:
553; SSE-NEXT:    pslld $16, %xmm1
554; SSE-NEXT:    psrad $16, %xmm1
555; SSE-NEXT:    pslld $16, %xmm0
556; SSE-NEXT:    psrad $16, %xmm0
557; SSE-NEXT:    packssdw %xmm1, %xmm0
558; SSE-NEXT:    paddw {{.*}}(%rip), %xmm0
559; SSE-NEXT:    retq
560;
561; AVX1-LABEL: trunc_add_const_v8i32_v8i16:
562; AVX1:       # %bb.0:
563; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
564; AVX1-NEXT:    vmovdqa {{.*#+}} xmm2 = <0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u>
565; AVX1-NEXT:    vpshufb %xmm2, %xmm1, %xmm1
566; AVX1-NEXT:    vpshufb %xmm2, %xmm0, %xmm0
567; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
568; AVX1-NEXT:    vpaddw {{.*}}(%rip), %xmm0, %xmm0
569; AVX1-NEXT:    vzeroupper
570; AVX1-NEXT:    retq
571;
572; AVX2-LABEL: trunc_add_const_v8i32_v8i16:
573; AVX2:       # %bb.0:
574; AVX2-NEXT:    vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u,16,17,20,21,24,25,28,29,u,u,u,u,u,u,u,u]
575; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
576; AVX2-NEXT:    vpaddw {{.*}}(%rip), %xmm0, %xmm0
577; AVX2-NEXT:    vzeroupper
578; AVX2-NEXT:    retq
579;
580; AVX512-LABEL: trunc_add_const_v8i32_v8i16:
581; AVX512:       # %bb.0:
582; AVX512-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
583; AVX512-NEXT:    vpmovdw %zmm0, %ymm0
584; AVX512-NEXT:    vpaddw {{.*}}(%rip), %xmm0, %xmm0
585; AVX512-NEXT:    vzeroupper
586; AVX512-NEXT:    retq
587  %1 = add <8 x i32> %a0, <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
588  %2 = trunc <8 x i32> %1 to <8 x i16>
589  ret <8 x i16> %2
590}
591
592define <16 x i8> @trunc_add_const_v16i64_v16i8(<16 x i64> %a0) nounwind {
593; SSE-LABEL: trunc_add_const_v16i64_v16i8:
594; SSE:       # %bb.0:
595; SSE-NEXT:    movdqa {{.*#+}} xmm8 = [255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0]
596; SSE-NEXT:    pand %xmm8, %xmm7
597; SSE-NEXT:    pand %xmm8, %xmm6
598; SSE-NEXT:    packuswb %xmm7, %xmm6
599; SSE-NEXT:    pand %xmm8, %xmm5
600; SSE-NEXT:    pand %xmm8, %xmm4
601; SSE-NEXT:    packuswb %xmm5, %xmm4
602; SSE-NEXT:    packuswb %xmm6, %xmm4
603; SSE-NEXT:    pand %xmm8, %xmm3
604; SSE-NEXT:    pand %xmm8, %xmm2
605; SSE-NEXT:    packuswb %xmm3, %xmm2
606; SSE-NEXT:    pand %xmm8, %xmm1
607; SSE-NEXT:    pand %xmm8, %xmm0
608; SSE-NEXT:    packuswb %xmm1, %xmm0
609; SSE-NEXT:    packuswb %xmm2, %xmm0
610; SSE-NEXT:    packuswb %xmm4, %xmm0
611; SSE-NEXT:    paddb {{.*}}(%rip), %xmm0
612; SSE-NEXT:    retq
613;
614; AVX1-LABEL: trunc_add_const_v16i64_v16i8:
615; AVX1:       # %bb.0:
616; AVX1-NEXT:    vmovaps {{.*#+}} ymm4 = [255,255,255,255]
617; AVX1-NEXT:    vandps %ymm4, %ymm3, %ymm3
618; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm5
619; AVX1-NEXT:    vpackusdw %xmm5, %xmm3, %xmm3
620; AVX1-NEXT:    vandps %ymm4, %ymm2, %ymm2
621; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm5
622; AVX1-NEXT:    vpackusdw %xmm5, %xmm2, %xmm2
623; AVX1-NEXT:    vpackusdw %xmm3, %xmm2, %xmm2
624; AVX1-NEXT:    vandps %ymm4, %ymm1, %ymm1
625; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
626; AVX1-NEXT:    vpackusdw %xmm3, %xmm1, %xmm1
627; AVX1-NEXT:    vandps %ymm4, %ymm0, %ymm0
628; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
629; AVX1-NEXT:    vpackusdw %xmm3, %xmm0, %xmm0
630; AVX1-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
631; AVX1-NEXT:    vpackuswb %xmm2, %xmm0, %xmm0
632; AVX1-NEXT:    vpaddb {{.*}}(%rip), %xmm0, %xmm0
633; AVX1-NEXT:    vzeroupper
634; AVX1-NEXT:    retq
635;
636; AVX2-LABEL: trunc_add_const_v16i64_v16i8:
637; AVX2:       # %bb.0:
638; AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm4 = [255,255,255,255]
639; AVX2-NEXT:    vpand %ymm4, %ymm3, %ymm3
640; AVX2-NEXT:    vpand %ymm4, %ymm2, %ymm2
641; AVX2-NEXT:    vpackusdw %ymm3, %ymm2, %ymm2
642; AVX2-NEXT:    vpermq {{.*#+}} ymm2 = ymm2[0,2,1,3]
643; AVX2-NEXT:    vpand %ymm4, %ymm1, %ymm1
644; AVX2-NEXT:    vpand %ymm4, %ymm0, %ymm0
645; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
646; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3]
647; AVX2-NEXT:    vpackusdw %ymm2, %ymm0, %ymm0
648; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
649; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
650; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
651; AVX2-NEXT:    vpaddb {{.*}}(%rip), %xmm0, %xmm0
652; AVX2-NEXT:    vzeroupper
653; AVX2-NEXT:    retq
654;
655; AVX512-LABEL: trunc_add_const_v16i64_v16i8:
656; AVX512:       # %bb.0:
657; AVX512-NEXT:    vpmovqb %zmm1, %xmm1
658; AVX512-NEXT:    vpmovqb %zmm0, %xmm0
659; AVX512-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
660; AVX512-NEXT:    vpaddb {{.*}}(%rip), %xmm0, %xmm0
661; AVX512-NEXT:    vzeroupper
662; AVX512-NEXT:    retq
663  %1 = add <16 x i64> %a0, <i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, i64 9, i64 10, i64 11, i64 12, i64 13, i64 14, i64 15>
664  %2 = trunc <16 x i64> %1 to <16 x i8>
665  ret <16 x i8> %2
666}
667
668define <16 x i8> @trunc_add_const_v16i32_v16i8(<16 x i32> %a0) nounwind {
669; SSE-LABEL: trunc_add_const_v16i32_v16i8:
670; SSE:       # %bb.0:
671; SSE-NEXT:    movdqa {{.*#+}} xmm4 = [255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0]
672; SSE-NEXT:    pand %xmm4, %xmm3
673; SSE-NEXT:    pand %xmm4, %xmm2
674; SSE-NEXT:    packuswb %xmm3, %xmm2
675; SSE-NEXT:    pand %xmm4, %xmm1
676; SSE-NEXT:    pand %xmm4, %xmm0
677; SSE-NEXT:    packuswb %xmm1, %xmm0
678; SSE-NEXT:    packuswb %xmm2, %xmm0
679; SSE-NEXT:    paddb {{.*}}(%rip), %xmm0
680; SSE-NEXT:    retq
681;
682; AVX1-LABEL: trunc_add_const_v16i32_v16i8:
683; AVX1:       # %bb.0:
684; AVX1-NEXT:    vmovaps {{.*#+}} ymm2 = [255,255,255,255,255,255,255,255]
685; AVX1-NEXT:    vandps %ymm2, %ymm1, %ymm1
686; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
687; AVX1-NEXT:    vpackusdw %xmm3, %xmm1, %xmm1
688; AVX1-NEXT:    vandps %ymm2, %ymm0, %ymm0
689; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
690; AVX1-NEXT:    vpackusdw %xmm2, %xmm0, %xmm0
691; AVX1-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
692; AVX1-NEXT:    vpaddb {{.*}}(%rip), %xmm0, %xmm0
693; AVX1-NEXT:    vzeroupper
694; AVX1-NEXT:    retq
695;
696; AVX2-LABEL: trunc_add_const_v16i32_v16i8:
697; AVX2:       # %bb.0:
698; AVX2-NEXT:    vpbroadcastd {{.*#+}} ymm2 = [255,255,255,255,255,255,255,255]
699; AVX2-NEXT:    vpand %ymm2, %ymm1, %ymm1
700; AVX2-NEXT:    vpand %ymm2, %ymm0, %ymm0
701; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
702; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
703; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
704; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
705; AVX2-NEXT:    vpaddb {{.*}}(%rip), %xmm0, %xmm0
706; AVX2-NEXT:    vzeroupper
707; AVX2-NEXT:    retq
708;
709; AVX512-LABEL: trunc_add_const_v16i32_v16i8:
710; AVX512:       # %bb.0:
711; AVX512-NEXT:    vpmovdb %zmm0, %xmm0
712; AVX512-NEXT:    vpaddb {{.*}}(%rip), %xmm0, %xmm0
713; AVX512-NEXT:    vzeroupper
714; AVX512-NEXT:    retq
715  %1 = add <16 x i32> %a0, <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>
716  %2 = trunc <16 x i32> %1 to <16 x i8>
717  ret <16 x i8> %2
718}
719
720define <16 x i8> @trunc_add_const_v16i16_v16i8(<16 x i16> %a0) nounwind {
721; SSE-LABEL: trunc_add_const_v16i16_v16i8:
722; SSE:       # %bb.0:
723; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0]
724; SSE-NEXT:    pand %xmm2, %xmm1
725; SSE-NEXT:    pand %xmm2, %xmm0
726; SSE-NEXT:    packuswb %xmm1, %xmm0
727; SSE-NEXT:    paddb {{.*}}(%rip), %xmm0
728; SSE-NEXT:    retq
729;
730; AVX1-LABEL: trunc_add_const_v16i16_v16i8:
731; AVX1:       # %bb.0:
732; AVX1-NEXT:    vandps {{.*}}(%rip), %ymm0, %ymm0
733; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
734; AVX1-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
735; AVX1-NEXT:    vpaddb {{.*}}(%rip), %xmm0, %xmm0
736; AVX1-NEXT:    vzeroupper
737; AVX1-NEXT:    retq
738;
739; AVX2-LABEL: trunc_add_const_v16i16_v16i8:
740; AVX2:       # %bb.0:
741; AVX2-NEXT:    vpand {{.*}}(%rip), %ymm0, %ymm0
742; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
743; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
744; AVX2-NEXT:    vpaddb {{.*}}(%rip), %xmm0, %xmm0
745; AVX2-NEXT:    vzeroupper
746; AVX2-NEXT:    retq
747;
748; AVX512F-LABEL: trunc_add_const_v16i16_v16i8:
749; AVX512F:       # %bb.0:
750; 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
751; AVX512F-NEXT:    vpmovdb %zmm0, %xmm0
752; AVX512F-NEXT:    vpaddb {{.*}}(%rip), %xmm0, %xmm0
753; AVX512F-NEXT:    vzeroupper
754; AVX512F-NEXT:    retq
755;
756; AVX512BW-LABEL: trunc_add_const_v16i16_v16i8:
757; AVX512BW:       # %bb.0:
758; AVX512BW-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
759; AVX512BW-NEXT:    vpmovwb %zmm0, %ymm0
760; AVX512BW-NEXT:    vpaddb {{.*}}(%rip), %xmm0, %xmm0
761; AVX512BW-NEXT:    vzeroupper
762; AVX512BW-NEXT:    retq
763;
764; AVX512DQ-LABEL: trunc_add_const_v16i16_v16i8:
765; AVX512DQ:       # %bb.0:
766; AVX512DQ-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
767; AVX512DQ-NEXT:    vpmovdb %zmm0, %xmm0
768; AVX512DQ-NEXT:    vpaddb {{.*}}(%rip), %xmm0, %xmm0
769; AVX512DQ-NEXT:    vzeroupper
770; AVX512DQ-NEXT:    retq
771  %1 = add <16 x i16> %a0, <i16 0, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7, i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15>
772  %2 = trunc <16 x i16> %1 to <16 x i8>
773  ret <16 x i8> %2
774}
775
776;
777; sub
778;
779
780define <4 x i32> @trunc_sub_v4i64_v4i32(<4 x i64> %a0, <4 x i64> %a1) nounwind {
781; SSE-LABEL: trunc_sub_v4i64_v4i32:
782; SSE:       # %bb.0:
783; SSE-NEXT:    psubq %xmm3, %xmm1
784; SSE-NEXT:    psubq %xmm2, %xmm0
785; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
786; SSE-NEXT:    retq
787;
788; AVX1-LABEL: trunc_sub_v4i64_v4i32:
789; AVX1:       # %bb.0:
790; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
791; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
792; AVX1-NEXT:    vpsubq %xmm2, %xmm3, %xmm2
793; AVX1-NEXT:    vpsubq %xmm1, %xmm0, %xmm0
794; AVX1-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm2[0,2]
795; AVX1-NEXT:    vzeroupper
796; AVX1-NEXT:    retq
797;
798; AVX2-SLOW-LABEL: trunc_sub_v4i64_v4i32:
799; AVX2-SLOW:       # %bb.0:
800; AVX2-SLOW-NEXT:    vpsubq %ymm1, %ymm0, %ymm0
801; AVX2-SLOW-NEXT:    vextracti128 $1, %ymm0, %xmm1
802; AVX2-SLOW-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
803; AVX2-SLOW-NEXT:    vzeroupper
804; AVX2-SLOW-NEXT:    retq
805;
806; AVX2-FAST-LABEL: trunc_sub_v4i64_v4i32:
807; AVX2-FAST:       # %bb.0:
808; AVX2-FAST-NEXT:    vpsubq %ymm1, %ymm0, %ymm0
809; AVX2-FAST-NEXT:    vmovdqa {{.*#+}} ymm1 = <0,2,4,6,u,u,u,u>
810; AVX2-FAST-NEXT:    vpermd %ymm0, %ymm1, %ymm0
811; AVX2-FAST-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
812; AVX2-FAST-NEXT:    vzeroupper
813; AVX2-FAST-NEXT:    retq
814;
815; AVX512-LABEL: trunc_sub_v4i64_v4i32:
816; AVX512:       # %bb.0:
817; AVX512-NEXT:    vpsubq %ymm1, %ymm0, %ymm0
818; AVX512-NEXT:    vpmovqd %zmm0, %ymm0
819; AVX512-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
820; AVX512-NEXT:    vzeroupper
821; AVX512-NEXT:    retq
822  %1 = sub <4 x i64> %a0, %a1
823  %2 = trunc <4 x i64> %1 to <4 x i32>
824  ret <4 x i32> %2
825}
826
827define <8 x i16> @trunc_sub_v8i64_v8i16(<8 x i64> %a0, <8 x i64> %a1) nounwind {
828; SSE-LABEL: trunc_sub_v8i64_v8i16:
829; SSE:       # %bb.0:
830; SSE-NEXT:    psubq %xmm6, %xmm2
831; SSE-NEXT:    psubq %xmm7, %xmm3
832; SSE-NEXT:    psubq %xmm4, %xmm0
833; SSE-NEXT:    psubq %xmm5, %xmm1
834; SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
835; SSE-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,2,2,3,4,5,6,7]
836; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
837; SSE-NEXT:    pshuflw {{.*#+}} xmm4 = xmm0[0,2,2,3,4,5,6,7]
838; SSE-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
839; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[0,2,2,3]
840; SSE-NEXT:    pshuflw {{.*#+}} xmm1 = xmm0[0,1,0,2,4,5,6,7]
841; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3]
842; SSE-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,1,0,2,4,5,6,7]
843; SSE-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
844; SSE-NEXT:    movsd {{.*#+}} xmm0 = xmm4[0],xmm0[1]
845; SSE-NEXT:    retq
846;
847; AVX1-LABEL: trunc_sub_v8i64_v8i16:
848; AVX1:       # %bb.0:
849; AVX1-NEXT:    vpsubq %xmm2, %xmm0, %xmm4
850; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm2
851; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
852; AVX1-NEXT:    vpsubq %xmm2, %xmm0, %xmm0
853; AVX1-NEXT:    vpsubq %xmm3, %xmm1, %xmm2
854; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm3
855; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm1
856; AVX1-NEXT:    vpsubq %xmm3, %xmm1, %xmm1
857; AVX1-NEXT:    vpxor %xmm3, %xmm3, %xmm3
858; AVX1-NEXT:    vpblendw {{.*#+}} xmm1 = xmm1[0],xmm3[1,2,3],xmm1[4],xmm3[5,6,7]
859; AVX1-NEXT:    vpblendw {{.*#+}} xmm2 = xmm2[0],xmm3[1,2,3],xmm2[4],xmm3[5,6,7]
860; AVX1-NEXT:    vpackusdw %xmm1, %xmm2, %xmm1
861; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0],xmm3[1,2,3],xmm0[4],xmm3[5,6,7]
862; AVX1-NEXT:    vpblendw {{.*#+}} xmm2 = xmm4[0],xmm3[1,2,3],xmm4[4],xmm3[5,6,7]
863; AVX1-NEXT:    vpackusdw %xmm0, %xmm2, %xmm0
864; AVX1-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
865; AVX1-NEXT:    vzeroupper
866; AVX1-NEXT:    retq
867;
868; AVX2-LABEL: trunc_sub_v8i64_v8i16:
869; AVX2:       # %bb.0:
870; AVX2-NEXT:    vpsubq %ymm2, %ymm0, %ymm0
871; AVX2-NEXT:    vpsubq %ymm3, %ymm1, %ymm1
872; AVX2-NEXT:    vpxor %xmm2, %xmm2, %xmm2
873; AVX2-NEXT:    vpblendw {{.*#+}} ymm1 = ymm1[0],ymm2[1,2,3],ymm1[4],ymm2[5,6,7],ymm1[8],ymm2[9,10,11],ymm1[12],ymm2[13,14,15]
874; AVX2-NEXT:    vpblendw {{.*#+}} ymm0 = ymm0[0],ymm2[1,2,3],ymm0[4],ymm2[5,6,7],ymm0[8],ymm2[9,10,11],ymm0[12],ymm2[13,14,15]
875; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
876; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
877; AVX2-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
878; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
879; AVX2-NEXT:    vzeroupper
880; AVX2-NEXT:    retq
881;
882; AVX512-LABEL: trunc_sub_v8i64_v8i16:
883; AVX512:       # %bb.0:
884; AVX512-NEXT:    vpsubq %zmm1, %zmm0, %zmm0
885; AVX512-NEXT:    vpmovqw %zmm0, %xmm0
886; AVX512-NEXT:    vzeroupper
887; AVX512-NEXT:    retq
888  %1 = sub <8 x i64> %a0, %a1
889  %2 = trunc <8 x i64> %1 to <8 x i16>
890  ret <8 x i16> %2
891}
892
893define <8 x i16> @trunc_sub_v8i32_v8i16(<8 x i32> %a0, <8 x i32> %a1) nounwind {
894; SSE-LABEL: trunc_sub_v8i32_v8i16:
895; SSE:       # %bb.0:
896; SSE-NEXT:    psubd %xmm2, %xmm0
897; SSE-NEXT:    psubd %xmm3, %xmm1
898; SSE-NEXT:    pslld $16, %xmm1
899; SSE-NEXT:    psrad $16, %xmm1
900; SSE-NEXT:    pslld $16, %xmm0
901; SSE-NEXT:    psrad $16, %xmm0
902; SSE-NEXT:    packssdw %xmm1, %xmm0
903; SSE-NEXT:    retq
904;
905; AVX1-LABEL: trunc_sub_v8i32_v8i16:
906; AVX1:       # %bb.0:
907; AVX1-NEXT:    vpsubd %xmm1, %xmm0, %xmm2
908; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm1
909; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
910; AVX1-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
911; AVX1-NEXT:    vmovdqa {{.*#+}} xmm1 = <0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u>
912; AVX1-NEXT:    vpshufb %xmm1, %xmm0, %xmm0
913; AVX1-NEXT:    vpshufb %xmm1, %xmm2, %xmm1
914; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0]
915; AVX1-NEXT:    vzeroupper
916; AVX1-NEXT:    retq
917;
918; AVX2-LABEL: trunc_sub_v8i32_v8i16:
919; AVX2:       # %bb.0:
920; AVX2-NEXT:    vpsubd %ymm1, %ymm0, %ymm0
921; AVX2-NEXT:    vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u,16,17,20,21,24,25,28,29,u,u,u,u,u,u,u,u]
922; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
923; AVX2-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
924; AVX2-NEXT:    vzeroupper
925; AVX2-NEXT:    retq
926;
927; AVX512-LABEL: trunc_sub_v8i32_v8i16:
928; AVX512:       # %bb.0:
929; AVX512-NEXT:    vpsubd %ymm1, %ymm0, %ymm0
930; AVX512-NEXT:    vpmovdw %zmm0, %ymm0
931; AVX512-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
932; AVX512-NEXT:    vzeroupper
933; AVX512-NEXT:    retq
934  %1 = sub <8 x i32> %a0, %a1
935  %2 = trunc <8 x i32> %1 to <8 x i16>
936  ret <8 x i16> %2
937}
938
939define <16 x i8> @trunc_sub_v16i64_v16i8(<16 x i64> %a0, <16 x i64> %a1) nounwind {
940; SSE-LABEL: trunc_sub_v16i64_v16i8:
941; SSE:       # %bb.0:
942; SSE-NEXT:    psubq {{[0-9]+}}(%rsp), %xmm0
943; SSE-NEXT:    psubq {{[0-9]+}}(%rsp), %xmm1
944; SSE-NEXT:    psubq {{[0-9]+}}(%rsp), %xmm2
945; SSE-NEXT:    psubq {{[0-9]+}}(%rsp), %xmm3
946; SSE-NEXT:    psubq {{[0-9]+}}(%rsp), %xmm4
947; SSE-NEXT:    psubq {{[0-9]+}}(%rsp), %xmm5
948; SSE-NEXT:    psubq {{[0-9]+}}(%rsp), %xmm6
949; SSE-NEXT:    psubq {{[0-9]+}}(%rsp), %xmm7
950; SSE-NEXT:    movdqa {{.*#+}} xmm8 = [255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0]
951; SSE-NEXT:    pand %xmm8, %xmm7
952; SSE-NEXT:    pand %xmm8, %xmm6
953; SSE-NEXT:    packuswb %xmm7, %xmm6
954; SSE-NEXT:    pand %xmm8, %xmm5
955; SSE-NEXT:    pand %xmm8, %xmm4
956; SSE-NEXT:    packuswb %xmm5, %xmm4
957; SSE-NEXT:    packuswb %xmm6, %xmm4
958; SSE-NEXT:    pand %xmm8, %xmm3
959; SSE-NEXT:    pand %xmm8, %xmm2
960; SSE-NEXT:    packuswb %xmm3, %xmm2
961; SSE-NEXT:    pand %xmm8, %xmm1
962; SSE-NEXT:    pand %xmm8, %xmm0
963; SSE-NEXT:    packuswb %xmm1, %xmm0
964; SSE-NEXT:    packuswb %xmm2, %xmm0
965; SSE-NEXT:    packuswb %xmm4, %xmm0
966; SSE-NEXT:    retq
967;
968; AVX1-LABEL: trunc_sub_v16i64_v16i8:
969; AVX1:       # %bb.0:
970; AVX1-NEXT:    vpsubq %xmm4, %xmm0, %xmm8
971; AVX1-NEXT:    vextractf128 $1, %ymm4, %xmm4
972; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
973; AVX1-NEXT:    vpsubq %xmm4, %xmm0, %xmm0
974; AVX1-NEXT:    vpsubq %xmm5, %xmm1, %xmm4
975; AVX1-NEXT:    vextractf128 $1, %ymm5, %xmm5
976; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm1
977; AVX1-NEXT:    vpsubq %xmm5, %xmm1, %xmm1
978; AVX1-NEXT:    vpsubq %xmm6, %xmm2, %xmm5
979; AVX1-NEXT:    vextractf128 $1, %ymm6, %xmm6
980; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm2
981; AVX1-NEXT:    vpsubq %xmm6, %xmm2, %xmm2
982; AVX1-NEXT:    vpsubq %xmm7, %xmm3, %xmm6
983; AVX1-NEXT:    vextractf128 $1, %ymm7, %xmm7
984; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm3
985; AVX1-NEXT:    vpsubq %xmm7, %xmm3, %xmm3
986; AVX1-NEXT:    vmovdqa {{.*#+}} xmm7 = [255,255]
987; AVX1-NEXT:    vpand %xmm7, %xmm3, %xmm3
988; AVX1-NEXT:    vpand %xmm7, %xmm6, %xmm6
989; AVX1-NEXT:    vpackusdw %xmm3, %xmm6, %xmm3
990; AVX1-NEXT:    vpand %xmm7, %xmm2, %xmm2
991; AVX1-NEXT:    vpand %xmm7, %xmm5, %xmm5
992; AVX1-NEXT:    vpackusdw %xmm2, %xmm5, %xmm2
993; AVX1-NEXT:    vpackusdw %xmm3, %xmm2, %xmm2
994; AVX1-NEXT:    vpand %xmm7, %xmm1, %xmm1
995; AVX1-NEXT:    vpand %xmm7, %xmm4, %xmm3
996; AVX1-NEXT:    vpackusdw %xmm1, %xmm3, %xmm1
997; AVX1-NEXT:    vpand %xmm7, %xmm0, %xmm0
998; AVX1-NEXT:    vpand %xmm7, %xmm8, %xmm3
999; AVX1-NEXT:    vpackusdw %xmm0, %xmm3, %xmm0
1000; AVX1-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
1001; AVX1-NEXT:    vpackuswb %xmm2, %xmm0, %xmm0
1002; AVX1-NEXT:    vzeroupper
1003; AVX1-NEXT:    retq
1004;
1005; AVX2-LABEL: trunc_sub_v16i64_v16i8:
1006; AVX2:       # %bb.0:
1007; AVX2-NEXT:    vpsubq %ymm4, %ymm0, %ymm0
1008; AVX2-NEXT:    vpsubq %ymm5, %ymm1, %ymm1
1009; AVX2-NEXT:    vpsubq %ymm6, %ymm2, %ymm2
1010; AVX2-NEXT:    vpsubq %ymm7, %ymm3, %ymm3
1011; AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm4 = [255,255,255,255]
1012; AVX2-NEXT:    vpand %ymm4, %ymm3, %ymm3
1013; AVX2-NEXT:    vpand %ymm4, %ymm2, %ymm2
1014; AVX2-NEXT:    vpackusdw %ymm3, %ymm2, %ymm2
1015; AVX2-NEXT:    vpermq {{.*#+}} ymm2 = ymm2[0,2,1,3]
1016; AVX2-NEXT:    vpand %ymm4, %ymm1, %ymm1
1017; AVX2-NEXT:    vpand %ymm4, %ymm0, %ymm0
1018; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
1019; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3]
1020; AVX2-NEXT:    vpackusdw %ymm2, %ymm0, %ymm0
1021; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
1022; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
1023; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
1024; AVX2-NEXT:    vzeroupper
1025; AVX2-NEXT:    retq
1026;
1027; AVX512-LABEL: trunc_sub_v16i64_v16i8:
1028; AVX512:       # %bb.0:
1029; AVX512-NEXT:    vpsubq %zmm2, %zmm0, %zmm0
1030; AVX512-NEXT:    vpsubq %zmm3, %zmm1, %zmm1
1031; AVX512-NEXT:    vpmovqb %zmm1, %xmm1
1032; AVX512-NEXT:    vpmovqb %zmm0, %xmm0
1033; AVX512-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1034; AVX512-NEXT:    vzeroupper
1035; AVX512-NEXT:    retq
1036  %1 = sub <16 x i64> %a0, %a1
1037  %2 = trunc <16 x i64> %1 to <16 x i8>
1038  ret <16 x i8> %2
1039}
1040
1041define <16 x i8> @trunc_sub_v16i32_v16i8(<16 x i32> %a0, <16 x i32> %a1) nounwind {
1042; SSE-LABEL: trunc_sub_v16i32_v16i8:
1043; SSE:       # %bb.0:
1044; SSE-NEXT:    psubd %xmm4, %xmm0
1045; SSE-NEXT:    psubd %xmm5, %xmm1
1046; SSE-NEXT:    psubd %xmm6, %xmm2
1047; SSE-NEXT:    psubd %xmm7, %xmm3
1048; SSE-NEXT:    movdqa {{.*#+}} xmm4 = [255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0]
1049; SSE-NEXT:    pand %xmm4, %xmm3
1050; SSE-NEXT:    pand %xmm4, %xmm2
1051; SSE-NEXT:    packuswb %xmm3, %xmm2
1052; SSE-NEXT:    pand %xmm4, %xmm1
1053; SSE-NEXT:    pand %xmm4, %xmm0
1054; SSE-NEXT:    packuswb %xmm1, %xmm0
1055; SSE-NEXT:    packuswb %xmm2, %xmm0
1056; SSE-NEXT:    retq
1057;
1058; AVX1-LABEL: trunc_sub_v16i32_v16i8:
1059; AVX1:       # %bb.0:
1060; AVX1-NEXT:    vpsubd %xmm2, %xmm0, %xmm4
1061; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm2
1062; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
1063; AVX1-NEXT:    vpsubd %xmm2, %xmm0, %xmm0
1064; AVX1-NEXT:    vpsubd %xmm3, %xmm1, %xmm2
1065; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm3
1066; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm1
1067; AVX1-NEXT:    vpsubd %xmm3, %xmm1, %xmm1
1068; AVX1-NEXT:    vmovdqa {{.*#+}} xmm3 = [255,255,255,255]
1069; AVX1-NEXT:    vpand %xmm3, %xmm1, %xmm1
1070; AVX1-NEXT:    vpand %xmm3, %xmm2, %xmm2
1071; AVX1-NEXT:    vpackusdw %xmm1, %xmm2, %xmm1
1072; AVX1-NEXT:    vpand %xmm3, %xmm0, %xmm0
1073; AVX1-NEXT:    vpand %xmm3, %xmm4, %xmm2
1074; AVX1-NEXT:    vpackusdw %xmm0, %xmm2, %xmm0
1075; AVX1-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
1076; AVX1-NEXT:    vzeroupper
1077; AVX1-NEXT:    retq
1078;
1079; AVX2-LABEL: trunc_sub_v16i32_v16i8:
1080; AVX2:       # %bb.0:
1081; AVX2-NEXT:    vpsubd %ymm2, %ymm0, %ymm0
1082; AVX2-NEXT:    vpsubd %ymm3, %ymm1, %ymm1
1083; AVX2-NEXT:    vpbroadcastd {{.*#+}} ymm2 = [255,255,255,255,255,255,255,255]
1084; AVX2-NEXT:    vpand %ymm2, %ymm1, %ymm1
1085; AVX2-NEXT:    vpand %ymm2, %ymm0, %ymm0
1086; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
1087; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
1088; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
1089; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
1090; AVX2-NEXT:    vzeroupper
1091; AVX2-NEXT:    retq
1092;
1093; AVX512-LABEL: trunc_sub_v16i32_v16i8:
1094; AVX512:       # %bb.0:
1095; AVX512-NEXT:    vpsubd %zmm1, %zmm0, %zmm0
1096; AVX512-NEXT:    vpmovdb %zmm0, %xmm0
1097; AVX512-NEXT:    vzeroupper
1098; AVX512-NEXT:    retq
1099  %1 = sub <16 x i32> %a0, %a1
1100  %2 = trunc <16 x i32> %1 to <16 x i8>
1101  ret <16 x i8> %2
1102}
1103
1104define <16 x i8> @trunc_sub_v16i16_v16i8(<16 x i16> %a0, <16 x i16> %a1) nounwind {
1105; SSE-LABEL: trunc_sub_v16i16_v16i8:
1106; SSE:       # %bb.0:
1107; SSE-NEXT:    psubw %xmm2, %xmm0
1108; SSE-NEXT:    psubw %xmm3, %xmm1
1109; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0]
1110; SSE-NEXT:    pand %xmm2, %xmm1
1111; SSE-NEXT:    pand %xmm2, %xmm0
1112; SSE-NEXT:    packuswb %xmm1, %xmm0
1113; SSE-NEXT:    retq
1114;
1115; AVX1-LABEL: trunc_sub_v16i16_v16i8:
1116; AVX1:       # %bb.0:
1117; AVX1-NEXT:    vpsubw %xmm1, %xmm0, %xmm2
1118; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm1
1119; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
1120; AVX1-NEXT:    vpsubw %xmm1, %xmm0, %xmm0
1121; AVX1-NEXT:    vmovdqa {{.*#+}} xmm1 = [255,255,255,255,255,255,255,255]
1122; AVX1-NEXT:    vpand %xmm1, %xmm0, %xmm0
1123; AVX1-NEXT:    vpand %xmm1, %xmm2, %xmm1
1124; AVX1-NEXT:    vpackuswb %xmm0, %xmm1, %xmm0
1125; AVX1-NEXT:    vzeroupper
1126; AVX1-NEXT:    retq
1127;
1128; AVX2-LABEL: trunc_sub_v16i16_v16i8:
1129; AVX2:       # %bb.0:
1130; AVX2-NEXT:    vpsubw %ymm1, %ymm0, %ymm0
1131; AVX2-NEXT:    vpand {{.*}}(%rip), %ymm0, %ymm0
1132; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
1133; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
1134; AVX2-NEXT:    vzeroupper
1135; AVX2-NEXT:    retq
1136;
1137; AVX512F-LABEL: trunc_sub_v16i16_v16i8:
1138; AVX512F:       # %bb.0:
1139; AVX512F-NEXT:    vpsubw %ymm1, %ymm0, %ymm0
1140; 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
1141; AVX512F-NEXT:    vpmovdb %zmm0, %xmm0
1142; AVX512F-NEXT:    vzeroupper
1143; AVX512F-NEXT:    retq
1144;
1145; AVX512BW-LABEL: trunc_sub_v16i16_v16i8:
1146; AVX512BW:       # %bb.0:
1147; AVX512BW-NEXT:    vpsubw %ymm1, %ymm0, %ymm0
1148; AVX512BW-NEXT:    vpmovwb %zmm0, %ymm0
1149; AVX512BW-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
1150; AVX512BW-NEXT:    vzeroupper
1151; AVX512BW-NEXT:    retq
1152;
1153; AVX512DQ-LABEL: trunc_sub_v16i16_v16i8:
1154; AVX512DQ:       # %bb.0:
1155; AVX512DQ-NEXT:    vpsubw %ymm1, %ymm0, %ymm0
1156; AVX512DQ-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
1157; AVX512DQ-NEXT:    vpmovdb %zmm0, %xmm0
1158; AVX512DQ-NEXT:    vzeroupper
1159; AVX512DQ-NEXT:    retq
1160  %1 = sub <16 x i16> %a0, %a1
1161  %2 = trunc <16 x i16> %1 to <16 x i8>
1162  ret <16 x i8> %2
1163}
1164
1165define <16 x i8> @trunc_ext_sub_v16i16_v16i8(<16 x i8> %x, <16 x i8> %y) {
1166; SSE-LABEL: trunc_ext_sub_v16i16_v16i8:
1167; SSE:       # %bb.0:
1168; SSE-NEXT:    psubb %xmm1, %xmm0
1169; SSE-NEXT:    retq
1170;
1171; AVX-LABEL: trunc_ext_sub_v16i16_v16i8:
1172; AVX:       # %bb.0:
1173; AVX-NEXT:    vpsubb %xmm1, %xmm0, %xmm0
1174; AVX-NEXT:    retq
1175  %a = zext <16 x i8> %x to <16 x i16>
1176  %b = zext <16 x i8> %y to <16 x i16>
1177  %c = sub <16 x i16> %a, %b
1178  %d = trunc <16 x i16> %c to <16 x i8>
1179  ret <16 x i8> %d
1180}
1181
1182;
1183; sub to constant
1184;
1185
1186define <4 x i32> @trunc_sub_const_v4i64_v4i32(<4 x i64> %a0) nounwind {
1187; SSE-LABEL: trunc_sub_const_v4i64_v4i32:
1188; SSE:       # %bb.0:
1189; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
1190; SSE-NEXT:    psubd {{.*}}(%rip), %xmm0
1191; SSE-NEXT:    retq
1192;
1193; AVX1-LABEL: trunc_sub_const_v4i64_v4i32:
1194; AVX1:       # %bb.0:
1195; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
1196; AVX1-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
1197; AVX1-NEXT:    vpsubd {{.*}}(%rip), %xmm0, %xmm0
1198; AVX1-NEXT:    vzeroupper
1199; AVX1-NEXT:    retq
1200;
1201; AVX2-SLOW-LABEL: trunc_sub_const_v4i64_v4i32:
1202; AVX2-SLOW:       # %bb.0:
1203; AVX2-SLOW-NEXT:    vextractf128 $1, %ymm0, %xmm1
1204; AVX2-SLOW-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
1205; AVX2-SLOW-NEXT:    vpsubd {{.*}}(%rip), %xmm0, %xmm0
1206; AVX2-SLOW-NEXT:    vzeroupper
1207; AVX2-SLOW-NEXT:    retq
1208;
1209; AVX2-FAST-LABEL: trunc_sub_const_v4i64_v4i32:
1210; AVX2-FAST:       # %bb.0:
1211; AVX2-FAST-NEXT:    vmovdqa {{.*#+}} ymm1 = <0,2,4,6,u,u,u,u>
1212; AVX2-FAST-NEXT:    vpermd %ymm0, %ymm1, %ymm0
1213; AVX2-FAST-NEXT:    vpsubd {{.*}}(%rip), %xmm0, %xmm0
1214; AVX2-FAST-NEXT:    vzeroupper
1215; AVX2-FAST-NEXT:    retq
1216;
1217; AVX512-LABEL: trunc_sub_const_v4i64_v4i32:
1218; AVX512:       # %bb.0:
1219; AVX512-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
1220; AVX512-NEXT:    vpmovqd %zmm0, %ymm0
1221; AVX512-NEXT:    vpsubd {{.*}}(%rip), %xmm0, %xmm0
1222; AVX512-NEXT:    vzeroupper
1223; AVX512-NEXT:    retq
1224  %1 = sub <4 x i64> %a0, <i64 0, i64 1, i64 2, i64 3>
1225  %2 = trunc <4 x i64> %1 to <4 x i32>
1226  ret <4 x i32> %2
1227}
1228
1229define <8 x i16> @trunc_sub_const_v8i64_v8i16(<8 x i64> %a0) nounwind {
1230; SSE-LABEL: trunc_sub_const_v8i64_v8i16:
1231; SSE:       # %bb.0:
1232; SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
1233; SSE-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,2,2,3,4,5,6,7]
1234; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
1235; SSE-NEXT:    pshuflw {{.*#+}} xmm4 = xmm0[0,2,2,3,4,5,6,7]
1236; SSE-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
1237; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[0,2,2,3]
1238; SSE-NEXT:    pshuflw {{.*#+}} xmm1 = xmm0[0,1,0,2,4,5,6,7]
1239; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3]
1240; SSE-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,1,0,2,4,5,6,7]
1241; SSE-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
1242; SSE-NEXT:    movsd {{.*#+}} xmm0 = xmm4[0],xmm0[1]
1243; SSE-NEXT:    psubw {{.*}}(%rip), %xmm0
1244; SSE-NEXT:    retq
1245;
1246; AVX1-LABEL: trunc_sub_const_v8i64_v8i16:
1247; AVX1:       # %bb.0:
1248; AVX1-NEXT:    vmovaps {{.*#+}} ymm2 = [65535,65535,65535,65535]
1249; AVX1-NEXT:    vandps %ymm2, %ymm1, %ymm1
1250; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
1251; AVX1-NEXT:    vpackusdw %xmm3, %xmm1, %xmm1
1252; AVX1-NEXT:    vandps %ymm2, %ymm0, %ymm0
1253; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
1254; AVX1-NEXT:    vpackusdw %xmm2, %xmm0, %xmm0
1255; AVX1-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
1256; AVX1-NEXT:    vpsubw {{.*}}(%rip), %xmm0, %xmm0
1257; AVX1-NEXT:    vzeroupper
1258; AVX1-NEXT:    retq
1259;
1260; AVX2-LABEL: trunc_sub_const_v8i64_v8i16:
1261; AVX2:       # %bb.0:
1262; AVX2-NEXT:    vpxor %xmm2, %xmm2, %xmm2
1263; AVX2-NEXT:    vpblendw {{.*#+}} ymm1 = ymm1[0],ymm2[1,2,3],ymm1[4],ymm2[5,6,7],ymm1[8],ymm2[9,10,11],ymm1[12],ymm2[13,14,15]
1264; AVX2-NEXT:    vpblendw {{.*#+}} ymm0 = ymm0[0],ymm2[1,2,3],ymm0[4],ymm2[5,6,7],ymm0[8],ymm2[9,10,11],ymm0[12],ymm2[13,14,15]
1265; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
1266; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
1267; AVX2-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
1268; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
1269; AVX2-NEXT:    vpsubw {{.*}}(%rip), %xmm0, %xmm0
1270; AVX2-NEXT:    vzeroupper
1271; AVX2-NEXT:    retq
1272;
1273; AVX512-LABEL: trunc_sub_const_v8i64_v8i16:
1274; AVX512:       # %bb.0:
1275; AVX512-NEXT:    vpmovqw %zmm0, %xmm0
1276; AVX512-NEXT:    vpsubw {{.*}}(%rip), %xmm0, %xmm0
1277; AVX512-NEXT:    vzeroupper
1278; AVX512-NEXT:    retq
1279  %1 = sub <8 x i64> %a0, <i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7>
1280  %2 = trunc <8 x i64> %1 to <8 x i16>
1281  ret <8 x i16> %2
1282}
1283
1284define <8 x i16> @trunc_sub_const_v8i32_v8i16(<8 x i32> %a0) nounwind {
1285; SSE-LABEL: trunc_sub_const_v8i32_v8i16:
1286; SSE:       # %bb.0:
1287; SSE-NEXT:    pslld $16, %xmm1
1288; SSE-NEXT:    psrad $16, %xmm1
1289; SSE-NEXT:    pslld $16, %xmm0
1290; SSE-NEXT:    psrad $16, %xmm0
1291; SSE-NEXT:    packssdw %xmm1, %xmm0
1292; SSE-NEXT:    psubw {{.*}}(%rip), %xmm0
1293; SSE-NEXT:    retq
1294;
1295; AVX1-LABEL: trunc_sub_const_v8i32_v8i16:
1296; AVX1:       # %bb.0:
1297; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
1298; AVX1-NEXT:    vmovdqa {{.*#+}} xmm2 = <0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u>
1299; AVX1-NEXT:    vpshufb %xmm2, %xmm1, %xmm1
1300; AVX1-NEXT:    vpshufb %xmm2, %xmm0, %xmm0
1301; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1302; AVX1-NEXT:    vpsubw {{.*}}(%rip), %xmm0, %xmm0
1303; AVX1-NEXT:    vzeroupper
1304; AVX1-NEXT:    retq
1305;
1306; AVX2-LABEL: trunc_sub_const_v8i32_v8i16:
1307; AVX2:       # %bb.0:
1308; AVX2-NEXT:    vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u,16,17,20,21,24,25,28,29,u,u,u,u,u,u,u,u]
1309; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
1310; AVX2-NEXT:    vpsubw {{.*}}(%rip), %xmm0, %xmm0
1311; AVX2-NEXT:    vzeroupper
1312; AVX2-NEXT:    retq
1313;
1314; AVX512-LABEL: trunc_sub_const_v8i32_v8i16:
1315; AVX512:       # %bb.0:
1316; AVX512-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
1317; AVX512-NEXT:    vpmovdw %zmm0, %ymm0
1318; AVX512-NEXT:    vpsubw {{.*}}(%rip), %xmm0, %xmm0
1319; AVX512-NEXT:    vzeroupper
1320; AVX512-NEXT:    retq
1321  %1 = sub <8 x i32> %a0, <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
1322  %2 = trunc <8 x i32> %1 to <8 x i16>
1323  ret <8 x i16> %2
1324}
1325
1326define <16 x i8> @trunc_sub_const_v16i64_v16i8(<16 x i64> %a0) nounwind {
1327; SSE-LABEL: trunc_sub_const_v16i64_v16i8:
1328; SSE:       # %bb.0:
1329; SSE-NEXT:    movdqa {{.*#+}} xmm8 = [255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0]
1330; SSE-NEXT:    pand %xmm8, %xmm7
1331; SSE-NEXT:    pand %xmm8, %xmm6
1332; SSE-NEXT:    packuswb %xmm7, %xmm6
1333; SSE-NEXT:    pand %xmm8, %xmm5
1334; SSE-NEXT:    pand %xmm8, %xmm4
1335; SSE-NEXT:    packuswb %xmm5, %xmm4
1336; SSE-NEXT:    packuswb %xmm6, %xmm4
1337; SSE-NEXT:    pand %xmm8, %xmm3
1338; SSE-NEXT:    pand %xmm8, %xmm2
1339; SSE-NEXT:    packuswb %xmm3, %xmm2
1340; SSE-NEXT:    pand %xmm8, %xmm1
1341; SSE-NEXT:    pand %xmm8, %xmm0
1342; SSE-NEXT:    packuswb %xmm1, %xmm0
1343; SSE-NEXT:    packuswb %xmm2, %xmm0
1344; SSE-NEXT:    packuswb %xmm4, %xmm0
1345; SSE-NEXT:    psubb {{.*}}(%rip), %xmm0
1346; SSE-NEXT:    retq
1347;
1348; AVX1-LABEL: trunc_sub_const_v16i64_v16i8:
1349; AVX1:       # %bb.0:
1350; AVX1-NEXT:    vmovaps {{.*#+}} ymm4 = [255,255,255,255]
1351; AVX1-NEXT:    vandps %ymm4, %ymm3, %ymm3
1352; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm5
1353; AVX1-NEXT:    vpackusdw %xmm5, %xmm3, %xmm3
1354; AVX1-NEXT:    vandps %ymm4, %ymm2, %ymm2
1355; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm5
1356; AVX1-NEXT:    vpackusdw %xmm5, %xmm2, %xmm2
1357; AVX1-NEXT:    vpackusdw %xmm3, %xmm2, %xmm2
1358; AVX1-NEXT:    vandps %ymm4, %ymm1, %ymm1
1359; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
1360; AVX1-NEXT:    vpackusdw %xmm3, %xmm1, %xmm1
1361; AVX1-NEXT:    vandps %ymm4, %ymm0, %ymm0
1362; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
1363; AVX1-NEXT:    vpackusdw %xmm3, %xmm0, %xmm0
1364; AVX1-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
1365; AVX1-NEXT:    vpackuswb %xmm2, %xmm0, %xmm0
1366; AVX1-NEXT:    vpsubb {{.*}}(%rip), %xmm0, %xmm0
1367; AVX1-NEXT:    vzeroupper
1368; AVX1-NEXT:    retq
1369;
1370; AVX2-LABEL: trunc_sub_const_v16i64_v16i8:
1371; AVX2:       # %bb.0:
1372; AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm4 = [255,255,255,255]
1373; AVX2-NEXT:    vpand %ymm4, %ymm3, %ymm3
1374; AVX2-NEXT:    vpand %ymm4, %ymm2, %ymm2
1375; AVX2-NEXT:    vpackusdw %ymm3, %ymm2, %ymm2
1376; AVX2-NEXT:    vpermq {{.*#+}} ymm2 = ymm2[0,2,1,3]
1377; AVX2-NEXT:    vpand %ymm4, %ymm1, %ymm1
1378; AVX2-NEXT:    vpand %ymm4, %ymm0, %ymm0
1379; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
1380; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3]
1381; AVX2-NEXT:    vpackusdw %ymm2, %ymm0, %ymm0
1382; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
1383; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
1384; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
1385; AVX2-NEXT:    vpsubb {{.*}}(%rip), %xmm0, %xmm0
1386; AVX2-NEXT:    vzeroupper
1387; AVX2-NEXT:    retq
1388;
1389; AVX512-LABEL: trunc_sub_const_v16i64_v16i8:
1390; AVX512:       # %bb.0:
1391; AVX512-NEXT:    vpmovqb %zmm1, %xmm1
1392; AVX512-NEXT:    vpmovqb %zmm0, %xmm0
1393; AVX512-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1394; AVX512-NEXT:    vpsubb {{.*}}(%rip), %xmm0, %xmm0
1395; AVX512-NEXT:    vzeroupper
1396; AVX512-NEXT:    retq
1397  %1 = sub <16 x i64> %a0, <i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, i64 9, i64 10, i64 11, i64 12, i64 13, i64 14, i64 15>
1398  %2 = trunc <16 x i64> %1 to <16 x i8>
1399  ret <16 x i8> %2
1400}
1401
1402define <16 x i8> @trunc_sub_const_v16i32_v16i8(<16 x i32> %a0) nounwind {
1403; SSE-LABEL: trunc_sub_const_v16i32_v16i8:
1404; SSE:       # %bb.0:
1405; SSE-NEXT:    movdqa {{.*#+}} xmm4 = [255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0]
1406; SSE-NEXT:    pand %xmm4, %xmm3
1407; SSE-NEXT:    pand %xmm4, %xmm2
1408; SSE-NEXT:    packuswb %xmm3, %xmm2
1409; SSE-NEXT:    pand %xmm4, %xmm1
1410; SSE-NEXT:    pand %xmm4, %xmm0
1411; SSE-NEXT:    packuswb %xmm1, %xmm0
1412; SSE-NEXT:    packuswb %xmm2, %xmm0
1413; SSE-NEXT:    psubb {{.*}}(%rip), %xmm0
1414; SSE-NEXT:    retq
1415;
1416; AVX1-LABEL: trunc_sub_const_v16i32_v16i8:
1417; AVX1:       # %bb.0:
1418; AVX1-NEXT:    vmovaps {{.*#+}} ymm2 = [255,255,255,255,255,255,255,255]
1419; AVX1-NEXT:    vandps %ymm2, %ymm1, %ymm1
1420; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
1421; AVX1-NEXT:    vpackusdw %xmm3, %xmm1, %xmm1
1422; AVX1-NEXT:    vandps %ymm2, %ymm0, %ymm0
1423; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
1424; AVX1-NEXT:    vpackusdw %xmm2, %xmm0, %xmm0
1425; AVX1-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
1426; AVX1-NEXT:    vpsubb {{.*}}(%rip), %xmm0, %xmm0
1427; AVX1-NEXT:    vzeroupper
1428; AVX1-NEXT:    retq
1429;
1430; AVX2-LABEL: trunc_sub_const_v16i32_v16i8:
1431; AVX2:       # %bb.0:
1432; AVX2-NEXT:    vpbroadcastd {{.*#+}} ymm2 = [255,255,255,255,255,255,255,255]
1433; AVX2-NEXT:    vpand %ymm2, %ymm1, %ymm1
1434; AVX2-NEXT:    vpand %ymm2, %ymm0, %ymm0
1435; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
1436; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
1437; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
1438; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
1439; AVX2-NEXT:    vpsubb {{.*}}(%rip), %xmm0, %xmm0
1440; AVX2-NEXT:    vzeroupper
1441; AVX2-NEXT:    retq
1442;
1443; AVX512-LABEL: trunc_sub_const_v16i32_v16i8:
1444; AVX512:       # %bb.0:
1445; AVX512-NEXT:    vpmovdb %zmm0, %xmm0
1446; AVX512-NEXT:    vpsubb {{.*}}(%rip), %xmm0, %xmm0
1447; AVX512-NEXT:    vzeroupper
1448; AVX512-NEXT:    retq
1449  %1 = sub <16 x i32> %a0, <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>
1450  %2 = trunc <16 x i32> %1 to <16 x i8>
1451  ret <16 x i8> %2
1452}
1453
1454define <16 x i8> @trunc_sub_const_v16i16_v16i8(<16 x i16> %a0) nounwind {
1455; SSE-LABEL: trunc_sub_const_v16i16_v16i8:
1456; SSE:       # %bb.0:
1457; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0]
1458; SSE-NEXT:    pand %xmm2, %xmm1
1459; SSE-NEXT:    pand %xmm2, %xmm0
1460; SSE-NEXT:    packuswb %xmm1, %xmm0
1461; SSE-NEXT:    psubb {{.*}}(%rip), %xmm0
1462; SSE-NEXT:    retq
1463;
1464; AVX1-LABEL: trunc_sub_const_v16i16_v16i8:
1465; AVX1:       # %bb.0:
1466; AVX1-NEXT:    vandps {{.*}}(%rip), %ymm0, %ymm0
1467; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
1468; AVX1-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
1469; AVX1-NEXT:    vpsubb {{.*}}(%rip), %xmm0, %xmm0
1470; AVX1-NEXT:    vzeroupper
1471; AVX1-NEXT:    retq
1472;
1473; AVX2-LABEL: trunc_sub_const_v16i16_v16i8:
1474; AVX2:       # %bb.0:
1475; AVX2-NEXT:    vpand {{.*}}(%rip), %ymm0, %ymm0
1476; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
1477; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
1478; AVX2-NEXT:    vpsubb {{.*}}(%rip), %xmm0, %xmm0
1479; AVX2-NEXT:    vzeroupper
1480; AVX2-NEXT:    retq
1481;
1482; AVX512F-LABEL: trunc_sub_const_v16i16_v16i8:
1483; AVX512F:       # %bb.0:
1484; 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
1485; AVX512F-NEXT:    vpmovdb %zmm0, %xmm0
1486; AVX512F-NEXT:    vpsubb {{.*}}(%rip), %xmm0, %xmm0
1487; AVX512F-NEXT:    vzeroupper
1488; AVX512F-NEXT:    retq
1489;
1490; AVX512BW-LABEL: trunc_sub_const_v16i16_v16i8:
1491; AVX512BW:       # %bb.0:
1492; AVX512BW-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
1493; AVX512BW-NEXT:    vpmovwb %zmm0, %ymm0
1494; AVX512BW-NEXT:    vpsubb {{.*}}(%rip), %xmm0, %xmm0
1495; AVX512BW-NEXT:    vzeroupper
1496; AVX512BW-NEXT:    retq
1497;
1498; AVX512DQ-LABEL: trunc_sub_const_v16i16_v16i8:
1499; AVX512DQ:       # %bb.0:
1500; AVX512DQ-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
1501; AVX512DQ-NEXT:    vpmovdb %zmm0, %xmm0
1502; AVX512DQ-NEXT:    vpsubb {{.*}}(%rip), %xmm0, %xmm0
1503; AVX512DQ-NEXT:    vzeroupper
1504; AVX512DQ-NEXT:    retq
1505  %1 = sub <16 x i16> %a0, <i16 0, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7, i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15>
1506  %2 = trunc <16 x i16> %1 to <16 x i8>
1507  ret <16 x i8> %2
1508}
1509
1510define <16 x i8> @trunc_ext_sub_const_rhs_v16i16_v16i8(<16 x i8> %x) {
1511; SSE-LABEL: trunc_ext_sub_const_rhs_v16i16_v16i8:
1512; SSE:       # %bb.0:
1513; SSE-NEXT:    psubb {{.*}}(%rip), %xmm0
1514; SSE-NEXT:    retq
1515;
1516; AVX-LABEL: trunc_ext_sub_const_rhs_v16i16_v16i8:
1517; AVX:       # %bb.0:
1518; AVX-NEXT:    vpsubb {{.*}}(%rip), %xmm0, %xmm0
1519; AVX-NEXT:    retq
1520  %a = zext <16 x i8> %x to <16 x i16>
1521  %b = sub <16 x i16> %a, <i16 0, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7, i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15>
1522  %c = trunc <16 x i16> %b to <16 x i8>
1523  ret <16 x i8> %c
1524}
1525
1526define <16 x i8> @trunc_ext_sub_const_lhs_v16i16_v16i8(<16 x i8> %x) {
1527; SSE-LABEL: trunc_ext_sub_const_lhs_v16i16_v16i8:
1528; SSE:       # %bb.0:
1529; SSE-NEXT:    movdqa {{.*#+}} xmm1 = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
1530; SSE-NEXT:    psubb %xmm0, %xmm1
1531; SSE-NEXT:    movdqa %xmm1, %xmm0
1532; SSE-NEXT:    retq
1533;
1534; AVX-LABEL: trunc_ext_sub_const_lhs_v16i16_v16i8:
1535; AVX:       # %bb.0:
1536; AVX-NEXT:    vmovdqa {{.*#+}} xmm1 = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
1537; AVX-NEXT:    vpsubb %xmm0, %xmm1, %xmm0
1538; AVX-NEXT:    retq
1539  %a = zext <16 x i8> %x to <16 x i16>
1540  %b = sub <16 x i16> <i16 0, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7, i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15>, %a
1541  %c = trunc <16 x i16> %b to <16 x i8>
1542  ret <16 x i8> %c
1543}
1544
1545;
1546; mul
1547;
1548
1549define <4 x i32> @trunc_mul_v4i64_v4i32(<4 x i64> %a0, <4 x i64> %a1) nounwind {
1550; SSE-LABEL: trunc_mul_v4i64_v4i32:
1551; SSE:       # %bb.0:
1552; SSE-NEXT:    pmuludq %xmm3, %xmm1
1553; SSE-NEXT:    pmuludq %xmm2, %xmm0
1554; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
1555; SSE-NEXT:    retq
1556;
1557; AVX1-LABEL: trunc_mul_v4i64_v4i32:
1558; AVX1:       # %bb.0:
1559; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
1560; AVX1-NEXT:    vshufps {{.*#+}} xmm1 = xmm1[0,2],xmm2[0,2]
1561; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
1562; AVX1-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm2[0,2]
1563; AVX1-NEXT:    vpmulld %xmm1, %xmm0, %xmm0
1564; AVX1-NEXT:    vzeroupper
1565; AVX1-NEXT:    retq
1566;
1567; AVX2-SLOW-LABEL: trunc_mul_v4i64_v4i32:
1568; AVX2-SLOW:       # %bb.0:
1569; AVX2-SLOW-NEXT:    vextractf128 $1, %ymm1, %xmm2
1570; AVX2-SLOW-NEXT:    vshufps {{.*#+}} xmm1 = xmm1[0,2],xmm2[0,2]
1571; AVX2-SLOW-NEXT:    vextractf128 $1, %ymm0, %xmm2
1572; AVX2-SLOW-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm2[0,2]
1573; AVX2-SLOW-NEXT:    vpmulld %xmm1, %xmm0, %xmm0
1574; AVX2-SLOW-NEXT:    vzeroupper
1575; AVX2-SLOW-NEXT:    retq
1576;
1577; AVX2-FAST-LABEL: trunc_mul_v4i64_v4i32:
1578; AVX2-FAST:       # %bb.0:
1579; AVX2-FAST-NEXT:    vmovdqa {{.*#+}} ymm2 = [0,2,4,6,4,6,6,7]
1580; AVX2-FAST-NEXT:    vpermd %ymm1, %ymm2, %ymm1
1581; AVX2-FAST-NEXT:    vpermd %ymm0, %ymm2, %ymm0
1582; AVX2-FAST-NEXT:    vpmulld %xmm1, %xmm0, %xmm0
1583; AVX2-FAST-NEXT:    vzeroupper
1584; AVX2-FAST-NEXT:    retq
1585;
1586; AVX512F-LABEL: trunc_mul_v4i64_v4i32:
1587; AVX512F:       # %bb.0:
1588; AVX512F-NEXT:    # kill: def $ymm1 killed $ymm1 def $zmm1
1589; AVX512F-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
1590; AVX512F-NEXT:    vpmovqd %zmm1, %ymm1
1591; AVX512F-NEXT:    vpmovqd %zmm0, %ymm0
1592; AVX512F-NEXT:    vpmulld %xmm1, %xmm0, %xmm0
1593; AVX512F-NEXT:    vzeroupper
1594; AVX512F-NEXT:    retq
1595;
1596; AVX512BW-LABEL: trunc_mul_v4i64_v4i32:
1597; AVX512BW:       # %bb.0:
1598; AVX512BW-NEXT:    # kill: def $ymm1 killed $ymm1 def $zmm1
1599; AVX512BW-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
1600; AVX512BW-NEXT:    vpmovqd %zmm1, %ymm1
1601; AVX512BW-NEXT:    vpmovqd %zmm0, %ymm0
1602; AVX512BW-NEXT:    vpmulld %xmm1, %xmm0, %xmm0
1603; AVX512BW-NEXT:    vzeroupper
1604; AVX512BW-NEXT:    retq
1605;
1606; AVX512DQ-LABEL: trunc_mul_v4i64_v4i32:
1607; AVX512DQ:       # %bb.0:
1608; AVX512DQ-NEXT:    # kill: def $ymm1 killed $ymm1 def $zmm1
1609; AVX512DQ-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
1610; AVX512DQ-NEXT:    vpmullq %zmm1, %zmm0, %zmm0
1611; AVX512DQ-NEXT:    vpmovqd %zmm0, %ymm0
1612; AVX512DQ-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
1613; AVX512DQ-NEXT:    vzeroupper
1614; AVX512DQ-NEXT:    retq
1615  %1 = mul <4 x i64> %a0, %a1
1616  %2 = trunc <4 x i64> %1 to <4 x i32>
1617  ret <4 x i32> %2
1618}
1619
1620define <8 x i16> @trunc_mul_v8i64_v8i16(<8 x i64> %a0, <8 x i64> %a1) nounwind {
1621; SSE-LABEL: trunc_mul_v8i64_v8i16:
1622; SSE:       # %bb.0:
1623; SSE-NEXT:    pshufd {{.*#+}} xmm5 = xmm5[0,2,2,3]
1624; SSE-NEXT:    pshuflw {{.*#+}} xmm5 = xmm5[0,2,2,3,4,5,6,7]
1625; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm4[0,2,2,3]
1626; SSE-NEXT:    pshuflw {{.*#+}} xmm4 = xmm4[0,2,2,3,4,5,6,7]
1627; SSE-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm5[0],xmm4[1],xmm5[1]
1628; SSE-NEXT:    pshufd {{.*#+}} xmm5 = xmm7[0,2,2,3]
1629; SSE-NEXT:    pshuflw {{.*#+}} xmm5 = xmm5[0,1,0,2,4,5,6,7]
1630; SSE-NEXT:    pshufd {{.*#+}} xmm6 = xmm6[0,2,2,3]
1631; SSE-NEXT:    pshuflw {{.*#+}} xmm6 = xmm6[0,1,0,2,4,5,6,7]
1632; SSE-NEXT:    punpckldq {{.*#+}} xmm6 = xmm6[0],xmm5[0],xmm6[1],xmm5[1]
1633; SSE-NEXT:    movsd {{.*#+}} xmm6 = xmm4[0],xmm6[1]
1634; SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
1635; SSE-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,2,2,3,4,5,6,7]
1636; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
1637; SSE-NEXT:    pshuflw {{.*#+}} xmm4 = xmm0[0,2,2,3,4,5,6,7]
1638; SSE-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
1639; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[0,2,2,3]
1640; SSE-NEXT:    pshuflw {{.*#+}} xmm1 = xmm0[0,1,0,2,4,5,6,7]
1641; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3]
1642; SSE-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,1,0,2,4,5,6,7]
1643; SSE-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
1644; SSE-NEXT:    movsd {{.*#+}} xmm0 = xmm4[0],xmm0[1]
1645; SSE-NEXT:    pmullw %xmm6, %xmm0
1646; SSE-NEXT:    retq
1647;
1648; AVX1-LABEL: trunc_mul_v8i64_v8i16:
1649; AVX1:       # %bb.0:
1650; AVX1-NEXT:    vmovaps {{.*#+}} ymm4 = [65535,65535,65535,65535]
1651; AVX1-NEXT:    vandps %ymm4, %ymm3, %ymm3
1652; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm5
1653; AVX1-NEXT:    vpackusdw %xmm5, %xmm3, %xmm3
1654; AVX1-NEXT:    vandps %ymm4, %ymm2, %ymm2
1655; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm5
1656; AVX1-NEXT:    vpackusdw %xmm5, %xmm2, %xmm2
1657; AVX1-NEXT:    vpackusdw %xmm3, %xmm2, %xmm2
1658; AVX1-NEXT:    vandps %ymm4, %ymm1, %ymm1
1659; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
1660; AVX1-NEXT:    vpackusdw %xmm3, %xmm1, %xmm1
1661; AVX1-NEXT:    vandps %ymm4, %ymm0, %ymm0
1662; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
1663; AVX1-NEXT:    vpackusdw %xmm3, %xmm0, %xmm0
1664; AVX1-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
1665; AVX1-NEXT:    vpmullw %xmm2, %xmm0, %xmm0
1666; AVX1-NEXT:    vzeroupper
1667; AVX1-NEXT:    retq
1668;
1669; AVX2-LABEL: trunc_mul_v8i64_v8i16:
1670; AVX2:       # %bb.0:
1671; AVX2-NEXT:    vpxor %xmm4, %xmm4, %xmm4
1672; AVX2-NEXT:    vpblendw {{.*#+}} ymm3 = ymm3[0],ymm4[1,2,3],ymm3[4],ymm4[5,6,7],ymm3[8],ymm4[9,10,11],ymm3[12],ymm4[13,14,15]
1673; AVX2-NEXT:    vpblendw {{.*#+}} ymm2 = ymm2[0],ymm4[1,2,3],ymm2[4],ymm4[5,6,7],ymm2[8],ymm4[9,10,11],ymm2[12],ymm4[13,14,15]
1674; AVX2-NEXT:    vpackusdw %ymm3, %ymm2, %ymm2
1675; AVX2-NEXT:    vextracti128 $1, %ymm2, %xmm3
1676; AVX2-NEXT:    vpackusdw %xmm3, %xmm2, %xmm2
1677; AVX2-NEXT:    vpblendw {{.*#+}} ymm1 = ymm1[0],ymm4[1,2,3],ymm1[4],ymm4[5,6,7],ymm1[8],ymm4[9,10,11],ymm1[12],ymm4[13,14,15]
1678; AVX2-NEXT:    vpblendw {{.*#+}} ymm0 = ymm0[0],ymm4[1,2,3],ymm0[4],ymm4[5,6,7],ymm0[8],ymm4[9,10,11],ymm0[12],ymm4[13,14,15]
1679; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
1680; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
1681; AVX2-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
1682; AVX2-NEXT:    vpmullw %xmm2, %xmm0, %xmm0
1683; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
1684; AVX2-NEXT:    vzeroupper
1685; AVX2-NEXT:    retq
1686;
1687; AVX512F-LABEL: trunc_mul_v8i64_v8i16:
1688; AVX512F:       # %bb.0:
1689; AVX512F-NEXT:    vpmovqw %zmm1, %xmm1
1690; AVX512F-NEXT:    vpmovqw %zmm0, %xmm0
1691; AVX512F-NEXT:    vpmullw %xmm1, %xmm0, %xmm0
1692; AVX512F-NEXT:    vzeroupper
1693; AVX512F-NEXT:    retq
1694;
1695; AVX512BW-LABEL: trunc_mul_v8i64_v8i16:
1696; AVX512BW:       # %bb.0:
1697; AVX512BW-NEXT:    vpmovqw %zmm1, %xmm1
1698; AVX512BW-NEXT:    vpmovqw %zmm0, %xmm0
1699; AVX512BW-NEXT:    vpmullw %xmm1, %xmm0, %xmm0
1700; AVX512BW-NEXT:    vzeroupper
1701; AVX512BW-NEXT:    retq
1702;
1703; AVX512DQ-LABEL: trunc_mul_v8i64_v8i16:
1704; AVX512DQ:       # %bb.0:
1705; AVX512DQ-NEXT:    vpmullq %zmm1, %zmm0, %zmm0
1706; AVX512DQ-NEXT:    vpmovqw %zmm0, %xmm0
1707; AVX512DQ-NEXT:    vzeroupper
1708; AVX512DQ-NEXT:    retq
1709  %1 = mul <8 x i64> %a0, %a1
1710  %2 = trunc <8 x i64> %1 to <8 x i16>
1711  ret <8 x i16> %2
1712}
1713
1714define <8 x i16> @trunc_mul_v8i32_v8i16(<8 x i32> %a0, <8 x i32> %a1) nounwind {
1715; SSE-LABEL: trunc_mul_v8i32_v8i16:
1716; SSE:       # %bb.0:
1717; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm0[1,1,3,3]
1718; SSE-NEXT:    pmuludq %xmm2, %xmm0
1719; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
1720; SSE-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[1,1,3,3]
1721; SSE-NEXT:    pmuludq %xmm4, %xmm2
1722; SSE-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[0,2,2,3]
1723; SSE-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
1724; SSE-NEXT:    pshufd {{.*#+}} xmm2 = xmm1[1,1,3,3]
1725; SSE-NEXT:    pmuludq %xmm3, %xmm1
1726; SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
1727; SSE-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[1,1,3,3]
1728; SSE-NEXT:    pmuludq %xmm2, %xmm3
1729; SSE-NEXT:    pshufd {{.*#+}} xmm2 = xmm3[0,2,2,3]
1730; SSE-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
1731; SSE-NEXT:    pslld $16, %xmm1
1732; SSE-NEXT:    psrad $16, %xmm1
1733; SSE-NEXT:    pslld $16, %xmm0
1734; SSE-NEXT:    psrad $16, %xmm0
1735; SSE-NEXT:    packssdw %xmm1, %xmm0
1736; SSE-NEXT:    retq
1737;
1738; AVX1-LABEL: trunc_mul_v8i32_v8i16:
1739; AVX1:       # %bb.0:
1740; AVX1-NEXT:    vpmulld %xmm1, %xmm0, %xmm2
1741; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm1
1742; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
1743; AVX1-NEXT:    vpmulld %xmm1, %xmm0, %xmm0
1744; AVX1-NEXT:    vmovdqa {{.*#+}} xmm1 = <0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u>
1745; AVX1-NEXT:    vpshufb %xmm1, %xmm0, %xmm0
1746; AVX1-NEXT:    vpshufb %xmm1, %xmm2, %xmm1
1747; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0]
1748; AVX1-NEXT:    vzeroupper
1749; AVX1-NEXT:    retq
1750;
1751; AVX2-LABEL: trunc_mul_v8i32_v8i16:
1752; AVX2:       # %bb.0:
1753; AVX2-NEXT:    vpmulld %ymm1, %ymm0, %ymm0
1754; AVX2-NEXT:    vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u,16,17,20,21,24,25,28,29,u,u,u,u,u,u,u,u]
1755; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
1756; AVX2-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
1757; AVX2-NEXT:    vzeroupper
1758; AVX2-NEXT:    retq
1759;
1760; AVX512-LABEL: trunc_mul_v8i32_v8i16:
1761; AVX512:       # %bb.0:
1762; AVX512-NEXT:    vpmulld %ymm1, %ymm0, %ymm0
1763; AVX512-NEXT:    vpmovdw %zmm0, %ymm0
1764; AVX512-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
1765; AVX512-NEXT:    vzeroupper
1766; AVX512-NEXT:    retq
1767  %1 = mul <8 x i32> %a0, %a1
1768  %2 = trunc <8 x i32> %1 to <8 x i16>
1769  ret <8 x i16> %2
1770}
1771
1772define <16 x i8> @trunc_mul_v16i64_v16i8(<16 x i64> %a0, <16 x i64> %a1) nounwind {
1773; SSE-LABEL: trunc_mul_v16i64_v16i8:
1774; SSE:       # %bb.0:
1775; SSE-NEXT:    pmuludq {{[0-9]+}}(%rsp), %xmm0
1776; SSE-NEXT:    pmuludq {{[0-9]+}}(%rsp), %xmm1
1777; SSE-NEXT:    pmuludq {{[0-9]+}}(%rsp), %xmm2
1778; SSE-NEXT:    pmuludq {{[0-9]+}}(%rsp), %xmm3
1779; SSE-NEXT:    pmuludq {{[0-9]+}}(%rsp), %xmm4
1780; SSE-NEXT:    pmuludq {{[0-9]+}}(%rsp), %xmm5
1781; SSE-NEXT:    pmuludq {{[0-9]+}}(%rsp), %xmm6
1782; SSE-NEXT:    pmuludq {{[0-9]+}}(%rsp), %xmm7
1783; SSE-NEXT:    movdqa {{.*#+}} xmm8 = [255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0]
1784; SSE-NEXT:    pand %xmm8, %xmm7
1785; SSE-NEXT:    pand %xmm8, %xmm6
1786; SSE-NEXT:    packuswb %xmm7, %xmm6
1787; SSE-NEXT:    pand %xmm8, %xmm5
1788; SSE-NEXT:    pand %xmm8, %xmm4
1789; SSE-NEXT:    packuswb %xmm5, %xmm4
1790; SSE-NEXT:    packuswb %xmm6, %xmm4
1791; SSE-NEXT:    pand %xmm8, %xmm3
1792; SSE-NEXT:    pand %xmm8, %xmm2
1793; SSE-NEXT:    packuswb %xmm3, %xmm2
1794; SSE-NEXT:    pand %xmm8, %xmm1
1795; SSE-NEXT:    pand %xmm8, %xmm0
1796; SSE-NEXT:    packuswb %xmm1, %xmm0
1797; SSE-NEXT:    packuswb %xmm2, %xmm0
1798; SSE-NEXT:    packuswb %xmm4, %xmm0
1799; SSE-NEXT:    retq
1800;
1801; AVX1-LABEL: trunc_mul_v16i64_v16i8:
1802; AVX1:       # %bb.0:
1803; AVX1-NEXT:    vpmuludq %xmm4, %xmm0, %xmm8
1804; AVX1-NEXT:    vextractf128 $1, %ymm4, %xmm4
1805; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
1806; AVX1-NEXT:    vpmuludq %xmm4, %xmm0, %xmm0
1807; AVX1-NEXT:    vpmuludq %xmm5, %xmm1, %xmm4
1808; AVX1-NEXT:    vextractf128 $1, %ymm5, %xmm5
1809; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm1
1810; AVX1-NEXT:    vpmuludq %xmm5, %xmm1, %xmm1
1811; AVX1-NEXT:    vpmuludq %xmm6, %xmm2, %xmm5
1812; AVX1-NEXT:    vextractf128 $1, %ymm6, %xmm6
1813; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm2
1814; AVX1-NEXT:    vpmuludq %xmm6, %xmm2, %xmm2
1815; AVX1-NEXT:    vpmuludq %xmm7, %xmm3, %xmm6
1816; AVX1-NEXT:    vextractf128 $1, %ymm7, %xmm7
1817; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm3
1818; AVX1-NEXT:    vpmuludq %xmm7, %xmm3, %xmm3
1819; AVX1-NEXT:    vmovdqa {{.*#+}} xmm7 = [255,255]
1820; AVX1-NEXT:    vpand %xmm7, %xmm3, %xmm3
1821; AVX1-NEXT:    vpand %xmm7, %xmm6, %xmm6
1822; AVX1-NEXT:    vpackusdw %xmm3, %xmm6, %xmm3
1823; AVX1-NEXT:    vpand %xmm7, %xmm2, %xmm2
1824; AVX1-NEXT:    vpand %xmm7, %xmm5, %xmm5
1825; AVX1-NEXT:    vpackusdw %xmm2, %xmm5, %xmm2
1826; AVX1-NEXT:    vpackusdw %xmm3, %xmm2, %xmm2
1827; AVX1-NEXT:    vpand %xmm7, %xmm1, %xmm1
1828; AVX1-NEXT:    vpand %xmm7, %xmm4, %xmm3
1829; AVX1-NEXT:    vpackusdw %xmm1, %xmm3, %xmm1
1830; AVX1-NEXT:    vpand %xmm7, %xmm0, %xmm0
1831; AVX1-NEXT:    vpand %xmm7, %xmm8, %xmm3
1832; AVX1-NEXT:    vpackusdw %xmm0, %xmm3, %xmm0
1833; AVX1-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
1834; AVX1-NEXT:    vpackuswb %xmm2, %xmm0, %xmm0
1835; AVX1-NEXT:    vzeroupper
1836; AVX1-NEXT:    retq
1837;
1838; AVX2-LABEL: trunc_mul_v16i64_v16i8:
1839; AVX2:       # %bb.0:
1840; AVX2-NEXT:    vpmuludq %ymm4, %ymm0, %ymm0
1841; AVX2-NEXT:    vpmuludq %ymm5, %ymm1, %ymm1
1842; AVX2-NEXT:    vpmuludq %ymm6, %ymm2, %ymm2
1843; AVX2-NEXT:    vpmuludq %ymm7, %ymm3, %ymm3
1844; AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm4 = [255,255,255,255]
1845; AVX2-NEXT:    vpand %ymm4, %ymm3, %ymm3
1846; AVX2-NEXT:    vpand %ymm4, %ymm2, %ymm2
1847; AVX2-NEXT:    vpackusdw %ymm3, %ymm2, %ymm2
1848; AVX2-NEXT:    vpermq {{.*#+}} ymm2 = ymm2[0,2,1,3]
1849; AVX2-NEXT:    vpand %ymm4, %ymm1, %ymm1
1850; AVX2-NEXT:    vpand %ymm4, %ymm0, %ymm0
1851; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
1852; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3]
1853; AVX2-NEXT:    vpackusdw %ymm2, %ymm0, %ymm0
1854; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
1855; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
1856; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
1857; AVX2-NEXT:    vzeroupper
1858; AVX2-NEXT:    retq
1859;
1860; AVX512F-LABEL: trunc_mul_v16i64_v16i8:
1861; AVX512F:       # %bb.0:
1862; AVX512F-NEXT:    vpmuludq %zmm2, %zmm0, %zmm0
1863; AVX512F-NEXT:    vpmuludq %zmm3, %zmm1, %zmm1
1864; AVX512F-NEXT:    vpmovqb %zmm1, %xmm1
1865; AVX512F-NEXT:    vpmovqb %zmm0, %xmm0
1866; AVX512F-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1867; AVX512F-NEXT:    vzeroupper
1868; AVX512F-NEXT:    retq
1869;
1870; AVX512BW-LABEL: trunc_mul_v16i64_v16i8:
1871; AVX512BW:       # %bb.0:
1872; AVX512BW-NEXT:    vpmuludq %zmm2, %zmm0, %zmm0
1873; AVX512BW-NEXT:    vpmuludq %zmm3, %zmm1, %zmm1
1874; AVX512BW-NEXT:    vpmovqb %zmm1, %xmm1
1875; AVX512BW-NEXT:    vpmovqb %zmm0, %xmm0
1876; AVX512BW-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1877; AVX512BW-NEXT:    vzeroupper
1878; AVX512BW-NEXT:    retq
1879;
1880; AVX512DQ-LABEL: trunc_mul_v16i64_v16i8:
1881; AVX512DQ:       # %bb.0:
1882; AVX512DQ-NEXT:    vpmullq %zmm2, %zmm0, %zmm0
1883; AVX512DQ-NEXT:    vpmullq %zmm3, %zmm1, %zmm1
1884; AVX512DQ-NEXT:    vpmovqb %zmm1, %xmm1
1885; AVX512DQ-NEXT:    vpmovqb %zmm0, %xmm0
1886; AVX512DQ-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1887; AVX512DQ-NEXT:    vzeroupper
1888; AVX512DQ-NEXT:    retq
1889  %1 = mul <16 x i64> %a0, %a1
1890  %2 = trunc <16 x i64> %1 to <16 x i8>
1891  ret <16 x i8> %2
1892}
1893
1894define <16 x i8> @trunc_mul_v16i32_v16i8(<16 x i32> %a0, <16 x i32> %a1) nounwind {
1895; SSE-LABEL: trunc_mul_v16i32_v16i8:
1896; SSE:       # %bb.0:
1897; SSE-NEXT:    pshufd {{.*#+}} xmm8 = xmm0[1,1,3,3]
1898; SSE-NEXT:    pmuludq %xmm4, %xmm0
1899; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
1900; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm4[1,1,3,3]
1901; SSE-NEXT:    pmuludq %xmm8, %xmm4
1902; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm4[0,2,2,3]
1903; SSE-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm4[0],xmm0[1],xmm4[1]
1904; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm1[1,1,3,3]
1905; SSE-NEXT:    pmuludq %xmm5, %xmm1
1906; SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
1907; SSE-NEXT:    pshufd {{.*#+}} xmm5 = xmm5[1,1,3,3]
1908; SSE-NEXT:    pmuludq %xmm4, %xmm5
1909; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm5[0,2,2,3]
1910; SSE-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm4[0],xmm1[1],xmm4[1]
1911; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm2[1,1,3,3]
1912; SSE-NEXT:    pmuludq %xmm6, %xmm2
1913; SSE-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[0,2,2,3]
1914; SSE-NEXT:    pshufd {{.*#+}} xmm5 = xmm6[1,1,3,3]
1915; SSE-NEXT:    pmuludq %xmm4, %xmm5
1916; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm5[0,2,2,3]
1917; SSE-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm4[0],xmm2[1],xmm4[1]
1918; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm3[1,1,3,3]
1919; SSE-NEXT:    pmuludq %xmm7, %xmm3
1920; SSE-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[0,2,2,3]
1921; SSE-NEXT:    pshufd {{.*#+}} xmm5 = xmm7[1,1,3,3]
1922; SSE-NEXT:    pmuludq %xmm4, %xmm5
1923; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm5[0,2,2,3]
1924; SSE-NEXT:    punpckldq {{.*#+}} xmm3 = xmm3[0],xmm4[0],xmm3[1],xmm4[1]
1925; SSE-NEXT:    movdqa {{.*#+}} xmm4 = [255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0]
1926; SSE-NEXT:    pand %xmm4, %xmm3
1927; SSE-NEXT:    pand %xmm4, %xmm2
1928; SSE-NEXT:    packuswb %xmm3, %xmm2
1929; SSE-NEXT:    pand %xmm4, %xmm1
1930; SSE-NEXT:    pand %xmm4, %xmm0
1931; SSE-NEXT:    packuswb %xmm1, %xmm0
1932; SSE-NEXT:    packuswb %xmm2, %xmm0
1933; SSE-NEXT:    retq
1934;
1935; AVX1-LABEL: trunc_mul_v16i32_v16i8:
1936; AVX1:       # %bb.0:
1937; AVX1-NEXT:    vpmulld %xmm2, %xmm0, %xmm4
1938; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm2
1939; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
1940; AVX1-NEXT:    vpmulld %xmm2, %xmm0, %xmm0
1941; AVX1-NEXT:    vpmulld %xmm3, %xmm1, %xmm2
1942; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm3
1943; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm1
1944; AVX1-NEXT:    vpmulld %xmm3, %xmm1, %xmm1
1945; AVX1-NEXT:    vmovdqa {{.*#+}} xmm3 = [255,255,255,255]
1946; AVX1-NEXT:    vpand %xmm3, %xmm1, %xmm1
1947; AVX1-NEXT:    vpand %xmm3, %xmm2, %xmm2
1948; AVX1-NEXT:    vpackusdw %xmm1, %xmm2, %xmm1
1949; AVX1-NEXT:    vpand %xmm3, %xmm0, %xmm0
1950; AVX1-NEXT:    vpand %xmm3, %xmm4, %xmm2
1951; AVX1-NEXT:    vpackusdw %xmm0, %xmm2, %xmm0
1952; AVX1-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
1953; AVX1-NEXT:    vzeroupper
1954; AVX1-NEXT:    retq
1955;
1956; AVX2-LABEL: trunc_mul_v16i32_v16i8:
1957; AVX2:       # %bb.0:
1958; AVX2-NEXT:    vpmulld %ymm2, %ymm0, %ymm0
1959; AVX2-NEXT:    vpmulld %ymm3, %ymm1, %ymm1
1960; AVX2-NEXT:    vpbroadcastd {{.*#+}} ymm2 = [255,255,255,255,255,255,255,255]
1961; AVX2-NEXT:    vpand %ymm2, %ymm1, %ymm1
1962; AVX2-NEXT:    vpand %ymm2, %ymm0, %ymm0
1963; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
1964; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
1965; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
1966; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
1967; AVX2-NEXT:    vzeroupper
1968; AVX2-NEXT:    retq
1969;
1970; AVX512-LABEL: trunc_mul_v16i32_v16i8:
1971; AVX512:       # %bb.0:
1972; AVX512-NEXT:    vpmulld %zmm1, %zmm0, %zmm0
1973; AVX512-NEXT:    vpmovdb %zmm0, %xmm0
1974; AVX512-NEXT:    vzeroupper
1975; AVX512-NEXT:    retq
1976  %1 = mul <16 x i32> %a0, %a1
1977  %2 = trunc <16 x i32> %1 to <16 x i8>
1978  ret <16 x i8> %2
1979}
1980
1981define <16 x i8> @trunc_mul_v16i16_v16i8(<16 x i16> %a0, <16 x i16> %a1) nounwind {
1982; SSE-LABEL: trunc_mul_v16i16_v16i8:
1983; SSE:       # %bb.0:
1984; SSE-NEXT:    pmullw %xmm2, %xmm0
1985; SSE-NEXT:    pmullw %xmm3, %xmm1
1986; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0]
1987; SSE-NEXT:    pand %xmm2, %xmm1
1988; SSE-NEXT:    pand %xmm2, %xmm0
1989; SSE-NEXT:    packuswb %xmm1, %xmm0
1990; SSE-NEXT:    retq
1991;
1992; AVX1-LABEL: trunc_mul_v16i16_v16i8:
1993; AVX1:       # %bb.0:
1994; AVX1-NEXT:    vpmullw %xmm1, %xmm0, %xmm2
1995; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm1
1996; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
1997; AVX1-NEXT:    vpmullw %xmm1, %xmm0, %xmm0
1998; AVX1-NEXT:    vmovdqa {{.*#+}} xmm1 = [255,255,255,255,255,255,255,255]
1999; AVX1-NEXT:    vpand %xmm1, %xmm0, %xmm0
2000; AVX1-NEXT:    vpand %xmm1, %xmm2, %xmm1
2001; AVX1-NEXT:    vpackuswb %xmm0, %xmm1, %xmm0
2002; AVX1-NEXT:    vzeroupper
2003; AVX1-NEXT:    retq
2004;
2005; AVX2-LABEL: trunc_mul_v16i16_v16i8:
2006; AVX2:       # %bb.0:
2007; AVX2-NEXT:    vpmullw %ymm1, %ymm0, %ymm0
2008; AVX2-NEXT:    vpand {{.*}}(%rip), %ymm0, %ymm0
2009; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
2010; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
2011; AVX2-NEXT:    vzeroupper
2012; AVX2-NEXT:    retq
2013;
2014; AVX512F-LABEL: trunc_mul_v16i16_v16i8:
2015; AVX512F:       # %bb.0:
2016; AVX512F-NEXT:    vpmullw %ymm1, %ymm0, %ymm0
2017; 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
2018; AVX512F-NEXT:    vpmovdb %zmm0, %xmm0
2019; AVX512F-NEXT:    vzeroupper
2020; AVX512F-NEXT:    retq
2021;
2022; AVX512BW-LABEL: trunc_mul_v16i16_v16i8:
2023; AVX512BW:       # %bb.0:
2024; AVX512BW-NEXT:    vpmullw %ymm1, %ymm0, %ymm0
2025; AVX512BW-NEXT:    vpmovwb %zmm0, %ymm0
2026; AVX512BW-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
2027; AVX512BW-NEXT:    vzeroupper
2028; AVX512BW-NEXT:    retq
2029;
2030; AVX512DQ-LABEL: trunc_mul_v16i16_v16i8:
2031; AVX512DQ:       # %bb.0:
2032; AVX512DQ-NEXT:    vpmullw %ymm1, %ymm0, %ymm0
2033; AVX512DQ-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
2034; AVX512DQ-NEXT:    vpmovdb %zmm0, %xmm0
2035; AVX512DQ-NEXT:    vzeroupper
2036; AVX512DQ-NEXT:    retq
2037  %1 = mul <16 x i16> %a0, %a1
2038  %2 = trunc <16 x i16> %1 to <16 x i8>
2039  ret <16 x i8> %2
2040}
2041
2042define <8 x i16> @trunc_mul_v8i32_v8i16_zext_8i8(<16 x i8> %a0, <8 x i32> %a1) {
2043; SSE-LABEL: trunc_mul_v8i32_v8i16_zext_8i8:
2044; SSE:       # %bb.0:
2045; SSE-NEXT:    pxor %xmm3, %xmm3
2046; SSE-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1],xmm0[2],xmm3[2],xmm0[3],xmm3[3],xmm0[4],xmm3[4],xmm0[5],xmm3[5],xmm0[6],xmm3[6],xmm0[7],xmm3[7]
2047; SSE-NEXT:    pslld $16, %xmm2
2048; SSE-NEXT:    psrad $16, %xmm2
2049; SSE-NEXT:    pslld $16, %xmm1
2050; SSE-NEXT:    psrad $16, %xmm1
2051; SSE-NEXT:    packssdw %xmm2, %xmm1
2052; SSE-NEXT:    pmullw %xmm1, %xmm0
2053; SSE-NEXT:    retq
2054;
2055; AVX1-LABEL: trunc_mul_v8i32_v8i16_zext_8i8:
2056; AVX1:       # %bb.0:
2057; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
2058; AVX1-NEXT:    vmovdqa {{.*#+}} xmm3 = <0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u>
2059; AVX1-NEXT:    vpshufb %xmm3, %xmm2, %xmm2
2060; AVX1-NEXT:    vpshufb %xmm3, %xmm1, %xmm1
2061; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0]
2062; AVX1-NEXT:    vpmovzxbw {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero
2063; AVX1-NEXT:    vpmullw %xmm1, %xmm0, %xmm0
2064; AVX1-NEXT:    vzeroupper
2065; AVX1-NEXT:    retq
2066;
2067; AVX2-LABEL: trunc_mul_v8i32_v8i16_zext_8i8:
2068; AVX2:       # %bb.0:
2069; AVX2-NEXT:    vpmovzxbw {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero
2070; AVX2-NEXT:    vpshufb {{.*#+}} ymm1 = ymm1[0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u,16,17,20,21,24,25,28,29,u,u,u,u,u,u,u,u]
2071; AVX2-NEXT:    vpermq {{.*#+}} ymm1 = ymm1[0,2,2,3]
2072; AVX2-NEXT:    vpmullw %xmm1, %xmm0, %xmm0
2073; AVX2-NEXT:    vzeroupper
2074; AVX2-NEXT:    retq
2075;
2076; AVX512-LABEL: trunc_mul_v8i32_v8i16_zext_8i8:
2077; AVX512:       # %bb.0:
2078; AVX512-NEXT:    # kill: def $ymm1 killed $ymm1 def $zmm1
2079; AVX512-NEXT:    vpmovdw %zmm1, %ymm1
2080; AVX512-NEXT:    vpmovzxbw {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero
2081; AVX512-NEXT:    vpmullw %xmm1, %xmm0, %xmm0
2082; AVX512-NEXT:    vzeroupper
2083; AVX512-NEXT:    retq
2084  %1 = shufflevector <16 x i8> %a0, <16 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
2085  %2 = zext <8 x i8> %1 to <8 x i32>
2086  %3 = mul <8 x i32> %2, %a1
2087  %4 = trunc <8 x i32> %3 to <8 x i16>
2088  ret <8 x i16> %4
2089}
2090
2091;
2092; mul to constant
2093;
2094
2095define <4 x i32> @trunc_mul_const_v4i64_v4i32(<4 x i64> %a0) nounwind {
2096; SSE-LABEL: trunc_mul_const_v4i64_v4i32:
2097; SSE:       # %bb.0:
2098; SSE-NEXT:    xorps %xmm2, %xmm2
2099; SSE-NEXT:    unpckhpd {{.*#+}} xmm2 = xmm2[1],xmm0[1]
2100; SSE-NEXT:    pmuludq {{.*}}(%rip), %xmm1
2101; SSE-NEXT:    shufps {{.*#+}} xmm2 = xmm2[0,2],xmm1[0,2]
2102; SSE-NEXT:    movaps %xmm2, %xmm0
2103; SSE-NEXT:    retq
2104;
2105; AVX1-LABEL: trunc_mul_const_v4i64_v4i32:
2106; AVX1:       # %bb.0:
2107; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
2108; AVX1-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
2109; AVX1-NEXT:    vpmulld {{.*}}(%rip), %xmm0, %xmm0
2110; AVX1-NEXT:    vzeroupper
2111; AVX1-NEXT:    retq
2112;
2113; AVX2-SLOW-LABEL: trunc_mul_const_v4i64_v4i32:
2114; AVX2-SLOW:       # %bb.0:
2115; AVX2-SLOW-NEXT:    vextractf128 $1, %ymm0, %xmm1
2116; AVX2-SLOW-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
2117; AVX2-SLOW-NEXT:    vpmulld {{.*}}(%rip), %xmm0, %xmm0
2118; AVX2-SLOW-NEXT:    vzeroupper
2119; AVX2-SLOW-NEXT:    retq
2120;
2121; AVX2-FAST-LABEL: trunc_mul_const_v4i64_v4i32:
2122; AVX2-FAST:       # %bb.0:
2123; AVX2-FAST-NEXT:    vmovdqa {{.*#+}} ymm1 = <0,2,4,6,u,u,u,u>
2124; AVX2-FAST-NEXT:    vpermd %ymm0, %ymm1, %ymm0
2125; AVX2-FAST-NEXT:    vpmulld {{.*}}(%rip), %xmm0, %xmm0
2126; AVX2-FAST-NEXT:    vzeroupper
2127; AVX2-FAST-NEXT:    retq
2128;
2129; AVX512-LABEL: trunc_mul_const_v4i64_v4i32:
2130; AVX512:       # %bb.0:
2131; AVX512-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
2132; AVX512-NEXT:    vpmovqd %zmm0, %ymm0
2133; AVX512-NEXT:    vpmulld {{.*}}(%rip), %xmm0, %xmm0
2134; AVX512-NEXT:    vzeroupper
2135; AVX512-NEXT:    retq
2136  %1 = mul <4 x i64> %a0, <i64 0, i64 1, i64 2, i64 3>
2137  %2 = trunc <4 x i64> %1 to <4 x i32>
2138  ret <4 x i32> %2
2139}
2140
2141define <8 x i16> @trunc_mul_const_v8i64_v8i16(<8 x i64> %a0) nounwind {
2142; SSE-LABEL: trunc_mul_const_v8i64_v8i16:
2143; SSE:       # %bb.0:
2144; SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
2145; SSE-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,2,2,3,4,5,6,7]
2146; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
2147; SSE-NEXT:    pshuflw {{.*#+}} xmm4 = xmm0[0,2,2,3,4,5,6,7]
2148; SSE-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
2149; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[0,2,2,3]
2150; SSE-NEXT:    pshuflw {{.*#+}} xmm1 = xmm0[0,1,0,2,4,5,6,7]
2151; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3]
2152; SSE-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,1,0,2,4,5,6,7]
2153; SSE-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
2154; SSE-NEXT:    movsd {{.*#+}} xmm0 = xmm4[0],xmm0[1]
2155; SSE-NEXT:    pmullw {{.*}}(%rip), %xmm0
2156; SSE-NEXT:    retq
2157;
2158; AVX1-LABEL: trunc_mul_const_v8i64_v8i16:
2159; AVX1:       # %bb.0:
2160; AVX1-NEXT:    vmovaps {{.*#+}} ymm2 = [65535,65535,65535,65535]
2161; AVX1-NEXT:    vandps %ymm2, %ymm1, %ymm1
2162; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
2163; AVX1-NEXT:    vpackusdw %xmm3, %xmm1, %xmm1
2164; AVX1-NEXT:    vandps %ymm2, %ymm0, %ymm0
2165; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
2166; AVX1-NEXT:    vpackusdw %xmm2, %xmm0, %xmm0
2167; AVX1-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
2168; AVX1-NEXT:    vpmullw {{.*}}(%rip), %xmm0, %xmm0
2169; AVX1-NEXT:    vzeroupper
2170; AVX1-NEXT:    retq
2171;
2172; AVX2-LABEL: trunc_mul_const_v8i64_v8i16:
2173; AVX2:       # %bb.0:
2174; AVX2-NEXT:    vpxor %xmm2, %xmm2, %xmm2
2175; AVX2-NEXT:    vpblendw {{.*#+}} ymm1 = ymm1[0],ymm2[1,2,3],ymm1[4],ymm2[5,6,7],ymm1[8],ymm2[9,10,11],ymm1[12],ymm2[13,14,15]
2176; AVX2-NEXT:    vpblendw {{.*#+}} ymm0 = ymm0[0],ymm2[1,2,3],ymm0[4],ymm2[5,6,7],ymm0[8],ymm2[9,10,11],ymm0[12],ymm2[13,14,15]
2177; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
2178; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
2179; AVX2-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
2180; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
2181; AVX2-NEXT:    vpmullw {{.*}}(%rip), %xmm0, %xmm0
2182; AVX2-NEXT:    vzeroupper
2183; AVX2-NEXT:    retq
2184;
2185; AVX512-LABEL: trunc_mul_const_v8i64_v8i16:
2186; AVX512:       # %bb.0:
2187; AVX512-NEXT:    vpmovqw %zmm0, %xmm0
2188; AVX512-NEXT:    vpmullw {{.*}}(%rip), %xmm0, %xmm0
2189; AVX512-NEXT:    vzeroupper
2190; AVX512-NEXT:    retq
2191  %1 = mul <8 x i64> %a0, <i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7>
2192  %2 = trunc <8 x i64> %1 to <8 x i16>
2193  ret <8 x i16> %2
2194}
2195
2196define <8 x i16> @trunc_mul_const_v8i32_v8i16(<8 x i32> %a0) nounwind {
2197; SSE-LABEL: trunc_mul_const_v8i32_v8i16:
2198; SSE:       # %bb.0:
2199; SSE-NEXT:    pslld $16, %xmm1
2200; SSE-NEXT:    psrad $16, %xmm1
2201; SSE-NEXT:    pslld $16, %xmm0
2202; SSE-NEXT:    psrad $16, %xmm0
2203; SSE-NEXT:    packssdw %xmm1, %xmm0
2204; SSE-NEXT:    pmullw {{.*}}(%rip), %xmm0
2205; SSE-NEXT:    retq
2206;
2207; AVX1-LABEL: trunc_mul_const_v8i32_v8i16:
2208; AVX1:       # %bb.0:
2209; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
2210; AVX1-NEXT:    vmovdqa {{.*#+}} xmm2 = <0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u>
2211; AVX1-NEXT:    vpshufb %xmm2, %xmm1, %xmm1
2212; AVX1-NEXT:    vpshufb %xmm2, %xmm0, %xmm0
2213; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
2214; AVX1-NEXT:    vpmullw {{.*}}(%rip), %xmm0, %xmm0
2215; AVX1-NEXT:    vzeroupper
2216; AVX1-NEXT:    retq
2217;
2218; AVX2-LABEL: trunc_mul_const_v8i32_v8i16:
2219; AVX2:       # %bb.0:
2220; AVX2-NEXT:    vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u,16,17,20,21,24,25,28,29,u,u,u,u,u,u,u,u]
2221; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
2222; AVX2-NEXT:    vpmullw {{.*}}(%rip), %xmm0, %xmm0
2223; AVX2-NEXT:    vzeroupper
2224; AVX2-NEXT:    retq
2225;
2226; AVX512-LABEL: trunc_mul_const_v8i32_v8i16:
2227; AVX512:       # %bb.0:
2228; AVX512-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
2229; AVX512-NEXT:    vpmovdw %zmm0, %ymm0
2230; AVX512-NEXT:    vpmullw {{.*}}(%rip), %xmm0, %xmm0
2231; AVX512-NEXT:    vzeroupper
2232; AVX512-NEXT:    retq
2233  %1 = mul <8 x i32> %a0, <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
2234  %2 = trunc <8 x i32> %1 to <8 x i16>
2235  ret <8 x i16> %2
2236}
2237
2238define <16 x i8> @trunc_mul_const_v16i64_v16i8(<16 x i64> %a0) nounwind {
2239; SSE-LABEL: trunc_mul_const_v16i64_v16i8:
2240; SSE:       # %bb.0:
2241; SSE-NEXT:    pmuludq {{.*}}(%rip), %xmm1
2242; SSE-NEXT:    pmuludq {{.*}}(%rip), %xmm2
2243; SSE-NEXT:    pmuludq {{.*}}(%rip), %xmm3
2244; SSE-NEXT:    pmuludq {{.*}}(%rip), %xmm4
2245; SSE-NEXT:    pmuludq {{.*}}(%rip), %xmm5
2246; SSE-NEXT:    pmuludq {{.*}}(%rip), %xmm6
2247; SSE-NEXT:    pmuludq {{.*}}(%rip), %xmm7
2248; SSE-NEXT:    movdqa {{.*#+}} xmm8 = [255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0]
2249; SSE-NEXT:    pand %xmm8, %xmm7
2250; SSE-NEXT:    pand %xmm8, %xmm6
2251; SSE-NEXT:    packuswb %xmm7, %xmm6
2252; SSE-NEXT:    pand %xmm8, %xmm5
2253; SSE-NEXT:    pand %xmm8, %xmm4
2254; SSE-NEXT:    packuswb %xmm5, %xmm4
2255; SSE-NEXT:    packuswb %xmm6, %xmm4
2256; SSE-NEXT:    pand %xmm8, %xmm3
2257; SSE-NEXT:    pand %xmm8, %xmm2
2258; SSE-NEXT:    packuswb %xmm3, %xmm2
2259; SSE-NEXT:    pand %xmm8, %xmm1
2260; SSE-NEXT:    pand {{.*}}(%rip), %xmm0
2261; SSE-NEXT:    packuswb %xmm1, %xmm0
2262; SSE-NEXT:    packuswb %xmm2, %xmm0
2263; SSE-NEXT:    packuswb %xmm4, %xmm0
2264; SSE-NEXT:    retq
2265;
2266; AVX1-LABEL: trunc_mul_const_v16i64_v16i8:
2267; AVX1:       # %bb.0:
2268; AVX1-NEXT:    vpmuludq {{.*}}(%rip), %xmm0, %xmm8
2269; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
2270; AVX1-NEXT:    vpmuludq {{.*}}(%rip), %xmm0, %xmm0
2271; AVX1-NEXT:    vpmuludq {{.*}}(%rip), %xmm1, %xmm5
2272; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm1
2273; AVX1-NEXT:    vpmuludq {{.*}}(%rip), %xmm1, %xmm1
2274; AVX1-NEXT:    vpmuludq {{.*}}(%rip), %xmm2, %xmm6
2275; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm2
2276; AVX1-NEXT:    vpmuludq {{.*}}(%rip), %xmm2, %xmm2
2277; AVX1-NEXT:    vpmuludq {{.*}}(%rip), %xmm3, %xmm7
2278; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm3
2279; AVX1-NEXT:    vpmuludq {{.*}}(%rip), %xmm3, %xmm3
2280; AVX1-NEXT:    vmovdqa {{.*#+}} xmm4 = [255,255]
2281; AVX1-NEXT:    vpand %xmm4, %xmm3, %xmm3
2282; AVX1-NEXT:    vpand %xmm4, %xmm7, %xmm7
2283; AVX1-NEXT:    vpackusdw %xmm3, %xmm7, %xmm3
2284; AVX1-NEXT:    vpand %xmm4, %xmm2, %xmm2
2285; AVX1-NEXT:    vpand %xmm4, %xmm6, %xmm6
2286; AVX1-NEXT:    vpackusdw %xmm2, %xmm6, %xmm2
2287; AVX1-NEXT:    vpackusdw %xmm3, %xmm2, %xmm2
2288; AVX1-NEXT:    vpand %xmm4, %xmm1, %xmm1
2289; AVX1-NEXT:    vpand %xmm4, %xmm5, %xmm3
2290; AVX1-NEXT:    vpackusdw %xmm1, %xmm3, %xmm1
2291; AVX1-NEXT:    vpand %xmm4, %xmm0, %xmm0
2292; AVX1-NEXT:    vpand %xmm4, %xmm8, %xmm3
2293; AVX1-NEXT:    vpackusdw %xmm0, %xmm3, %xmm0
2294; AVX1-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
2295; AVX1-NEXT:    vpackuswb %xmm2, %xmm0, %xmm0
2296; AVX1-NEXT:    vzeroupper
2297; AVX1-NEXT:    retq
2298;
2299; AVX2-LABEL: trunc_mul_const_v16i64_v16i8:
2300; AVX2:       # %bb.0:
2301; AVX2-NEXT:    vpmuludq {{.*}}(%rip), %ymm0, %ymm0
2302; AVX2-NEXT:    vpmuludq {{.*}}(%rip), %ymm1, %ymm1
2303; AVX2-NEXT:    vpmuludq {{.*}}(%rip), %ymm2, %ymm2
2304; AVX2-NEXT:    vpmuludq {{.*}}(%rip), %ymm3, %ymm3
2305; AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm4 = [255,255,255,255]
2306; AVX2-NEXT:    vpand %ymm4, %ymm3, %ymm3
2307; AVX2-NEXT:    vpand %ymm4, %ymm2, %ymm2
2308; AVX2-NEXT:    vpackusdw %ymm3, %ymm2, %ymm2
2309; AVX2-NEXT:    vpermq {{.*#+}} ymm2 = ymm2[0,2,1,3]
2310; AVX2-NEXT:    vpand %ymm4, %ymm1, %ymm1
2311; AVX2-NEXT:    vpand %ymm4, %ymm0, %ymm0
2312; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
2313; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3]
2314; AVX2-NEXT:    vpackusdw %ymm2, %ymm0, %ymm0
2315; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
2316; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
2317; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
2318; AVX2-NEXT:    vzeroupper
2319; AVX2-NEXT:    retq
2320;
2321; AVX512F-LABEL: trunc_mul_const_v16i64_v16i8:
2322; AVX512F:       # %bb.0:
2323; AVX512F-NEXT:    vpmuludq {{.*}}(%rip), %zmm0, %zmm0
2324; AVX512F-NEXT:    vpmuludq {{.*}}(%rip), %zmm1, %zmm1
2325; AVX512F-NEXT:    vpmovqb %zmm1, %xmm1
2326; AVX512F-NEXT:    vpmovqb %zmm0, %xmm0
2327; AVX512F-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
2328; AVX512F-NEXT:    vzeroupper
2329; AVX512F-NEXT:    retq
2330;
2331; AVX512BW-LABEL: trunc_mul_const_v16i64_v16i8:
2332; AVX512BW:       # %bb.0:
2333; AVX512BW-NEXT:    vpmuludq {{.*}}(%rip), %zmm0, %zmm0
2334; AVX512BW-NEXT:    vpmuludq {{.*}}(%rip), %zmm1, %zmm1
2335; AVX512BW-NEXT:    vpmovqb %zmm1, %xmm1
2336; AVX512BW-NEXT:    vpmovqb %zmm0, %xmm0
2337; AVX512BW-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
2338; AVX512BW-NEXT:    vzeroupper
2339; AVX512BW-NEXT:    retq
2340;
2341; AVX512DQ-LABEL: trunc_mul_const_v16i64_v16i8:
2342; AVX512DQ:       # %bb.0:
2343; AVX512DQ-NEXT:    vpmullq {{.*}}(%rip), %zmm0, %zmm0
2344; AVX512DQ-NEXT:    vpmullq {{.*}}(%rip), %zmm1, %zmm1
2345; AVX512DQ-NEXT:    vpmovqb %zmm1, %xmm1
2346; AVX512DQ-NEXT:    vpmovqb %zmm0, %xmm0
2347; AVX512DQ-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
2348; AVX512DQ-NEXT:    vzeroupper
2349; AVX512DQ-NEXT:    retq
2350  %1 = mul <16 x i64> %a0, <i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, i64 9, i64 10, i64 11, i64 12, i64 13, i64 14, i64 15>
2351  %2 = trunc <16 x i64> %1 to <16 x i8>
2352  ret <16 x i8> %2
2353}
2354
2355define <16 x i8> @trunc_mul_const_v16i32_v16i8(<16 x i32> %a0) nounwind {
2356; SSE-LABEL: trunc_mul_const_v16i32_v16i8:
2357; SSE:       # %bb.0:
2358; SSE-NEXT:    movdqa {{.*#+}} xmm4 = [0,1,2,3]
2359; SSE-NEXT:    pshufd {{.*#+}} xmm5 = xmm0[1,1,3,3]
2360; SSE-NEXT:    pmuludq %xmm4, %xmm0
2361; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
2362; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm4[1,1,3,3]
2363; SSE-NEXT:    pmuludq %xmm5, %xmm4
2364; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm4[0,2,2,3]
2365; SSE-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm4[0],xmm0[1],xmm4[1]
2366; SSE-NEXT:    movdqa {{.*#+}} xmm4 = [4,5,6,7]
2367; SSE-NEXT:    pshufd {{.*#+}} xmm5 = xmm1[1,1,3,3]
2368; SSE-NEXT:    pmuludq %xmm4, %xmm1
2369; SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
2370; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm4[1,1,3,3]
2371; SSE-NEXT:    pmuludq %xmm5, %xmm4
2372; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm4[0,2,2,3]
2373; SSE-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm4[0],xmm1[1],xmm4[1]
2374; SSE-NEXT:    movdqa {{.*#+}} xmm4 = [8,9,10,11]
2375; SSE-NEXT:    pshufd {{.*#+}} xmm5 = xmm2[1,1,3,3]
2376; SSE-NEXT:    pmuludq %xmm4, %xmm2
2377; SSE-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[0,2,2,3]
2378; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm4[1,1,3,3]
2379; SSE-NEXT:    pmuludq %xmm5, %xmm4
2380; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm4[0,2,2,3]
2381; SSE-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm4[0],xmm2[1],xmm4[1]
2382; SSE-NEXT:    movdqa {{.*#+}} xmm4 = [12,13,14,15]
2383; SSE-NEXT:    pshufd {{.*#+}} xmm5 = xmm3[1,1,3,3]
2384; SSE-NEXT:    pmuludq %xmm4, %xmm3
2385; SSE-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[0,2,2,3]
2386; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm4[1,1,3,3]
2387; SSE-NEXT:    pmuludq %xmm5, %xmm4
2388; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm4[0,2,2,3]
2389; SSE-NEXT:    punpckldq {{.*#+}} xmm3 = xmm3[0],xmm4[0],xmm3[1],xmm4[1]
2390; SSE-NEXT:    movdqa {{.*#+}} xmm4 = [255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0]
2391; SSE-NEXT:    pand %xmm4, %xmm3
2392; SSE-NEXT:    pand %xmm4, %xmm2
2393; SSE-NEXT:    packuswb %xmm3, %xmm2
2394; SSE-NEXT:    pand %xmm4, %xmm1
2395; SSE-NEXT:    pand %xmm4, %xmm0
2396; SSE-NEXT:    packuswb %xmm1, %xmm0
2397; SSE-NEXT:    packuswb %xmm2, %xmm0
2398; SSE-NEXT:    retq
2399;
2400; AVX1-LABEL: trunc_mul_const_v16i32_v16i8:
2401; AVX1:       # %bb.0:
2402; AVX1-NEXT:    vpmulld {{.*}}(%rip), %xmm0, %xmm2
2403; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
2404; AVX1-NEXT:    vpmulld {{.*}}(%rip), %xmm0, %xmm0
2405; AVX1-NEXT:    vpmulld {{.*}}(%rip), %xmm1, %xmm3
2406; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm1
2407; AVX1-NEXT:    vpmulld {{.*}}(%rip), %xmm1, %xmm1
2408; AVX1-NEXT:    vmovdqa {{.*#+}} xmm4 = [255,255,255,255]
2409; AVX1-NEXT:    vpand %xmm4, %xmm1, %xmm1
2410; AVX1-NEXT:    vpand %xmm4, %xmm3, %xmm3
2411; AVX1-NEXT:    vpackusdw %xmm1, %xmm3, %xmm1
2412; AVX1-NEXT:    vpand %xmm4, %xmm0, %xmm0
2413; AVX1-NEXT:    vpand %xmm4, %xmm2, %xmm2
2414; AVX1-NEXT:    vpackusdw %xmm0, %xmm2, %xmm0
2415; AVX1-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
2416; AVX1-NEXT:    vzeroupper
2417; AVX1-NEXT:    retq
2418;
2419; AVX2-LABEL: trunc_mul_const_v16i32_v16i8:
2420; AVX2:       # %bb.0:
2421; AVX2-NEXT:    vpmulld {{.*}}(%rip), %ymm0, %ymm0
2422; AVX2-NEXT:    vpmulld {{.*}}(%rip), %ymm1, %ymm1
2423; AVX2-NEXT:    vpbroadcastd {{.*#+}} ymm2 = [255,255,255,255,255,255,255,255]
2424; AVX2-NEXT:    vpand %ymm2, %ymm1, %ymm1
2425; AVX2-NEXT:    vpand %ymm2, %ymm0, %ymm0
2426; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
2427; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
2428; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
2429; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
2430; AVX2-NEXT:    vzeroupper
2431; AVX2-NEXT:    retq
2432;
2433; AVX512-LABEL: trunc_mul_const_v16i32_v16i8:
2434; AVX512:       # %bb.0:
2435; AVX512-NEXT:    vpmulld {{.*}}(%rip), %zmm0, %zmm0
2436; AVX512-NEXT:    vpmovdb %zmm0, %xmm0
2437; AVX512-NEXT:    vzeroupper
2438; AVX512-NEXT:    retq
2439  %1 = mul <16 x i32> %a0, <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>
2440  %2 = trunc <16 x i32> %1 to <16 x i8>
2441  ret <16 x i8> %2
2442}
2443
2444define <16 x i8> @trunc_mul_const_v16i16_v16i8(<16 x i16> %a0) nounwind {
2445; SSE-LABEL: trunc_mul_const_v16i16_v16i8:
2446; SSE:       # %bb.0:
2447; SSE-NEXT:    pmullw {{.*}}(%rip), %xmm0
2448; SSE-NEXT:    pmullw {{.*}}(%rip), %xmm1
2449; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0]
2450; SSE-NEXT:    pand %xmm2, %xmm1
2451; SSE-NEXT:    pand %xmm2, %xmm0
2452; SSE-NEXT:    packuswb %xmm1, %xmm0
2453; SSE-NEXT:    retq
2454;
2455; AVX1-LABEL: trunc_mul_const_v16i16_v16i8:
2456; AVX1:       # %bb.0:
2457; AVX1-NEXT:    vpmullw {{.*}}(%rip), %xmm0, %xmm1
2458; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
2459; AVX1-NEXT:    vpmullw {{.*}}(%rip), %xmm0, %xmm0
2460; AVX1-NEXT:    vmovdqa {{.*#+}} xmm2 = [255,255,255,255,255,255,255,255]
2461; AVX1-NEXT:    vpand %xmm2, %xmm0, %xmm0
2462; AVX1-NEXT:    vpand %xmm2, %xmm1, %xmm1
2463; AVX1-NEXT:    vpackuswb %xmm0, %xmm1, %xmm0
2464; AVX1-NEXT:    vzeroupper
2465; AVX1-NEXT:    retq
2466;
2467; AVX2-LABEL: trunc_mul_const_v16i16_v16i8:
2468; AVX2:       # %bb.0:
2469; AVX2-NEXT:    vpmullw {{.*}}(%rip), %ymm0, %ymm0
2470; AVX2-NEXT:    vpand {{.*}}(%rip), %ymm0, %ymm0
2471; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
2472; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
2473; AVX2-NEXT:    vzeroupper
2474; AVX2-NEXT:    retq
2475;
2476; AVX512F-LABEL: trunc_mul_const_v16i16_v16i8:
2477; AVX512F:       # %bb.0:
2478; AVX512F-NEXT:    vpmullw {{.*}}(%rip), %ymm0, %ymm0
2479; 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
2480; AVX512F-NEXT:    vpmovdb %zmm0, %xmm0
2481; AVX512F-NEXT:    vzeroupper
2482; AVX512F-NEXT:    retq
2483;
2484; AVX512BW-LABEL: trunc_mul_const_v16i16_v16i8:
2485; AVX512BW:       # %bb.0:
2486; AVX512BW-NEXT:    vpmullw {{.*}}(%rip), %ymm0, %ymm0
2487; AVX512BW-NEXT:    vpmovwb %zmm0, %ymm0
2488; AVX512BW-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
2489; AVX512BW-NEXT:    vzeroupper
2490; AVX512BW-NEXT:    retq
2491;
2492; AVX512DQ-LABEL: trunc_mul_const_v16i16_v16i8:
2493; AVX512DQ:       # %bb.0:
2494; AVX512DQ-NEXT:    vpmullw {{.*}}(%rip), %ymm0, %ymm0
2495; AVX512DQ-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
2496; AVX512DQ-NEXT:    vpmovdb %zmm0, %xmm0
2497; AVX512DQ-NEXT:    vzeroupper
2498; AVX512DQ-NEXT:    retq
2499  %1 = mul <16 x i16> %a0, <i16 0, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7, i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15>
2500  %2 = trunc <16 x i16> %1 to <16 x i8>
2501  ret <16 x i8> %2
2502}
2503
2504;
2505; and
2506;
2507
2508define <4 x i32> @trunc_and_v4i64_v4i32(<4 x i64> %a0, <4 x i64> %a1) nounwind {
2509; SSE-LABEL: trunc_and_v4i64_v4i32:
2510; SSE:       # %bb.0:
2511; SSE-NEXT:    andps %xmm3, %xmm1
2512; SSE-NEXT:    andps %xmm2, %xmm0
2513; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
2514; SSE-NEXT:    retq
2515;
2516; AVX1-LABEL: trunc_and_v4i64_v4i32:
2517; AVX1:       # %bb.0:
2518; AVX1-NEXT:    vandps %ymm1, %ymm0, %ymm0
2519; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
2520; AVX1-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
2521; AVX1-NEXT:    vzeroupper
2522; AVX1-NEXT:    retq
2523;
2524; AVX2-SLOW-LABEL: trunc_and_v4i64_v4i32:
2525; AVX2-SLOW:       # %bb.0:
2526; AVX2-SLOW-NEXT:    vandps %ymm1, %ymm0, %ymm0
2527; AVX2-SLOW-NEXT:    vextractf128 $1, %ymm0, %xmm1
2528; AVX2-SLOW-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
2529; AVX2-SLOW-NEXT:    vzeroupper
2530; AVX2-SLOW-NEXT:    retq
2531;
2532; AVX2-FAST-LABEL: trunc_and_v4i64_v4i32:
2533; AVX2-FAST:       # %bb.0:
2534; AVX2-FAST-NEXT:    vandps %ymm1, %ymm0, %ymm0
2535; AVX2-FAST-NEXT:    vmovaps {{.*#+}} ymm1 = <0,2,4,6,u,u,u,u>
2536; AVX2-FAST-NEXT:    vpermps %ymm0, %ymm1, %ymm0
2537; AVX2-FAST-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
2538; AVX2-FAST-NEXT:    vzeroupper
2539; AVX2-FAST-NEXT:    retq
2540;
2541; AVX512-LABEL: trunc_and_v4i64_v4i32:
2542; AVX512:       # %bb.0:
2543; AVX512-NEXT:    vpand %ymm1, %ymm0, %ymm0
2544; AVX512-NEXT:    vpmovqd %zmm0, %ymm0
2545; AVX512-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
2546; AVX512-NEXT:    vzeroupper
2547; AVX512-NEXT:    retq
2548  %1 = and <4 x i64> %a0, %a1
2549  %2 = trunc <4 x i64> %1 to <4 x i32>
2550  ret <4 x i32> %2
2551}
2552
2553define <8 x i16> @trunc_and_v8i64_v8i16(<8 x i64> %a0, <8 x i64> %a1) nounwind {
2554; SSE-LABEL: trunc_and_v8i64_v8i16:
2555; SSE:       # %bb.0:
2556; SSE-NEXT:    pand %xmm6, %xmm2
2557; SSE-NEXT:    pand %xmm7, %xmm3
2558; SSE-NEXT:    pand %xmm4, %xmm0
2559; SSE-NEXT:    pand %xmm5, %xmm1
2560; SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
2561; SSE-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,2,2,3,4,5,6,7]
2562; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
2563; SSE-NEXT:    pshuflw {{.*#+}} xmm4 = xmm0[0,2,2,3,4,5,6,7]
2564; SSE-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
2565; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[0,2,2,3]
2566; SSE-NEXT:    pshuflw {{.*#+}} xmm1 = xmm0[0,1,0,2,4,5,6,7]
2567; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3]
2568; SSE-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,1,0,2,4,5,6,7]
2569; SSE-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
2570; SSE-NEXT:    movsd {{.*#+}} xmm0 = xmm4[0],xmm0[1]
2571; SSE-NEXT:    retq
2572;
2573; AVX1-LABEL: trunc_and_v8i64_v8i16:
2574; AVX1:       # %bb.0:
2575; AVX1-NEXT:    vmovaps {{.*#+}} ymm4 = [65535,65535,65535,65535]
2576; AVX1-NEXT:    vandps %ymm4, %ymm3, %ymm3
2577; AVX1-NEXT:    vandps %ymm3, %ymm1, %ymm1
2578; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
2579; AVX1-NEXT:    vpackusdw %xmm3, %xmm1, %xmm1
2580; AVX1-NEXT:    vandps %ymm4, %ymm2, %ymm2
2581; AVX1-NEXT:    vandps %ymm2, %ymm0, %ymm0
2582; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
2583; AVX1-NEXT:    vpackusdw %xmm2, %xmm0, %xmm0
2584; AVX1-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
2585; AVX1-NEXT:    vzeroupper
2586; AVX1-NEXT:    retq
2587;
2588; AVX2-LABEL: trunc_and_v8i64_v8i16:
2589; AVX2:       # %bb.0:
2590; AVX2-NEXT:    vpand %ymm2, %ymm0, %ymm0
2591; AVX2-NEXT:    vpand %ymm3, %ymm1, %ymm1
2592; AVX2-NEXT:    vpxor %xmm2, %xmm2, %xmm2
2593; AVX2-NEXT:    vpblendw {{.*#+}} ymm1 = ymm1[0],ymm2[1,2,3],ymm1[4],ymm2[5,6,7],ymm1[8],ymm2[9,10,11],ymm1[12],ymm2[13,14,15]
2594; AVX2-NEXT:    vpblendw {{.*#+}} ymm0 = ymm0[0],ymm2[1,2,3],ymm0[4],ymm2[5,6,7],ymm0[8],ymm2[9,10,11],ymm0[12],ymm2[13,14,15]
2595; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
2596; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
2597; AVX2-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
2598; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
2599; AVX2-NEXT:    vzeroupper
2600; AVX2-NEXT:    retq
2601;
2602; AVX512-LABEL: trunc_and_v8i64_v8i16:
2603; AVX512:       # %bb.0:
2604; AVX512-NEXT:    vpandq %zmm1, %zmm0, %zmm0
2605; AVX512-NEXT:    vpmovqw %zmm0, %xmm0
2606; AVX512-NEXT:    vzeroupper
2607; AVX512-NEXT:    retq
2608  %1 = and <8 x i64> %a0, %a1
2609  %2 = trunc <8 x i64> %1 to <8 x i16>
2610  ret <8 x i16> %2
2611}
2612
2613define <8 x i16> @trunc_and_v8i32_v8i16(<8 x i32> %a0, <8 x i32> %a1) nounwind {
2614; SSE-LABEL: trunc_and_v8i32_v8i16:
2615; SSE:       # %bb.0:
2616; SSE-NEXT:    pand %xmm2, %xmm0
2617; SSE-NEXT:    pand %xmm3, %xmm1
2618; SSE-NEXT:    pslld $16, %xmm1
2619; SSE-NEXT:    psrad $16, %xmm1
2620; SSE-NEXT:    pslld $16, %xmm0
2621; SSE-NEXT:    psrad $16, %xmm0
2622; SSE-NEXT:    packssdw %xmm1, %xmm0
2623; SSE-NEXT:    retq
2624;
2625; AVX1-LABEL: trunc_and_v8i32_v8i16:
2626; AVX1:       # %bb.0:
2627; AVX1-NEXT:    vandps %ymm1, %ymm0, %ymm0
2628; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
2629; AVX1-NEXT:    vmovdqa {{.*#+}} xmm2 = <0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u>
2630; AVX1-NEXT:    vpshufb %xmm2, %xmm1, %xmm1
2631; AVX1-NEXT:    vpshufb %xmm2, %xmm0, %xmm0
2632; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
2633; AVX1-NEXT:    vzeroupper
2634; AVX1-NEXT:    retq
2635;
2636; AVX2-LABEL: trunc_and_v8i32_v8i16:
2637; AVX2:       # %bb.0:
2638; AVX2-NEXT:    vpand %ymm1, %ymm0, %ymm0
2639; AVX2-NEXT:    vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u,16,17,20,21,24,25,28,29,u,u,u,u,u,u,u,u]
2640; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
2641; AVX2-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
2642; AVX2-NEXT:    vzeroupper
2643; AVX2-NEXT:    retq
2644;
2645; AVX512-LABEL: trunc_and_v8i32_v8i16:
2646; AVX512:       # %bb.0:
2647; AVX512-NEXT:    vpand %ymm1, %ymm0, %ymm0
2648; AVX512-NEXT:    vpmovdw %zmm0, %ymm0
2649; AVX512-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
2650; AVX512-NEXT:    vzeroupper
2651; AVX512-NEXT:    retq
2652  %1 = and <8 x i32> %a0, %a1
2653  %2 = trunc <8 x i32> %1 to <8 x i16>
2654  ret <8 x i16> %2
2655}
2656
2657define <16 x i8> @trunc_and_v16i64_v16i8(<16 x i64> %a0, <16 x i64> %a1) nounwind {
2658; SSE-LABEL: trunc_and_v16i64_v16i8:
2659; SSE:       # %bb.0:
2660; SSE-NEXT:    pand {{[0-9]+}}(%rsp), %xmm0
2661; SSE-NEXT:    pand {{[0-9]+}}(%rsp), %xmm1
2662; SSE-NEXT:    pand {{[0-9]+}}(%rsp), %xmm2
2663; SSE-NEXT:    pand {{[0-9]+}}(%rsp), %xmm3
2664; SSE-NEXT:    pand {{[0-9]+}}(%rsp), %xmm4
2665; SSE-NEXT:    pand {{[0-9]+}}(%rsp), %xmm5
2666; SSE-NEXT:    pand {{[0-9]+}}(%rsp), %xmm6
2667; SSE-NEXT:    pand {{[0-9]+}}(%rsp), %xmm7
2668; SSE-NEXT:    movdqa {{.*#+}} xmm8 = [255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0]
2669; SSE-NEXT:    pand %xmm8, %xmm7
2670; SSE-NEXT:    pand %xmm8, %xmm6
2671; SSE-NEXT:    packuswb %xmm7, %xmm6
2672; SSE-NEXT:    pand %xmm8, %xmm5
2673; SSE-NEXT:    pand %xmm8, %xmm4
2674; SSE-NEXT:    packuswb %xmm5, %xmm4
2675; SSE-NEXT:    packuswb %xmm6, %xmm4
2676; SSE-NEXT:    pand %xmm8, %xmm3
2677; SSE-NEXT:    pand %xmm8, %xmm2
2678; SSE-NEXT:    packuswb %xmm3, %xmm2
2679; SSE-NEXT:    pand %xmm8, %xmm1
2680; SSE-NEXT:    pand %xmm8, %xmm0
2681; SSE-NEXT:    packuswb %xmm1, %xmm0
2682; SSE-NEXT:    packuswb %xmm2, %xmm0
2683; SSE-NEXT:    packuswb %xmm4, %xmm0
2684; SSE-NEXT:    retq
2685;
2686; AVX1-LABEL: trunc_and_v16i64_v16i8:
2687; AVX1:       # %bb.0:
2688; AVX1-NEXT:    vmovaps {{.*#+}} ymm8 = [255,255,255,255]
2689; AVX1-NEXT:    vandps %ymm7, %ymm8, %ymm7
2690; AVX1-NEXT:    vandps %ymm7, %ymm3, %ymm3
2691; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm7
2692; AVX1-NEXT:    vpackusdw %xmm7, %xmm3, %xmm3
2693; AVX1-NEXT:    vandps %ymm6, %ymm8, %ymm6
2694; AVX1-NEXT:    vandps %ymm6, %ymm2, %ymm2
2695; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm6
2696; AVX1-NEXT:    vpackusdw %xmm6, %xmm2, %xmm2
2697; AVX1-NEXT:    vpackusdw %xmm3, %xmm2, %xmm2
2698; AVX1-NEXT:    vandps %ymm5, %ymm8, %ymm3
2699; AVX1-NEXT:    vandps %ymm3, %ymm1, %ymm1
2700; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
2701; AVX1-NEXT:    vpackusdw %xmm3, %xmm1, %xmm1
2702; AVX1-NEXT:    vandps %ymm4, %ymm8, %ymm3
2703; AVX1-NEXT:    vandps %ymm3, %ymm0, %ymm0
2704; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
2705; AVX1-NEXT:    vpackusdw %xmm3, %xmm0, %xmm0
2706; AVX1-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
2707; AVX1-NEXT:    vpackuswb %xmm2, %xmm0, %xmm0
2708; AVX1-NEXT:    vzeroupper
2709; AVX1-NEXT:    retq
2710;
2711; AVX2-LABEL: trunc_and_v16i64_v16i8:
2712; AVX2:       # %bb.0:
2713; AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm8 = [255,255,255,255]
2714; AVX2-NEXT:    vpand %ymm7, %ymm8, %ymm7
2715; AVX2-NEXT:    vpand %ymm7, %ymm3, %ymm3
2716; AVX2-NEXT:    vpand %ymm6, %ymm8, %ymm6
2717; AVX2-NEXT:    vpand %ymm6, %ymm2, %ymm2
2718; AVX2-NEXT:    vpackusdw %ymm3, %ymm2, %ymm2
2719; AVX2-NEXT:    vpermq {{.*#+}} ymm2 = ymm2[0,2,1,3]
2720; AVX2-NEXT:    vpand %ymm5, %ymm8, %ymm3
2721; AVX2-NEXT:    vpand %ymm3, %ymm1, %ymm1
2722; AVX2-NEXT:    vpand %ymm4, %ymm8, %ymm3
2723; AVX2-NEXT:    vpand %ymm3, %ymm0, %ymm0
2724; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
2725; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3]
2726; AVX2-NEXT:    vpackusdw %ymm2, %ymm0, %ymm0
2727; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
2728; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
2729; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
2730; AVX2-NEXT:    vzeroupper
2731; AVX2-NEXT:    retq
2732;
2733; AVX512-LABEL: trunc_and_v16i64_v16i8:
2734; AVX512:       # %bb.0:
2735; AVX512-NEXT:    vpandq %zmm2, %zmm0, %zmm0
2736; AVX512-NEXT:    vpandq %zmm3, %zmm1, %zmm1
2737; AVX512-NEXT:    vpmovqb %zmm1, %xmm1
2738; AVX512-NEXT:    vpmovqb %zmm0, %xmm0
2739; AVX512-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
2740; AVX512-NEXT:    vzeroupper
2741; AVX512-NEXT:    retq
2742  %1 = and <16 x i64> %a0, %a1
2743  %2 = trunc <16 x i64> %1 to <16 x i8>
2744  ret <16 x i8> %2
2745}
2746
2747define <16 x i8> @trunc_and_v16i32_v16i8(<16 x i32> %a0, <16 x i32> %a1) nounwind {
2748; SSE-LABEL: trunc_and_v16i32_v16i8:
2749; SSE:       # %bb.0:
2750; SSE-NEXT:    movdqa {{.*#+}} xmm8 = [255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0]
2751; SSE-NEXT:    pand %xmm8, %xmm7
2752; SSE-NEXT:    pand %xmm3, %xmm7
2753; SSE-NEXT:    pand %xmm8, %xmm6
2754; SSE-NEXT:    pand %xmm2, %xmm6
2755; SSE-NEXT:    packuswb %xmm7, %xmm6
2756; SSE-NEXT:    pand %xmm8, %xmm5
2757; SSE-NEXT:    pand %xmm1, %xmm5
2758; SSE-NEXT:    pand %xmm8, %xmm4
2759; SSE-NEXT:    pand %xmm4, %xmm0
2760; SSE-NEXT:    packuswb %xmm5, %xmm0
2761; SSE-NEXT:    packuswb %xmm6, %xmm0
2762; SSE-NEXT:    retq
2763;
2764; AVX1-LABEL: trunc_and_v16i32_v16i8:
2765; AVX1:       # %bb.0:
2766; AVX1-NEXT:    vmovaps {{.*#+}} ymm4 = [255,255,255,255,255,255,255,255]
2767; AVX1-NEXT:    vandps %ymm4, %ymm3, %ymm3
2768; AVX1-NEXT:    vandps %ymm3, %ymm1, %ymm1
2769; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
2770; AVX1-NEXT:    vpackusdw %xmm3, %xmm1, %xmm1
2771; AVX1-NEXT:    vandps %ymm4, %ymm2, %ymm2
2772; AVX1-NEXT:    vandps %ymm2, %ymm0, %ymm0
2773; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
2774; AVX1-NEXT:    vpackusdw %xmm2, %xmm0, %xmm0
2775; AVX1-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
2776; AVX1-NEXT:    vzeroupper
2777; AVX1-NEXT:    retq
2778;
2779; AVX2-LABEL: trunc_and_v16i32_v16i8:
2780; AVX2:       # %bb.0:
2781; AVX2-NEXT:    vpbroadcastd {{.*#+}} ymm4 = [255,255,255,255,255,255,255,255]
2782; AVX2-NEXT:    vpand %ymm4, %ymm3, %ymm3
2783; AVX2-NEXT:    vpand %ymm3, %ymm1, %ymm1
2784; AVX2-NEXT:    vpand %ymm4, %ymm2, %ymm2
2785; AVX2-NEXT:    vpand %ymm2, %ymm0, %ymm0
2786; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
2787; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
2788; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
2789; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
2790; AVX2-NEXT:    vzeroupper
2791; AVX2-NEXT:    retq
2792;
2793; AVX512-LABEL: trunc_and_v16i32_v16i8:
2794; AVX512:       # %bb.0:
2795; AVX512-NEXT:    vpandd %zmm1, %zmm0, %zmm0
2796; AVX512-NEXT:    vpmovdb %zmm0, %xmm0
2797; AVX512-NEXT:    vzeroupper
2798; AVX512-NEXT:    retq
2799  %1 = and <16 x i32> %a0, %a1
2800  %2 = trunc <16 x i32> %1 to <16 x i8>
2801  ret <16 x i8> %2
2802}
2803
2804define <16 x i8> @trunc_and_v16i16_v16i8(<16 x i16> %a0, <16 x i16> %a1) nounwind {
2805; SSE-LABEL: trunc_and_v16i16_v16i8:
2806; SSE:       # %bb.0:
2807; SSE-NEXT:    movdqa {{.*#+}} xmm4 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0]
2808; SSE-NEXT:    pand %xmm4, %xmm3
2809; SSE-NEXT:    pand %xmm1, %xmm3
2810; SSE-NEXT:    pand %xmm4, %xmm2
2811; SSE-NEXT:    pand %xmm2, %xmm0
2812; SSE-NEXT:    packuswb %xmm3, %xmm0
2813; SSE-NEXT:    retq
2814;
2815; AVX1-LABEL: trunc_and_v16i16_v16i8:
2816; AVX1:       # %bb.0:
2817; AVX1-NEXT:    vandps %ymm1, %ymm0, %ymm0
2818; AVX1-NEXT:    vandps {{.*}}(%rip), %ymm0, %ymm0
2819; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
2820; AVX1-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
2821; AVX1-NEXT:    vzeroupper
2822; AVX1-NEXT:    retq
2823;
2824; AVX2-LABEL: trunc_and_v16i16_v16i8:
2825; AVX2:       # %bb.0:
2826; AVX2-NEXT:    vpand %ymm1, %ymm0, %ymm0
2827; AVX2-NEXT:    vpand {{.*}}(%rip), %ymm0, %ymm0
2828; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
2829; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
2830; AVX2-NEXT:    vzeroupper
2831; AVX2-NEXT:    retq
2832;
2833; AVX512F-LABEL: trunc_and_v16i16_v16i8:
2834; AVX512F:       # %bb.0:
2835; AVX512F-NEXT:    vpand %ymm1, %ymm0, %ymm0
2836; 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
2837; AVX512F-NEXT:    vpmovdb %zmm0, %xmm0
2838; AVX512F-NEXT:    vzeroupper
2839; AVX512F-NEXT:    retq
2840;
2841; AVX512BW-LABEL: trunc_and_v16i16_v16i8:
2842; AVX512BW:       # %bb.0:
2843; AVX512BW-NEXT:    vpand %ymm1, %ymm0, %ymm0
2844; AVX512BW-NEXT:    vpmovwb %zmm0, %ymm0
2845; AVX512BW-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
2846; AVX512BW-NEXT:    vzeroupper
2847; AVX512BW-NEXT:    retq
2848;
2849; AVX512DQ-LABEL: trunc_and_v16i16_v16i8:
2850; AVX512DQ:       # %bb.0:
2851; AVX512DQ-NEXT:    vpand %ymm1, %ymm0, %ymm0
2852; AVX512DQ-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
2853; AVX512DQ-NEXT:    vpmovdb %zmm0, %xmm0
2854; AVX512DQ-NEXT:    vzeroupper
2855; AVX512DQ-NEXT:    retq
2856  %1 = and <16 x i16> %a0, %a1
2857  %2 = trunc <16 x i16> %1 to <16 x i8>
2858  ret <16 x i8> %2
2859}
2860
2861;
2862; and to constant
2863;
2864
2865define <4 x i32> @trunc_and_const_v4i64_v4i32(<4 x i64> %a0) nounwind {
2866; SSE-LABEL: trunc_and_const_v4i64_v4i32:
2867; SSE:       # %bb.0:
2868; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
2869; SSE-NEXT:    andps {{.*}}(%rip), %xmm0
2870; SSE-NEXT:    retq
2871;
2872; AVX1-LABEL: trunc_and_const_v4i64_v4i32:
2873; AVX1:       # %bb.0:
2874; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
2875; AVX1-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
2876; AVX1-NEXT:    vandps {{.*}}(%rip), %xmm0, %xmm0
2877; AVX1-NEXT:    vzeroupper
2878; AVX1-NEXT:    retq
2879;
2880; AVX2-SLOW-LABEL: trunc_and_const_v4i64_v4i32:
2881; AVX2-SLOW:       # %bb.0:
2882; AVX2-SLOW-NEXT:    vextractf128 $1, %ymm0, %xmm1
2883; AVX2-SLOW-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
2884; AVX2-SLOW-NEXT:    vandps {{.*}}(%rip), %xmm0, %xmm0
2885; AVX2-SLOW-NEXT:    vzeroupper
2886; AVX2-SLOW-NEXT:    retq
2887;
2888; AVX2-FAST-LABEL: trunc_and_const_v4i64_v4i32:
2889; AVX2-FAST:       # %bb.0:
2890; AVX2-FAST-NEXT:    vmovaps {{.*#+}} ymm1 = <0,2,4,6,u,u,u,u>
2891; AVX2-FAST-NEXT:    vpermps %ymm0, %ymm1, %ymm0
2892; AVX2-FAST-NEXT:    vandps {{.*}}(%rip), %xmm0, %xmm0
2893; AVX2-FAST-NEXT:    vzeroupper
2894; AVX2-FAST-NEXT:    retq
2895;
2896; AVX512-LABEL: trunc_and_const_v4i64_v4i32:
2897; AVX512:       # %bb.0:
2898; AVX512-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
2899; AVX512-NEXT:    vpmovqd %zmm0, %ymm0
2900; AVX512-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
2901; AVX512-NEXT:    vzeroupper
2902; AVX512-NEXT:    retq
2903  %1 = and <4 x i64> %a0, <i64 0, i64 1, i64 2, i64 3>
2904  %2 = trunc <4 x i64> %1 to <4 x i32>
2905  ret <4 x i32> %2
2906}
2907
2908define <8 x i16> @trunc_and_const_v8i64_v8i16(<8 x i64> %a0) nounwind {
2909; SSE-LABEL: trunc_and_const_v8i64_v8i16:
2910; SSE:       # %bb.0:
2911; SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
2912; SSE-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,2,2,3,4,5,6,7]
2913; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
2914; SSE-NEXT:    pshuflw {{.*#+}} xmm4 = xmm0[0,2,2,3,4,5,6,7]
2915; SSE-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
2916; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[0,2,2,3]
2917; SSE-NEXT:    pshuflw {{.*#+}} xmm1 = xmm0[0,1,0,2,4,5,6,7]
2918; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3]
2919; SSE-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,1,0,2,4,5,6,7]
2920; SSE-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
2921; SSE-NEXT:    movsd {{.*#+}} xmm0 = xmm4[0],xmm0[1]
2922; SSE-NEXT:    andpd {{.*}}(%rip), %xmm0
2923; SSE-NEXT:    retq
2924;
2925; AVX1-LABEL: trunc_and_const_v8i64_v8i16:
2926; AVX1:       # %bb.0:
2927; AVX1-NEXT:    vmovaps {{.*#+}} ymm2 = [65535,65535,65535,65535]
2928; AVX1-NEXT:    vandps %ymm2, %ymm1, %ymm1
2929; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
2930; AVX1-NEXT:    vpackusdw %xmm3, %xmm1, %xmm1
2931; AVX1-NEXT:    vandps %ymm2, %ymm0, %ymm0
2932; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
2933; AVX1-NEXT:    vpackusdw %xmm2, %xmm0, %xmm0
2934; AVX1-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
2935; AVX1-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
2936; AVX1-NEXT:    vzeroupper
2937; AVX1-NEXT:    retq
2938;
2939; AVX2-LABEL: trunc_and_const_v8i64_v8i16:
2940; AVX2:       # %bb.0:
2941; AVX2-NEXT:    vpxor %xmm2, %xmm2, %xmm2
2942; AVX2-NEXT:    vpblendw {{.*#+}} ymm1 = ymm1[0],ymm2[1,2,3],ymm1[4],ymm2[5,6,7],ymm1[8],ymm2[9,10,11],ymm1[12],ymm2[13,14,15]
2943; AVX2-NEXT:    vpblendw {{.*#+}} ymm0 = ymm0[0],ymm2[1,2,3],ymm0[4],ymm2[5,6,7],ymm0[8],ymm2[9,10,11],ymm0[12],ymm2[13,14,15]
2944; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
2945; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
2946; AVX2-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
2947; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
2948; AVX2-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
2949; AVX2-NEXT:    vzeroupper
2950; AVX2-NEXT:    retq
2951;
2952; AVX512-LABEL: trunc_and_const_v8i64_v8i16:
2953; AVX512:       # %bb.0:
2954; AVX512-NEXT:    vpmovqw %zmm0, %xmm0
2955; AVX512-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
2956; AVX512-NEXT:    vzeroupper
2957; AVX512-NEXT:    retq
2958  %1 = and <8 x i64> %a0, <i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7>
2959  %2 = trunc <8 x i64> %1 to <8 x i16>
2960  ret <8 x i16> %2
2961}
2962
2963define <8 x i16> @trunc_and_const_v8i32_v8i16(<8 x i32> %a0) nounwind {
2964; SSE-LABEL: trunc_and_const_v8i32_v8i16:
2965; SSE:       # %bb.0:
2966; SSE-NEXT:    pslld $16, %xmm1
2967; SSE-NEXT:    psrad $16, %xmm1
2968; SSE-NEXT:    pslld $16, %xmm0
2969; SSE-NEXT:    psrad $16, %xmm0
2970; SSE-NEXT:    packssdw %xmm1, %xmm0
2971; SSE-NEXT:    pand {{.*}}(%rip), %xmm0
2972; SSE-NEXT:    retq
2973;
2974; AVX1-LABEL: trunc_and_const_v8i32_v8i16:
2975; AVX1:       # %bb.0:
2976; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
2977; AVX1-NEXT:    vmovdqa {{.*#+}} xmm2 = <0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u>
2978; AVX1-NEXT:    vpshufb %xmm2, %xmm1, %xmm1
2979; AVX1-NEXT:    vpshufb %xmm2, %xmm0, %xmm0
2980; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
2981; AVX1-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
2982; AVX1-NEXT:    vzeroupper
2983; AVX1-NEXT:    retq
2984;
2985; AVX2-LABEL: trunc_and_const_v8i32_v8i16:
2986; AVX2:       # %bb.0:
2987; AVX2-NEXT:    vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u,16,17,20,21,24,25,28,29,u,u,u,u,u,u,u,u]
2988; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
2989; AVX2-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
2990; AVX2-NEXT:    vzeroupper
2991; AVX2-NEXT:    retq
2992;
2993; AVX512-LABEL: trunc_and_const_v8i32_v8i16:
2994; AVX512:       # %bb.0:
2995; AVX512-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
2996; AVX512-NEXT:    vpmovdw %zmm0, %ymm0
2997; AVX512-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
2998; AVX512-NEXT:    vzeroupper
2999; AVX512-NEXT:    retq
3000  %1 = and <8 x i32> %a0, <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
3001  %2 = trunc <8 x i32> %1 to <8 x i16>
3002  ret <8 x i16> %2
3003}
3004
3005define <16 x i8> @trunc_and_const_v16i64_v16i8(<16 x i64> %a0) nounwind {
3006; SSE-LABEL: trunc_and_const_v16i64_v16i8:
3007; SSE:       # %bb.0:
3008; SSE-NEXT:    movdqa {{.*#+}} xmm8 = [255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0]
3009; SSE-NEXT:    pand %xmm8, %xmm7
3010; SSE-NEXT:    pand %xmm8, %xmm6
3011; SSE-NEXT:    packuswb %xmm7, %xmm6
3012; SSE-NEXT:    pand %xmm8, %xmm5
3013; SSE-NEXT:    pand %xmm8, %xmm4
3014; SSE-NEXT:    packuswb %xmm5, %xmm4
3015; SSE-NEXT:    packuswb %xmm6, %xmm4
3016; SSE-NEXT:    pand %xmm8, %xmm3
3017; SSE-NEXT:    pand %xmm8, %xmm2
3018; SSE-NEXT:    packuswb %xmm3, %xmm2
3019; SSE-NEXT:    pand %xmm8, %xmm1
3020; SSE-NEXT:    pand %xmm8, %xmm0
3021; SSE-NEXT:    packuswb %xmm1, %xmm0
3022; SSE-NEXT:    packuswb %xmm2, %xmm0
3023; SSE-NEXT:    packuswb %xmm4, %xmm0
3024; SSE-NEXT:    pand {{.*}}(%rip), %xmm0
3025; SSE-NEXT:    retq
3026;
3027; AVX1-LABEL: trunc_and_const_v16i64_v16i8:
3028; AVX1:       # %bb.0:
3029; AVX1-NEXT:    vmovaps {{.*#+}} ymm4 = [255,255,255,255]
3030; AVX1-NEXT:    vandps %ymm4, %ymm3, %ymm3
3031; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm5
3032; AVX1-NEXT:    vpackusdw %xmm5, %xmm3, %xmm3
3033; AVX1-NEXT:    vandps %ymm4, %ymm2, %ymm2
3034; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm5
3035; AVX1-NEXT:    vpackusdw %xmm5, %xmm2, %xmm2
3036; AVX1-NEXT:    vpackusdw %xmm3, %xmm2, %xmm2
3037; AVX1-NEXT:    vandps %ymm4, %ymm1, %ymm1
3038; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
3039; AVX1-NEXT:    vpackusdw %xmm3, %xmm1, %xmm1
3040; AVX1-NEXT:    vandps %ymm4, %ymm0, %ymm0
3041; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
3042; AVX1-NEXT:    vpackusdw %xmm3, %xmm0, %xmm0
3043; AVX1-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
3044; AVX1-NEXT:    vpackuswb %xmm2, %xmm0, %xmm0
3045; AVX1-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
3046; AVX1-NEXT:    vzeroupper
3047; AVX1-NEXT:    retq
3048;
3049; AVX2-LABEL: trunc_and_const_v16i64_v16i8:
3050; AVX2:       # %bb.0:
3051; AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm4 = [255,255,255,255]
3052; AVX2-NEXT:    vpand %ymm4, %ymm3, %ymm3
3053; AVX2-NEXT:    vpand %ymm4, %ymm2, %ymm2
3054; AVX2-NEXT:    vpackusdw %ymm3, %ymm2, %ymm2
3055; AVX2-NEXT:    vpermq {{.*#+}} ymm2 = ymm2[0,2,1,3]
3056; AVX2-NEXT:    vpand %ymm4, %ymm1, %ymm1
3057; AVX2-NEXT:    vpand %ymm4, %ymm0, %ymm0
3058; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
3059; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3]
3060; AVX2-NEXT:    vpackusdw %ymm2, %ymm0, %ymm0
3061; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
3062; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
3063; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
3064; AVX2-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
3065; AVX2-NEXT:    vzeroupper
3066; AVX2-NEXT:    retq
3067;
3068; AVX512-LABEL: trunc_and_const_v16i64_v16i8:
3069; AVX512:       # %bb.0:
3070; AVX512-NEXT:    vpmovqb %zmm1, %xmm1
3071; AVX512-NEXT:    vpmovqb %zmm0, %xmm0
3072; AVX512-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
3073; AVX512-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
3074; AVX512-NEXT:    vzeroupper
3075; AVX512-NEXT:    retq
3076  %1 = and <16 x i64> %a0, <i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, i64 9, i64 10, i64 11, i64 12, i64 13, i64 14, i64 15>
3077  %2 = trunc <16 x i64> %1 to <16 x i8>
3078  ret <16 x i8> %2
3079}
3080
3081define <16 x i8> @trunc_and_const_v16i32_v16i8(<16 x i32> %a0) nounwind {
3082; SSE-LABEL: trunc_and_const_v16i32_v16i8:
3083; SSE:       # %bb.0:
3084; SSE-NEXT:    movdqa {{.*#+}} xmm4 = [255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0]
3085; SSE-NEXT:    pand %xmm4, %xmm3
3086; SSE-NEXT:    pand %xmm4, %xmm2
3087; SSE-NEXT:    packuswb %xmm3, %xmm2
3088; SSE-NEXT:    pand %xmm4, %xmm1
3089; SSE-NEXT:    pand %xmm4, %xmm0
3090; SSE-NEXT:    packuswb %xmm1, %xmm0
3091; SSE-NEXT:    packuswb %xmm2, %xmm0
3092; SSE-NEXT:    pand {{.*}}(%rip), %xmm0
3093; SSE-NEXT:    retq
3094;
3095; AVX1-LABEL: trunc_and_const_v16i32_v16i8:
3096; AVX1:       # %bb.0:
3097; AVX1-NEXT:    vmovaps {{.*#+}} ymm2 = [255,255,255,255,255,255,255,255]
3098; AVX1-NEXT:    vandps %ymm2, %ymm1, %ymm1
3099; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
3100; AVX1-NEXT:    vpackusdw %xmm3, %xmm1, %xmm1
3101; AVX1-NEXT:    vandps %ymm2, %ymm0, %ymm0
3102; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
3103; AVX1-NEXT:    vpackusdw %xmm2, %xmm0, %xmm0
3104; AVX1-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
3105; AVX1-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
3106; AVX1-NEXT:    vzeroupper
3107; AVX1-NEXT:    retq
3108;
3109; AVX2-LABEL: trunc_and_const_v16i32_v16i8:
3110; AVX2:       # %bb.0:
3111; AVX2-NEXT:    vpbroadcastd {{.*#+}} ymm2 = [255,255,255,255,255,255,255,255]
3112; AVX2-NEXT:    vpand %ymm2, %ymm1, %ymm1
3113; AVX2-NEXT:    vpand %ymm2, %ymm0, %ymm0
3114; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
3115; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
3116; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
3117; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
3118; AVX2-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
3119; AVX2-NEXT:    vzeroupper
3120; AVX2-NEXT:    retq
3121;
3122; AVX512-LABEL: trunc_and_const_v16i32_v16i8:
3123; AVX512:       # %bb.0:
3124; AVX512-NEXT:    vpmovdb %zmm0, %xmm0
3125; AVX512-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
3126; AVX512-NEXT:    vzeroupper
3127; AVX512-NEXT:    retq
3128  %1 = and <16 x i32> %a0, <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>
3129  %2 = trunc <16 x i32> %1 to <16 x i8>
3130  ret <16 x i8> %2
3131}
3132
3133define <16 x i8> @trunc_and_const_v16i16_v16i8(<16 x i16> %a0) nounwind {
3134; SSE-LABEL: trunc_and_const_v16i16_v16i8:
3135; SSE:       # %bb.0:
3136; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0]
3137; SSE-NEXT:    pand %xmm2, %xmm1
3138; SSE-NEXT:    pand %xmm2, %xmm0
3139; SSE-NEXT:    packuswb %xmm1, %xmm0
3140; SSE-NEXT:    pand {{.*}}(%rip), %xmm0
3141; SSE-NEXT:    retq
3142;
3143; AVX1-LABEL: trunc_and_const_v16i16_v16i8:
3144; AVX1:       # %bb.0:
3145; AVX1-NEXT:    vandps {{.*}}(%rip), %ymm0, %ymm0
3146; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
3147; AVX1-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
3148; AVX1-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
3149; AVX1-NEXT:    vzeroupper
3150; AVX1-NEXT:    retq
3151;
3152; AVX2-LABEL: trunc_and_const_v16i16_v16i8:
3153; AVX2:       # %bb.0:
3154; AVX2-NEXT:    vpand {{.*}}(%rip), %ymm0, %ymm0
3155; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
3156; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
3157; AVX2-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
3158; AVX2-NEXT:    vzeroupper
3159; AVX2-NEXT:    retq
3160;
3161; AVX512F-LABEL: trunc_and_const_v16i16_v16i8:
3162; AVX512F:       # %bb.0:
3163; 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
3164; AVX512F-NEXT:    vpmovdb %zmm0, %xmm0
3165; AVX512F-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
3166; AVX512F-NEXT:    vzeroupper
3167; AVX512F-NEXT:    retq
3168;
3169; AVX512BW-LABEL: trunc_and_const_v16i16_v16i8:
3170; AVX512BW:       # %bb.0:
3171; AVX512BW-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
3172; AVX512BW-NEXT:    vpmovwb %zmm0, %ymm0
3173; AVX512BW-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
3174; AVX512BW-NEXT:    vzeroupper
3175; AVX512BW-NEXT:    retq
3176;
3177; AVX512DQ-LABEL: trunc_and_const_v16i16_v16i8:
3178; AVX512DQ:       # %bb.0:
3179; AVX512DQ-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
3180; AVX512DQ-NEXT:    vpmovdb %zmm0, %xmm0
3181; AVX512DQ-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
3182; AVX512DQ-NEXT:    vzeroupper
3183; AVX512DQ-NEXT:    retq
3184  %1 = and <16 x i16> %a0, <i16 0, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7, i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15>
3185  %2 = trunc <16 x i16> %1 to <16 x i8>
3186  ret <16 x i8> %2
3187}
3188
3189;
3190; xor
3191;
3192
3193define <4 x i32> @trunc_xor_v4i64_v4i32(<4 x i64> %a0, <4 x i64> %a1) nounwind {
3194; SSE-LABEL: trunc_xor_v4i64_v4i32:
3195; SSE:       # %bb.0:
3196; SSE-NEXT:    xorps %xmm3, %xmm1
3197; SSE-NEXT:    xorps %xmm2, %xmm0
3198; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
3199; SSE-NEXT:    retq
3200;
3201; AVX1-LABEL: trunc_xor_v4i64_v4i32:
3202; AVX1:       # %bb.0:
3203; AVX1-NEXT:    vxorps %ymm1, %ymm0, %ymm0
3204; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
3205; AVX1-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
3206; AVX1-NEXT:    vzeroupper
3207; AVX1-NEXT:    retq
3208;
3209; AVX2-SLOW-LABEL: trunc_xor_v4i64_v4i32:
3210; AVX2-SLOW:       # %bb.0:
3211; AVX2-SLOW-NEXT:    vxorps %ymm1, %ymm0, %ymm0
3212; AVX2-SLOW-NEXT:    vextractf128 $1, %ymm0, %xmm1
3213; AVX2-SLOW-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
3214; AVX2-SLOW-NEXT:    vzeroupper
3215; AVX2-SLOW-NEXT:    retq
3216;
3217; AVX2-FAST-LABEL: trunc_xor_v4i64_v4i32:
3218; AVX2-FAST:       # %bb.0:
3219; AVX2-FAST-NEXT:    vxorps %ymm1, %ymm0, %ymm0
3220; AVX2-FAST-NEXT:    vmovaps {{.*#+}} ymm1 = <0,2,4,6,u,u,u,u>
3221; AVX2-FAST-NEXT:    vpermps %ymm0, %ymm1, %ymm0
3222; AVX2-FAST-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
3223; AVX2-FAST-NEXT:    vzeroupper
3224; AVX2-FAST-NEXT:    retq
3225;
3226; AVX512-LABEL: trunc_xor_v4i64_v4i32:
3227; AVX512:       # %bb.0:
3228; AVX512-NEXT:    vpxor %ymm1, %ymm0, %ymm0
3229; AVX512-NEXT:    vpmovqd %zmm0, %ymm0
3230; AVX512-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
3231; AVX512-NEXT:    vzeroupper
3232; AVX512-NEXT:    retq
3233  %1 = xor <4 x i64> %a0, %a1
3234  %2 = trunc <4 x i64> %1 to <4 x i32>
3235  ret <4 x i32> %2
3236}
3237
3238define <8 x i16> @trunc_xor_v8i64_v8i16(<8 x i64> %a0, <8 x i64> %a1) nounwind {
3239; SSE-LABEL: trunc_xor_v8i64_v8i16:
3240; SSE:       # %bb.0:
3241; SSE-NEXT:    pxor %xmm6, %xmm2
3242; SSE-NEXT:    pxor %xmm7, %xmm3
3243; SSE-NEXT:    pxor %xmm4, %xmm0
3244; SSE-NEXT:    pxor %xmm5, %xmm1
3245; SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
3246; SSE-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,2,2,3,4,5,6,7]
3247; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
3248; SSE-NEXT:    pshuflw {{.*#+}} xmm4 = xmm0[0,2,2,3,4,5,6,7]
3249; SSE-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
3250; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[0,2,2,3]
3251; SSE-NEXT:    pshuflw {{.*#+}} xmm1 = xmm0[0,1,0,2,4,5,6,7]
3252; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3]
3253; SSE-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,1,0,2,4,5,6,7]
3254; SSE-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
3255; SSE-NEXT:    movsd {{.*#+}} xmm0 = xmm4[0],xmm0[1]
3256; SSE-NEXT:    retq
3257;
3258; AVX1-LABEL: trunc_xor_v8i64_v8i16:
3259; AVX1:       # %bb.0:
3260; AVX1-NEXT:    vxorps %ymm2, %ymm0, %ymm0
3261; AVX1-NEXT:    vxorps %ymm3, %ymm1, %ymm1
3262; AVX1-NEXT:    vmovaps {{.*#+}} ymm2 = [65535,65535,65535,65535]
3263; AVX1-NEXT:    vandps %ymm2, %ymm1, %ymm1
3264; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
3265; AVX1-NEXT:    vpackusdw %xmm3, %xmm1, %xmm1
3266; AVX1-NEXT:    vandps %ymm2, %ymm0, %ymm0
3267; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
3268; AVX1-NEXT:    vpackusdw %xmm2, %xmm0, %xmm0
3269; AVX1-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
3270; AVX1-NEXT:    vzeroupper
3271; AVX1-NEXT:    retq
3272;
3273; AVX2-LABEL: trunc_xor_v8i64_v8i16:
3274; AVX2:       # %bb.0:
3275; AVX2-NEXT:    vpxor %ymm2, %ymm0, %ymm0
3276; AVX2-NEXT:    vpxor %ymm3, %ymm1, %ymm1
3277; AVX2-NEXT:    vpxor %xmm2, %xmm2, %xmm2
3278; AVX2-NEXT:    vpblendw {{.*#+}} ymm1 = ymm1[0],ymm2[1,2,3],ymm1[4],ymm2[5,6,7],ymm1[8],ymm2[9,10,11],ymm1[12],ymm2[13,14,15]
3279; AVX2-NEXT:    vpblendw {{.*#+}} ymm0 = ymm0[0],ymm2[1,2,3],ymm0[4],ymm2[5,6,7],ymm0[8],ymm2[9,10,11],ymm0[12],ymm2[13,14,15]
3280; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
3281; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
3282; AVX2-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
3283; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
3284; AVX2-NEXT:    vzeroupper
3285; AVX2-NEXT:    retq
3286;
3287; AVX512-LABEL: trunc_xor_v8i64_v8i16:
3288; AVX512:       # %bb.0:
3289; AVX512-NEXT:    vpxorq %zmm1, %zmm0, %zmm0
3290; AVX512-NEXT:    vpmovqw %zmm0, %xmm0
3291; AVX512-NEXT:    vzeroupper
3292; AVX512-NEXT:    retq
3293  %1 = xor <8 x i64> %a0, %a1
3294  %2 = trunc <8 x i64> %1 to <8 x i16>
3295  ret <8 x i16> %2
3296}
3297
3298define <8 x i16> @trunc_xor_v8i32_v8i16(<8 x i32> %a0, <8 x i32> %a1) nounwind {
3299; SSE-LABEL: trunc_xor_v8i32_v8i16:
3300; SSE:       # %bb.0:
3301; SSE-NEXT:    pxor %xmm2, %xmm0
3302; SSE-NEXT:    pxor %xmm3, %xmm1
3303; SSE-NEXT:    pslld $16, %xmm1
3304; SSE-NEXT:    psrad $16, %xmm1
3305; SSE-NEXT:    pslld $16, %xmm0
3306; SSE-NEXT:    psrad $16, %xmm0
3307; SSE-NEXT:    packssdw %xmm1, %xmm0
3308; SSE-NEXT:    retq
3309;
3310; AVX1-LABEL: trunc_xor_v8i32_v8i16:
3311; AVX1:       # %bb.0:
3312; AVX1-NEXT:    vxorps %ymm1, %ymm0, %ymm0
3313; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
3314; AVX1-NEXT:    vmovdqa {{.*#+}} xmm2 = <0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u>
3315; AVX1-NEXT:    vpshufb %xmm2, %xmm1, %xmm1
3316; AVX1-NEXT:    vpshufb %xmm2, %xmm0, %xmm0
3317; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
3318; AVX1-NEXT:    vzeroupper
3319; AVX1-NEXT:    retq
3320;
3321; AVX2-LABEL: trunc_xor_v8i32_v8i16:
3322; AVX2:       # %bb.0:
3323; AVX2-NEXT:    vpxor %ymm1, %ymm0, %ymm0
3324; AVX2-NEXT:    vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u,16,17,20,21,24,25,28,29,u,u,u,u,u,u,u,u]
3325; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
3326; AVX2-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
3327; AVX2-NEXT:    vzeroupper
3328; AVX2-NEXT:    retq
3329;
3330; AVX512-LABEL: trunc_xor_v8i32_v8i16:
3331; AVX512:       # %bb.0:
3332; AVX512-NEXT:    vpxor %ymm1, %ymm0, %ymm0
3333; AVX512-NEXT:    vpmovdw %zmm0, %ymm0
3334; AVX512-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
3335; AVX512-NEXT:    vzeroupper
3336; AVX512-NEXT:    retq
3337  %1 = xor <8 x i32> %a0, %a1
3338  %2 = trunc <8 x i32> %1 to <8 x i16>
3339  ret <8 x i16> %2
3340}
3341
3342define <16 x i8> @trunc_xor_v16i64_v16i8(<16 x i64> %a0, <16 x i64> %a1) nounwind {
3343; SSE-LABEL: trunc_xor_v16i64_v16i8:
3344; SSE:       # %bb.0:
3345; SSE-NEXT:    pxor {{[0-9]+}}(%rsp), %xmm0
3346; SSE-NEXT:    pxor {{[0-9]+}}(%rsp), %xmm1
3347; SSE-NEXT:    pxor {{[0-9]+}}(%rsp), %xmm2
3348; SSE-NEXT:    pxor {{[0-9]+}}(%rsp), %xmm3
3349; SSE-NEXT:    pxor {{[0-9]+}}(%rsp), %xmm4
3350; SSE-NEXT:    pxor {{[0-9]+}}(%rsp), %xmm5
3351; SSE-NEXT:    pxor {{[0-9]+}}(%rsp), %xmm6
3352; SSE-NEXT:    pxor {{[0-9]+}}(%rsp), %xmm7
3353; SSE-NEXT:    movdqa {{.*#+}} xmm8 = [255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0]
3354; SSE-NEXT:    pand %xmm8, %xmm7
3355; SSE-NEXT:    pand %xmm8, %xmm6
3356; SSE-NEXT:    packuswb %xmm7, %xmm6
3357; SSE-NEXT:    pand %xmm8, %xmm5
3358; SSE-NEXT:    pand %xmm8, %xmm4
3359; SSE-NEXT:    packuswb %xmm5, %xmm4
3360; SSE-NEXT:    packuswb %xmm6, %xmm4
3361; SSE-NEXT:    pand %xmm8, %xmm3
3362; SSE-NEXT:    pand %xmm8, %xmm2
3363; SSE-NEXT:    packuswb %xmm3, %xmm2
3364; SSE-NEXT:    pand %xmm8, %xmm1
3365; SSE-NEXT:    pand %xmm8, %xmm0
3366; SSE-NEXT:    packuswb %xmm1, %xmm0
3367; SSE-NEXT:    packuswb %xmm2, %xmm0
3368; SSE-NEXT:    packuswb %xmm4, %xmm0
3369; SSE-NEXT:    retq
3370;
3371; AVX1-LABEL: trunc_xor_v16i64_v16i8:
3372; AVX1:       # %bb.0:
3373; AVX1-NEXT:    vxorps %ymm4, %ymm0, %ymm0
3374; AVX1-NEXT:    vxorps %ymm5, %ymm1, %ymm1
3375; AVX1-NEXT:    vxorps %ymm6, %ymm2, %ymm2
3376; AVX1-NEXT:    vxorps %ymm7, %ymm3, %ymm3
3377; AVX1-NEXT:    vmovaps {{.*#+}} ymm4 = [255,255,255,255]
3378; AVX1-NEXT:    vandps %ymm4, %ymm3, %ymm3
3379; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm5
3380; AVX1-NEXT:    vpackusdw %xmm5, %xmm3, %xmm3
3381; AVX1-NEXT:    vandps %ymm4, %ymm2, %ymm2
3382; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm5
3383; AVX1-NEXT:    vpackusdw %xmm5, %xmm2, %xmm2
3384; AVX1-NEXT:    vpackusdw %xmm3, %xmm2, %xmm2
3385; AVX1-NEXT:    vandps %ymm4, %ymm1, %ymm1
3386; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
3387; AVX1-NEXT:    vpackusdw %xmm3, %xmm1, %xmm1
3388; AVX1-NEXT:    vandps %ymm4, %ymm0, %ymm0
3389; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
3390; AVX1-NEXT:    vpackusdw %xmm3, %xmm0, %xmm0
3391; AVX1-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
3392; AVX1-NEXT:    vpackuswb %xmm2, %xmm0, %xmm0
3393; AVX1-NEXT:    vzeroupper
3394; AVX1-NEXT:    retq
3395;
3396; AVX2-LABEL: trunc_xor_v16i64_v16i8:
3397; AVX2:       # %bb.0:
3398; AVX2-NEXT:    vpxor %ymm4, %ymm0, %ymm0
3399; AVX2-NEXT:    vpxor %ymm5, %ymm1, %ymm1
3400; AVX2-NEXT:    vpxor %ymm6, %ymm2, %ymm2
3401; AVX2-NEXT:    vpxor %ymm7, %ymm3, %ymm3
3402; AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm4 = [255,255,255,255]
3403; AVX2-NEXT:    vpand %ymm4, %ymm3, %ymm3
3404; AVX2-NEXT:    vpand %ymm4, %ymm2, %ymm2
3405; AVX2-NEXT:    vpackusdw %ymm3, %ymm2, %ymm2
3406; AVX2-NEXT:    vpermq {{.*#+}} ymm2 = ymm2[0,2,1,3]
3407; AVX2-NEXT:    vpand %ymm4, %ymm1, %ymm1
3408; AVX2-NEXT:    vpand %ymm4, %ymm0, %ymm0
3409; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
3410; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3]
3411; AVX2-NEXT:    vpackusdw %ymm2, %ymm0, %ymm0
3412; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
3413; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
3414; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
3415; AVX2-NEXT:    vzeroupper
3416; AVX2-NEXT:    retq
3417;
3418; AVX512-LABEL: trunc_xor_v16i64_v16i8:
3419; AVX512:       # %bb.0:
3420; AVX512-NEXT:    vpxorq %zmm2, %zmm0, %zmm0
3421; AVX512-NEXT:    vpxorq %zmm3, %zmm1, %zmm1
3422; AVX512-NEXT:    vpmovqb %zmm1, %xmm1
3423; AVX512-NEXT:    vpmovqb %zmm0, %xmm0
3424; AVX512-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
3425; AVX512-NEXT:    vzeroupper
3426; AVX512-NEXT:    retq
3427  %1 = xor <16 x i64> %a0, %a1
3428  %2 = trunc <16 x i64> %1 to <16 x i8>
3429  ret <16 x i8> %2
3430}
3431
3432define <16 x i8> @trunc_xor_v16i32_v16i8(<16 x i32> %a0, <16 x i32> %a1) nounwind {
3433; SSE-LABEL: trunc_xor_v16i32_v16i8:
3434; SSE:       # %bb.0:
3435; SSE-NEXT:    pxor %xmm4, %xmm0
3436; SSE-NEXT:    pxor %xmm5, %xmm1
3437; SSE-NEXT:    pxor %xmm6, %xmm2
3438; SSE-NEXT:    pxor %xmm7, %xmm3
3439; SSE-NEXT:    movdqa {{.*#+}} xmm4 = [255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0]
3440; SSE-NEXT:    pand %xmm4, %xmm3
3441; SSE-NEXT:    pand %xmm4, %xmm2
3442; SSE-NEXT:    packuswb %xmm3, %xmm2
3443; SSE-NEXT:    pand %xmm4, %xmm1
3444; SSE-NEXT:    pand %xmm4, %xmm0
3445; SSE-NEXT:    packuswb %xmm1, %xmm0
3446; SSE-NEXT:    packuswb %xmm2, %xmm0
3447; SSE-NEXT:    retq
3448;
3449; AVX1-LABEL: trunc_xor_v16i32_v16i8:
3450; AVX1:       # %bb.0:
3451; AVX1-NEXT:    vxorps %ymm2, %ymm0, %ymm0
3452; AVX1-NEXT:    vxorps %ymm3, %ymm1, %ymm1
3453; AVX1-NEXT:    vmovaps {{.*#+}} ymm2 = [255,255,255,255,255,255,255,255]
3454; AVX1-NEXT:    vandps %ymm2, %ymm1, %ymm1
3455; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
3456; AVX1-NEXT:    vpackusdw %xmm3, %xmm1, %xmm1
3457; AVX1-NEXT:    vandps %ymm2, %ymm0, %ymm0
3458; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
3459; AVX1-NEXT:    vpackusdw %xmm2, %xmm0, %xmm0
3460; AVX1-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
3461; AVX1-NEXT:    vzeroupper
3462; AVX1-NEXT:    retq
3463;
3464; AVX2-LABEL: trunc_xor_v16i32_v16i8:
3465; AVX2:       # %bb.0:
3466; AVX2-NEXT:    vpxor %ymm2, %ymm0, %ymm0
3467; AVX2-NEXT:    vpxor %ymm3, %ymm1, %ymm1
3468; AVX2-NEXT:    vpbroadcastd {{.*#+}} ymm2 = [255,255,255,255,255,255,255,255]
3469; AVX2-NEXT:    vpand %ymm2, %ymm1, %ymm1
3470; AVX2-NEXT:    vpand %ymm2, %ymm0, %ymm0
3471; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
3472; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
3473; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
3474; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
3475; AVX2-NEXT:    vzeroupper
3476; AVX2-NEXT:    retq
3477;
3478; AVX512-LABEL: trunc_xor_v16i32_v16i8:
3479; AVX512:       # %bb.0:
3480; AVX512-NEXT:    vpxord %zmm1, %zmm0, %zmm0
3481; AVX512-NEXT:    vpmovdb %zmm0, %xmm0
3482; AVX512-NEXT:    vzeroupper
3483; AVX512-NEXT:    retq
3484  %1 = xor <16 x i32> %a0, %a1
3485  %2 = trunc <16 x i32> %1 to <16 x i8>
3486  ret <16 x i8> %2
3487}
3488
3489define <16 x i8> @trunc_xor_v16i16_v16i8(<16 x i16> %a0, <16 x i16> %a1) nounwind {
3490; SSE-LABEL: trunc_xor_v16i16_v16i8:
3491; SSE:       # %bb.0:
3492; SSE-NEXT:    pxor %xmm2, %xmm0
3493; SSE-NEXT:    pxor %xmm3, %xmm1
3494; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0]
3495; SSE-NEXT:    pand %xmm2, %xmm1
3496; SSE-NEXT:    pand %xmm2, %xmm0
3497; SSE-NEXT:    packuswb %xmm1, %xmm0
3498; SSE-NEXT:    retq
3499;
3500; AVX1-LABEL: trunc_xor_v16i16_v16i8:
3501; AVX1:       # %bb.0:
3502; AVX1-NEXT:    vxorps %ymm1, %ymm0, %ymm0
3503; AVX1-NEXT:    vandps {{.*}}(%rip), %ymm0, %ymm0
3504; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
3505; AVX1-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
3506; AVX1-NEXT:    vzeroupper
3507; AVX1-NEXT:    retq
3508;
3509; AVX2-LABEL: trunc_xor_v16i16_v16i8:
3510; AVX2:       # %bb.0:
3511; AVX2-NEXT:    vpxor %ymm1, %ymm0, %ymm0
3512; AVX2-NEXT:    vpand {{.*}}(%rip), %ymm0, %ymm0
3513; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
3514; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
3515; AVX2-NEXT:    vzeroupper
3516; AVX2-NEXT:    retq
3517;
3518; AVX512F-LABEL: trunc_xor_v16i16_v16i8:
3519; AVX512F:       # %bb.0:
3520; AVX512F-NEXT:    vpxor %ymm1, %ymm0, %ymm0
3521; 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
3522; AVX512F-NEXT:    vpmovdb %zmm0, %xmm0
3523; AVX512F-NEXT:    vzeroupper
3524; AVX512F-NEXT:    retq
3525;
3526; AVX512BW-LABEL: trunc_xor_v16i16_v16i8:
3527; AVX512BW:       # %bb.0:
3528; AVX512BW-NEXT:    vpxor %ymm1, %ymm0, %ymm0
3529; AVX512BW-NEXT:    vpmovwb %zmm0, %ymm0
3530; AVX512BW-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
3531; AVX512BW-NEXT:    vzeroupper
3532; AVX512BW-NEXT:    retq
3533;
3534; AVX512DQ-LABEL: trunc_xor_v16i16_v16i8:
3535; AVX512DQ:       # %bb.0:
3536; AVX512DQ-NEXT:    vpxor %ymm1, %ymm0, %ymm0
3537; AVX512DQ-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
3538; AVX512DQ-NEXT:    vpmovdb %zmm0, %xmm0
3539; AVX512DQ-NEXT:    vzeroupper
3540; AVX512DQ-NEXT:    retq
3541  %1 = xor <16 x i16> %a0, %a1
3542  %2 = trunc <16 x i16> %1 to <16 x i8>
3543  ret <16 x i8> %2
3544}
3545
3546;
3547; xor to constant
3548;
3549
3550define <4 x i32> @trunc_xor_const_v4i64_v4i32(<4 x i64> %a0) nounwind {
3551; SSE-LABEL: trunc_xor_const_v4i64_v4i32:
3552; SSE:       # %bb.0:
3553; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
3554; SSE-NEXT:    xorps {{.*}}(%rip), %xmm0
3555; SSE-NEXT:    retq
3556;
3557; AVX1-LABEL: trunc_xor_const_v4i64_v4i32:
3558; AVX1:       # %bb.0:
3559; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
3560; AVX1-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
3561; AVX1-NEXT:    vxorps {{.*}}(%rip), %xmm0, %xmm0
3562; AVX1-NEXT:    vzeroupper
3563; AVX1-NEXT:    retq
3564;
3565; AVX2-SLOW-LABEL: trunc_xor_const_v4i64_v4i32:
3566; AVX2-SLOW:       # %bb.0:
3567; AVX2-SLOW-NEXT:    vextractf128 $1, %ymm0, %xmm1
3568; AVX2-SLOW-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
3569; AVX2-SLOW-NEXT:    vxorps {{.*}}(%rip), %xmm0, %xmm0
3570; AVX2-SLOW-NEXT:    vzeroupper
3571; AVX2-SLOW-NEXT:    retq
3572;
3573; AVX2-FAST-LABEL: trunc_xor_const_v4i64_v4i32:
3574; AVX2-FAST:       # %bb.0:
3575; AVX2-FAST-NEXT:    vmovaps {{.*#+}} ymm1 = <0,2,4,6,u,u,u,u>
3576; AVX2-FAST-NEXT:    vpermps %ymm0, %ymm1, %ymm0
3577; AVX2-FAST-NEXT:    vxorps {{.*}}(%rip), %xmm0, %xmm0
3578; AVX2-FAST-NEXT:    vzeroupper
3579; AVX2-FAST-NEXT:    retq
3580;
3581; AVX512-LABEL: trunc_xor_const_v4i64_v4i32:
3582; AVX512:       # %bb.0:
3583; AVX512-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
3584; AVX512-NEXT:    vpmovqd %zmm0, %ymm0
3585; AVX512-NEXT:    vpxor {{.*}}(%rip), %xmm0, %xmm0
3586; AVX512-NEXT:    vzeroupper
3587; AVX512-NEXT:    retq
3588  %1 = xor <4 x i64> %a0, <i64 0, i64 1, i64 2, i64 3>
3589  %2 = trunc <4 x i64> %1 to <4 x i32>
3590  ret <4 x i32> %2
3591}
3592
3593define <8 x i16> @trunc_xor_const_v8i64_v8i16(<8 x i64> %a0) nounwind {
3594; SSE-LABEL: trunc_xor_const_v8i64_v8i16:
3595; SSE:       # %bb.0:
3596; SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
3597; SSE-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,2,2,3,4,5,6,7]
3598; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
3599; SSE-NEXT:    pshuflw {{.*#+}} xmm4 = xmm0[0,2,2,3,4,5,6,7]
3600; SSE-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
3601; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[0,2,2,3]
3602; SSE-NEXT:    pshuflw {{.*#+}} xmm1 = xmm0[0,1,0,2,4,5,6,7]
3603; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3]
3604; SSE-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,1,0,2,4,5,6,7]
3605; SSE-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
3606; SSE-NEXT:    movsd {{.*#+}} xmm0 = xmm4[0],xmm0[1]
3607; SSE-NEXT:    xorpd {{.*}}(%rip), %xmm0
3608; SSE-NEXT:    retq
3609;
3610; AVX1-LABEL: trunc_xor_const_v8i64_v8i16:
3611; AVX1:       # %bb.0:
3612; AVX1-NEXT:    vmovaps {{.*#+}} ymm2 = [65535,65535,65535,65535]
3613; AVX1-NEXT:    vandps %ymm2, %ymm1, %ymm1
3614; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
3615; AVX1-NEXT:    vpackusdw %xmm3, %xmm1, %xmm1
3616; AVX1-NEXT:    vandps %ymm2, %ymm0, %ymm0
3617; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
3618; AVX1-NEXT:    vpackusdw %xmm2, %xmm0, %xmm0
3619; AVX1-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
3620; AVX1-NEXT:    vpxor {{.*}}(%rip), %xmm0, %xmm0
3621; AVX1-NEXT:    vzeroupper
3622; AVX1-NEXT:    retq
3623;
3624; AVX2-LABEL: trunc_xor_const_v8i64_v8i16:
3625; AVX2:       # %bb.0:
3626; AVX2-NEXT:    vpxor %xmm2, %xmm2, %xmm2
3627; AVX2-NEXT:    vpblendw {{.*#+}} ymm1 = ymm1[0],ymm2[1,2,3],ymm1[4],ymm2[5,6,7],ymm1[8],ymm2[9,10,11],ymm1[12],ymm2[13,14,15]
3628; AVX2-NEXT:    vpblendw {{.*#+}} ymm0 = ymm0[0],ymm2[1,2,3],ymm0[4],ymm2[5,6,7],ymm0[8],ymm2[9,10,11],ymm0[12],ymm2[13,14,15]
3629; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
3630; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
3631; AVX2-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
3632; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
3633; AVX2-NEXT:    vpxor {{.*}}(%rip), %xmm0, %xmm0
3634; AVX2-NEXT:    vzeroupper
3635; AVX2-NEXT:    retq
3636;
3637; AVX512-LABEL: trunc_xor_const_v8i64_v8i16:
3638; AVX512:       # %bb.0:
3639; AVX512-NEXT:    vpmovqw %zmm0, %xmm0
3640; AVX512-NEXT:    vpxor {{.*}}(%rip), %xmm0, %xmm0
3641; AVX512-NEXT:    vzeroupper
3642; AVX512-NEXT:    retq
3643  %1 = xor <8 x i64> %a0, <i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7>
3644  %2 = trunc <8 x i64> %1 to <8 x i16>
3645  ret <8 x i16> %2
3646}
3647
3648define <8 x i16> @trunc_xor_const_v8i32_v8i16(<8 x i32> %a0) nounwind {
3649; SSE-LABEL: trunc_xor_const_v8i32_v8i16:
3650; SSE:       # %bb.0:
3651; SSE-NEXT:    pslld $16, %xmm1
3652; SSE-NEXT:    psrad $16, %xmm1
3653; SSE-NEXT:    pslld $16, %xmm0
3654; SSE-NEXT:    psrad $16, %xmm0
3655; SSE-NEXT:    packssdw %xmm1, %xmm0
3656; SSE-NEXT:    pxor {{.*}}(%rip), %xmm0
3657; SSE-NEXT:    retq
3658;
3659; AVX1-LABEL: trunc_xor_const_v8i32_v8i16:
3660; AVX1:       # %bb.0:
3661; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
3662; AVX1-NEXT:    vmovdqa {{.*#+}} xmm2 = <0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u>
3663; AVX1-NEXT:    vpshufb %xmm2, %xmm1, %xmm1
3664; AVX1-NEXT:    vpshufb %xmm2, %xmm0, %xmm0
3665; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
3666; AVX1-NEXT:    vpxor {{.*}}(%rip), %xmm0, %xmm0
3667; AVX1-NEXT:    vzeroupper
3668; AVX1-NEXT:    retq
3669;
3670; AVX2-LABEL: trunc_xor_const_v8i32_v8i16:
3671; AVX2:       # %bb.0:
3672; AVX2-NEXT:    vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u,16,17,20,21,24,25,28,29,u,u,u,u,u,u,u,u]
3673; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
3674; AVX2-NEXT:    vpxor {{.*}}(%rip), %xmm0, %xmm0
3675; AVX2-NEXT:    vzeroupper
3676; AVX2-NEXT:    retq
3677;
3678; AVX512-LABEL: trunc_xor_const_v8i32_v8i16:
3679; AVX512:       # %bb.0:
3680; AVX512-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
3681; AVX512-NEXT:    vpmovdw %zmm0, %ymm0
3682; AVX512-NEXT:    vpxor {{.*}}(%rip), %xmm0, %xmm0
3683; AVX512-NEXT:    vzeroupper
3684; AVX512-NEXT:    retq
3685  %1 = xor <8 x i32> %a0, <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
3686  %2 = trunc <8 x i32> %1 to <8 x i16>
3687  ret <8 x i16> %2
3688}
3689
3690define <16 x i8> @trunc_xor_const_v16i64_v16i8(<16 x i64> %a0) nounwind {
3691; SSE-LABEL: trunc_xor_const_v16i64_v16i8:
3692; SSE:       # %bb.0:
3693; SSE-NEXT:    movdqa {{.*#+}} xmm8 = [255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0]
3694; SSE-NEXT:    pand %xmm8, %xmm7
3695; SSE-NEXT:    pand %xmm8, %xmm6
3696; SSE-NEXT:    packuswb %xmm7, %xmm6
3697; SSE-NEXT:    pand %xmm8, %xmm5
3698; SSE-NEXT:    pand %xmm8, %xmm4
3699; SSE-NEXT:    packuswb %xmm5, %xmm4
3700; SSE-NEXT:    packuswb %xmm6, %xmm4
3701; SSE-NEXT:    pand %xmm8, %xmm3
3702; SSE-NEXT:    pand %xmm8, %xmm2
3703; SSE-NEXT:    packuswb %xmm3, %xmm2
3704; SSE-NEXT:    pand %xmm8, %xmm1
3705; SSE-NEXT:    pand %xmm8, %xmm0
3706; SSE-NEXT:    packuswb %xmm1, %xmm0
3707; SSE-NEXT:    packuswb %xmm2, %xmm0
3708; SSE-NEXT:    packuswb %xmm4, %xmm0
3709; SSE-NEXT:    pxor {{.*}}(%rip), %xmm0
3710; SSE-NEXT:    retq
3711;
3712; AVX1-LABEL: trunc_xor_const_v16i64_v16i8:
3713; AVX1:       # %bb.0:
3714; AVX1-NEXT:    vmovaps {{.*#+}} ymm4 = [255,255,255,255]
3715; AVX1-NEXT:    vandps %ymm4, %ymm3, %ymm3
3716; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm5
3717; AVX1-NEXT:    vpackusdw %xmm5, %xmm3, %xmm3
3718; AVX1-NEXT:    vandps %ymm4, %ymm2, %ymm2
3719; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm5
3720; AVX1-NEXT:    vpackusdw %xmm5, %xmm2, %xmm2
3721; AVX1-NEXT:    vpackusdw %xmm3, %xmm2, %xmm2
3722; AVX1-NEXT:    vandps %ymm4, %ymm1, %ymm1
3723; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
3724; AVX1-NEXT:    vpackusdw %xmm3, %xmm1, %xmm1
3725; AVX1-NEXT:    vandps %ymm4, %ymm0, %ymm0
3726; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
3727; AVX1-NEXT:    vpackusdw %xmm3, %xmm0, %xmm0
3728; AVX1-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
3729; AVX1-NEXT:    vpackuswb %xmm2, %xmm0, %xmm0
3730; AVX1-NEXT:    vpxor {{.*}}(%rip), %xmm0, %xmm0
3731; AVX1-NEXT:    vzeroupper
3732; AVX1-NEXT:    retq
3733;
3734; AVX2-LABEL: trunc_xor_const_v16i64_v16i8:
3735; AVX2:       # %bb.0:
3736; AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm4 = [255,255,255,255]
3737; AVX2-NEXT:    vpand %ymm4, %ymm3, %ymm3
3738; AVX2-NEXT:    vpand %ymm4, %ymm2, %ymm2
3739; AVX2-NEXT:    vpackusdw %ymm3, %ymm2, %ymm2
3740; AVX2-NEXT:    vpermq {{.*#+}} ymm2 = ymm2[0,2,1,3]
3741; AVX2-NEXT:    vpand %ymm4, %ymm1, %ymm1
3742; AVX2-NEXT:    vpand %ymm4, %ymm0, %ymm0
3743; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
3744; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3]
3745; AVX2-NEXT:    vpackusdw %ymm2, %ymm0, %ymm0
3746; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
3747; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
3748; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
3749; AVX2-NEXT:    vpxor {{.*}}(%rip), %xmm0, %xmm0
3750; AVX2-NEXT:    vzeroupper
3751; AVX2-NEXT:    retq
3752;
3753; AVX512-LABEL: trunc_xor_const_v16i64_v16i8:
3754; AVX512:       # %bb.0:
3755; AVX512-NEXT:    vpmovqb %zmm1, %xmm1
3756; AVX512-NEXT:    vpmovqb %zmm0, %xmm0
3757; AVX512-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
3758; AVX512-NEXT:    vpxor {{.*}}(%rip), %xmm0, %xmm0
3759; AVX512-NEXT:    vzeroupper
3760; AVX512-NEXT:    retq
3761  %1 = xor <16 x i64> %a0, <i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, i64 9, i64 10, i64 11, i64 12, i64 13, i64 14, i64 15>
3762  %2 = trunc <16 x i64> %1 to <16 x i8>
3763  ret <16 x i8> %2
3764}
3765
3766define <16 x i8> @trunc_xor_const_v16i32_v16i8(<16 x i32> %a0) nounwind {
3767; SSE-LABEL: trunc_xor_const_v16i32_v16i8:
3768; SSE:       # %bb.0:
3769; SSE-NEXT:    movdqa {{.*#+}} xmm4 = [255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0]
3770; SSE-NEXT:    pand %xmm4, %xmm3
3771; SSE-NEXT:    pand %xmm4, %xmm2
3772; SSE-NEXT:    packuswb %xmm3, %xmm2
3773; SSE-NEXT:    pand %xmm4, %xmm1
3774; SSE-NEXT:    pand %xmm4, %xmm0
3775; SSE-NEXT:    packuswb %xmm1, %xmm0
3776; SSE-NEXT:    packuswb %xmm2, %xmm0
3777; SSE-NEXT:    pxor {{.*}}(%rip), %xmm0
3778; SSE-NEXT:    retq
3779;
3780; AVX1-LABEL: trunc_xor_const_v16i32_v16i8:
3781; AVX1:       # %bb.0:
3782; AVX1-NEXT:    vmovaps {{.*#+}} ymm2 = [255,255,255,255,255,255,255,255]
3783; AVX1-NEXT:    vandps %ymm2, %ymm1, %ymm1
3784; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
3785; AVX1-NEXT:    vpackusdw %xmm3, %xmm1, %xmm1
3786; AVX1-NEXT:    vandps %ymm2, %ymm0, %ymm0
3787; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
3788; AVX1-NEXT:    vpackusdw %xmm2, %xmm0, %xmm0
3789; AVX1-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
3790; AVX1-NEXT:    vpxor {{.*}}(%rip), %xmm0, %xmm0
3791; AVX1-NEXT:    vzeroupper
3792; AVX1-NEXT:    retq
3793;
3794; AVX2-LABEL: trunc_xor_const_v16i32_v16i8:
3795; AVX2:       # %bb.0:
3796; AVX2-NEXT:    vpbroadcastd {{.*#+}} ymm2 = [255,255,255,255,255,255,255,255]
3797; AVX2-NEXT:    vpand %ymm2, %ymm1, %ymm1
3798; AVX2-NEXT:    vpand %ymm2, %ymm0, %ymm0
3799; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
3800; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
3801; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
3802; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
3803; AVX2-NEXT:    vpxor {{.*}}(%rip), %xmm0, %xmm0
3804; AVX2-NEXT:    vzeroupper
3805; AVX2-NEXT:    retq
3806;
3807; AVX512-LABEL: trunc_xor_const_v16i32_v16i8:
3808; AVX512:       # %bb.0:
3809; AVX512-NEXT:    vpmovdb %zmm0, %xmm0
3810; AVX512-NEXT:    vpxor {{.*}}(%rip), %xmm0, %xmm0
3811; AVX512-NEXT:    vzeroupper
3812; AVX512-NEXT:    retq
3813  %1 = xor <16 x i32> %a0, <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>
3814  %2 = trunc <16 x i32> %1 to <16 x i8>
3815  ret <16 x i8> %2
3816}
3817
3818define <16 x i8> @trunc_xor_const_v16i16_v16i8(<16 x i16> %a0) nounwind {
3819; SSE-LABEL: trunc_xor_const_v16i16_v16i8:
3820; SSE:       # %bb.0:
3821; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0]
3822; SSE-NEXT:    pand %xmm2, %xmm1
3823; SSE-NEXT:    pand %xmm2, %xmm0
3824; SSE-NEXT:    packuswb %xmm1, %xmm0
3825; SSE-NEXT:    pxor {{.*}}(%rip), %xmm0
3826; SSE-NEXT:    retq
3827;
3828; AVX1-LABEL: trunc_xor_const_v16i16_v16i8:
3829; AVX1:       # %bb.0:
3830; AVX1-NEXT:    vandps {{.*}}(%rip), %ymm0, %ymm0
3831; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
3832; AVX1-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
3833; AVX1-NEXT:    vpxor {{.*}}(%rip), %xmm0, %xmm0
3834; AVX1-NEXT:    vzeroupper
3835; AVX1-NEXT:    retq
3836;
3837; AVX2-LABEL: trunc_xor_const_v16i16_v16i8:
3838; AVX2:       # %bb.0:
3839; AVX2-NEXT:    vpand {{.*}}(%rip), %ymm0, %ymm0
3840; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
3841; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
3842; AVX2-NEXT:    vpxor {{.*}}(%rip), %xmm0, %xmm0
3843; AVX2-NEXT:    vzeroupper
3844; AVX2-NEXT:    retq
3845;
3846; AVX512F-LABEL: trunc_xor_const_v16i16_v16i8:
3847; AVX512F:       # %bb.0:
3848; 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
3849; AVX512F-NEXT:    vpmovdb %zmm0, %xmm0
3850; AVX512F-NEXT:    vpxor {{.*}}(%rip), %xmm0, %xmm0
3851; AVX512F-NEXT:    vzeroupper
3852; AVX512F-NEXT:    retq
3853;
3854; AVX512BW-LABEL: trunc_xor_const_v16i16_v16i8:
3855; AVX512BW:       # %bb.0:
3856; AVX512BW-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
3857; AVX512BW-NEXT:    vpmovwb %zmm0, %ymm0
3858; AVX512BW-NEXT:    vpxor {{.*}}(%rip), %xmm0, %xmm0
3859; AVX512BW-NEXT:    vzeroupper
3860; AVX512BW-NEXT:    retq
3861;
3862; AVX512DQ-LABEL: trunc_xor_const_v16i16_v16i8:
3863; AVX512DQ:       # %bb.0:
3864; AVX512DQ-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
3865; AVX512DQ-NEXT:    vpmovdb %zmm0, %xmm0
3866; AVX512DQ-NEXT:    vpxor {{.*}}(%rip), %xmm0, %xmm0
3867; AVX512DQ-NEXT:    vzeroupper
3868; AVX512DQ-NEXT:    retq
3869  %1 = xor <16 x i16> %a0, <i16 0, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7, i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15>
3870  %2 = trunc <16 x i16> %1 to <16 x i8>
3871  ret <16 x i8> %2
3872}
3873
3874;
3875; or
3876;
3877
3878define <4 x i32> @trunc_or_v4i64_v4i32(<4 x i64> %a0, <4 x i64> %a1) nounwind {
3879; SSE-LABEL: trunc_or_v4i64_v4i32:
3880; SSE:       # %bb.0:
3881; SSE-NEXT:    orps %xmm3, %xmm1
3882; SSE-NEXT:    orps %xmm2, %xmm0
3883; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
3884; SSE-NEXT:    retq
3885;
3886; AVX1-LABEL: trunc_or_v4i64_v4i32:
3887; AVX1:       # %bb.0:
3888; AVX1-NEXT:    vorps %ymm1, %ymm0, %ymm0
3889; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
3890; AVX1-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
3891; AVX1-NEXT:    vzeroupper
3892; AVX1-NEXT:    retq
3893;
3894; AVX2-SLOW-LABEL: trunc_or_v4i64_v4i32:
3895; AVX2-SLOW:       # %bb.0:
3896; AVX2-SLOW-NEXT:    vorps %ymm1, %ymm0, %ymm0
3897; AVX2-SLOW-NEXT:    vextractf128 $1, %ymm0, %xmm1
3898; AVX2-SLOW-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
3899; AVX2-SLOW-NEXT:    vzeroupper
3900; AVX2-SLOW-NEXT:    retq
3901;
3902; AVX2-FAST-LABEL: trunc_or_v4i64_v4i32:
3903; AVX2-FAST:       # %bb.0:
3904; AVX2-FAST-NEXT:    vorps %ymm1, %ymm0, %ymm0
3905; AVX2-FAST-NEXT:    vmovaps {{.*#+}} ymm1 = <0,2,4,6,u,u,u,u>
3906; AVX2-FAST-NEXT:    vpermps %ymm0, %ymm1, %ymm0
3907; AVX2-FAST-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
3908; AVX2-FAST-NEXT:    vzeroupper
3909; AVX2-FAST-NEXT:    retq
3910;
3911; AVX512-LABEL: trunc_or_v4i64_v4i32:
3912; AVX512:       # %bb.0:
3913; AVX512-NEXT:    vpor %ymm1, %ymm0, %ymm0
3914; AVX512-NEXT:    vpmovqd %zmm0, %ymm0
3915; AVX512-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
3916; AVX512-NEXT:    vzeroupper
3917; AVX512-NEXT:    retq
3918  %1 = or <4 x i64> %a0, %a1
3919  %2 = trunc <4 x i64> %1 to <4 x i32>
3920  ret <4 x i32> %2
3921}
3922
3923define <8 x i16> @trunc_or_v8i64_v8i16(<8 x i64> %a0, <8 x i64> %a1) nounwind {
3924; SSE-LABEL: trunc_or_v8i64_v8i16:
3925; SSE:       # %bb.0:
3926; SSE-NEXT:    por %xmm6, %xmm2
3927; SSE-NEXT:    por %xmm7, %xmm3
3928; SSE-NEXT:    por %xmm4, %xmm0
3929; SSE-NEXT:    por %xmm5, %xmm1
3930; SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
3931; SSE-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,2,2,3,4,5,6,7]
3932; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
3933; SSE-NEXT:    pshuflw {{.*#+}} xmm4 = xmm0[0,2,2,3,4,5,6,7]
3934; SSE-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
3935; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[0,2,2,3]
3936; SSE-NEXT:    pshuflw {{.*#+}} xmm1 = xmm0[0,1,0,2,4,5,6,7]
3937; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3]
3938; SSE-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,1,0,2,4,5,6,7]
3939; SSE-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
3940; SSE-NEXT:    movsd {{.*#+}} xmm0 = xmm4[0],xmm0[1]
3941; SSE-NEXT:    retq
3942;
3943; AVX1-LABEL: trunc_or_v8i64_v8i16:
3944; AVX1:       # %bb.0:
3945; AVX1-NEXT:    vorps %ymm2, %ymm0, %ymm0
3946; AVX1-NEXT:    vorps %ymm3, %ymm1, %ymm1
3947; AVX1-NEXT:    vmovaps {{.*#+}} ymm2 = [65535,65535,65535,65535]
3948; AVX1-NEXT:    vandps %ymm2, %ymm1, %ymm1
3949; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
3950; AVX1-NEXT:    vpackusdw %xmm3, %xmm1, %xmm1
3951; AVX1-NEXT:    vandps %ymm2, %ymm0, %ymm0
3952; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
3953; AVX1-NEXT:    vpackusdw %xmm2, %xmm0, %xmm0
3954; AVX1-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
3955; AVX1-NEXT:    vzeroupper
3956; AVX1-NEXT:    retq
3957;
3958; AVX2-LABEL: trunc_or_v8i64_v8i16:
3959; AVX2:       # %bb.0:
3960; AVX2-NEXT:    vpor %ymm2, %ymm0, %ymm0
3961; AVX2-NEXT:    vpor %ymm3, %ymm1, %ymm1
3962; AVX2-NEXT:    vpxor %xmm2, %xmm2, %xmm2
3963; AVX2-NEXT:    vpblendw {{.*#+}} ymm1 = ymm1[0],ymm2[1,2,3],ymm1[4],ymm2[5,6,7],ymm1[8],ymm2[9,10,11],ymm1[12],ymm2[13,14,15]
3964; AVX2-NEXT:    vpblendw {{.*#+}} ymm0 = ymm0[0],ymm2[1,2,3],ymm0[4],ymm2[5,6,7],ymm0[8],ymm2[9,10,11],ymm0[12],ymm2[13,14,15]
3965; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
3966; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
3967; AVX2-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
3968; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
3969; AVX2-NEXT:    vzeroupper
3970; AVX2-NEXT:    retq
3971;
3972; AVX512-LABEL: trunc_or_v8i64_v8i16:
3973; AVX512:       # %bb.0:
3974; AVX512-NEXT:    vporq %zmm1, %zmm0, %zmm0
3975; AVX512-NEXT:    vpmovqw %zmm0, %xmm0
3976; AVX512-NEXT:    vzeroupper
3977; AVX512-NEXT:    retq
3978  %1 = or <8 x i64> %a0, %a1
3979  %2 = trunc <8 x i64> %1 to <8 x i16>
3980  ret <8 x i16> %2
3981}
3982
3983define <8 x i16> @trunc_or_v8i32_v8i16(<8 x i32> %a0, <8 x i32> %a1) nounwind {
3984; SSE-LABEL: trunc_or_v8i32_v8i16:
3985; SSE:       # %bb.0:
3986; SSE-NEXT:    por %xmm2, %xmm0
3987; SSE-NEXT:    por %xmm3, %xmm1
3988; SSE-NEXT:    pslld $16, %xmm1
3989; SSE-NEXT:    psrad $16, %xmm1
3990; SSE-NEXT:    pslld $16, %xmm0
3991; SSE-NEXT:    psrad $16, %xmm0
3992; SSE-NEXT:    packssdw %xmm1, %xmm0
3993; SSE-NEXT:    retq
3994;
3995; AVX1-LABEL: trunc_or_v8i32_v8i16:
3996; AVX1:       # %bb.0:
3997; AVX1-NEXT:    vorps %ymm1, %ymm0, %ymm0
3998; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
3999; AVX1-NEXT:    vmovdqa {{.*#+}} xmm2 = <0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u>
4000; AVX1-NEXT:    vpshufb %xmm2, %xmm1, %xmm1
4001; AVX1-NEXT:    vpshufb %xmm2, %xmm0, %xmm0
4002; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
4003; AVX1-NEXT:    vzeroupper
4004; AVX1-NEXT:    retq
4005;
4006; AVX2-LABEL: trunc_or_v8i32_v8i16:
4007; AVX2:       # %bb.0:
4008; AVX2-NEXT:    vpor %ymm1, %ymm0, %ymm0
4009; AVX2-NEXT:    vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u,16,17,20,21,24,25,28,29,u,u,u,u,u,u,u,u]
4010; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
4011; AVX2-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
4012; AVX2-NEXT:    vzeroupper
4013; AVX2-NEXT:    retq
4014;
4015; AVX512-LABEL: trunc_or_v8i32_v8i16:
4016; AVX512:       # %bb.0:
4017; AVX512-NEXT:    vpor %ymm1, %ymm0, %ymm0
4018; AVX512-NEXT:    vpmovdw %zmm0, %ymm0
4019; AVX512-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
4020; AVX512-NEXT:    vzeroupper
4021; AVX512-NEXT:    retq
4022  %1 = or <8 x i32> %a0, %a1
4023  %2 = trunc <8 x i32> %1 to <8 x i16>
4024  ret <8 x i16> %2
4025}
4026
4027define <16 x i8> @trunc_or_v16i64_v16i8(<16 x i64> %a0, <16 x i64> %a1) nounwind {
4028; SSE-LABEL: trunc_or_v16i64_v16i8:
4029; SSE:       # %bb.0:
4030; SSE-NEXT:    por {{[0-9]+}}(%rsp), %xmm0
4031; SSE-NEXT:    por {{[0-9]+}}(%rsp), %xmm1
4032; SSE-NEXT:    por {{[0-9]+}}(%rsp), %xmm2
4033; SSE-NEXT:    por {{[0-9]+}}(%rsp), %xmm3
4034; SSE-NEXT:    por {{[0-9]+}}(%rsp), %xmm4
4035; SSE-NEXT:    por {{[0-9]+}}(%rsp), %xmm5
4036; SSE-NEXT:    por {{[0-9]+}}(%rsp), %xmm6
4037; SSE-NEXT:    por {{[0-9]+}}(%rsp), %xmm7
4038; SSE-NEXT:    movdqa {{.*#+}} xmm8 = [255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0]
4039; SSE-NEXT:    pand %xmm8, %xmm7
4040; SSE-NEXT:    pand %xmm8, %xmm6
4041; SSE-NEXT:    packuswb %xmm7, %xmm6
4042; SSE-NEXT:    pand %xmm8, %xmm5
4043; SSE-NEXT:    pand %xmm8, %xmm4
4044; SSE-NEXT:    packuswb %xmm5, %xmm4
4045; SSE-NEXT:    packuswb %xmm6, %xmm4
4046; SSE-NEXT:    pand %xmm8, %xmm3
4047; SSE-NEXT:    pand %xmm8, %xmm2
4048; SSE-NEXT:    packuswb %xmm3, %xmm2
4049; SSE-NEXT:    pand %xmm8, %xmm1
4050; SSE-NEXT:    pand %xmm8, %xmm0
4051; SSE-NEXT:    packuswb %xmm1, %xmm0
4052; SSE-NEXT:    packuswb %xmm2, %xmm0
4053; SSE-NEXT:    packuswb %xmm4, %xmm0
4054; SSE-NEXT:    retq
4055;
4056; AVX1-LABEL: trunc_or_v16i64_v16i8:
4057; AVX1:       # %bb.0:
4058; AVX1-NEXT:    vorps %ymm4, %ymm0, %ymm0
4059; AVX1-NEXT:    vorps %ymm5, %ymm1, %ymm1
4060; AVX1-NEXT:    vorps %ymm6, %ymm2, %ymm2
4061; AVX1-NEXT:    vorps %ymm7, %ymm3, %ymm3
4062; AVX1-NEXT:    vmovaps {{.*#+}} ymm4 = [255,255,255,255]
4063; AVX1-NEXT:    vandps %ymm4, %ymm3, %ymm3
4064; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm5
4065; AVX1-NEXT:    vpackusdw %xmm5, %xmm3, %xmm3
4066; AVX1-NEXT:    vandps %ymm4, %ymm2, %ymm2
4067; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm5
4068; AVX1-NEXT:    vpackusdw %xmm5, %xmm2, %xmm2
4069; AVX1-NEXT:    vpackusdw %xmm3, %xmm2, %xmm2
4070; AVX1-NEXT:    vandps %ymm4, %ymm1, %ymm1
4071; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
4072; AVX1-NEXT:    vpackusdw %xmm3, %xmm1, %xmm1
4073; AVX1-NEXT:    vandps %ymm4, %ymm0, %ymm0
4074; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
4075; AVX1-NEXT:    vpackusdw %xmm3, %xmm0, %xmm0
4076; AVX1-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
4077; AVX1-NEXT:    vpackuswb %xmm2, %xmm0, %xmm0
4078; AVX1-NEXT:    vzeroupper
4079; AVX1-NEXT:    retq
4080;
4081; AVX2-LABEL: trunc_or_v16i64_v16i8:
4082; AVX2:       # %bb.0:
4083; AVX2-NEXT:    vpor %ymm4, %ymm0, %ymm0
4084; AVX2-NEXT:    vpor %ymm5, %ymm1, %ymm1
4085; AVX2-NEXT:    vpor %ymm6, %ymm2, %ymm2
4086; AVX2-NEXT:    vpor %ymm7, %ymm3, %ymm3
4087; AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm4 = [255,255,255,255]
4088; AVX2-NEXT:    vpand %ymm4, %ymm3, %ymm3
4089; AVX2-NEXT:    vpand %ymm4, %ymm2, %ymm2
4090; AVX2-NEXT:    vpackusdw %ymm3, %ymm2, %ymm2
4091; AVX2-NEXT:    vpermq {{.*#+}} ymm2 = ymm2[0,2,1,3]
4092; AVX2-NEXT:    vpand %ymm4, %ymm1, %ymm1
4093; AVX2-NEXT:    vpand %ymm4, %ymm0, %ymm0
4094; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
4095; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3]
4096; AVX2-NEXT:    vpackusdw %ymm2, %ymm0, %ymm0
4097; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
4098; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
4099; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
4100; AVX2-NEXT:    vzeroupper
4101; AVX2-NEXT:    retq
4102;
4103; AVX512-LABEL: trunc_or_v16i64_v16i8:
4104; AVX512:       # %bb.0:
4105; AVX512-NEXT:    vporq %zmm2, %zmm0, %zmm0
4106; AVX512-NEXT:    vporq %zmm3, %zmm1, %zmm1
4107; AVX512-NEXT:    vpmovqb %zmm1, %xmm1
4108; AVX512-NEXT:    vpmovqb %zmm0, %xmm0
4109; AVX512-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
4110; AVX512-NEXT:    vzeroupper
4111; AVX512-NEXT:    retq
4112  %1 = or <16 x i64> %a0, %a1
4113  %2 = trunc <16 x i64> %1 to <16 x i8>
4114  ret <16 x i8> %2
4115}
4116
4117define <16 x i8> @trunc_or_v16i32_v16i8(<16 x i32> %a0, <16 x i32> %a1) nounwind {
4118; SSE-LABEL: trunc_or_v16i32_v16i8:
4119; SSE:       # %bb.0:
4120; SSE-NEXT:    por %xmm4, %xmm0
4121; SSE-NEXT:    por %xmm5, %xmm1
4122; SSE-NEXT:    por %xmm6, %xmm2
4123; SSE-NEXT:    por %xmm7, %xmm3
4124; SSE-NEXT:    movdqa {{.*#+}} xmm4 = [255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0]
4125; SSE-NEXT:    pand %xmm4, %xmm3
4126; SSE-NEXT:    pand %xmm4, %xmm2
4127; SSE-NEXT:    packuswb %xmm3, %xmm2
4128; SSE-NEXT:    pand %xmm4, %xmm1
4129; SSE-NEXT:    pand %xmm4, %xmm0
4130; SSE-NEXT:    packuswb %xmm1, %xmm0
4131; SSE-NEXT:    packuswb %xmm2, %xmm0
4132; SSE-NEXT:    retq
4133;
4134; AVX1-LABEL: trunc_or_v16i32_v16i8:
4135; AVX1:       # %bb.0:
4136; AVX1-NEXT:    vorps %ymm2, %ymm0, %ymm0
4137; AVX1-NEXT:    vorps %ymm3, %ymm1, %ymm1
4138; AVX1-NEXT:    vmovaps {{.*#+}} ymm2 = [255,255,255,255,255,255,255,255]
4139; AVX1-NEXT:    vandps %ymm2, %ymm1, %ymm1
4140; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
4141; AVX1-NEXT:    vpackusdw %xmm3, %xmm1, %xmm1
4142; AVX1-NEXT:    vandps %ymm2, %ymm0, %ymm0
4143; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
4144; AVX1-NEXT:    vpackusdw %xmm2, %xmm0, %xmm0
4145; AVX1-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
4146; AVX1-NEXT:    vzeroupper
4147; AVX1-NEXT:    retq
4148;
4149; AVX2-LABEL: trunc_or_v16i32_v16i8:
4150; AVX2:       # %bb.0:
4151; AVX2-NEXT:    vpor %ymm2, %ymm0, %ymm0
4152; AVX2-NEXT:    vpor %ymm3, %ymm1, %ymm1
4153; AVX2-NEXT:    vpbroadcastd {{.*#+}} ymm2 = [255,255,255,255,255,255,255,255]
4154; AVX2-NEXT:    vpand %ymm2, %ymm1, %ymm1
4155; AVX2-NEXT:    vpand %ymm2, %ymm0, %ymm0
4156; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
4157; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
4158; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
4159; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
4160; AVX2-NEXT:    vzeroupper
4161; AVX2-NEXT:    retq
4162;
4163; AVX512-LABEL: trunc_or_v16i32_v16i8:
4164; AVX512:       # %bb.0:
4165; AVX512-NEXT:    vpord %zmm1, %zmm0, %zmm0
4166; AVX512-NEXT:    vpmovdb %zmm0, %xmm0
4167; AVX512-NEXT:    vzeroupper
4168; AVX512-NEXT:    retq
4169  %1 = or <16 x i32> %a0, %a1
4170  %2 = trunc <16 x i32> %1 to <16 x i8>
4171  ret <16 x i8> %2
4172}
4173
4174define <16 x i8> @trunc_or_v16i16_v16i8(<16 x i16> %a0, <16 x i16> %a1) nounwind {
4175; SSE-LABEL: trunc_or_v16i16_v16i8:
4176; SSE:       # %bb.0:
4177; SSE-NEXT:    por %xmm2, %xmm0
4178; SSE-NEXT:    por %xmm3, %xmm1
4179; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0]
4180; SSE-NEXT:    pand %xmm2, %xmm1
4181; SSE-NEXT:    pand %xmm2, %xmm0
4182; SSE-NEXT:    packuswb %xmm1, %xmm0
4183; SSE-NEXT:    retq
4184;
4185; AVX1-LABEL: trunc_or_v16i16_v16i8:
4186; AVX1:       # %bb.0:
4187; AVX1-NEXT:    vorps %ymm1, %ymm0, %ymm0
4188; AVX1-NEXT:    vandps {{.*}}(%rip), %ymm0, %ymm0
4189; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
4190; AVX1-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
4191; AVX1-NEXT:    vzeroupper
4192; AVX1-NEXT:    retq
4193;
4194; AVX2-LABEL: trunc_or_v16i16_v16i8:
4195; AVX2:       # %bb.0:
4196; AVX2-NEXT:    vpor %ymm1, %ymm0, %ymm0
4197; AVX2-NEXT:    vpand {{.*}}(%rip), %ymm0, %ymm0
4198; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
4199; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
4200; AVX2-NEXT:    vzeroupper
4201; AVX2-NEXT:    retq
4202;
4203; AVX512F-LABEL: trunc_or_v16i16_v16i8:
4204; AVX512F:       # %bb.0:
4205; AVX512F-NEXT:    vpor %ymm1, %ymm0, %ymm0
4206; 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
4207; AVX512F-NEXT:    vpmovdb %zmm0, %xmm0
4208; AVX512F-NEXT:    vzeroupper
4209; AVX512F-NEXT:    retq
4210;
4211; AVX512BW-LABEL: trunc_or_v16i16_v16i8:
4212; AVX512BW:       # %bb.0:
4213; AVX512BW-NEXT:    vpor %ymm1, %ymm0, %ymm0
4214; AVX512BW-NEXT:    vpmovwb %zmm0, %ymm0
4215; AVX512BW-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
4216; AVX512BW-NEXT:    vzeroupper
4217; AVX512BW-NEXT:    retq
4218;
4219; AVX512DQ-LABEL: trunc_or_v16i16_v16i8:
4220; AVX512DQ:       # %bb.0:
4221; AVX512DQ-NEXT:    vpor %ymm1, %ymm0, %ymm0
4222; AVX512DQ-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
4223; AVX512DQ-NEXT:    vpmovdb %zmm0, %xmm0
4224; AVX512DQ-NEXT:    vzeroupper
4225; AVX512DQ-NEXT:    retq
4226  %1 = or <16 x i16> %a0, %a1
4227  %2 = trunc <16 x i16> %1 to <16 x i8>
4228  ret <16 x i8> %2
4229}
4230
4231;
4232; or to constant
4233;
4234
4235define <4 x i32> @trunc_or_const_v4i64_v4i32(<4 x i64> %a0) nounwind {
4236; SSE-LABEL: trunc_or_const_v4i64_v4i32:
4237; SSE:       # %bb.0:
4238; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
4239; SSE-NEXT:    orps {{.*}}(%rip), %xmm0
4240; SSE-NEXT:    retq
4241;
4242; AVX1-LABEL: trunc_or_const_v4i64_v4i32:
4243; AVX1:       # %bb.0:
4244; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
4245; AVX1-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
4246; AVX1-NEXT:    vorps {{.*}}(%rip), %xmm0, %xmm0
4247; AVX1-NEXT:    vzeroupper
4248; AVX1-NEXT:    retq
4249;
4250; AVX2-SLOW-LABEL: trunc_or_const_v4i64_v4i32:
4251; AVX2-SLOW:       # %bb.0:
4252; AVX2-SLOW-NEXT:    vextractf128 $1, %ymm0, %xmm1
4253; AVX2-SLOW-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
4254; AVX2-SLOW-NEXT:    vorps {{.*}}(%rip), %xmm0, %xmm0
4255; AVX2-SLOW-NEXT:    vzeroupper
4256; AVX2-SLOW-NEXT:    retq
4257;
4258; AVX2-FAST-LABEL: trunc_or_const_v4i64_v4i32:
4259; AVX2-FAST:       # %bb.0:
4260; AVX2-FAST-NEXT:    vmovaps {{.*#+}} ymm1 = <0,2,4,6,u,u,u,u>
4261; AVX2-FAST-NEXT:    vpermps %ymm0, %ymm1, %ymm0
4262; AVX2-FAST-NEXT:    vorps {{.*}}(%rip), %xmm0, %xmm0
4263; AVX2-FAST-NEXT:    vzeroupper
4264; AVX2-FAST-NEXT:    retq
4265;
4266; AVX512-LABEL: trunc_or_const_v4i64_v4i32:
4267; AVX512:       # %bb.0:
4268; AVX512-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
4269; AVX512-NEXT:    vpmovqd %zmm0, %ymm0
4270; AVX512-NEXT:    vpor {{.*}}(%rip), %xmm0, %xmm0
4271; AVX512-NEXT:    vzeroupper
4272; AVX512-NEXT:    retq
4273  %1 = or <4 x i64> %a0, <i64 0, i64 1, i64 2, i64 3>
4274  %2 = trunc <4 x i64> %1 to <4 x i32>
4275  ret <4 x i32> %2
4276}
4277
4278define <8 x i16> @trunc_or_const_v8i64_v8i16(<8 x i64> %a0) nounwind {
4279; SSE-LABEL: trunc_or_const_v8i64_v8i16:
4280; SSE:       # %bb.0:
4281; SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
4282; SSE-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,2,2,3,4,5,6,7]
4283; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
4284; SSE-NEXT:    pshuflw {{.*#+}} xmm4 = xmm0[0,2,2,3,4,5,6,7]
4285; SSE-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
4286; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[0,2,2,3]
4287; SSE-NEXT:    pshuflw {{.*#+}} xmm1 = xmm0[0,1,0,2,4,5,6,7]
4288; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3]
4289; SSE-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,1,0,2,4,5,6,7]
4290; SSE-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
4291; SSE-NEXT:    movsd {{.*#+}} xmm0 = xmm4[0],xmm0[1]
4292; SSE-NEXT:    orpd {{.*}}(%rip), %xmm0
4293; SSE-NEXT:    retq
4294;
4295; AVX1-LABEL: trunc_or_const_v8i64_v8i16:
4296; AVX1:       # %bb.0:
4297; AVX1-NEXT:    vmovaps {{.*#+}} ymm2 = [65535,65535,65535,65535]
4298; AVX1-NEXT:    vandps %ymm2, %ymm1, %ymm1
4299; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
4300; AVX1-NEXT:    vpackusdw %xmm3, %xmm1, %xmm1
4301; AVX1-NEXT:    vandps %ymm2, %ymm0, %ymm0
4302; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
4303; AVX1-NEXT:    vpackusdw %xmm2, %xmm0, %xmm0
4304; AVX1-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
4305; AVX1-NEXT:    vpor {{.*}}(%rip), %xmm0, %xmm0
4306; AVX1-NEXT:    vzeroupper
4307; AVX1-NEXT:    retq
4308;
4309; AVX2-LABEL: trunc_or_const_v8i64_v8i16:
4310; AVX2:       # %bb.0:
4311; AVX2-NEXT:    vpxor %xmm2, %xmm2, %xmm2
4312; AVX2-NEXT:    vpblendw {{.*#+}} ymm1 = ymm1[0],ymm2[1,2,3],ymm1[4],ymm2[5,6,7],ymm1[8],ymm2[9,10,11],ymm1[12],ymm2[13,14,15]
4313; AVX2-NEXT:    vpblendw {{.*#+}} ymm0 = ymm0[0],ymm2[1,2,3],ymm0[4],ymm2[5,6,7],ymm0[8],ymm2[9,10,11],ymm0[12],ymm2[13,14,15]
4314; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
4315; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
4316; AVX2-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
4317; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
4318; AVX2-NEXT:    vpor {{.*}}(%rip), %xmm0, %xmm0
4319; AVX2-NEXT:    vzeroupper
4320; AVX2-NEXT:    retq
4321;
4322; AVX512-LABEL: trunc_or_const_v8i64_v8i16:
4323; AVX512:       # %bb.0:
4324; AVX512-NEXT:    vpmovqw %zmm0, %xmm0
4325; AVX512-NEXT:    vpor {{.*}}(%rip), %xmm0, %xmm0
4326; AVX512-NEXT:    vzeroupper
4327; AVX512-NEXT:    retq
4328  %1 = or <8 x i64> %a0, <i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7>
4329  %2 = trunc <8 x i64> %1 to <8 x i16>
4330  ret <8 x i16> %2
4331}
4332
4333define <8 x i16> @trunc_or_const_v8i32_v8i16(<8 x i32> %a0) nounwind {
4334; SSE-LABEL: trunc_or_const_v8i32_v8i16:
4335; SSE:       # %bb.0:
4336; SSE-NEXT:    pslld $16, %xmm1
4337; SSE-NEXT:    psrad $16, %xmm1
4338; SSE-NEXT:    pslld $16, %xmm0
4339; SSE-NEXT:    psrad $16, %xmm0
4340; SSE-NEXT:    packssdw %xmm1, %xmm0
4341; SSE-NEXT:    por {{.*}}(%rip), %xmm0
4342; SSE-NEXT:    retq
4343;
4344; AVX1-LABEL: trunc_or_const_v8i32_v8i16:
4345; AVX1:       # %bb.0:
4346; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
4347; AVX1-NEXT:    vmovdqa {{.*#+}} xmm2 = <0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u>
4348; AVX1-NEXT:    vpshufb %xmm2, %xmm1, %xmm1
4349; AVX1-NEXT:    vpshufb %xmm2, %xmm0, %xmm0
4350; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
4351; AVX1-NEXT:    vpor {{.*}}(%rip), %xmm0, %xmm0
4352; AVX1-NEXT:    vzeroupper
4353; AVX1-NEXT:    retq
4354;
4355; AVX2-LABEL: trunc_or_const_v8i32_v8i16:
4356; AVX2:       # %bb.0:
4357; AVX2-NEXT:    vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u,16,17,20,21,24,25,28,29,u,u,u,u,u,u,u,u]
4358; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
4359; AVX2-NEXT:    vpor {{.*}}(%rip), %xmm0, %xmm0
4360; AVX2-NEXT:    vzeroupper
4361; AVX2-NEXT:    retq
4362;
4363; AVX512-LABEL: trunc_or_const_v8i32_v8i16:
4364; AVX512:       # %bb.0:
4365; AVX512-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
4366; AVX512-NEXT:    vpmovdw %zmm0, %ymm0
4367; AVX512-NEXT:    vpor {{.*}}(%rip), %xmm0, %xmm0
4368; AVX512-NEXT:    vzeroupper
4369; AVX512-NEXT:    retq
4370  %1 = or <8 x i32> %a0, <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
4371  %2 = trunc <8 x i32> %1 to <8 x i16>
4372  ret <8 x i16> %2
4373}
4374
4375define <16 x i8> @trunc_or_const_v16i64_v16i8(<16 x i64> %a0) nounwind {
4376; SSE-LABEL: trunc_or_const_v16i64_v16i8:
4377; SSE:       # %bb.0:
4378; SSE-NEXT:    movdqa {{.*#+}} xmm8 = [255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0]
4379; SSE-NEXT:    pand %xmm8, %xmm7
4380; SSE-NEXT:    pand %xmm8, %xmm6
4381; SSE-NEXT:    packuswb %xmm7, %xmm6
4382; SSE-NEXT:    pand %xmm8, %xmm5
4383; SSE-NEXT:    pand %xmm8, %xmm4
4384; SSE-NEXT:    packuswb %xmm5, %xmm4
4385; SSE-NEXT:    packuswb %xmm6, %xmm4
4386; SSE-NEXT:    pand %xmm8, %xmm3
4387; SSE-NEXT:    pand %xmm8, %xmm2
4388; SSE-NEXT:    packuswb %xmm3, %xmm2
4389; SSE-NEXT:    pand %xmm8, %xmm1
4390; SSE-NEXT:    pand %xmm8, %xmm0
4391; SSE-NEXT:    packuswb %xmm1, %xmm0
4392; SSE-NEXT:    packuswb %xmm2, %xmm0
4393; SSE-NEXT:    packuswb %xmm4, %xmm0
4394; SSE-NEXT:    por {{.*}}(%rip), %xmm0
4395; SSE-NEXT:    retq
4396;
4397; AVX1-LABEL: trunc_or_const_v16i64_v16i8:
4398; AVX1:       # %bb.0:
4399; AVX1-NEXT:    vmovaps {{.*#+}} ymm4 = [255,255,255,255]
4400; AVX1-NEXT:    vandps %ymm4, %ymm3, %ymm3
4401; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm5
4402; AVX1-NEXT:    vpackusdw %xmm5, %xmm3, %xmm3
4403; AVX1-NEXT:    vandps %ymm4, %ymm2, %ymm2
4404; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm5
4405; AVX1-NEXT:    vpackusdw %xmm5, %xmm2, %xmm2
4406; AVX1-NEXT:    vpackusdw %xmm3, %xmm2, %xmm2
4407; AVX1-NEXT:    vandps %ymm4, %ymm1, %ymm1
4408; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
4409; AVX1-NEXT:    vpackusdw %xmm3, %xmm1, %xmm1
4410; AVX1-NEXT:    vandps %ymm4, %ymm0, %ymm0
4411; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
4412; AVX1-NEXT:    vpackusdw %xmm3, %xmm0, %xmm0
4413; AVX1-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
4414; AVX1-NEXT:    vpackuswb %xmm2, %xmm0, %xmm0
4415; AVX1-NEXT:    vpor {{.*}}(%rip), %xmm0, %xmm0
4416; AVX1-NEXT:    vzeroupper
4417; AVX1-NEXT:    retq
4418;
4419; AVX2-LABEL: trunc_or_const_v16i64_v16i8:
4420; AVX2:       # %bb.0:
4421; AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm4 = [255,255,255,255]
4422; AVX2-NEXT:    vpand %ymm4, %ymm3, %ymm3
4423; AVX2-NEXT:    vpand %ymm4, %ymm2, %ymm2
4424; AVX2-NEXT:    vpackusdw %ymm3, %ymm2, %ymm2
4425; AVX2-NEXT:    vpermq {{.*#+}} ymm2 = ymm2[0,2,1,3]
4426; AVX2-NEXT:    vpand %ymm4, %ymm1, %ymm1
4427; AVX2-NEXT:    vpand %ymm4, %ymm0, %ymm0
4428; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
4429; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3]
4430; AVX2-NEXT:    vpackusdw %ymm2, %ymm0, %ymm0
4431; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
4432; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
4433; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
4434; AVX2-NEXT:    vpor {{.*}}(%rip), %xmm0, %xmm0
4435; AVX2-NEXT:    vzeroupper
4436; AVX2-NEXT:    retq
4437;
4438; AVX512-LABEL: trunc_or_const_v16i64_v16i8:
4439; AVX512:       # %bb.0:
4440; AVX512-NEXT:    vpmovqb %zmm1, %xmm1
4441; AVX512-NEXT:    vpmovqb %zmm0, %xmm0
4442; AVX512-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
4443; AVX512-NEXT:    vpor {{.*}}(%rip), %xmm0, %xmm0
4444; AVX512-NEXT:    vzeroupper
4445; AVX512-NEXT:    retq
4446  %1 = or <16 x i64> %a0, <i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, i64 9, i64 10, i64 11, i64 12, i64 13, i64 14, i64 15>
4447  %2 = trunc <16 x i64> %1 to <16 x i8>
4448  ret <16 x i8> %2
4449}
4450
4451define <16 x i8> @trunc_or_const_v16i32_v16i8(<16 x i32> %a0) nounwind {
4452; SSE-LABEL: trunc_or_const_v16i32_v16i8:
4453; SSE:       # %bb.0:
4454; SSE-NEXT:    movdqa {{.*#+}} xmm4 = [255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0]
4455; SSE-NEXT:    pand %xmm4, %xmm3
4456; SSE-NEXT:    pand %xmm4, %xmm2
4457; SSE-NEXT:    packuswb %xmm3, %xmm2
4458; SSE-NEXT:    pand %xmm4, %xmm1
4459; SSE-NEXT:    pand %xmm4, %xmm0
4460; SSE-NEXT:    packuswb %xmm1, %xmm0
4461; SSE-NEXT:    packuswb %xmm2, %xmm0
4462; SSE-NEXT:    por {{.*}}(%rip), %xmm0
4463; SSE-NEXT:    retq
4464;
4465; AVX1-LABEL: trunc_or_const_v16i32_v16i8:
4466; AVX1:       # %bb.0:
4467; AVX1-NEXT:    vmovaps {{.*#+}} ymm2 = [255,255,255,255,255,255,255,255]
4468; AVX1-NEXT:    vandps %ymm2, %ymm1, %ymm1
4469; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
4470; AVX1-NEXT:    vpackusdw %xmm3, %xmm1, %xmm1
4471; AVX1-NEXT:    vandps %ymm2, %ymm0, %ymm0
4472; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
4473; AVX1-NEXT:    vpackusdw %xmm2, %xmm0, %xmm0
4474; AVX1-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
4475; AVX1-NEXT:    vpor {{.*}}(%rip), %xmm0, %xmm0
4476; AVX1-NEXT:    vzeroupper
4477; AVX1-NEXT:    retq
4478;
4479; AVX2-LABEL: trunc_or_const_v16i32_v16i8:
4480; AVX2:       # %bb.0:
4481; AVX2-NEXT:    vpbroadcastd {{.*#+}} ymm2 = [255,255,255,255,255,255,255,255]
4482; AVX2-NEXT:    vpand %ymm2, %ymm1, %ymm1
4483; AVX2-NEXT:    vpand %ymm2, %ymm0, %ymm0
4484; AVX2-NEXT:    vpackusdw %ymm1, %ymm0, %ymm0
4485; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
4486; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
4487; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
4488; AVX2-NEXT:    vpor {{.*}}(%rip), %xmm0, %xmm0
4489; AVX2-NEXT:    vzeroupper
4490; AVX2-NEXT:    retq
4491;
4492; AVX512-LABEL: trunc_or_const_v16i32_v16i8:
4493; AVX512:       # %bb.0:
4494; AVX512-NEXT:    vpmovdb %zmm0, %xmm0
4495; AVX512-NEXT:    vpor {{.*}}(%rip), %xmm0, %xmm0
4496; AVX512-NEXT:    vzeroupper
4497; AVX512-NEXT:    retq
4498  %1 = or <16 x i32> %a0, <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>
4499  %2 = trunc <16 x i32> %1 to <16 x i8>
4500  ret <16 x i8> %2
4501}
4502
4503define <16 x i8> @trunc_or_const_v16i16_v16i8(<16 x i16> %a0) nounwind {
4504; SSE-LABEL: trunc_or_const_v16i16_v16i8:
4505; SSE:       # %bb.0:
4506; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0]
4507; SSE-NEXT:    pand %xmm2, %xmm1
4508; SSE-NEXT:    pand %xmm2, %xmm0
4509; SSE-NEXT:    packuswb %xmm1, %xmm0
4510; SSE-NEXT:    por {{.*}}(%rip), %xmm0
4511; SSE-NEXT:    retq
4512;
4513; AVX1-LABEL: trunc_or_const_v16i16_v16i8:
4514; AVX1:       # %bb.0:
4515; AVX1-NEXT:    vandps {{.*}}(%rip), %ymm0, %ymm0
4516; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
4517; AVX1-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
4518; AVX1-NEXT:    vpor {{.*}}(%rip), %xmm0, %xmm0
4519; AVX1-NEXT:    vzeroupper
4520; AVX1-NEXT:    retq
4521;
4522; AVX2-LABEL: trunc_or_const_v16i16_v16i8:
4523; AVX2:       # %bb.0:
4524; AVX2-NEXT:    vpand {{.*}}(%rip), %ymm0, %ymm0
4525; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
4526; AVX2-NEXT:    vpackuswb %xmm1, %xmm0, %xmm0
4527; AVX2-NEXT:    vpor {{.*}}(%rip), %xmm0, %xmm0
4528; AVX2-NEXT:    vzeroupper
4529; AVX2-NEXT:    retq
4530;
4531; AVX512F-LABEL: trunc_or_const_v16i16_v16i8:
4532; AVX512F:       # %bb.0:
4533; 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
4534; AVX512F-NEXT:    vpmovdb %zmm0, %xmm0
4535; AVX512F-NEXT:    vpor {{.*}}(%rip), %xmm0, %xmm0
4536; AVX512F-NEXT:    vzeroupper
4537; AVX512F-NEXT:    retq
4538;
4539; AVX512BW-LABEL: trunc_or_const_v16i16_v16i8:
4540; AVX512BW:       # %bb.0:
4541; AVX512BW-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
4542; AVX512BW-NEXT:    vpmovwb %zmm0, %ymm0
4543; AVX512BW-NEXT:    vpor {{.*}}(%rip), %xmm0, %xmm0
4544; AVX512BW-NEXT:    vzeroupper
4545; AVX512BW-NEXT:    retq
4546;
4547; AVX512DQ-LABEL: trunc_or_const_v16i16_v16i8:
4548; AVX512DQ:       # %bb.0:
4549; AVX512DQ-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
4550; AVX512DQ-NEXT:    vpmovdb %zmm0, %xmm0
4551; AVX512DQ-NEXT:    vpor {{.*}}(%rip), %xmm0, %xmm0
4552; AVX512DQ-NEXT:    vzeroupper
4553; AVX512DQ-NEXT:    retq
4554  %1 = or <16 x i16> %a0, <i16 0, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7, i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15>
4555  %2 = trunc <16 x i16> %1 to <16 x i8>
4556  ret <16 x i8> %2
4557}
4558
4559;
4560; complex patterns - often created by vectorizer
4561;
4562
4563define <4 x i32> @mul_add_const_v4i64_v4i32(<4 x i32> %a0, <4 x i32> %a1) nounwind {
4564; SSE-LABEL: mul_add_const_v4i64_v4i32:
4565; SSE:       # %bb.0:
4566; SSE-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[0,1,1,3]
4567; SSE-NEXT:    pshufd {{.*#+}} xmm3 = xmm0[2,3,3,3]
4568; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[0,1,1,3]
4569; SSE-NEXT:    pmuludq %xmm2, %xmm0
4570; SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[2,3,3,3]
4571; SSE-NEXT:    pmuludq %xmm3, %xmm1
4572; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
4573; SSE-NEXT:    paddd {{.*}}(%rip), %xmm0
4574; SSE-NEXT:    retq
4575;
4576; AVX-LABEL: mul_add_const_v4i64_v4i32:
4577; AVX:       # %bb.0:
4578; AVX-NEXT:    vpmulld %xmm1, %xmm0, %xmm0
4579; AVX-NEXT:    vpaddd {{.*}}(%rip), %xmm0, %xmm0
4580; AVX-NEXT:    retq
4581  %1 = sext <4 x i32> %a0 to <4 x i64>
4582  %2 = sext <4 x i32> %a1 to <4 x i64>
4583  %3 = mul <4 x i64> %1, %2
4584  %4 = add <4 x i64> %3, <i64 -3, i64 -1, i64 1, i64 3>
4585  %5 = trunc <4 x i64> %4 to <4 x i32>
4586  ret <4 x i32> %5
4587}
4588
4589define <4 x i32> @mul_add_self_v4i64_v4i32(<4 x i32> %a0, <4 x i32> %a1) nounwind {
4590; SSE-LABEL: mul_add_self_v4i64_v4i32:
4591; SSE:       # %bb.0:
4592; SSE-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[0,1,1,3]
4593; SSE-NEXT:    pshufd {{.*#+}} xmm3 = xmm0[2,3,3,3]
4594; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[0,1,1,3]
4595; SSE-NEXT:    pmuludq %xmm2, %xmm0
4596; SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[2,3,3,3]
4597; SSE-NEXT:    pmuludq %xmm3, %xmm1
4598; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
4599; SSE-NEXT:    paddd %xmm0, %xmm0
4600; SSE-NEXT:    retq
4601;
4602; AVX-LABEL: mul_add_self_v4i64_v4i32:
4603; AVX:       # %bb.0:
4604; AVX-NEXT:    vpmulld %xmm1, %xmm0, %xmm0
4605; AVX-NEXT:    vpaddd %xmm0, %xmm0, %xmm0
4606; AVX-NEXT:    retq
4607  %1 = sext <4 x i32> %a0 to <4 x i64>
4608  %2 = sext <4 x i32> %a1 to <4 x i64>
4609  %3 = mul <4 x i64> %1, %2
4610  %4 = add <4 x i64> %3, %3
4611  %5 = trunc <4 x i64> %4 to <4 x i32>
4612  ret <4 x i32> %5
4613}
4614
4615define <4 x i32> @mul_add_multiuse_v4i64_v4i32(<4 x i32> %a0, <4 x i32> %a1) nounwind {
4616; SSE-LABEL: mul_add_multiuse_v4i64_v4i32:
4617; SSE:       # %bb.0:
4618; SSE-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[0,1,1,3]
4619; SSE-NEXT:    pshufd {{.*#+}} xmm3 = xmm0[2,3,3,3]
4620; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm1[0,1,1,3]
4621; SSE-NEXT:    pmuludq %xmm2, %xmm4
4622; SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[2,3,3,3]
4623; SSE-NEXT:    pmuludq %xmm3, %xmm1
4624; SSE-NEXT:    shufps {{.*#+}} xmm4 = xmm4[0,2],xmm1[0,2]
4625; SSE-NEXT:    paddd %xmm4, %xmm0
4626; SSE-NEXT:    retq
4627;
4628; AVX-LABEL: mul_add_multiuse_v4i64_v4i32:
4629; AVX:       # %bb.0:
4630; AVX-NEXT:    vpmulld %xmm1, %xmm0, %xmm1
4631; AVX-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
4632; AVX-NEXT:    retq
4633  %1 = sext <4 x i32> %a0 to <4 x i64>
4634  %2 = sext <4 x i32> %a1 to <4 x i64>
4635  %3 = mul <4 x i64> %1, %2
4636  %4 = add <4 x i64> %1, %3
4637  %5 = trunc <4 x i64> %4 to <4 x i32>
4638  ret <4 x i32> %5
4639}
4640