1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+sse4.2 | FileCheck %s --check-prefix=SSE
3; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx | FileCheck %s --check-prefix=AVX --check-prefix=AVX1
4; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx2 | FileCheck %s --check-prefix=AVX --check-prefix=AVX2
5; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx512f,+avx512bw,+avx512vl | FileCheck %s --check-prefix=AVX512
6
7define i64 @test_v2f64_sext(<2 x double> %a0, <2 x double> %a1) {
8; SSE-LABEL: test_v2f64_sext:
9; SSE:       # %bb.0:
10; SSE-NEXT:    cmpltpd %xmm0, %xmm1
11; SSE-NEXT:    movmskpd %xmm1, %ecx
12; SSE-NEXT:    xorl %eax, %eax
13; SSE-NEXT:    cmpl $3, %ecx
14; SSE-NEXT:    sete %al
15; SSE-NEXT:    negq %rax
16; SSE-NEXT:    retq
17;
18; AVX-LABEL: test_v2f64_sext:
19; AVX:       # %bb.0:
20; AVX-NEXT:    vcmpltpd %xmm0, %xmm1, %xmm0
21; AVX-NEXT:    vmovmskpd %xmm0, %ecx
22; AVX-NEXT:    xorl %eax, %eax
23; AVX-NEXT:    cmpl $3, %ecx
24; AVX-NEXT:    sete %al
25; AVX-NEXT:    negq %rax
26; AVX-NEXT:    retq
27;
28; AVX512-LABEL: test_v2f64_sext:
29; AVX512:       # %bb.0:
30; AVX512-NEXT:    vcmpltpd %xmm0, %xmm1, %xmm0
31; AVX512-NEXT:    vmovmskpd %xmm0, %ecx
32; AVX512-NEXT:    xorl %eax, %eax
33; AVX512-NEXT:    cmpl $3, %ecx
34; AVX512-NEXT:    sete %al
35; AVX512-NEXT:    negq %rax
36; AVX512-NEXT:    retq
37  %c = fcmp ogt <2 x double> %a0, %a1
38  %s = sext <2 x i1> %c to <2 x i64>
39  %1 = shufflevector <2 x i64> %s, <2 x i64> undef, <2 x i32> <i32 1, i32 undef>
40  %2 = and <2 x i64> %s, %1
41  %3 = extractelement <2 x i64> %2, i32 0
42  ret i64 %3
43}
44
45define i64 @test_v4f64_sext(<4 x double> %a0, <4 x double> %a1) {
46; SSE-LABEL: test_v4f64_sext:
47; SSE:       # %bb.0:
48; SSE-NEXT:    cmpltpd %xmm1, %xmm3
49; SSE-NEXT:    cmpltpd %xmm0, %xmm2
50; SSE-NEXT:    andpd %xmm3, %xmm2
51; SSE-NEXT:    movmskpd %xmm2, %ecx
52; SSE-NEXT:    xorl %eax, %eax
53; SSE-NEXT:    cmpl $3, %ecx
54; SSE-NEXT:    sete %al
55; SSE-NEXT:    negq %rax
56; SSE-NEXT:    retq
57;
58; AVX-LABEL: test_v4f64_sext:
59; AVX:       # %bb.0:
60; AVX-NEXT:    vcmpltpd %ymm0, %ymm1, %ymm0
61; AVX-NEXT:    vmovmskpd %ymm0, %ecx
62; AVX-NEXT:    xorl %eax, %eax
63; AVX-NEXT:    cmpl $15, %ecx
64; AVX-NEXT:    sete %al
65; AVX-NEXT:    negq %rax
66; AVX-NEXT:    vzeroupper
67; AVX-NEXT:    retq
68;
69; AVX512-LABEL: test_v4f64_sext:
70; AVX512:       # %bb.0:
71; AVX512-NEXT:    vcmpltpd %ymm0, %ymm1, %ymm0
72; AVX512-NEXT:    vmovmskpd %ymm0, %ecx
73; AVX512-NEXT:    xorl %eax, %eax
74; AVX512-NEXT:    cmpl $15, %ecx
75; AVX512-NEXT:    sete %al
76; AVX512-NEXT:    negq %rax
77; AVX512-NEXT:    vzeroupper
78; AVX512-NEXT:    retq
79  %c = fcmp ogt <4 x double> %a0, %a1
80  %s = sext <4 x i1> %c to <4 x i64>
81  %1 = shufflevector <4 x i64> %s, <4 x i64> undef, <4 x i32> <i32 2, i32 3, i32 undef, i32 undef>
82  %2 = and <4 x i64> %s, %1
83  %3 = shufflevector <4 x i64> %2, <4 x i64> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
84  %4 = and <4 x i64> %2, %3
85  %5 = extractelement <4 x i64> %4, i64 0
86  ret i64 %5
87}
88
89define i64 @test_v4f64_legal_sext(<4 x double> %a0, <4 x double> %a1) {
90; SSE-LABEL: test_v4f64_legal_sext:
91; SSE:       # %bb.0:
92; SSE-NEXT:    cmpltpd %xmm1, %xmm3
93; SSE-NEXT:    cmpltpd %xmm0, %xmm2
94; SSE-NEXT:    packssdw %xmm3, %xmm2
95; SSE-NEXT:    movmskps %xmm2, %ecx
96; SSE-NEXT:    xorl %eax, %eax
97; SSE-NEXT:    cmpl $15, %ecx
98; SSE-NEXT:    sete %al
99; SSE-NEXT:    negq %rax
100; SSE-NEXT:    retq
101;
102; AVX-LABEL: test_v4f64_legal_sext:
103; AVX:       # %bb.0:
104; AVX-NEXT:    vcmpltpd %ymm0, %ymm1, %ymm0
105; AVX-NEXT:    vextractf128 $1, %ymm0, %xmm1
106; AVX-NEXT:    vpackssdw %xmm1, %xmm0, %xmm0
107; AVX-NEXT:    vmovmskps %xmm0, %ecx
108; AVX-NEXT:    xorl %eax, %eax
109; AVX-NEXT:    cmpl $15, %ecx
110; AVX-NEXT:    sete %al
111; AVX-NEXT:    negq %rax
112; AVX-NEXT:    vzeroupper
113; AVX-NEXT:    retq
114;
115; AVX512-LABEL: test_v4f64_legal_sext:
116; AVX512:       # %bb.0:
117; AVX512-NEXT:    vcmpltpd %ymm0, %ymm1, %k1
118; AVX512-NEXT:    vpcmpeqd %xmm0, %xmm0, %xmm0
119; AVX512-NEXT:    vmovdqa32 %xmm0, %xmm0 {%k1} {z}
120; AVX512-NEXT:    vmovmskps %xmm0, %ecx
121; AVX512-NEXT:    xorl %eax, %eax
122; AVX512-NEXT:    cmpl $15, %ecx
123; AVX512-NEXT:    sete %al
124; AVX512-NEXT:    negq %rax
125; AVX512-NEXT:    vzeroupper
126; AVX512-NEXT:    retq
127  %c = fcmp ogt <4 x double> %a0, %a1
128  %s = sext <4 x i1> %c to <4 x i32>
129  %1 = shufflevector <4 x i32> %s, <4 x i32> undef, <4 x i32> <i32 2, i32 3, i32 undef, i32 undef>
130  %2 = and <4 x i32> %s, %1
131  %3 = shufflevector <4 x i32> %2, <4 x i32> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
132  %4 = and <4 x i32> %2, %3
133  %5 = extractelement <4 x i32> %4, i64 0
134  %6 = sext i32 %5 to i64
135  ret i64 %6
136}
137
138define i32 @test_v4f32_sext(<4 x float> %a0, <4 x float> %a1) {
139; SSE-LABEL: test_v4f32_sext:
140; SSE:       # %bb.0:
141; SSE-NEXT:    cmpltps %xmm0, %xmm1
142; SSE-NEXT:    movmskps %xmm1, %ecx
143; SSE-NEXT:    xorl %eax, %eax
144; SSE-NEXT:    cmpl $15, %ecx
145; SSE-NEXT:    sete %al
146; SSE-NEXT:    negl %eax
147; SSE-NEXT:    retq
148;
149; AVX-LABEL: test_v4f32_sext:
150; AVX:       # %bb.0:
151; AVX-NEXT:    vcmpltps %xmm0, %xmm1, %xmm0
152; AVX-NEXT:    vmovmskps %xmm0, %ecx
153; AVX-NEXT:    xorl %eax, %eax
154; AVX-NEXT:    cmpl $15, %ecx
155; AVX-NEXT:    sete %al
156; AVX-NEXT:    negl %eax
157; AVX-NEXT:    retq
158;
159; AVX512-LABEL: test_v4f32_sext:
160; AVX512:       # %bb.0:
161; AVX512-NEXT:    vcmpltps %xmm0, %xmm1, %xmm0
162; AVX512-NEXT:    vmovmskps %xmm0, %ecx
163; AVX512-NEXT:    xorl %eax, %eax
164; AVX512-NEXT:    cmpl $15, %ecx
165; AVX512-NEXT:    sete %al
166; AVX512-NEXT:    negl %eax
167; AVX512-NEXT:    retq
168  %c = fcmp ogt <4 x float> %a0, %a1
169  %s = sext <4 x i1> %c to <4 x i32>
170  %1 = shufflevector <4 x i32> %s, <4 x i32> undef, <4 x i32> <i32 2, i32 3, i32 undef, i32 undef>
171  %2 = and <4 x i32> %s, %1
172  %3 = shufflevector <4 x i32> %2, <4 x i32> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
173  %4 = and <4 x i32> %2, %3
174  %5 = extractelement <4 x i32> %4, i32 0
175  ret i32 %5
176}
177
178define i32 @test_v8f32_sext(<8 x float> %a0, <8 x float> %a1) {
179; SSE-LABEL: test_v8f32_sext:
180; SSE:       # %bb.0:
181; SSE-NEXT:    cmpltps %xmm1, %xmm3
182; SSE-NEXT:    cmpltps %xmm0, %xmm2
183; SSE-NEXT:    andps %xmm3, %xmm2
184; SSE-NEXT:    movmskps %xmm2, %ecx
185; SSE-NEXT:    xorl %eax, %eax
186; SSE-NEXT:    cmpl $15, %ecx
187; SSE-NEXT:    sete %al
188; SSE-NEXT:    negl %eax
189; SSE-NEXT:    retq
190;
191; AVX-LABEL: test_v8f32_sext:
192; AVX:       # %bb.0:
193; AVX-NEXT:    vcmpltps %ymm0, %ymm1, %ymm0
194; AVX-NEXT:    vmovmskps %ymm0, %ecx
195; AVX-NEXT:    xorl %eax, %eax
196; AVX-NEXT:    cmpl $255, %ecx
197; AVX-NEXT:    sete %al
198; AVX-NEXT:    negl %eax
199; AVX-NEXT:    vzeroupper
200; AVX-NEXT:    retq
201;
202; AVX512-LABEL: test_v8f32_sext:
203; AVX512:       # %bb.0:
204; AVX512-NEXT:    vcmpltps %ymm0, %ymm1, %ymm0
205; AVX512-NEXT:    vmovmskps %ymm0, %ecx
206; AVX512-NEXT:    xorl %eax, %eax
207; AVX512-NEXT:    cmpl $255, %ecx
208; AVX512-NEXT:    sete %al
209; AVX512-NEXT:    negl %eax
210; AVX512-NEXT:    vzeroupper
211; AVX512-NEXT:    retq
212  %c = fcmp ogt <8 x float> %a0, %a1
213  %s = sext <8 x i1> %c to <8 x i32>
214  %1 = shufflevector <8 x i32> %s, <8 x i32> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
215  %2 = and <8 x i32> %s, %1
216  %3 = shufflevector <8 x i32> %2, <8 x i32> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
217  %4 = and <8 x i32> %2, %3
218  %5 = shufflevector <8 x i32> %4, <8 x i32> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
219  %6 = and <8 x i32> %4, %5
220  %7 = extractelement <8 x i32> %6, i32 0
221  ret i32 %7
222}
223
224define i32 @test_v8f32_legal_sext(<8 x float> %a0, <8 x float> %a1) {
225; SSE-LABEL: test_v8f32_legal_sext:
226; SSE:       # %bb.0:
227; SSE-NEXT:    cmpltps %xmm1, %xmm3
228; SSE-NEXT:    cmpltps %xmm0, %xmm2
229; SSE-NEXT:    packssdw %xmm3, %xmm2
230; SSE-NEXT:    pmovmskb %xmm2, %ecx
231; SSE-NEXT:    xorl %eax, %eax
232; SSE-NEXT:    cmpl $65535, %ecx # imm = 0xFFFF
233; SSE-NEXT:    sete %al
234; SSE-NEXT:    negl %eax
235; SSE-NEXT:    retq
236;
237; AVX-LABEL: test_v8f32_legal_sext:
238; AVX:       # %bb.0:
239; AVX-NEXT:    vcmpltps %ymm0, %ymm1, %ymm0
240; AVX-NEXT:    vextractf128 $1, %ymm0, %xmm1
241; AVX-NEXT:    vpackssdw %xmm1, %xmm0, %xmm0
242; AVX-NEXT:    vpmovmskb %xmm0, %ecx
243; AVX-NEXT:    xorl %eax, %eax
244; AVX-NEXT:    cmpl $65535, %ecx # imm = 0xFFFF
245; AVX-NEXT:    sete %al
246; AVX-NEXT:    negl %eax
247; AVX-NEXT:    vzeroupper
248; AVX-NEXT:    retq
249;
250; AVX512-LABEL: test_v8f32_legal_sext:
251; AVX512:       # %bb.0:
252; AVX512-NEXT:    vcmpltps %ymm0, %ymm1, %k0
253; AVX512-NEXT:    vpmovm2w %k0, %xmm0
254; AVX512-NEXT:    vpmovmskb %xmm0, %ecx
255; AVX512-NEXT:    xorl %eax, %eax
256; AVX512-NEXT:    cmpl $65535, %ecx # imm = 0xFFFF
257; AVX512-NEXT:    sete %al
258; AVX512-NEXT:    negl %eax
259; AVX512-NEXT:    vzeroupper
260; AVX512-NEXT:    retq
261  %c = fcmp ogt <8 x float> %a0, %a1
262  %s = sext <8 x i1> %c to <8 x i16>
263  %1 = shufflevector <8 x i16> %s, <8 x i16> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
264  %2 = and <8 x i16> %s, %1
265  %3 = shufflevector <8 x i16> %2, <8 x i16> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
266  %4 = and <8 x i16> %2, %3
267  %5 = shufflevector <8 x i16> %4, <8 x i16> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
268  %6 = and <8 x i16> %4, %5
269  %7 = extractelement <8 x i16> %6, i32 0
270  %8 = sext i16 %7 to i32
271  ret i32 %8
272}
273
274define i64 @test_v2i64_sext(<2 x i64> %a0, <2 x i64> %a1) {
275; SSE-LABEL: test_v2i64_sext:
276; SSE:       # %bb.0:
277; SSE-NEXT:    pcmpgtq %xmm1, %xmm0
278; SSE-NEXT:    movmskpd %xmm0, %ecx
279; SSE-NEXT:    xorl %eax, %eax
280; SSE-NEXT:    cmpl $3, %ecx
281; SSE-NEXT:    sete %al
282; SSE-NEXT:    negq %rax
283; SSE-NEXT:    retq
284;
285; AVX-LABEL: test_v2i64_sext:
286; AVX:       # %bb.0:
287; AVX-NEXT:    vpcmpgtq %xmm1, %xmm0, %xmm0
288; AVX-NEXT:    vmovmskpd %xmm0, %ecx
289; AVX-NEXT:    xorl %eax, %eax
290; AVX-NEXT:    cmpl $3, %ecx
291; AVX-NEXT:    sete %al
292; AVX-NEXT:    negq %rax
293; AVX-NEXT:    retq
294;
295; AVX512-LABEL: test_v2i64_sext:
296; AVX512:       # %bb.0:
297; AVX512-NEXT:    vpcmpgtq %xmm1, %xmm0, %xmm0
298; AVX512-NEXT:    vmovmskpd %xmm0, %ecx
299; AVX512-NEXT:    xorl %eax, %eax
300; AVX512-NEXT:    cmpl $3, %ecx
301; AVX512-NEXT:    sete %al
302; AVX512-NEXT:    negq %rax
303; AVX512-NEXT:    retq
304  %c = icmp sgt <2 x i64> %a0, %a1
305  %s = sext <2 x i1> %c to <2 x i64>
306  %1 = shufflevector <2 x i64> %s, <2 x i64> undef, <2 x i32> <i32 1, i32 undef>
307  %2 = and <2 x i64> %s, %1
308  %3 = extractelement <2 x i64> %2, i32 0
309  ret i64 %3
310}
311
312define i64 @test_v4i64_sext(<4 x i64> %a0, <4 x i64> %a1) {
313; SSE-LABEL: test_v4i64_sext:
314; SSE:       # %bb.0:
315; SSE-NEXT:    pcmpgtq %xmm3, %xmm1
316; SSE-NEXT:    pcmpgtq %xmm2, %xmm0
317; SSE-NEXT:    pand %xmm1, %xmm0
318; SSE-NEXT:    movmskpd %xmm0, %ecx
319; SSE-NEXT:    xorl %eax, %eax
320; SSE-NEXT:    cmpl $3, %ecx
321; SSE-NEXT:    sete %al
322; SSE-NEXT:    negq %rax
323; SSE-NEXT:    retq
324;
325; AVX1-LABEL: test_v4i64_sext:
326; AVX1:       # %bb.0:
327; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
328; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
329; AVX1-NEXT:    vpcmpgtq %xmm2, %xmm3, %xmm2
330; AVX1-NEXT:    vpcmpgtq %xmm1, %xmm0, %xmm0
331; AVX1-NEXT:    vpand %xmm2, %xmm0, %xmm0
332; AVX1-NEXT:    vmovmskpd %xmm0, %ecx
333; AVX1-NEXT:    xorl %eax, %eax
334; AVX1-NEXT:    cmpl $3, %ecx
335; AVX1-NEXT:    sete %al
336; AVX1-NEXT:    negq %rax
337; AVX1-NEXT:    vzeroupper
338; AVX1-NEXT:    retq
339;
340; AVX2-LABEL: test_v4i64_sext:
341; AVX2:       # %bb.0:
342; AVX2-NEXT:    vpcmpgtq %ymm1, %ymm0, %ymm0
343; AVX2-NEXT:    vmovmskpd %ymm0, %ecx
344; AVX2-NEXT:    xorl %eax, %eax
345; AVX2-NEXT:    cmpl $15, %ecx
346; AVX2-NEXT:    sete %al
347; AVX2-NEXT:    negq %rax
348; AVX2-NEXT:    vzeroupper
349; AVX2-NEXT:    retq
350;
351; AVX512-LABEL: test_v4i64_sext:
352; AVX512:       # %bb.0:
353; AVX512-NEXT:    vpcmpgtq %ymm1, %ymm0, %ymm0
354; AVX512-NEXT:    vmovmskpd %ymm0, %ecx
355; AVX512-NEXT:    xorl %eax, %eax
356; AVX512-NEXT:    cmpl $15, %ecx
357; AVX512-NEXT:    sete %al
358; AVX512-NEXT:    negq %rax
359; AVX512-NEXT:    vzeroupper
360; AVX512-NEXT:    retq
361  %c = icmp sgt <4 x i64> %a0, %a1
362  %s = sext <4 x i1> %c to <4 x i64>
363  %1 = shufflevector <4 x i64> %s, <4 x i64> undef, <4 x i32> <i32 2, i32 3, i32 undef, i32 undef>
364  %2 = and <4 x i64> %s, %1
365  %3 = shufflevector <4 x i64> %2, <4 x i64> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
366  %4 = and <4 x i64> %2, %3
367  %5 = extractelement <4 x i64> %4, i64 0
368  ret i64 %5
369}
370
371define i64 @test_v4i64_legal_sext(<4 x i64> %a0, <4 x i64> %a1) {
372; SSE-LABEL: test_v4i64_legal_sext:
373; SSE:       # %bb.0:
374; SSE-NEXT:    pcmpgtq %xmm3, %xmm1
375; SSE-NEXT:    pcmpgtq %xmm2, %xmm0
376; SSE-NEXT:    packssdw %xmm1, %xmm0
377; SSE-NEXT:    movmskps %xmm0, %ecx
378; SSE-NEXT:    xorl %eax, %eax
379; SSE-NEXT:    cmpl $15, %ecx
380; SSE-NEXT:    sete %al
381; SSE-NEXT:    negq %rax
382; SSE-NEXT:    retq
383;
384; AVX1-LABEL: test_v4i64_legal_sext:
385; AVX1:       # %bb.0:
386; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
387; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
388; AVX1-NEXT:    vpcmpgtq %xmm2, %xmm3, %xmm2
389; AVX1-NEXT:    vpcmpgtq %xmm1, %xmm0, %xmm0
390; AVX1-NEXT:    vpackssdw %xmm2, %xmm0, %xmm0
391; AVX1-NEXT:    vmovmskps %xmm0, %ecx
392; AVX1-NEXT:    xorl %eax, %eax
393; AVX1-NEXT:    cmpl $15, %ecx
394; AVX1-NEXT:    sete %al
395; AVX1-NEXT:    negq %rax
396; AVX1-NEXT:    vzeroupper
397; AVX1-NEXT:    retq
398;
399; AVX2-LABEL: test_v4i64_legal_sext:
400; AVX2:       # %bb.0:
401; AVX2-NEXT:    vpcmpgtq %ymm1, %ymm0, %ymm0
402; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
403; AVX2-NEXT:    vpackssdw %xmm1, %xmm0, %xmm0
404; AVX2-NEXT:    vmovmskps %xmm0, %ecx
405; AVX2-NEXT:    xorl %eax, %eax
406; AVX2-NEXT:    cmpl $15, %ecx
407; AVX2-NEXT:    sete %al
408; AVX2-NEXT:    negq %rax
409; AVX2-NEXT:    vzeroupper
410; AVX2-NEXT:    retq
411;
412; AVX512-LABEL: test_v4i64_legal_sext:
413; AVX512:       # %bb.0:
414; AVX512-NEXT:    vpcmpgtq %ymm1, %ymm0, %k1
415; AVX512-NEXT:    vpcmpeqd %xmm0, %xmm0, %xmm0
416; AVX512-NEXT:    vmovdqa32 %xmm0, %xmm0 {%k1} {z}
417; AVX512-NEXT:    vmovmskps %xmm0, %ecx
418; AVX512-NEXT:    xorl %eax, %eax
419; AVX512-NEXT:    cmpl $15, %ecx
420; AVX512-NEXT:    sete %al
421; AVX512-NEXT:    negq %rax
422; AVX512-NEXT:    vzeroupper
423; AVX512-NEXT:    retq
424  %c = icmp sgt <4 x i64> %a0, %a1
425  %s = sext <4 x i1> %c to <4 x i32>
426  %1 = shufflevector <4 x i32> %s, <4 x i32> undef, <4 x i32> <i32 2, i32 3, i32 undef, i32 undef>
427  %2 = and <4 x i32> %s, %1
428  %3 = shufflevector <4 x i32> %2, <4 x i32> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
429  %4 = and <4 x i32> %2, %3
430  %5 = extractelement <4 x i32> %4, i64 0
431  %6 = sext i32 %5 to i64
432  ret i64 %6
433}
434
435define i32 @test_v4i32_sext(<4 x i32> %a0, <4 x i32> %a1) {
436; SSE-LABEL: test_v4i32_sext:
437; SSE:       # %bb.0:
438; SSE-NEXT:    pcmpgtd %xmm1, %xmm0
439; SSE-NEXT:    movmskps %xmm0, %ecx
440; SSE-NEXT:    xorl %eax, %eax
441; SSE-NEXT:    cmpl $15, %ecx
442; SSE-NEXT:    sete %al
443; SSE-NEXT:    negl %eax
444; SSE-NEXT:    retq
445;
446; AVX-LABEL: test_v4i32_sext:
447; AVX:       # %bb.0:
448; AVX-NEXT:    vpcmpgtd %xmm1, %xmm0, %xmm0
449; AVX-NEXT:    vmovmskps %xmm0, %ecx
450; AVX-NEXT:    xorl %eax, %eax
451; AVX-NEXT:    cmpl $15, %ecx
452; AVX-NEXT:    sete %al
453; AVX-NEXT:    negl %eax
454; AVX-NEXT:    retq
455;
456; AVX512-LABEL: test_v4i32_sext:
457; AVX512:       # %bb.0:
458; AVX512-NEXT:    vpcmpgtd %xmm1, %xmm0, %xmm0
459; AVX512-NEXT:    vmovmskps %xmm0, %ecx
460; AVX512-NEXT:    xorl %eax, %eax
461; AVX512-NEXT:    cmpl $15, %ecx
462; AVX512-NEXT:    sete %al
463; AVX512-NEXT:    negl %eax
464; AVX512-NEXT:    retq
465  %c = icmp sgt <4 x i32> %a0, %a1
466  %s = sext <4 x i1> %c to <4 x i32>
467  %1 = shufflevector <4 x i32> %s, <4 x i32> undef, <4 x i32> <i32 2, i32 3, i32 undef, i32 undef>
468  %2 = and <4 x i32> %s, %1
469  %3 = shufflevector <4 x i32> %2, <4 x i32> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
470  %4 = and <4 x i32> %2, %3
471  %5 = extractelement <4 x i32> %4, i32 0
472  ret i32 %5
473}
474
475define i32 @test_v8i32_sext(<8 x i32> %a0, <8 x i32> %a1) {
476; SSE-LABEL: test_v8i32_sext:
477; SSE:       # %bb.0:
478; SSE-NEXT:    pcmpgtd %xmm3, %xmm1
479; SSE-NEXT:    pcmpgtd %xmm2, %xmm0
480; SSE-NEXT:    pand %xmm1, %xmm0
481; SSE-NEXT:    movmskps %xmm0, %ecx
482; SSE-NEXT:    xorl %eax, %eax
483; SSE-NEXT:    cmpl $15, %ecx
484; SSE-NEXT:    sete %al
485; SSE-NEXT:    negl %eax
486; SSE-NEXT:    retq
487;
488; AVX1-LABEL: test_v8i32_sext:
489; AVX1:       # %bb.0:
490; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
491; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
492; AVX1-NEXT:    vpcmpgtd %xmm2, %xmm3, %xmm2
493; AVX1-NEXT:    vpcmpgtd %xmm1, %xmm0, %xmm0
494; AVX1-NEXT:    vpand %xmm2, %xmm0, %xmm0
495; AVX1-NEXT:    vmovmskps %xmm0, %ecx
496; AVX1-NEXT:    xorl %eax, %eax
497; AVX1-NEXT:    cmpl $15, %ecx
498; AVX1-NEXT:    sete %al
499; AVX1-NEXT:    negl %eax
500; AVX1-NEXT:    vzeroupper
501; AVX1-NEXT:    retq
502;
503; AVX2-LABEL: test_v8i32_sext:
504; AVX2:       # %bb.0:
505; AVX2-NEXT:    vpcmpgtd %ymm1, %ymm0, %ymm0
506; AVX2-NEXT:    vmovmskps %ymm0, %ecx
507; AVX2-NEXT:    xorl %eax, %eax
508; AVX2-NEXT:    cmpl $255, %ecx
509; AVX2-NEXT:    sete %al
510; AVX2-NEXT:    negl %eax
511; AVX2-NEXT:    vzeroupper
512; AVX2-NEXT:    retq
513;
514; AVX512-LABEL: test_v8i32_sext:
515; AVX512:       # %bb.0:
516; AVX512-NEXT:    vpcmpgtd %ymm1, %ymm0, %ymm0
517; AVX512-NEXT:    vmovmskps %ymm0, %ecx
518; AVX512-NEXT:    xorl %eax, %eax
519; AVX512-NEXT:    cmpl $255, %ecx
520; AVX512-NEXT:    sete %al
521; AVX512-NEXT:    negl %eax
522; AVX512-NEXT:    vzeroupper
523; AVX512-NEXT:    retq
524  %c = icmp sgt <8 x i32> %a0, %a1
525  %s = sext <8 x i1> %c to <8 x i32>
526  %1 = shufflevector <8 x i32> %s, <8 x i32> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
527  %2 = and <8 x i32> %s, %1
528  %3 = shufflevector <8 x i32> %2, <8 x i32> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
529  %4 = and <8 x i32> %2, %3
530  %5 = shufflevector <8 x i32> %4, <8 x i32> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
531  %6 = and <8 x i32> %4, %5
532  %7 = extractelement <8 x i32> %6, i32 0
533  ret i32 %7
534}
535
536define i32 @test_v8i32_legal_sext(<8 x i32> %a0, <8 x i32> %a1) {
537; SSE-LABEL: test_v8i32_legal_sext:
538; SSE:       # %bb.0:
539; SSE-NEXT:    pcmpgtd %xmm3, %xmm1
540; SSE-NEXT:    pcmpgtd %xmm2, %xmm0
541; SSE-NEXT:    packssdw %xmm1, %xmm0
542; SSE-NEXT:    pmovmskb %xmm0, %ecx
543; SSE-NEXT:    xorl %eax, %eax
544; SSE-NEXT:    cmpl $65535, %ecx # imm = 0xFFFF
545; SSE-NEXT:    sete %al
546; SSE-NEXT:    negl %eax
547; SSE-NEXT:    retq
548;
549; AVX1-LABEL: test_v8i32_legal_sext:
550; AVX1:       # %bb.0:
551; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
552; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
553; AVX1-NEXT:    vpcmpgtd %xmm2, %xmm3, %xmm2
554; AVX1-NEXT:    vpcmpgtd %xmm1, %xmm0, %xmm0
555; AVX1-NEXT:    vpackssdw %xmm2, %xmm0, %xmm0
556; AVX1-NEXT:    vpmovmskb %xmm0, %ecx
557; AVX1-NEXT:    xorl %eax, %eax
558; AVX1-NEXT:    cmpl $65535, %ecx # imm = 0xFFFF
559; AVX1-NEXT:    sete %al
560; AVX1-NEXT:    negl %eax
561; AVX1-NEXT:    vzeroupper
562; AVX1-NEXT:    retq
563;
564; AVX2-LABEL: test_v8i32_legal_sext:
565; AVX2:       # %bb.0:
566; AVX2-NEXT:    vpcmpgtd %ymm1, %ymm0, %ymm0
567; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
568; AVX2-NEXT:    vpackssdw %xmm1, %xmm0, %xmm0
569; AVX2-NEXT:    vpmovmskb %xmm0, %ecx
570; AVX2-NEXT:    xorl %eax, %eax
571; AVX2-NEXT:    cmpl $65535, %ecx # imm = 0xFFFF
572; AVX2-NEXT:    sete %al
573; AVX2-NEXT:    negl %eax
574; AVX2-NEXT:    vzeroupper
575; AVX2-NEXT:    retq
576;
577; AVX512-LABEL: test_v8i32_legal_sext:
578; AVX512:       # %bb.0:
579; AVX512-NEXT:    vpcmpgtd %ymm1, %ymm0, %k0
580; AVX512-NEXT:    vpmovm2w %k0, %xmm0
581; AVX512-NEXT:    vpmovmskb %xmm0, %ecx
582; AVX512-NEXT:    xorl %eax, %eax
583; AVX512-NEXT:    cmpl $65535, %ecx # imm = 0xFFFF
584; AVX512-NEXT:    sete %al
585; AVX512-NEXT:    negl %eax
586; AVX512-NEXT:    vzeroupper
587; AVX512-NEXT:    retq
588  %c = icmp sgt <8 x i32> %a0, %a1
589  %s = sext <8 x i1> %c to <8 x i16>
590  %1 = shufflevector <8 x i16> %s, <8 x i16> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
591  %2 = and <8 x i16> %s, %1
592  %3 = shufflevector <8 x i16> %2, <8 x i16> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
593  %4 = and <8 x i16> %2, %3
594  %5 = shufflevector <8 x i16> %4, <8 x i16> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
595  %6 = and <8 x i16> %4, %5
596  %7 = extractelement <8 x i16> %6, i32 0
597  %8 = sext i16 %7 to i32
598  ret i32 %8
599}
600
601define i16 @test_v8i16_sext(<8 x i16> %a0, <8 x i16> %a1) {
602; SSE-LABEL: test_v8i16_sext:
603; SSE:       # %bb.0:
604; SSE-NEXT:    pcmpgtw %xmm1, %xmm0
605; SSE-NEXT:    pmovmskb %xmm0, %ecx
606; SSE-NEXT:    xorl %eax, %eax
607; SSE-NEXT:    cmpl $65535, %ecx # imm = 0xFFFF
608; SSE-NEXT:    sete %al
609; SSE-NEXT:    negl %eax
610; SSE-NEXT:    # kill: def $ax killed $ax killed $eax
611; SSE-NEXT:    retq
612;
613; AVX-LABEL: test_v8i16_sext:
614; AVX:       # %bb.0:
615; AVX-NEXT:    vpcmpgtw %xmm1, %xmm0, %xmm0
616; AVX-NEXT:    vpmovmskb %xmm0, %ecx
617; AVX-NEXT:    xorl %eax, %eax
618; AVX-NEXT:    cmpl $65535, %ecx # imm = 0xFFFF
619; AVX-NEXT:    sete %al
620; AVX-NEXT:    negl %eax
621; AVX-NEXT:    # kill: def $ax killed $ax killed $eax
622; AVX-NEXT:    retq
623;
624; AVX512-LABEL: test_v8i16_sext:
625; AVX512:       # %bb.0:
626; AVX512-NEXT:    vpcmpgtw %xmm1, %xmm0, %xmm0
627; AVX512-NEXT:    vpmovmskb %xmm0, %ecx
628; AVX512-NEXT:    xorl %eax, %eax
629; AVX512-NEXT:    cmpl $65535, %ecx # imm = 0xFFFF
630; AVX512-NEXT:    sete %al
631; AVX512-NEXT:    negl %eax
632; AVX512-NEXT:    # kill: def $ax killed $ax killed $eax
633; AVX512-NEXT:    retq
634  %c = icmp sgt <8 x i16> %a0, %a1
635  %s = sext <8 x i1> %c to <8 x i16>
636  %1 = shufflevector <8 x i16> %s, <8 x i16> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
637  %2 = and <8 x i16> %s, %1
638  %3 = shufflevector <8 x i16> %2, <8 x i16> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
639  %4 = and <8 x i16> %2, %3
640  %5 = shufflevector <8 x i16> %4, <8 x i16> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
641  %6 = and <8 x i16> %4, %5
642  %7 = extractelement <8 x i16> %6, i32 0
643  ret i16 %7
644}
645
646define i16 @test_v16i16_sext(<16 x i16> %a0, <16 x i16> %a1) {
647; SSE-LABEL: test_v16i16_sext:
648; SSE:       # %bb.0:
649; SSE-NEXT:    pcmpgtw %xmm3, %xmm1
650; SSE-NEXT:    pcmpgtw %xmm2, %xmm0
651; SSE-NEXT:    pand %xmm1, %xmm0
652; SSE-NEXT:    pmovmskb %xmm0, %ecx
653; SSE-NEXT:    xorl %eax, %eax
654; SSE-NEXT:    cmpl $65535, %ecx # imm = 0xFFFF
655; SSE-NEXT:    sete %al
656; SSE-NEXT:    negl %eax
657; SSE-NEXT:    # kill: def $ax killed $ax killed $eax
658; SSE-NEXT:    retq
659;
660; AVX1-LABEL: test_v16i16_sext:
661; AVX1:       # %bb.0:
662; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
663; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
664; AVX1-NEXT:    vpcmpgtw %xmm2, %xmm3, %xmm2
665; AVX1-NEXT:    vpcmpgtw %xmm1, %xmm0, %xmm0
666; AVX1-NEXT:    vpand %xmm2, %xmm0, %xmm0
667; AVX1-NEXT:    vpmovmskb %xmm0, %ecx
668; AVX1-NEXT:    xorl %eax, %eax
669; AVX1-NEXT:    cmpl $65535, %ecx # imm = 0xFFFF
670; AVX1-NEXT:    sete %al
671; AVX1-NEXT:    negl %eax
672; AVX1-NEXT:    # kill: def $ax killed $ax killed $eax
673; AVX1-NEXT:    vzeroupper
674; AVX1-NEXT:    retq
675;
676; AVX2-LABEL: test_v16i16_sext:
677; AVX2:       # %bb.0:
678; AVX2-NEXT:    vpcmpgtw %ymm1, %ymm0, %ymm0
679; AVX2-NEXT:    vpmovmskb %ymm0, %ecx
680; AVX2-NEXT:    xorl %eax, %eax
681; AVX2-NEXT:    cmpl $-1, %ecx
682; AVX2-NEXT:    sete %al
683; AVX2-NEXT:    negl %eax
684; AVX2-NEXT:    # kill: def $ax killed $ax killed $eax
685; AVX2-NEXT:    vzeroupper
686; AVX2-NEXT:    retq
687;
688; AVX512-LABEL: test_v16i16_sext:
689; AVX512:       # %bb.0:
690; AVX512-NEXT:    vpcmpgtw %ymm1, %ymm0, %ymm0
691; AVX512-NEXT:    vpmovmskb %ymm0, %ecx
692; AVX512-NEXT:    xorl %eax, %eax
693; AVX512-NEXT:    cmpl $-1, %ecx
694; AVX512-NEXT:    sete %al
695; AVX512-NEXT:    negl %eax
696; AVX512-NEXT:    # kill: def $ax killed $ax killed $eax
697; AVX512-NEXT:    vzeroupper
698; AVX512-NEXT:    retq
699  %c = icmp sgt <16 x i16> %a0, %a1
700  %s = sext <16 x i1> %c to <16 x i16>
701  %1 = shufflevector <16 x i16> %s, <16 x i16> undef, <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
702  %2 = and <16 x i16> %s, %1
703  %3 = shufflevector <16 x i16> %2, <16 x i16> undef, <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
704  %4 = and <16 x i16> %2, %3
705  %5 = shufflevector <16 x i16> %4, <16 x i16> undef, <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
706  %6 = and <16 x i16> %4, %5
707  %7 = shufflevector <16 x i16> %6, <16 x i16> undef, <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
708  %8 = and <16 x i16> %6, %7
709  %9 = extractelement <16 x i16> %8, i32 0
710  ret i16 %9
711}
712
713define i16 @test_v16i16_legal_sext(<16 x i16> %a0, <16 x i16> %a1) {
714; SSE-LABEL: test_v16i16_legal_sext:
715; SSE:       # %bb.0:
716; SSE-NEXT:    pcmpgtw %xmm3, %xmm1
717; SSE-NEXT:    pcmpgtw %xmm2, %xmm0
718; SSE-NEXT:    packsswb %xmm1, %xmm0
719; SSE-NEXT:    pmovmskb %xmm0, %eax
720; SSE-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
721; SSE-NEXT:    sete %al
722; SSE-NEXT:    negb %al
723; SSE-NEXT:    movsbl %al, %eax
724; SSE-NEXT:    # kill: def $ax killed $ax killed $eax
725; SSE-NEXT:    retq
726;
727; AVX1-LABEL: test_v16i16_legal_sext:
728; AVX1:       # %bb.0:
729; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
730; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
731; AVX1-NEXT:    vpcmpgtw %xmm2, %xmm3, %xmm2
732; AVX1-NEXT:    vpcmpgtw %xmm1, %xmm0, %xmm0
733; AVX1-NEXT:    vpacksswb %xmm2, %xmm0, %xmm0
734; AVX1-NEXT:    vpmovmskb %xmm0, %eax
735; AVX1-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
736; AVX1-NEXT:    sete %al
737; AVX1-NEXT:    negb %al
738; AVX1-NEXT:    movsbl %al, %eax
739; AVX1-NEXT:    # kill: def $ax killed $ax killed $eax
740; AVX1-NEXT:    vzeroupper
741; AVX1-NEXT:    retq
742;
743; AVX2-LABEL: test_v16i16_legal_sext:
744; AVX2:       # %bb.0:
745; AVX2-NEXT:    vpcmpgtw %ymm1, %ymm0, %ymm0
746; AVX2-NEXT:    vpmovmskb %ymm0, %eax
747; AVX2-NEXT:    cmpl $-1, %eax
748; AVX2-NEXT:    sete %al
749; AVX2-NEXT:    negb %al
750; AVX2-NEXT:    movsbl %al, %eax
751; AVX2-NEXT:    # kill: def $ax killed $ax killed $eax
752; AVX2-NEXT:    vzeroupper
753; AVX2-NEXT:    retq
754;
755; AVX512-LABEL: test_v16i16_legal_sext:
756; AVX512:       # %bb.0:
757; AVX512-NEXT:    vpcmpgtw %ymm1, %ymm0, %k0
758; AVX512-NEXT:    vpmovm2b %k0, %xmm0
759; AVX512-NEXT:    vpmovmskb %xmm0, %eax
760; AVX512-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
761; AVX512-NEXT:    sete %al
762; AVX512-NEXT:    negb %al
763; AVX512-NEXT:    movsbl %al, %eax
764; AVX512-NEXT:    # kill: def $ax killed $ax killed $eax
765; AVX512-NEXT:    vzeroupper
766; AVX512-NEXT:    retq
767  %c  = icmp sgt <16 x i16> %a0, %a1
768  %s  = sext <16 x i1> %c to <16 x i8>
769  %1  = shufflevector <16 x i8> %s, <16 x i8> undef, <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
770  %2  = and <16 x i8> %s, %1
771  %3  = shufflevector <16 x i8> %2, <16 x i8> undef, <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
772  %4  = and <16 x i8> %2, %3
773  %5  = shufflevector <16 x i8> %4, <16 x i8> undef, <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
774  %6  = and <16 x i8> %4, %5
775  %7  = shufflevector <16 x i8> %6, <16 x i8> undef, <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
776  %8  = and <16 x i8> %6, %7
777  %9  = extractelement <16 x i8> %8, i32 0
778  %10 = sext i8 %9 to i16
779  ret i16 %10
780}
781
782define i8 @test_v16i8_sext(<16 x i8> %a0, <16 x i8> %a1) {
783; SSE-LABEL: test_v16i8_sext:
784; SSE:       # %bb.0:
785; SSE-NEXT:    pcmpgtb %xmm1, %xmm0
786; SSE-NEXT:    pmovmskb %xmm0, %eax
787; SSE-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
788; SSE-NEXT:    sete %al
789; SSE-NEXT:    negb %al
790; SSE-NEXT:    retq
791;
792; AVX-LABEL: test_v16i8_sext:
793; AVX:       # %bb.0:
794; AVX-NEXT:    vpcmpgtb %xmm1, %xmm0, %xmm0
795; AVX-NEXT:    vpmovmskb %xmm0, %eax
796; AVX-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
797; AVX-NEXT:    sete %al
798; AVX-NEXT:    negb %al
799; AVX-NEXT:    retq
800;
801; AVX512-LABEL: test_v16i8_sext:
802; AVX512:       # %bb.0:
803; AVX512-NEXT:    vpcmpgtb %xmm1, %xmm0, %xmm0
804; AVX512-NEXT:    vpmovmskb %xmm0, %eax
805; AVX512-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
806; AVX512-NEXT:    sete %al
807; AVX512-NEXT:    negb %al
808; AVX512-NEXT:    retq
809  %c = icmp sgt <16 x i8> %a0, %a1
810  %s = sext <16 x i1> %c to <16 x i8>
811  %1 = shufflevector <16 x i8> %s, <16 x i8> undef, <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
812  %2 = and <16 x i8> %s, %1
813  %3 = shufflevector <16 x i8> %2, <16 x i8> undef, <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
814  %4 = and <16 x i8> %2, %3
815  %5 = shufflevector <16 x i8> %4, <16 x i8> undef, <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
816  %6 = and <16 x i8> %4, %5
817  %7 = shufflevector <16 x i8> %6, <16 x i8> undef, <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
818  %8 = and <16 x i8> %6, %7
819  %9 = extractelement <16 x i8> %8, i32 0
820  ret i8 %9
821}
822
823define i8 @test_v32i8_sext(<32 x i8> %a0, <32 x i8> %a1) {
824; SSE-LABEL: test_v32i8_sext:
825; SSE:       # %bb.0:
826; SSE-NEXT:    pcmpgtb %xmm3, %xmm1
827; SSE-NEXT:    pcmpgtb %xmm2, %xmm0
828; SSE-NEXT:    pand %xmm1, %xmm0
829; SSE-NEXT:    pmovmskb %xmm0, %eax
830; SSE-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
831; SSE-NEXT:    sete %al
832; SSE-NEXT:    negb %al
833; SSE-NEXT:    retq
834;
835; AVX1-LABEL: test_v32i8_sext:
836; AVX1:       # %bb.0:
837; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
838; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
839; AVX1-NEXT:    vpcmpgtb %xmm2, %xmm3, %xmm2
840; AVX1-NEXT:    vpcmpgtb %xmm1, %xmm0, %xmm0
841; AVX1-NEXT:    vpand %xmm2, %xmm0, %xmm0
842; AVX1-NEXT:    vpmovmskb %xmm0, %eax
843; AVX1-NEXT:    cmpl $65535, %eax # imm = 0xFFFF
844; AVX1-NEXT:    sete %al
845; AVX1-NEXT:    negb %al
846; AVX1-NEXT:    vzeroupper
847; AVX1-NEXT:    retq
848;
849; AVX2-LABEL: test_v32i8_sext:
850; AVX2:       # %bb.0:
851; AVX2-NEXT:    vpcmpgtb %ymm1, %ymm0, %ymm0
852; AVX2-NEXT:    vpmovmskb %ymm0, %eax
853; AVX2-NEXT:    cmpl $-1, %eax
854; AVX2-NEXT:    sete %al
855; AVX2-NEXT:    negb %al
856; AVX2-NEXT:    vzeroupper
857; AVX2-NEXT:    retq
858;
859; AVX512-LABEL: test_v32i8_sext:
860; AVX512:       # %bb.0:
861; AVX512-NEXT:    vpcmpgtb %ymm1, %ymm0, %ymm0
862; AVX512-NEXT:    vpmovmskb %ymm0, %eax
863; AVX512-NEXT:    cmpl $-1, %eax
864; AVX512-NEXT:    sete %al
865; AVX512-NEXT:    negb %al
866; AVX512-NEXT:    vzeroupper
867; AVX512-NEXT:    retq
868  %c  = icmp sgt <32 x i8> %a0, %a1
869  %s  = sext <32 x i1> %c to <32 x i8>
870  %1  = shufflevector <32 x i8> %s, <32 x i8> undef, <32 x i32> <i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
871  %2  = and <32 x i8> %s, %1
872  %3  = shufflevector <32 x i8> %2, <32 x i8> undef, <32 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
873  %4  = and <32 x i8> %2, %3
874  %5  = shufflevector <32 x i8> %4, <32 x i8> undef, <32 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
875  %6  = and <32 x i8> %4, %5
876  %7  = shufflevector <32 x i8> %6, <32 x i8> undef, <32 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
877  %8  = and <32 x i8> %6, %7
878  %9  = shufflevector <32 x i8> %8, <32 x i8> undef, <32 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
879  %10 = and <32 x i8> %8, %9
880  %11 = extractelement <32 x i8> %10, i32 0
881  ret i8 %11
882}
883
884; Should not "MOVMSK(PCMPEQ(..)) -> PTESTZ(..)" when cmp result has muti-uses.
885define i32 @test_v32i8_muti_uses(<32 x i8> %x, <32 x i8>%y, i32 %z) {
886; SSE-LABEL: test_v32i8_muti_uses:
887; SSE:       # %bb.0:
888; SSE-NEXT:    pcmpeqb %xmm2, %xmm0
889; SSE-NEXT:    pmovmskb %xmm0, %eax
890; SSE-NEXT:    pcmpeqb %xmm3, %xmm1
891; SSE-NEXT:    pmovmskb %xmm1, %ecx
892; SSE-NEXT:    shll $16, %ecx
893; SSE-NEXT:    orl %eax, %ecx
894; SSE-NEXT:    cmpl $-1, %ecx
895; SSE-NEXT:    movl $16, %eax
896; SSE-NEXT:    cmovnel %ecx, %eax
897; SSE-NEXT:    retq
898;
899; AVX1-LABEL: test_v32i8_muti_uses:
900; AVX1:       # %bb.0:
901; AVX1-NEXT:    vpcmpeqb %xmm1, %xmm0, %xmm2
902; AVX1-NEXT:    vpmovmskb %xmm2, %eax
903; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm1
904; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
905; AVX1-NEXT:    vpcmpeqb %xmm1, %xmm0, %xmm0
906; AVX1-NEXT:    vpmovmskb %xmm0, %ecx
907; AVX1-NEXT:    shll $16, %ecx
908; AVX1-NEXT:    orl %eax, %ecx
909; AVX1-NEXT:    cmpl $-1, %ecx
910; AVX1-NEXT:    movl $16, %eax
911; AVX1-NEXT:    cmovnel %ecx, %eax
912; AVX1-NEXT:    vzeroupper
913; AVX1-NEXT:    retq
914;
915; AVX2-LABEL: test_v32i8_muti_uses:
916; AVX2:       # %bb.0:
917; AVX2-NEXT:    vpcmpeqb %ymm1, %ymm0, %ymm0
918; AVX2-NEXT:    vpmovmskb %ymm0, %ecx
919; AVX2-NEXT:    cmpl $-1, %ecx
920; AVX2-NEXT:    movl $16, %eax
921; AVX2-NEXT:    cmovnel %ecx, %eax
922; AVX2-NEXT:    vzeroupper
923; AVX2-NEXT:    retq
924;
925; AVX512-LABEL: test_v32i8_muti_uses:
926; AVX512:       # %bb.0:
927; AVX512-NEXT:    vpcmpeqb %ymm1, %ymm0, %k0
928; AVX512-NEXT:    kortestd %k0, %k0
929; AVX512-NEXT:    kmovd %k0, %ecx
930; AVX512-NEXT:    movl $16, %eax
931; AVX512-NEXT:    cmovael %ecx, %eax
932; AVX512-NEXT:    vzeroupper
933; AVX512-NEXT:    retq
934  %a = icmp eq <32 x i8> %x, %y
935  %b = bitcast <32 x i1> %a to i32
936  %c = icmp eq i32 %b, -1
937  %res = select i1 %c, i32 16, i32 %b
938  ret i32 %res
939}
940
941define i1 @bool_reduction_v2f64(<2 x double> %x, <2 x double> %y) {
942; SSE-LABEL: bool_reduction_v2f64:
943; SSE:       # %bb.0:
944; SSE-NEXT:    cmpltpd %xmm0, %xmm1
945; SSE-NEXT:    movmskpd %xmm1, %eax
946; SSE-NEXT:    cmpb $3, %al
947; SSE-NEXT:    sete %al
948; SSE-NEXT:    retq
949;
950; AVX-LABEL: bool_reduction_v2f64:
951; AVX:       # %bb.0:
952; AVX-NEXT:    vcmpltpd %xmm0, %xmm1, %xmm0
953; AVX-NEXT:    vmovmskpd %xmm0, %eax
954; AVX-NEXT:    cmpb $3, %al
955; AVX-NEXT:    sete %al
956; AVX-NEXT:    retq
957;
958; AVX512-LABEL: bool_reduction_v2f64:
959; AVX512:       # %bb.0:
960; AVX512-NEXT:    vcmpltpd %xmm0, %xmm1, %k0
961; AVX512-NEXT:    kmovd %k0, %eax
962; AVX512-NEXT:    cmpb $3, %al
963; AVX512-NEXT:    sete %al
964; AVX512-NEXT:    retq
965  %a = fcmp ogt <2 x double> %x, %y
966  %b = shufflevector <2 x i1> %a, <2 x i1> undef, <2 x i32> <i32 1, i32 undef>
967  %c = and <2 x i1> %a, %b
968  %d = extractelement <2 x i1> %c, i32 0
969  ret i1 %d
970}
971
972define i1 @bool_reduction_v4f32(<4 x float> %x, <4 x float> %y) {
973; SSE-LABEL: bool_reduction_v4f32:
974; SSE:       # %bb.0:
975; SSE-NEXT:    cmpeqps %xmm1, %xmm0
976; SSE-NEXT:    movmskps %xmm0, %eax
977; SSE-NEXT:    cmpb $15, %al
978; SSE-NEXT:    sete %al
979; SSE-NEXT:    retq
980;
981; AVX-LABEL: bool_reduction_v4f32:
982; AVX:       # %bb.0:
983; AVX-NEXT:    vcmpeqps %xmm1, %xmm0, %xmm0
984; AVX-NEXT:    vmovmskps %xmm0, %eax
985; AVX-NEXT:    cmpb $15, %al
986; AVX-NEXT:    sete %al
987; AVX-NEXT:    retq
988;
989; AVX512-LABEL: bool_reduction_v4f32:
990; AVX512:       # %bb.0:
991; AVX512-NEXT:    vcmpeqps %xmm1, %xmm0, %k0
992; AVX512-NEXT:    kmovd %k0, %eax
993; AVX512-NEXT:    cmpb $15, %al
994; AVX512-NEXT:    sete %al
995; AVX512-NEXT:    retq
996  %a = fcmp oeq <4 x float> %x, %y
997  %s1 = shufflevector <4 x i1> %a, <4 x i1> undef, <4 x i32> <i32 2, i32 3, i32 undef, i32 undef>
998  %b = and <4 x i1> %s1, %a
999  %s2 = shufflevector <4 x i1> %b, <4 x i1> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
1000  %c = and <4 x i1> %s2, %b
1001  %d = extractelement <4 x i1> %c, i32 0
1002  ret i1 %d
1003}
1004
1005define i1 @bool_reduction_v4f64(<4 x double> %x, <4 x double> %y) {
1006; SSE-LABEL: bool_reduction_v4f64:
1007; SSE:       # %bb.0:
1008; SSE-NEXT:    cmplepd %xmm1, %xmm3
1009; SSE-NEXT:    cmplepd %xmm0, %xmm2
1010; SSE-NEXT:    packssdw %xmm3, %xmm2
1011; SSE-NEXT:    movmskps %xmm2, %eax
1012; SSE-NEXT:    cmpb $15, %al
1013; SSE-NEXT:    sete %al
1014; SSE-NEXT:    retq
1015;
1016; AVX-LABEL: bool_reduction_v4f64:
1017; AVX:       # %bb.0:
1018; AVX-NEXT:    vcmplepd %ymm0, %ymm1, %ymm0
1019; AVX-NEXT:    vmovmskpd %ymm0, %eax
1020; AVX-NEXT:    cmpb $15, %al
1021; AVX-NEXT:    sete %al
1022; AVX-NEXT:    vzeroupper
1023; AVX-NEXT:    retq
1024;
1025; AVX512-LABEL: bool_reduction_v4f64:
1026; AVX512:       # %bb.0:
1027; AVX512-NEXT:    vcmplepd %ymm0, %ymm1, %k0
1028; AVX512-NEXT:    kmovd %k0, %eax
1029; AVX512-NEXT:    cmpb $15, %al
1030; AVX512-NEXT:    sete %al
1031; AVX512-NEXT:    vzeroupper
1032; AVX512-NEXT:    retq
1033  %a = fcmp oge <4 x double> %x, %y
1034  %s1 = shufflevector <4 x i1> %a, <4 x i1> undef, <4 x i32> <i32 2, i32 3, i32 undef, i32 undef>
1035  %b = and <4 x i1> %s1, %a
1036  %s2 = shufflevector <4 x i1> %b, <4 x i1> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
1037  %c = and <4 x i1> %s2, %b
1038  %d = extractelement <4 x i1> %c, i32 0
1039  ret i1 %d
1040}
1041
1042define i1 @bool_reduction_v8f32(<8 x float> %x, <8 x float> %y) {
1043; SSE-LABEL: bool_reduction_v8f32:
1044; SSE:       # %bb.0:
1045; SSE-NEXT:    cmpneqps %xmm3, %xmm1
1046; SSE-NEXT:    cmpneqps %xmm2, %xmm0
1047; SSE-NEXT:    packssdw %xmm1, %xmm0
1048; SSE-NEXT:    packsswb %xmm0, %xmm0
1049; SSE-NEXT:    pmovmskb %xmm0, %eax
1050; SSE-NEXT:    cmpb $-1, %al
1051; SSE-NEXT:    sete %al
1052; SSE-NEXT:    retq
1053;
1054; AVX-LABEL: bool_reduction_v8f32:
1055; AVX:       # %bb.0:
1056; AVX-NEXT:    vcmpneqps %ymm1, %ymm0, %ymm0
1057; AVX-NEXT:    vmovmskps %ymm0, %eax
1058; AVX-NEXT:    cmpb $-1, %al
1059; AVX-NEXT:    sete %al
1060; AVX-NEXT:    vzeroupper
1061; AVX-NEXT:    retq
1062;
1063; AVX512-LABEL: bool_reduction_v8f32:
1064; AVX512:       # %bb.0:
1065; AVX512-NEXT:    vcmpneqps %ymm1, %ymm0, %k0
1066; AVX512-NEXT:    kmovd %k0, %eax
1067; AVX512-NEXT:    cmpb $-1, %al
1068; AVX512-NEXT:    sete %al
1069; AVX512-NEXT:    vzeroupper
1070; AVX512-NEXT:    retq
1071  %a = fcmp une <8 x float> %x, %y
1072  %s1 = shufflevector <8 x i1> %a, <8 x i1> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
1073  %b = and <8 x i1> %s1, %a
1074  %s2 = shufflevector <8 x i1> %b, <8 x i1> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1075  %c = and <8 x i1> %s2, %b
1076  %s3 = shufflevector <8 x i1> %c, <8 x i1> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1077  %d = and <8 x i1> %s3, %c
1078  %e = extractelement <8 x i1> %d, i32 0
1079  ret i1 %e
1080}
1081
1082define i1 @bool_reduction_v2i64(<2 x i64> %x, <2 x i64> %y) {
1083; SSE-LABEL: bool_reduction_v2i64:
1084; SSE:       # %bb.0:
1085; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [9223372036854775808,9223372036854775808]
1086; SSE-NEXT:    pxor %xmm2, %xmm1
1087; SSE-NEXT:    pxor %xmm2, %xmm0
1088; SSE-NEXT:    pcmpgtq %xmm1, %xmm0
1089; SSE-NEXT:    movmskpd %xmm0, %eax
1090; SSE-NEXT:    cmpb $3, %al
1091; SSE-NEXT:    sete %al
1092; SSE-NEXT:    retq
1093;
1094; AVX-LABEL: bool_reduction_v2i64:
1095; AVX:       # %bb.0:
1096; AVX-NEXT:    vmovdqa {{.*#+}} xmm2 = [9223372036854775808,9223372036854775808]
1097; AVX-NEXT:    vpxor %xmm2, %xmm1, %xmm1
1098; AVX-NEXT:    vpxor %xmm2, %xmm0, %xmm0
1099; AVX-NEXT:    vpcmpgtq %xmm1, %xmm0, %xmm0
1100; AVX-NEXT:    vmovmskpd %xmm0, %eax
1101; AVX-NEXT:    cmpb $3, %al
1102; AVX-NEXT:    sete %al
1103; AVX-NEXT:    retq
1104;
1105; AVX512-LABEL: bool_reduction_v2i64:
1106; AVX512:       # %bb.0:
1107; AVX512-NEXT:    vpcmpnleuq %xmm1, %xmm0, %k0
1108; AVX512-NEXT:    kmovd %k0, %eax
1109; AVX512-NEXT:    cmpb $3, %al
1110; AVX512-NEXT:    sete %al
1111; AVX512-NEXT:    retq
1112  %a = icmp ugt <2 x i64> %x, %y
1113  %b = shufflevector <2 x i1> %a, <2 x i1> undef, <2 x i32> <i32 1, i32 undef>
1114  %c = and <2 x i1> %a, %b
1115  %d = extractelement <2 x i1> %c, i32 0
1116  ret i1 %d
1117}
1118
1119define i1 @bool_reduction_v4i32(<4 x i32> %x, <4 x i32> %y) {
1120; SSE-LABEL: bool_reduction_v4i32:
1121; SSE:       # %bb.0:
1122; SSE-NEXT:    pcmpeqd %xmm1, %xmm0
1123; SSE-NEXT:    movmskps %xmm0, %eax
1124; SSE-NEXT:    xorl $15, %eax
1125; SSE-NEXT:    cmpb $15, %al
1126; SSE-NEXT:    sete %al
1127; SSE-NEXT:    retq
1128;
1129; AVX-LABEL: bool_reduction_v4i32:
1130; AVX:       # %bb.0:
1131; AVX-NEXT:    vpcmpeqd %xmm1, %xmm0, %xmm0
1132; AVX-NEXT:    vmovmskps %xmm0, %eax
1133; AVX-NEXT:    xorl $15, %eax
1134; AVX-NEXT:    cmpb $15, %al
1135; AVX-NEXT:    sete %al
1136; AVX-NEXT:    retq
1137;
1138; AVX512-LABEL: bool_reduction_v4i32:
1139; AVX512:       # %bb.0:
1140; AVX512-NEXT:    vpcmpneqd %xmm1, %xmm0, %k0
1141; AVX512-NEXT:    kmovd %k0, %eax
1142; AVX512-NEXT:    cmpb $15, %al
1143; AVX512-NEXT:    sete %al
1144; AVX512-NEXT:    retq
1145  %a = icmp ne <4 x i32> %x, %y
1146  %s1 = shufflevector <4 x i1> %a, <4 x i1> undef, <4 x i32> <i32 2, i32 3, i32 undef, i32 undef>
1147  %b = and <4 x i1> %s1, %a
1148  %s2 = shufflevector <4 x i1> %b, <4 x i1> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
1149  %c = and <4 x i1> %s2, %b
1150  %d = extractelement <4 x i1> %c, i32 0
1151  ret i1 %d
1152}
1153
1154define i1 @bool_reduction_v8i16(<8 x i16> %x, <8 x i16> %y) {
1155; SSE-LABEL: bool_reduction_v8i16:
1156; SSE:       # %bb.0:
1157; SSE-NEXT:    pcmpgtw %xmm0, %xmm1
1158; SSE-NEXT:    packsswb %xmm1, %xmm1
1159; SSE-NEXT:    pmovmskb %xmm1, %eax
1160; SSE-NEXT:    cmpb $-1, %al
1161; SSE-NEXT:    sete %al
1162; SSE-NEXT:    retq
1163;
1164; AVX-LABEL: bool_reduction_v8i16:
1165; AVX:       # %bb.0:
1166; AVX-NEXT:    vpcmpgtw %xmm0, %xmm1, %xmm0
1167; AVX-NEXT:    vpacksswb %xmm0, %xmm0, %xmm0
1168; AVX-NEXT:    vpmovmskb %xmm0, %eax
1169; AVX-NEXT:    cmpb $-1, %al
1170; AVX-NEXT:    sete %al
1171; AVX-NEXT:    retq
1172;
1173; AVX512-LABEL: bool_reduction_v8i16:
1174; AVX512:       # %bb.0:
1175; AVX512-NEXT:    vpcmpgtw %xmm0, %xmm1, %k0
1176; AVX512-NEXT:    kmovd %k0, %eax
1177; AVX512-NEXT:    cmpb $-1, %al
1178; AVX512-NEXT:    sete %al
1179; AVX512-NEXT:    retq
1180  %a = icmp slt <8 x i16> %x, %y
1181  %s1 = shufflevector <8 x i1> %a, <8 x i1> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
1182  %b = and <8 x i1> %s1, %a
1183  %s2 = shufflevector <8 x i1> %b, <8 x i1> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1184  %c = and <8 x i1> %s2, %b
1185  %s3 = shufflevector <8 x i1> %c, <8 x i1> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1186  %d = and <8 x i1> %s3, %c
1187  %e = extractelement <8 x i1> %d, i32 0
1188  ret i1 %e
1189}
1190
1191define i1 @bool_reduction_v16i8(<16 x i8> %x, <16 x i8> %y) {
1192; SSE-LABEL: bool_reduction_v16i8:
1193; SSE:       # %bb.0:
1194; SSE-NEXT:    pcmpgtb %xmm1, %xmm0
1195; SSE-NEXT:    pmovmskb %xmm0, %eax
1196; SSE-NEXT:    cmpw $-1, %ax
1197; SSE-NEXT:    sete %al
1198; SSE-NEXT:    retq
1199;
1200; AVX-LABEL: bool_reduction_v16i8:
1201; AVX:       # %bb.0:
1202; AVX-NEXT:    vpcmpgtb %xmm1, %xmm0, %xmm0
1203; AVX-NEXT:    vpmovmskb %xmm0, %eax
1204; AVX-NEXT:    cmpw $-1, %ax
1205; AVX-NEXT:    sete %al
1206; AVX-NEXT:    retq
1207;
1208; AVX512-LABEL: bool_reduction_v16i8:
1209; AVX512:       # %bb.0:
1210; AVX512-NEXT:    vpcmpgtb %xmm1, %xmm0, %k0
1211; AVX512-NEXT:    kortestw %k0, %k0
1212; AVX512-NEXT:    setb %al
1213; AVX512-NEXT:    retq
1214  %a = icmp sgt <16 x i8> %x, %y
1215  %s1 = shufflevector <16 x i1> %a, <16 x i1> undef, <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1216  %b = and <16 x i1> %s1, %a
1217  %s2 = shufflevector <16 x i1> %b, <16 x i1> undef, <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1218  %c = and <16 x i1> %s2, %b
1219  %s3 = shufflevector <16 x i1> %c, <16 x i1> undef, <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1220  %d = and <16 x i1> %s3, %c
1221  %s4 = shufflevector <16 x i1> %d, <16 x i1> undef, <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1222  %e = and <16 x i1> %s4, %d
1223  %f = extractelement <16 x i1> %e, i32 0
1224  ret i1 %f
1225}
1226
1227define i1 @bool_reduction_v4i64(<4 x i64> %x, <4 x i64> %y) {
1228; SSE-LABEL: bool_reduction_v4i64:
1229; SSE:       # %bb.0:
1230; SSE-NEXT:    pcmpgtq %xmm1, %xmm3
1231; SSE-NEXT:    pcmpgtq %xmm0, %xmm2
1232; SSE-NEXT:    packssdw %xmm3, %xmm2
1233; SSE-NEXT:    movmskps %xmm2, %eax
1234; SSE-NEXT:    cmpb $15, %al
1235; SSE-NEXT:    sete %al
1236; SSE-NEXT:    retq
1237;
1238; AVX1-LABEL: bool_reduction_v4i64:
1239; AVX1:       # %bb.0:
1240; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
1241; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
1242; AVX1-NEXT:    vpcmpgtq %xmm2, %xmm3, %xmm2
1243; AVX1-NEXT:    vpcmpgtq %xmm0, %xmm1, %xmm0
1244; AVX1-NEXT:    vpand %xmm2, %xmm0, %xmm0
1245; AVX1-NEXT:    vmovmskpd %xmm0, %eax
1246; AVX1-NEXT:    cmpl $3, %eax
1247; AVX1-NEXT:    sete %al
1248; AVX1-NEXT:    vzeroupper
1249; AVX1-NEXT:    retq
1250;
1251; AVX2-LABEL: bool_reduction_v4i64:
1252; AVX2:       # %bb.0:
1253; AVX2-NEXT:    vpcmpgtq %ymm0, %ymm1, %ymm0
1254; AVX2-NEXT:    vmovmskpd %ymm0, %eax
1255; AVX2-NEXT:    cmpb $15, %al
1256; AVX2-NEXT:    sete %al
1257; AVX2-NEXT:    vzeroupper
1258; AVX2-NEXT:    retq
1259;
1260; AVX512-LABEL: bool_reduction_v4i64:
1261; AVX512:       # %bb.0:
1262; AVX512-NEXT:    vpcmpgtq %ymm0, %ymm1, %k0
1263; AVX512-NEXT:    kmovd %k0, %eax
1264; AVX512-NEXT:    cmpb $15, %al
1265; AVX512-NEXT:    sete %al
1266; AVX512-NEXT:    vzeroupper
1267; AVX512-NEXT:    retq
1268  %a = icmp slt <4 x i64> %x, %y
1269  %s1 = shufflevector <4 x i1> %a, <4 x i1> undef, <4 x i32> <i32 2, i32 3, i32 undef, i32 undef>
1270  %b = and <4 x i1> %s1, %a
1271  %s2 = shufflevector <4 x i1> %b, <4 x i1> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
1272  %c = and <4 x i1> %s2, %b
1273  %d = extractelement <4 x i1> %c, i32 0
1274  ret i1 %d
1275}
1276
1277define i1 @bool_reduction_v8i32(<8 x i32> %x, <8 x i32> %y) {
1278; SSE-LABEL: bool_reduction_v8i32:
1279; SSE:       # %bb.0:
1280; SSE-NEXT:    pminud %xmm1, %xmm3
1281; SSE-NEXT:    pcmpeqd %xmm1, %xmm3
1282; SSE-NEXT:    pminud %xmm0, %xmm2
1283; SSE-NEXT:    pcmpeqd %xmm0, %xmm2
1284; SSE-NEXT:    packssdw %xmm3, %xmm2
1285; SSE-NEXT:    packsswb %xmm2, %xmm2
1286; SSE-NEXT:    pmovmskb %xmm2, %eax
1287; SSE-NEXT:    cmpb $-1, %al
1288; SSE-NEXT:    sete %al
1289; SSE-NEXT:    retq
1290;
1291; AVX1-LABEL: bool_reduction_v8i32:
1292; AVX1:       # %bb.0:
1293; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
1294; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
1295; AVX1-NEXT:    vpminud %xmm2, %xmm3, %xmm2
1296; AVX1-NEXT:    vpsubd %xmm2, %xmm3, %xmm2
1297; AVX1-NEXT:    vpminud %xmm1, %xmm0, %xmm1
1298; AVX1-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
1299; AVX1-NEXT:    vpor %xmm2, %xmm0, %xmm0
1300; AVX1-NEXT:    vptest %xmm0, %xmm0
1301; AVX1-NEXT:    sete %al
1302; AVX1-NEXT:    vzeroupper
1303; AVX1-NEXT:    retq
1304;
1305; AVX2-LABEL: bool_reduction_v8i32:
1306; AVX2:       # %bb.0:
1307; AVX2-NEXT:    vpminud %ymm1, %ymm0, %ymm1
1308; AVX2-NEXT:    vpsubd %ymm1, %ymm0, %ymm0
1309; AVX2-NEXT:    vptest %ymm0, %ymm0
1310; AVX2-NEXT:    sete %al
1311; AVX2-NEXT:    vzeroupper
1312; AVX2-NEXT:    retq
1313;
1314; AVX512-LABEL: bool_reduction_v8i32:
1315; AVX512:       # %bb.0:
1316; AVX512-NEXT:    vpcmpleud %ymm1, %ymm0, %k0
1317; AVX512-NEXT:    kmovd %k0, %eax
1318; AVX512-NEXT:    cmpb $-1, %al
1319; AVX512-NEXT:    sete %al
1320; AVX512-NEXT:    vzeroupper
1321; AVX512-NEXT:    retq
1322  %a = icmp ule <8 x i32> %x, %y
1323  %s1 = shufflevector <8 x i1> %a, <8 x i1> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
1324  %b = and <8 x i1> %s1, %a
1325  %s2 = shufflevector <8 x i1> %b, <8 x i1> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1326  %c = and <8 x i1> %s2, %b
1327  %s3 = shufflevector <8 x i1> %c, <8 x i1> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1328  %d = and <8 x i1> %s3, %c
1329  %e = extractelement <8 x i1> %d, i32 0
1330  ret i1 %e
1331}
1332
1333define i1 @bool_reduction_v16i16(<16 x i16> %x, <16 x i16> %y) {
1334; SSE-LABEL: bool_reduction_v16i16:
1335; SSE:       # %bb.0:
1336; SSE-NEXT:    psubb %xmm3, %xmm1
1337; SSE-NEXT:    psubb %xmm2, %xmm0
1338; SSE-NEXT:    por %xmm1, %xmm0
1339; SSE-NEXT:    ptest %xmm0, %xmm0
1340; SSE-NEXT:    sete %al
1341; SSE-NEXT:    retq
1342;
1343; AVX1-LABEL: bool_reduction_v16i16:
1344; AVX1:       # %bb.0:
1345; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
1346; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
1347; AVX1-NEXT:    vpsubb %xmm2, %xmm3, %xmm2
1348; AVX1-NEXT:    vpsubb %xmm1, %xmm0, %xmm0
1349; AVX1-NEXT:    vpor %xmm2, %xmm0, %xmm0
1350; AVX1-NEXT:    vptest %xmm0, %xmm0
1351; AVX1-NEXT:    sete %al
1352; AVX1-NEXT:    vzeroupper
1353; AVX1-NEXT:    retq
1354;
1355; AVX2-LABEL: bool_reduction_v16i16:
1356; AVX2:       # %bb.0:
1357; AVX2-NEXT:    vpsubb %ymm1, %ymm0, %ymm0
1358; AVX2-NEXT:    vptest %ymm0, %ymm0
1359; AVX2-NEXT:    sete %al
1360; AVX2-NEXT:    vzeroupper
1361; AVX2-NEXT:    retq
1362;
1363; AVX512-LABEL: bool_reduction_v16i16:
1364; AVX512:       # %bb.0:
1365; AVX512-NEXT:    vpcmpeqw %ymm1, %ymm0, %k0
1366; AVX512-NEXT:    kortestw %k0, %k0
1367; AVX512-NEXT:    setb %al
1368; AVX512-NEXT:    vzeroupper
1369; AVX512-NEXT:    retq
1370  %a = icmp eq <16 x i16> %x, %y
1371  %s1 = shufflevector <16 x i1> %a, <16 x i1> undef, <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1372  %b = and <16 x i1> %s1, %a
1373  %s2 = shufflevector <16 x i1> %b, <16 x i1> undef, <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1374  %c = and <16 x i1> %s2, %b
1375  %s3 = shufflevector <16 x i1> %c, <16 x i1> undef, <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1376  %d = and <16 x i1> %s3, %c
1377  %s4 = shufflevector <16 x i1> %d, <16 x i1> undef, <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1378  %e = and <16 x i1> %s4, %d
1379  %f = extractelement <16 x i1> %e, i32 0
1380  ret i1 %f
1381}
1382
1383define i1 @bool_reduction_v32i8(<32 x i8> %x, <32 x i8> %y) {
1384; SSE-LABEL: bool_reduction_v32i8:
1385; SSE:       # %bb.0:
1386; SSE-NEXT:    psubb %xmm3, %xmm1
1387; SSE-NEXT:    psubb %xmm2, %xmm0
1388; SSE-NEXT:    por %xmm1, %xmm0
1389; SSE-NEXT:    ptest %xmm0, %xmm0
1390; SSE-NEXT:    sete %al
1391; SSE-NEXT:    retq
1392;
1393; AVX1-LABEL: bool_reduction_v32i8:
1394; AVX1:       # %bb.0:
1395; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
1396; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
1397; AVX1-NEXT:    vpsubb %xmm2, %xmm3, %xmm2
1398; AVX1-NEXT:    vpsubb %xmm1, %xmm0, %xmm0
1399; AVX1-NEXT:    vpor %xmm2, %xmm0, %xmm0
1400; AVX1-NEXT:    vptest %xmm0, %xmm0
1401; AVX1-NEXT:    sete %al
1402; AVX1-NEXT:    vzeroupper
1403; AVX1-NEXT:    retq
1404;
1405; AVX2-LABEL: bool_reduction_v32i8:
1406; AVX2:       # %bb.0:
1407; AVX2-NEXT:    vpsubb %ymm1, %ymm0, %ymm0
1408; AVX2-NEXT:    vptest %ymm0, %ymm0
1409; AVX2-NEXT:    sete %al
1410; AVX2-NEXT:    vzeroupper
1411; AVX2-NEXT:    retq
1412;
1413; AVX512-LABEL: bool_reduction_v32i8:
1414; AVX512:       # %bb.0:
1415; AVX512-NEXT:    vpcmpeqb %ymm1, %ymm0, %k0
1416; AVX512-NEXT:    kortestd %k0, %k0
1417; AVX512-NEXT:    setb %al
1418; AVX512-NEXT:    vzeroupper
1419; AVX512-NEXT:    retq
1420  %a = icmp eq <32 x i8> %x, %y
1421  %s1 = shufflevector <32 x i1> %a, <32 x i1> undef, <32 x i32> <i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1422  %b = and <32 x i1> %s1, %a
1423  %s2 = shufflevector <32 x i1> %b, <32 x i1> undef, <32 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1424  %c = and <32 x i1> %s2, %b
1425  %s3 = shufflevector <32 x i1> %c, <32 x i1> undef, <32 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1426  %d = and <32 x i1> %s3, %c
1427  %s4 = shufflevector <32 x i1> %d, <32 x i1> undef, <32 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1428  %e = and <32 x i1> %s4, %d
1429  %s5 = shufflevector <32 x i1> %e, <32 x i1> undef, <32 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1430  %f = and <32 x i1> %s5, %e
1431  %g = extractelement <32 x i1> %f, i32 0
1432  ret i1 %g
1433}
1434