1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefix=SSE --check-prefix=X86-SSE
3; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+avx  | FileCheck %s --check-prefix=AVX --check-prefix=AVX1 --check-prefix=X86-AVX --check-prefix=X86-AVX1
4; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefix=AVX --check-prefix=AVX2 --check-prefix=X86-AVX --check-prefix=X86-AVX2
5; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefix=SSE --check-prefix=X64-SSE
6; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx  | FileCheck %s --check-prefix=AVX --check-prefix=AVX1 --check-prefix=X64-AVX --check-prefix=X64-AVX1
7; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefix=AVX --check-prefix=AVX2 --check-prefix=X64-AVX --check-prefix=X64-AVX2
8
9define <4 x i32> @trunc_ashr_v4i64(<4 x i64> %a) nounwind {
10; SSE-LABEL: trunc_ashr_v4i64:
11; SSE:       # %bb.0:
12; SSE-NEXT:    psrad $31, %xmm1
13; SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[1,1,3,3]
14; SSE-NEXT:    psrad $31, %xmm0
15; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]
16; SSE-NEXT:    packssdw %xmm1, %xmm0
17; SSE-NEXT:    ret{{[l|q]}}
18;
19; AVX1-LABEL: trunc_ashr_v4i64:
20; AVX1:       # %bb.0:
21; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
22; AVX1-NEXT:    vpxor %xmm2, %xmm2, %xmm2
23; AVX1-NEXT:    vpcmpgtq %xmm1, %xmm2, %xmm1
24; AVX1-NEXT:    vpcmpgtq %xmm0, %xmm2, %xmm0
25; AVX1-NEXT:    vpackssdw %xmm1, %xmm0, %xmm0
26; AVX1-NEXT:    vzeroupper
27; AVX1-NEXT:    ret{{[l|q]}}
28;
29; AVX2-LABEL: trunc_ashr_v4i64:
30; AVX2:       # %bb.0:
31; AVX2-NEXT:    vpxor %xmm1, %xmm1, %xmm1
32; AVX2-NEXT:    vpcmpgtq %ymm0, %ymm1, %ymm0
33; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
34; AVX2-NEXT:    vpackssdw %xmm1, %xmm0, %xmm0
35; AVX2-NEXT:    vzeroupper
36; AVX2-NEXT:    ret{{[l|q]}}
37  %1 = ashr <4 x i64> %a, <i64 63, i64 63, i64 63, i64 63>
38  %2 = trunc <4 x i64> %1 to <4 x i32>
39  ret <4 x i32> %2
40}
41
42define <8 x i16> @trunc_ashr_v4i64_bitcast(<4 x i64> %a0) {
43; SSE-LABEL: trunc_ashr_v4i64_bitcast:
44; SSE:       # %bb.0:
45; SSE-NEXT:    movdqa %xmm1, %xmm2
46; SSE-NEXT:    psrad $31, %xmm2
47; SSE-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[1,3,2,3]
48; SSE-NEXT:    psrad $17, %xmm1
49; SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[1,3,2,3]
50; SSE-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
51; SSE-NEXT:    movdqa %xmm0, %xmm2
52; SSE-NEXT:    psrad $31, %xmm2
53; SSE-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[1,3,2,3]
54; SSE-NEXT:    psrad $17, %xmm0
55; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,3,2,3]
56; SSE-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
57; SSE-NEXT:    packssdw %xmm1, %xmm0
58; SSE-NEXT:    ret{{[l|q]}}
59;
60; AVX1-LABEL: trunc_ashr_v4i64_bitcast:
61; AVX1:       # %bb.0:
62; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
63; AVX1-NEXT:    vpsrad $31, %xmm1, %xmm2
64; AVX1-NEXT:    vpsrad $17, %xmm1, %xmm1
65; AVX1-NEXT:    vpshufd {{.*#+}} xmm1 = xmm1[1,1,3,3]
66; AVX1-NEXT:    vpblendw {{.*#+}} xmm1 = xmm1[0,1],xmm2[2,3],xmm1[4,5],xmm2[6,7]
67; AVX1-NEXT:    vpsrad $31, %xmm0, %xmm2
68; AVX1-NEXT:    vpsrad $17, %xmm0, %xmm0
69; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]
70; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7]
71; AVX1-NEXT:    vpackssdw %xmm1, %xmm0, %xmm0
72; AVX1-NEXT:    vzeroupper
73; AVX1-NEXT:    ret{{[l|q]}}
74;
75; AVX2-LABEL: trunc_ashr_v4i64_bitcast:
76; AVX2:       # %bb.0:
77; AVX2-NEXT:    vpsrad $31, %ymm0, %ymm1
78; AVX2-NEXT:    vpsrad $17, %ymm0, %ymm0
79; AVX2-NEXT:    vpshufd {{.*#+}} ymm0 = ymm0[1,1,3,3,5,5,7,7]
80; AVX2-NEXT:    vpblendd {{.*#+}} ymm0 = ymm0[0],ymm1[1],ymm0[2],ymm1[3],ymm0[4],ymm1[5],ymm0[6],ymm1[7]
81; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
82; AVX2-NEXT:    vpackssdw %xmm1, %xmm0, %xmm0
83; AVX2-NEXT:    vzeroupper
84; AVX2-NEXT:    ret{{[l|q]}}
85   %1 = ashr <4 x i64> %a0, <i64 49, i64 49, i64 49, i64 49>
86   %2 = bitcast <4 x i64> %1 to <8 x i32>
87   %3 = trunc <8 x i32> %2 to <8 x i16>
88   ret <8 x i16> %3
89}
90
91define <8 x i16> @trunc_ashr_v8i32(<8 x i32> %a) nounwind {
92; SSE-LABEL: trunc_ashr_v8i32:
93; SSE:       # %bb.0:
94; SSE-NEXT:    psrad $31, %xmm1
95; SSE-NEXT:    psrad $31, %xmm0
96; SSE-NEXT:    packssdw %xmm1, %xmm0
97; SSE-NEXT:    ret{{[l|q]}}
98;
99; AVX1-LABEL: trunc_ashr_v8i32:
100; AVX1:       # %bb.0:
101; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
102; AVX1-NEXT:    vpsrad $31, %xmm1, %xmm1
103; AVX1-NEXT:    vpsrad $31, %xmm0, %xmm0
104; AVX1-NEXT:    vpackssdw %xmm1, %xmm0, %xmm0
105; AVX1-NEXT:    vzeroupper
106; AVX1-NEXT:    ret{{[l|q]}}
107;
108; AVX2-LABEL: trunc_ashr_v8i32:
109; AVX2:       # %bb.0:
110; AVX2-NEXT:    vpsrad $31, %ymm0, %ymm0
111; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
112; AVX2-NEXT:    vpackssdw %xmm1, %xmm0, %xmm0
113; AVX2-NEXT:    vzeroupper
114; AVX2-NEXT:    ret{{[l|q]}}
115  %1 = ashr <8 x i32> %a, <i32 31, i32 31, i32 31, i32 31, i32 31, i32 31, i32 31, i32 31>
116  %2 = trunc <8 x i32> %1 to <8 x i16>
117  ret <8 x i16> %2
118}
119
120define <8 x i16> @trunc_ashr_v4i32_icmp_v4i32(<4 x i32> %a, <4 x i32> %b) nounwind {
121; X86-SSE-LABEL: trunc_ashr_v4i32_icmp_v4i32:
122; X86-SSE:       # %bb.0:
123; X86-SSE-NEXT:    psrad $31, %xmm0
124; X86-SSE-NEXT:    pcmpgtd {{\.LCPI.*}}, %xmm1
125; X86-SSE-NEXT:    packssdw %xmm1, %xmm0
126; X86-SSE-NEXT:    retl
127;
128; X86-AVX-LABEL: trunc_ashr_v4i32_icmp_v4i32:
129; X86-AVX:       # %bb.0:
130; X86-AVX-NEXT:    vpsrad $31, %xmm0, %xmm0
131; X86-AVX-NEXT:    vpcmpgtd {{\.LCPI.*}}, %xmm1, %xmm1
132; X86-AVX-NEXT:    vpackssdw %xmm1, %xmm0, %xmm0
133; X86-AVX-NEXT:    retl
134;
135; X64-SSE-LABEL: trunc_ashr_v4i32_icmp_v4i32:
136; X64-SSE:       # %bb.0:
137; X64-SSE-NEXT:    psrad $31, %xmm0
138; X64-SSE-NEXT:    pcmpgtd {{.*}}(%rip), %xmm1
139; X64-SSE-NEXT:    packssdw %xmm1, %xmm0
140; X64-SSE-NEXT:    retq
141;
142; X64-AVX-LABEL: trunc_ashr_v4i32_icmp_v4i32:
143; X64-AVX:       # %bb.0:
144; X64-AVX-NEXT:    vpsrad $31, %xmm0, %xmm0
145; X64-AVX-NEXT:    vpcmpgtd {{.*}}(%rip), %xmm1, %xmm1
146; X64-AVX-NEXT:    vpackssdw %xmm1, %xmm0, %xmm0
147; X64-AVX-NEXT:    retq
148  %1 = ashr <4 x i32> %a, <i32 31, i32 31, i32 31, i32 31>
149  %2 = icmp sgt <4 x i32> %b, <i32 1, i32 16, i32 255, i32 65535>
150  %3 = sext <4 x i1> %2 to <4 x i32>
151  %4 = shufflevector <4 x i32> %1, <4 x i32> %3, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
152  %5 = trunc <8 x i32> %4 to <8 x i16>
153  ret <8 x i16> %5
154}
155
156define <8 x i16> @trunc_ashr_v4i64_demandedelts(<4 x i64> %a0) {
157; X86-SSE-LABEL: trunc_ashr_v4i64_demandedelts:
158; X86-SSE:       # %bb.0:
159; X86-SSE-NEXT:    psllq $63, %xmm1
160; X86-SSE-NEXT:    psllq $63, %xmm0
161; X86-SSE-NEXT:    psrlq $63, %xmm0
162; X86-SSE-NEXT:    movdqa {{.*#+}} xmm2 = [4.9406564584124654E-324,-0.0E+0]
163; X86-SSE-NEXT:    pxor %xmm2, %xmm0
164; X86-SSE-NEXT:    psubq %xmm2, %xmm0
165; X86-SSE-NEXT:    psrlq $63, %xmm1
166; X86-SSE-NEXT:    pxor %xmm2, %xmm1
167; X86-SSE-NEXT:    psubq %xmm2, %xmm1
168; X86-SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,0,0,0]
169; X86-SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,0,0,0]
170; X86-SSE-NEXT:    packssdw %xmm1, %xmm0
171; X86-SSE-NEXT:    retl
172;
173; X86-AVX1-LABEL: trunc_ashr_v4i64_demandedelts:
174; X86-AVX1:       # %bb.0:
175; X86-AVX1-NEXT:    vpsllq $63, %xmm0, %xmm1
176; X86-AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
177; X86-AVX1-NEXT:    vpsllq $63, %xmm2, %xmm3
178; X86-AVX1-NEXT:    vpsrlq $63, %xmm3, %xmm3
179; X86-AVX1-NEXT:    vpblendw {{.*#+}} xmm2 = xmm3[0,1,2,3],xmm2[4,5,6,7]
180; X86-AVX1-NEXT:    vmovdqa {{.*#+}} xmm3 = [1,0,0,0,0,0,0,32768]
181; X86-AVX1-NEXT:    vpxor %xmm3, %xmm2, %xmm2
182; X86-AVX1-NEXT:    vpsubq %xmm3, %xmm2, %xmm2
183; X86-AVX1-NEXT:    vpsrlq $63, %xmm1, %xmm1
184; X86-AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm1[0,1,2,3],xmm0[4,5,6,7]
185; X86-AVX1-NEXT:    vpxor %xmm3, %xmm0, %xmm0
186; X86-AVX1-NEXT:    vpsubq %xmm3, %xmm0, %xmm0
187; X86-AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
188; X86-AVX1-NEXT:    vpermilps {{.*#+}} ymm0 = ymm0[0,0,0,0,4,4,4,4]
189; X86-AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
190; X86-AVX1-NEXT:    vpackssdw %xmm1, %xmm0, %xmm0
191; X86-AVX1-NEXT:    vzeroupper
192; X86-AVX1-NEXT:    retl
193;
194; X86-AVX2-LABEL: trunc_ashr_v4i64_demandedelts:
195; X86-AVX2:       # %bb.0:
196; X86-AVX2-NEXT:    vmovdqa {{.*#+}} ymm1 = [63,0,0,0,63,0,0,0]
197; X86-AVX2-NEXT:    vpsllvq %ymm1, %ymm0, %ymm0
198; X86-AVX2-NEXT:    vmovdqa {{.*#+}} ymm2 = [0,2147483648,0,2147483648,0,2147483648,0,2147483648]
199; X86-AVX2-NEXT:    vpsrlvq %ymm1, %ymm2, %ymm2
200; X86-AVX2-NEXT:    vpsrlvq %ymm1, %ymm0, %ymm0
201; X86-AVX2-NEXT:    vpxor %ymm2, %ymm0, %ymm0
202; X86-AVX2-NEXT:    vpsubq %ymm2, %ymm0, %ymm0
203; X86-AVX2-NEXT:    vpshufd {{.*#+}} ymm0 = ymm0[0,0,0,0,4,4,4,4]
204; X86-AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
205; X86-AVX2-NEXT:    vpackssdw %xmm1, %xmm0, %xmm0
206; X86-AVX2-NEXT:    vzeroupper
207; X86-AVX2-NEXT:    retl
208;
209; X64-SSE-LABEL: trunc_ashr_v4i64_demandedelts:
210; X64-SSE:       # %bb.0:
211; X64-SSE-NEXT:    psllq $63, %xmm1
212; X64-SSE-NEXT:    psllq $63, %xmm0
213; X64-SSE-NEXT:    psrlq $63, %xmm0
214; X64-SSE-NEXT:    movdqa {{.*#+}} xmm2 = [1,9223372036854775808]
215; X64-SSE-NEXT:    pxor %xmm2, %xmm0
216; X64-SSE-NEXT:    psubq %xmm2, %xmm0
217; X64-SSE-NEXT:    psrlq $63, %xmm1
218; X64-SSE-NEXT:    pxor %xmm2, %xmm1
219; X64-SSE-NEXT:    psubq %xmm2, %xmm1
220; X64-SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,0,0,0]
221; X64-SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,0,0,0]
222; X64-SSE-NEXT:    packssdw %xmm1, %xmm0
223; X64-SSE-NEXT:    retq
224;
225; X64-AVX1-LABEL: trunc_ashr_v4i64_demandedelts:
226; X64-AVX1:       # %bb.0:
227; X64-AVX1-NEXT:    vpsllq $63, %xmm0, %xmm1
228; X64-AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
229; X64-AVX1-NEXT:    vpsllq $63, %xmm2, %xmm3
230; X64-AVX1-NEXT:    vpsrlq $63, %xmm3, %xmm3
231; X64-AVX1-NEXT:    vpblendw {{.*#+}} xmm2 = xmm3[0,1,2,3],xmm2[4,5,6,7]
232; X64-AVX1-NEXT:    vmovdqa {{.*#+}} xmm3 = [1,9223372036854775808]
233; X64-AVX1-NEXT:    vpxor %xmm3, %xmm2, %xmm2
234; X64-AVX1-NEXT:    vpsubq %xmm3, %xmm2, %xmm2
235; X64-AVX1-NEXT:    vpsrlq $63, %xmm1, %xmm1
236; X64-AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm1[0,1,2,3],xmm0[4,5,6,7]
237; X64-AVX1-NEXT:    vpxor %xmm3, %xmm0, %xmm0
238; X64-AVX1-NEXT:    vpsubq %xmm3, %xmm0, %xmm0
239; X64-AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
240; X64-AVX1-NEXT:    vpermilps {{.*#+}} ymm0 = ymm0[0,0,0,0,4,4,4,4]
241; X64-AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
242; X64-AVX1-NEXT:    vpackssdw %xmm1, %xmm0, %xmm0
243; X64-AVX1-NEXT:    vzeroupper
244; X64-AVX1-NEXT:    retq
245;
246; X64-AVX2-LABEL: trunc_ashr_v4i64_demandedelts:
247; X64-AVX2:       # %bb.0:
248; X64-AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm1 = [1,1,1,1]
249; X64-AVX2-NEXT:    vpand %ymm1, %ymm0, %ymm0
250; X64-AVX2-NEXT:    vbroadcasti128 {{.*#+}} ymm1 = [1,9223372036854775808,1,9223372036854775808]
251; X64-AVX2-NEXT:    # ymm1 = mem[0,1,0,1]
252; X64-AVX2-NEXT:    vpxor %ymm1, %ymm0, %ymm0
253; X64-AVX2-NEXT:    vpsubq %ymm1, %ymm0, %ymm0
254; X64-AVX2-NEXT:    vpshufd {{.*#+}} ymm0 = ymm0[0,0,0,0,4,4,4,4]
255; X64-AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
256; X64-AVX2-NEXT:    vpackssdw %xmm1, %xmm0, %xmm0
257; X64-AVX2-NEXT:    vzeroupper
258; X64-AVX2-NEXT:    retq
259  %1 = shl <4 x i64> %a0, <i64 63, i64 0, i64 63, i64 0>
260  %2 = ashr <4 x i64> %1, <i64 63, i64 0, i64 63, i64 0>
261  %3 = bitcast <4 x i64> %2 to <8 x i32>
262  %4 = shufflevector <8 x i32> %3, <8 x i32> undef, <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 4, i32 4, i32 4, i32 4>
263  %5 = trunc <8 x i32> %4 to <8 x i16>
264  ret <8 x i16> %5
265}
266