| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py |
| ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+sse2 | FileCheck %s --check-prefixes=SSE,SSE2 |
| ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+sse4.2 | FileCheck %s --check-prefixes=SSE,SSE42 |
| ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx | FileCheck %s --check-prefixes=AVX,AVX1OR2,AVX1 |
| ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx2 | FileCheck %s --check-prefixes=AVX,AVX1OR2,AVX2 |
| ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx512f,+avx512bw,+avx512vl | FileCheck %s --check-prefixes=AVX,AVX512 |
| |
| define i64 @test_v2f64_sext(<2 x double> %a0, <2 x double> %a1) { |
| ; SSE-LABEL: test_v2f64_sext: |
| ; SSE: # %bb.0: |
| ; SSE-NEXT: cmpltpd %xmm0, %xmm1 |
| ; SSE-NEXT: movmskpd %xmm1, %ecx |
| ; SSE-NEXT: xorl %eax, %eax |
| ; SSE-NEXT: negl %ecx |
| ; SSE-NEXT: sbbq %rax, %rax |
| ; SSE-NEXT: retq |
| ; |
| ; AVX-LABEL: test_v2f64_sext: |
| ; AVX: # %bb.0: |
| ; AVX-NEXT: vcmpltpd %xmm0, %xmm1, %xmm0 |
| ; AVX-NEXT: xorl %eax, %eax |
| ; AVX-NEXT: vtestpd %xmm0, %xmm0 |
| ; AVX-NEXT: setne %al |
| ; AVX-NEXT: negq %rax |
| ; AVX-NEXT: retq |
| %c = fcmp ogt <2 x double> %a0, %a1 |
| %s = sext <2 x i1> %c to <2 x i64> |
| %r = call i64 @llvm.vector.reduce.or.v2i64(<2 x i64> %s) |
| ret i64 %r |
| } |
| |
| define i64 @test_v4f64_sext(<4 x double> %a0, <4 x double> %a1) { |
| ; SSE-LABEL: test_v4f64_sext: |
| ; SSE: # %bb.0: |
| ; SSE-NEXT: cmpltpd %xmm1, %xmm3 |
| ; SSE-NEXT: cmpltpd %xmm0, %xmm2 |
| ; SSE-NEXT: orpd %xmm3, %xmm2 |
| ; SSE-NEXT: movmskpd %xmm2, %ecx |
| ; SSE-NEXT: xorl %eax, %eax |
| ; SSE-NEXT: negl %ecx |
| ; SSE-NEXT: sbbq %rax, %rax |
| ; SSE-NEXT: retq |
| ; |
| ; AVX-LABEL: test_v4f64_sext: |
| ; AVX: # %bb.0: |
| ; AVX-NEXT: vcmpltpd %ymm0, %ymm1, %ymm0 |
| ; AVX-NEXT: xorl %eax, %eax |
| ; AVX-NEXT: vtestpd %ymm0, %ymm0 |
| ; AVX-NEXT: setne %al |
| ; AVX-NEXT: negq %rax |
| ; AVX-NEXT: vzeroupper |
| ; AVX-NEXT: retq |
| %c = fcmp ogt <4 x double> %a0, %a1 |
| %s = sext <4 x i1> %c to <4 x i64> |
| %r = call i64 @llvm.vector.reduce.or.v4i64(<4 x i64> %s) |
| ret i64 %r |
| } |
| |
| define i64 @test_v4f64_legal_sext(<4 x double> %a0, <4 x double> %a1) { |
| ; SSE-LABEL: test_v4f64_legal_sext: |
| ; SSE: # %bb.0: |
| ; SSE-NEXT: cmpltpd %xmm1, %xmm3 |
| ; SSE-NEXT: cmpltpd %xmm0, %xmm2 |
| ; SSE-NEXT: shufps {{.*#+}} xmm2 = xmm2[0,2],xmm3[0,2] |
| ; SSE-NEXT: movmskps %xmm2, %ecx |
| ; SSE-NEXT: xorl %eax, %eax |
| ; SSE-NEXT: negl %ecx |
| ; SSE-NEXT: sbbq %rax, %rax |
| ; SSE-NEXT: retq |
| ; |
| ; AVX1OR2-LABEL: test_v4f64_legal_sext: |
| ; AVX1OR2: # %bb.0: |
| ; AVX1OR2-NEXT: vcmpltpd %ymm0, %ymm1, %ymm0 |
| ; AVX1OR2-NEXT: vextractf128 $1, %ymm0, %xmm1 |
| ; AVX1OR2-NEXT: vpackssdw %xmm1, %xmm0, %xmm0 |
| ; AVX1OR2-NEXT: xorl %eax, %eax |
| ; AVX1OR2-NEXT: vtestps %xmm0, %xmm0 |
| ; AVX1OR2-NEXT: setne %al |
| ; AVX1OR2-NEXT: negq %rax |
| ; AVX1OR2-NEXT: vzeroupper |
| ; AVX1OR2-NEXT: retq |
| ; |
| ; AVX512-LABEL: test_v4f64_legal_sext: |
| ; AVX512: # %bb.0: |
| ; AVX512-NEXT: vcmpltpd %ymm0, %ymm1, %k1 |
| ; AVX512-NEXT: vpcmpeqd %xmm0, %xmm0, %xmm0 |
| ; AVX512-NEXT: vmovdqa32 %xmm0, %xmm0 {%k1} {z} |
| ; AVX512-NEXT: xorl %eax, %eax |
| ; AVX512-NEXT: vtestps %xmm0, %xmm0 |
| ; AVX512-NEXT: setne %al |
| ; AVX512-NEXT: negq %rax |
| ; AVX512-NEXT: vzeroupper |
| ; AVX512-NEXT: retq |
| %c = fcmp ogt <4 x double> %a0, %a1 |
| %s = sext <4 x i1> %c to <4 x i32> |
| %r = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> %s) |
| %x = sext i32 %r to i64 |
| ret i64 %x |
| } |
| |
| define i32 @test_v4f32_sext(<4 x float> %a0, <4 x float> %a1) { |
| ; SSE-LABEL: test_v4f32_sext: |
| ; SSE: # %bb.0: |
| ; SSE-NEXT: cmpltps %xmm0, %xmm1 |
| ; SSE-NEXT: movmskps %xmm1, %ecx |
| ; SSE-NEXT: xorl %eax, %eax |
| ; SSE-NEXT: negl %ecx |
| ; SSE-NEXT: sbbl %eax, %eax |
| ; SSE-NEXT: retq |
| ; |
| ; AVX-LABEL: test_v4f32_sext: |
| ; AVX: # %bb.0: |
| ; AVX-NEXT: vcmpltps %xmm0, %xmm1, %xmm0 |
| ; AVX-NEXT: xorl %eax, %eax |
| ; AVX-NEXT: vtestps %xmm0, %xmm0 |
| ; AVX-NEXT: setne %al |
| ; AVX-NEXT: negl %eax |
| ; AVX-NEXT: retq |
| %c = fcmp ogt <4 x float> %a0, %a1 |
| %s = sext <4 x i1> %c to <4 x i32> |
| %r = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> %s) |
| ret i32 %r |
| } |
| |
| define i32 @test_v8f32_sext(<8 x float> %a0, <8 x float> %a1) { |
| ; SSE-LABEL: test_v8f32_sext: |
| ; SSE: # %bb.0: |
| ; SSE-NEXT: cmpltps %xmm1, %xmm3 |
| ; SSE-NEXT: cmpltps %xmm0, %xmm2 |
| ; SSE-NEXT: orps %xmm3, %xmm2 |
| ; SSE-NEXT: movmskps %xmm2, %ecx |
| ; SSE-NEXT: xorl %eax, %eax |
| ; SSE-NEXT: negl %ecx |
| ; SSE-NEXT: sbbl %eax, %eax |
| ; SSE-NEXT: retq |
| ; |
| ; AVX-LABEL: test_v8f32_sext: |
| ; AVX: # %bb.0: |
| ; AVX-NEXT: vcmpltps %ymm0, %ymm1, %ymm0 |
| ; AVX-NEXT: xorl %eax, %eax |
| ; AVX-NEXT: vtestps %ymm0, %ymm0 |
| ; AVX-NEXT: setne %al |
| ; AVX-NEXT: negl %eax |
| ; AVX-NEXT: vzeroupper |
| ; AVX-NEXT: retq |
| %c = fcmp ogt <8 x float> %a0, %a1 |
| %s = sext <8 x i1> %c to <8 x i32> |
| %r = call i32 @llvm.vector.reduce.or.v8i32(<8 x i32> %s) |
| ret i32 %r |
| } |
| |
| define i32 @test_v8f32_legal_sext(<8 x float> %a0, <8 x float> %a1) { |
| ; SSE-LABEL: test_v8f32_legal_sext: |
| ; SSE: # %bb.0: |
| ; SSE-NEXT: cmpltps %xmm1, %xmm3 |
| ; SSE-NEXT: cmpltps %xmm0, %xmm2 |
| ; SSE-NEXT: packssdw %xmm3, %xmm2 |
| ; SSE-NEXT: pmovmskb %xmm2, %ecx |
| ; SSE-NEXT: xorl %eax, %eax |
| ; SSE-NEXT: negl %ecx |
| ; SSE-NEXT: sbbl %eax, %eax |
| ; SSE-NEXT: retq |
| ; |
| ; AVX1OR2-LABEL: test_v8f32_legal_sext: |
| ; AVX1OR2: # %bb.0: |
| ; AVX1OR2-NEXT: vcmpltps %ymm0, %ymm1, %ymm0 |
| ; AVX1OR2-NEXT: vextractf128 $1, %ymm0, %xmm1 |
| ; AVX1OR2-NEXT: vpackssdw %xmm1, %xmm0, %xmm0 |
| ; AVX1OR2-NEXT: vpmovmskb %xmm0, %ecx |
| ; AVX1OR2-NEXT: xorl %eax, %eax |
| ; AVX1OR2-NEXT: negl %ecx |
| ; AVX1OR2-NEXT: sbbl %eax, %eax |
| ; AVX1OR2-NEXT: vzeroupper |
| ; AVX1OR2-NEXT: retq |
| ; |
| ; AVX512-LABEL: test_v8f32_legal_sext: |
| ; AVX512: # %bb.0: |
| ; AVX512-NEXT: vcmpltps %ymm0, %ymm1, %k0 |
| ; AVX512-NEXT: vpmovm2w %k0, %xmm0 |
| ; AVX512-NEXT: vpmovmskb %xmm0, %ecx |
| ; AVX512-NEXT: xorl %eax, %eax |
| ; AVX512-NEXT: negl %ecx |
| ; AVX512-NEXT: sbbl %eax, %eax |
| ; AVX512-NEXT: vzeroupper |
| ; AVX512-NEXT: retq |
| %c = fcmp ogt <8 x float> %a0, %a1 |
| %s = sext <8 x i1> %c to <8 x i16> |
| %r = call i16 @llvm.vector.reduce.or.v8i16(<8 x i16> %s) |
| %x = sext i16 %r to i32 |
| ret i32 %x |
| } |
| |
| define i64 @test_v2i64_sext(<2 x i64> %a0, <2 x i64> %a1) { |
| ; SSE2-LABEL: test_v2i64_sext: |
| ; SSE2: # %bb.0: |
| ; SSE2-NEXT: movdqa {{.*#+}} xmm2 = [2147483648,2147483648] |
| ; SSE2-NEXT: pxor %xmm2, %xmm1 |
| ; SSE2-NEXT: pxor %xmm2, %xmm0 |
| ; SSE2-NEXT: movdqa %xmm0, %xmm2 |
| ; SSE2-NEXT: pcmpgtd %xmm1, %xmm2 |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm3 = xmm2[0,0,2,2] |
| ; SSE2-NEXT: pcmpeqd %xmm1, %xmm0 |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3] |
| ; SSE2-NEXT: pand %xmm3, %xmm0 |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm2[1,1,3,3] |
| ; SSE2-NEXT: por %xmm0, %xmm1 |
| ; SSE2-NEXT: movmskpd %xmm1, %ecx |
| ; SSE2-NEXT: xorl %eax, %eax |
| ; SSE2-NEXT: negl %ecx |
| ; SSE2-NEXT: sbbq %rax, %rax |
| ; SSE2-NEXT: retq |
| ; |
| ; SSE42-LABEL: test_v2i64_sext: |
| ; SSE42: # %bb.0: |
| ; SSE42-NEXT: pcmpgtq %xmm1, %xmm0 |
| ; SSE42-NEXT: movmskpd %xmm0, %ecx |
| ; SSE42-NEXT: xorl %eax, %eax |
| ; SSE42-NEXT: negl %ecx |
| ; SSE42-NEXT: sbbq %rax, %rax |
| ; SSE42-NEXT: retq |
| ; |
| ; AVX-LABEL: test_v2i64_sext: |
| ; AVX: # %bb.0: |
| ; AVX-NEXT: vpcmpgtq %xmm1, %xmm0, %xmm0 |
| ; AVX-NEXT: xorl %eax, %eax |
| ; AVX-NEXT: vtestpd %xmm0, %xmm0 |
| ; AVX-NEXT: setne %al |
| ; AVX-NEXT: negq %rax |
| ; AVX-NEXT: retq |
| %c = icmp sgt <2 x i64> %a0, %a1 |
| %s = sext <2 x i1> %c to <2 x i64> |
| %r = call i64 @llvm.vector.reduce.or.v2i64(<2 x i64> %s) |
| ret i64 %r |
| } |
| |
| define i64 @test_v4i64_sext(<4 x i64> %a0, <4 x i64> %a1) { |
| ; SSE2-LABEL: test_v4i64_sext: |
| ; SSE2: # %bb.0: |
| ; SSE2-NEXT: movdqa {{.*#+}} xmm4 = [2147483648,2147483648] |
| ; SSE2-NEXT: pxor %xmm4, %xmm3 |
| ; SSE2-NEXT: pxor %xmm4, %xmm1 |
| ; SSE2-NEXT: movdqa %xmm1, %xmm5 |
| ; SSE2-NEXT: pcmpgtd %xmm3, %xmm5 |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm6 = xmm5[0,0,2,2] |
| ; SSE2-NEXT: pcmpeqd %xmm3, %xmm1 |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,1,3,3] |
| ; SSE2-NEXT: pand %xmm6, %xmm1 |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm3 = xmm5[1,1,3,3] |
| ; SSE2-NEXT: por %xmm1, %xmm3 |
| ; SSE2-NEXT: pxor %xmm4, %xmm2 |
| ; SSE2-NEXT: pxor %xmm4, %xmm0 |
| ; SSE2-NEXT: movdqa %xmm0, %xmm1 |
| ; SSE2-NEXT: pcmpgtd %xmm2, %xmm1 |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm4 = xmm1[0,0,2,2] |
| ; SSE2-NEXT: pcmpeqd %xmm2, %xmm0 |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3] |
| ; SSE2-NEXT: pand %xmm4, %xmm0 |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,1,3,3] |
| ; SSE2-NEXT: por %xmm0, %xmm1 |
| ; SSE2-NEXT: por %xmm3, %xmm1 |
| ; SSE2-NEXT: movmskpd %xmm1, %ecx |
| ; SSE2-NEXT: xorl %eax, %eax |
| ; SSE2-NEXT: negl %ecx |
| ; SSE2-NEXT: sbbq %rax, %rax |
| ; SSE2-NEXT: retq |
| ; |
| ; SSE42-LABEL: test_v4i64_sext: |
| ; SSE42: # %bb.0: |
| ; SSE42-NEXT: pcmpgtq %xmm3, %xmm1 |
| ; SSE42-NEXT: pcmpgtq %xmm2, %xmm0 |
| ; SSE42-NEXT: por %xmm1, %xmm0 |
| ; SSE42-NEXT: movmskpd %xmm0, %ecx |
| ; SSE42-NEXT: xorl %eax, %eax |
| ; SSE42-NEXT: negl %ecx |
| ; SSE42-NEXT: sbbq %rax, %rax |
| ; SSE42-NEXT: retq |
| ; |
| ; AVX1-LABEL: test_v4i64_sext: |
| ; AVX1: # %bb.0: |
| ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2 |
| ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3 |
| ; AVX1-NEXT: vpcmpgtq %xmm2, %xmm3, %xmm2 |
| ; AVX1-NEXT: vpcmpgtq %xmm1, %xmm0, %xmm0 |
| ; AVX1-NEXT: vpor %xmm2, %xmm0, %xmm0 |
| ; AVX1-NEXT: xorl %eax, %eax |
| ; AVX1-NEXT: vtestpd %xmm0, %xmm0 |
| ; AVX1-NEXT: setne %al |
| ; AVX1-NEXT: negq %rax |
| ; AVX1-NEXT: vzeroupper |
| ; AVX1-NEXT: retq |
| ; |
| ; AVX2-LABEL: test_v4i64_sext: |
| ; AVX2: # %bb.0: |
| ; AVX2-NEXT: vpcmpgtq %ymm1, %ymm0, %ymm0 |
| ; AVX2-NEXT: xorl %eax, %eax |
| ; AVX2-NEXT: vtestpd %ymm0, %ymm0 |
| ; AVX2-NEXT: setne %al |
| ; AVX2-NEXT: negq %rax |
| ; AVX2-NEXT: vzeroupper |
| ; AVX2-NEXT: retq |
| ; |
| ; AVX512-LABEL: test_v4i64_sext: |
| ; AVX512: # %bb.0: |
| ; AVX512-NEXT: vpcmpgtq %ymm1, %ymm0, %ymm0 |
| ; AVX512-NEXT: xorl %eax, %eax |
| ; AVX512-NEXT: vtestpd %ymm0, %ymm0 |
| ; AVX512-NEXT: setne %al |
| ; AVX512-NEXT: negq %rax |
| ; AVX512-NEXT: vzeroupper |
| ; AVX512-NEXT: retq |
| %c = icmp sgt <4 x i64> %a0, %a1 |
| %s = sext <4 x i1> %c to <4 x i64> |
| %r = call i64 @llvm.vector.reduce.or.v4i64(<4 x i64> %s) |
| ret i64 %r |
| } |
| |
| define i64 @test_v4i64_legal_sext(<4 x i64> %a0, <4 x i64> %a1) { |
| ; SSE2-LABEL: test_v4i64_legal_sext: |
| ; SSE2: # %bb.0: |
| ; SSE2-NEXT: movdqa {{.*#+}} xmm4 = [2147483648,2147483648] |
| ; SSE2-NEXT: pxor %xmm4, %xmm3 |
| ; SSE2-NEXT: pxor %xmm4, %xmm1 |
| ; SSE2-NEXT: movdqa %xmm1, %xmm5 |
| ; SSE2-NEXT: pcmpgtd %xmm3, %xmm5 |
| ; SSE2-NEXT: pxor %xmm4, %xmm2 |
| ; SSE2-NEXT: pxor %xmm4, %xmm0 |
| ; SSE2-NEXT: movdqa %xmm0, %xmm4 |
| ; SSE2-NEXT: pcmpgtd %xmm2, %xmm4 |
| ; SSE2-NEXT: movdqa %xmm4, %xmm6 |
| ; SSE2-NEXT: shufps {{.*#+}} xmm6 = xmm6[0,2],xmm5[0,2] |
| ; SSE2-NEXT: pcmpeqd %xmm3, %xmm1 |
| ; SSE2-NEXT: pcmpeqd %xmm2, %xmm0 |
| ; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,3],xmm1[1,3] |
| ; SSE2-NEXT: andps %xmm6, %xmm0 |
| ; SSE2-NEXT: shufps {{.*#+}} xmm4 = xmm4[1,3],xmm5[1,3] |
| ; SSE2-NEXT: orps %xmm0, %xmm4 |
| ; SSE2-NEXT: movmskps %xmm4, %ecx |
| ; SSE2-NEXT: xorl %eax, %eax |
| ; SSE2-NEXT: negl %ecx |
| ; SSE2-NEXT: sbbq %rax, %rax |
| ; SSE2-NEXT: retq |
| ; |
| ; SSE42-LABEL: test_v4i64_legal_sext: |
| ; SSE42: # %bb.0: |
| ; SSE42-NEXT: pcmpgtq %xmm3, %xmm1 |
| ; SSE42-NEXT: pcmpgtq %xmm2, %xmm0 |
| ; SSE42-NEXT: packssdw %xmm1, %xmm0 |
| ; SSE42-NEXT: movmskps %xmm0, %ecx |
| ; SSE42-NEXT: xorl %eax, %eax |
| ; SSE42-NEXT: negl %ecx |
| ; SSE42-NEXT: sbbq %rax, %rax |
| ; SSE42-NEXT: retq |
| ; |
| ; AVX1-LABEL: test_v4i64_legal_sext: |
| ; AVX1: # %bb.0: |
| ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2 |
| ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3 |
| ; AVX1-NEXT: vpcmpgtq %xmm2, %xmm3, %xmm2 |
| ; AVX1-NEXT: vpcmpgtq %xmm1, %xmm0, %xmm0 |
| ; AVX1-NEXT: vpackssdw %xmm2, %xmm0, %xmm0 |
| ; AVX1-NEXT: xorl %eax, %eax |
| ; AVX1-NEXT: vtestps %xmm0, %xmm0 |
| ; AVX1-NEXT: setne %al |
| ; AVX1-NEXT: negq %rax |
| ; AVX1-NEXT: vzeroupper |
| ; AVX1-NEXT: retq |
| ; |
| ; AVX2-LABEL: test_v4i64_legal_sext: |
| ; AVX2: # %bb.0: |
| ; AVX2-NEXT: vpcmpgtq %ymm1, %ymm0, %ymm0 |
| ; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1 |
| ; AVX2-NEXT: vpackssdw %xmm1, %xmm0, %xmm0 |
| ; AVX2-NEXT: xorl %eax, %eax |
| ; AVX2-NEXT: vtestps %xmm0, %xmm0 |
| ; AVX2-NEXT: setne %al |
| ; AVX2-NEXT: negq %rax |
| ; AVX2-NEXT: vzeroupper |
| ; AVX2-NEXT: retq |
| ; |
| ; AVX512-LABEL: test_v4i64_legal_sext: |
| ; AVX512: # %bb.0: |
| ; AVX512-NEXT: vpcmpgtq %ymm1, %ymm0, %k1 |
| ; AVX512-NEXT: vpcmpeqd %xmm0, %xmm0, %xmm0 |
| ; AVX512-NEXT: vmovdqa32 %xmm0, %xmm0 {%k1} {z} |
| ; AVX512-NEXT: xorl %eax, %eax |
| ; AVX512-NEXT: vtestps %xmm0, %xmm0 |
| ; AVX512-NEXT: setne %al |
| ; AVX512-NEXT: negq %rax |
| ; AVX512-NEXT: vzeroupper |
| ; AVX512-NEXT: retq |
| %c = icmp sgt <4 x i64> %a0, %a1 |
| %s = sext <4 x i1> %c to <4 x i32> |
| %r = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> %s) |
| %x = sext i32 %r to i64 |
| ret i64 %x |
| } |
| |
| define i32 @test_v4i32_sext(<4 x i32> %a0, <4 x i32> %a1) { |
| ; SSE-LABEL: test_v4i32_sext: |
| ; SSE: # %bb.0: |
| ; SSE-NEXT: pcmpgtd %xmm1, %xmm0 |
| ; SSE-NEXT: movmskps %xmm0, %ecx |
| ; SSE-NEXT: xorl %eax, %eax |
| ; SSE-NEXT: negl %ecx |
| ; SSE-NEXT: sbbl %eax, %eax |
| ; SSE-NEXT: retq |
| ; |
| ; AVX-LABEL: test_v4i32_sext: |
| ; AVX: # %bb.0: |
| ; AVX-NEXT: vpcmpgtd %xmm1, %xmm0, %xmm0 |
| ; AVX-NEXT: xorl %eax, %eax |
| ; AVX-NEXT: vtestps %xmm0, %xmm0 |
| ; AVX-NEXT: setne %al |
| ; AVX-NEXT: negl %eax |
| ; AVX-NEXT: retq |
| %c = icmp sgt <4 x i32> %a0, %a1 |
| %s = sext <4 x i1> %c to <4 x i32> |
| %r = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> %s) |
| ret i32 %r |
| } |
| |
| define i32 @test_v8i32_sext(<8 x i32> %a0, <8 x i32> %a1) { |
| ; SSE-LABEL: test_v8i32_sext: |
| ; SSE: # %bb.0: |
| ; SSE-NEXT: pcmpgtd %xmm3, %xmm1 |
| ; SSE-NEXT: pcmpgtd %xmm2, %xmm0 |
| ; SSE-NEXT: por %xmm1, %xmm0 |
| ; SSE-NEXT: movmskps %xmm0, %ecx |
| ; SSE-NEXT: xorl %eax, %eax |
| ; SSE-NEXT: negl %ecx |
| ; SSE-NEXT: sbbl %eax, %eax |
| ; SSE-NEXT: retq |
| ; |
| ; AVX1-LABEL: test_v8i32_sext: |
| ; AVX1: # %bb.0: |
| ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2 |
| ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3 |
| ; AVX1-NEXT: vpcmpgtd %xmm2, %xmm3, %xmm2 |
| ; AVX1-NEXT: vpcmpgtd %xmm1, %xmm0, %xmm0 |
| ; AVX1-NEXT: vpor %xmm2, %xmm0, %xmm0 |
| ; AVX1-NEXT: xorl %eax, %eax |
| ; AVX1-NEXT: vtestps %xmm0, %xmm0 |
| ; AVX1-NEXT: setne %al |
| ; AVX1-NEXT: negl %eax |
| ; AVX1-NEXT: vzeroupper |
| ; AVX1-NEXT: retq |
| ; |
| ; AVX2-LABEL: test_v8i32_sext: |
| ; AVX2: # %bb.0: |
| ; AVX2-NEXT: vpcmpgtd %ymm1, %ymm0, %ymm0 |
| ; AVX2-NEXT: xorl %eax, %eax |
| ; AVX2-NEXT: vtestps %ymm0, %ymm0 |
| ; AVX2-NEXT: setne %al |
| ; AVX2-NEXT: negl %eax |
| ; AVX2-NEXT: vzeroupper |
| ; AVX2-NEXT: retq |
| ; |
| ; AVX512-LABEL: test_v8i32_sext: |
| ; AVX512: # %bb.0: |
| ; AVX512-NEXT: vpcmpgtd %ymm1, %ymm0, %ymm0 |
| ; AVX512-NEXT: xorl %eax, %eax |
| ; AVX512-NEXT: vtestps %ymm0, %ymm0 |
| ; AVX512-NEXT: setne %al |
| ; AVX512-NEXT: negl %eax |
| ; AVX512-NEXT: vzeroupper |
| ; AVX512-NEXT: retq |
| %c = icmp sgt <8 x i32> %a0, %a1 |
| %s = sext <8 x i1> %c to <8 x i32> |
| %r = call i32 @llvm.vector.reduce.or.v8i32(<8 x i32> %s) |
| ret i32 %r |
| } |
| |
| define i32 @test_v8i32_legal_sext(<8 x i32> %a0, <8 x i32> %a1) { |
| ; SSE-LABEL: test_v8i32_legal_sext: |
| ; SSE: # %bb.0: |
| ; SSE-NEXT: pcmpgtd %xmm3, %xmm1 |
| ; SSE-NEXT: pcmpgtd %xmm2, %xmm0 |
| ; SSE-NEXT: packssdw %xmm1, %xmm0 |
| ; SSE-NEXT: pmovmskb %xmm0, %ecx |
| ; SSE-NEXT: xorl %eax, %eax |
| ; SSE-NEXT: negl %ecx |
| ; SSE-NEXT: sbbl %eax, %eax |
| ; SSE-NEXT: retq |
| ; |
| ; AVX1-LABEL: test_v8i32_legal_sext: |
| ; AVX1: # %bb.0: |
| ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2 |
| ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3 |
| ; AVX1-NEXT: vpcmpgtd %xmm2, %xmm3, %xmm2 |
| ; AVX1-NEXT: vpcmpgtd %xmm1, %xmm0, %xmm0 |
| ; AVX1-NEXT: vpackssdw %xmm2, %xmm0, %xmm0 |
| ; AVX1-NEXT: vpmovmskb %xmm0, %ecx |
| ; AVX1-NEXT: xorl %eax, %eax |
| ; AVX1-NEXT: negl %ecx |
| ; AVX1-NEXT: sbbl %eax, %eax |
| ; AVX1-NEXT: vzeroupper |
| ; AVX1-NEXT: retq |
| ; |
| ; AVX2-LABEL: test_v8i32_legal_sext: |
| ; AVX2: # %bb.0: |
| ; AVX2-NEXT: vpcmpgtd %ymm1, %ymm0, %ymm0 |
| ; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1 |
| ; AVX2-NEXT: vpackssdw %xmm1, %xmm0, %xmm0 |
| ; AVX2-NEXT: vpmovmskb %xmm0, %ecx |
| ; AVX2-NEXT: xorl %eax, %eax |
| ; AVX2-NEXT: negl %ecx |
| ; AVX2-NEXT: sbbl %eax, %eax |
| ; AVX2-NEXT: vzeroupper |
| ; AVX2-NEXT: retq |
| ; |
| ; AVX512-LABEL: test_v8i32_legal_sext: |
| ; AVX512: # %bb.0: |
| ; AVX512-NEXT: vpcmpgtd %ymm1, %ymm0, %k0 |
| ; AVX512-NEXT: vpmovm2w %k0, %xmm0 |
| ; AVX512-NEXT: vpmovmskb %xmm0, %ecx |
| ; AVX512-NEXT: xorl %eax, %eax |
| ; AVX512-NEXT: negl %ecx |
| ; AVX512-NEXT: sbbl %eax, %eax |
| ; AVX512-NEXT: vzeroupper |
| ; AVX512-NEXT: retq |
| %c = icmp sgt <8 x i32> %a0, %a1 |
| %s = sext <8 x i1> %c to <8 x i16> |
| %r = call i16 @llvm.vector.reduce.or.v8i16(<8 x i16> %s) |
| %x = sext i16 %r to i32 |
| ret i32 %x |
| } |
| |
| define i16 @test_v8i16_sext(<8 x i16> %a0, <8 x i16> %a1) { |
| ; SSE-LABEL: test_v8i16_sext: |
| ; SSE: # %bb.0: |
| ; SSE-NEXT: pcmpgtw %xmm1, %xmm0 |
| ; SSE-NEXT: pmovmskb %xmm0, %ecx |
| ; SSE-NEXT: xorl %eax, %eax |
| ; SSE-NEXT: negl %ecx |
| ; SSE-NEXT: sbbl %eax, %eax |
| ; SSE-NEXT: # kill: def $ax killed $ax killed $eax |
| ; SSE-NEXT: retq |
| ; |
| ; AVX-LABEL: test_v8i16_sext: |
| ; AVX: # %bb.0: |
| ; AVX-NEXT: vpcmpgtw %xmm1, %xmm0, %xmm0 |
| ; AVX-NEXT: vpmovmskb %xmm0, %ecx |
| ; AVX-NEXT: xorl %eax, %eax |
| ; AVX-NEXT: negl %ecx |
| ; AVX-NEXT: sbbl %eax, %eax |
| ; AVX-NEXT: # kill: def $ax killed $ax killed $eax |
| ; AVX-NEXT: retq |
| %c = icmp sgt <8 x i16> %a0, %a1 |
| %s = sext <8 x i1> %c to <8 x i16> |
| %r = call i16 @llvm.vector.reduce.or.v8i16(<8 x i16> %s) |
| ret i16 %r |
| } |
| |
| define i16 @test_v16i16_sext(<16 x i16> %a0, <16 x i16> %a1) { |
| ; SSE-LABEL: test_v16i16_sext: |
| ; SSE: # %bb.0: |
| ; SSE-NEXT: pcmpgtw %xmm3, %xmm1 |
| ; SSE-NEXT: pcmpgtw %xmm2, %xmm0 |
| ; SSE-NEXT: por %xmm1, %xmm0 |
| ; SSE-NEXT: pmovmskb %xmm0, %ecx |
| ; SSE-NEXT: xorl %eax, %eax |
| ; SSE-NEXT: negl %ecx |
| ; SSE-NEXT: sbbl %eax, %eax |
| ; SSE-NEXT: # kill: def $ax killed $ax killed $eax |
| ; SSE-NEXT: retq |
| ; |
| ; AVX1-LABEL: test_v16i16_sext: |
| ; AVX1: # %bb.0: |
| ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2 |
| ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3 |
| ; AVX1-NEXT: vpcmpgtw %xmm2, %xmm3, %xmm2 |
| ; AVX1-NEXT: vpcmpgtw %xmm1, %xmm0, %xmm0 |
| ; AVX1-NEXT: vpor %xmm2, %xmm0, %xmm0 |
| ; AVX1-NEXT: vpmovmskb %xmm0, %ecx |
| ; AVX1-NEXT: xorl %eax, %eax |
| ; AVX1-NEXT: negl %ecx |
| ; AVX1-NEXT: sbbl %eax, %eax |
| ; AVX1-NEXT: # kill: def $ax killed $ax killed $eax |
| ; AVX1-NEXT: vzeroupper |
| ; AVX1-NEXT: retq |
| ; |
| ; AVX2-LABEL: test_v16i16_sext: |
| ; AVX2: # %bb.0: |
| ; AVX2-NEXT: vpcmpgtw %ymm1, %ymm0, %ymm0 |
| ; AVX2-NEXT: vpmovmskb %ymm0, %ecx |
| ; AVX2-NEXT: xorl %eax, %eax |
| ; AVX2-NEXT: negl %ecx |
| ; AVX2-NEXT: sbbl %eax, %eax |
| ; AVX2-NEXT: # kill: def $ax killed $ax killed $eax |
| ; AVX2-NEXT: vzeroupper |
| ; AVX2-NEXT: retq |
| ; |
| ; AVX512-LABEL: test_v16i16_sext: |
| ; AVX512: # %bb.0: |
| ; AVX512-NEXT: vpcmpgtw %ymm1, %ymm0, %ymm0 |
| ; AVX512-NEXT: vpmovmskb %ymm0, %ecx |
| ; AVX512-NEXT: xorl %eax, %eax |
| ; AVX512-NEXT: negl %ecx |
| ; AVX512-NEXT: sbbl %eax, %eax |
| ; AVX512-NEXT: # kill: def $ax killed $ax killed $eax |
| ; AVX512-NEXT: vzeroupper |
| ; AVX512-NEXT: retq |
| %c = icmp sgt <16 x i16> %a0, %a1 |
| %s = sext <16 x i1> %c to <16 x i16> |
| %r = call i16 @llvm.vector.reduce.or.v16i16(<16 x i16> %s) |
| ret i16 %r |
| } |
| |
| define i16 @test_v16i16_legal_sext(<16 x i16> %a0, <16 x i16> %a1) { |
| ; SSE-LABEL: test_v16i16_legal_sext: |
| ; SSE: # %bb.0: |
| ; SSE-NEXT: pcmpgtw %xmm3, %xmm1 |
| ; SSE-NEXT: pcmpgtw %xmm2, %xmm0 |
| ; SSE-NEXT: packsswb %xmm1, %xmm0 |
| ; SSE-NEXT: pmovmskb %xmm0, %ecx |
| ; SSE-NEXT: xorl %eax, %eax |
| ; SSE-NEXT: negl %ecx |
| ; SSE-NEXT: sbbl %eax, %eax |
| ; SSE-NEXT: # kill: def $ax killed $ax killed $eax |
| ; SSE-NEXT: retq |
| ; |
| ; AVX1-LABEL: test_v16i16_legal_sext: |
| ; AVX1: # %bb.0: |
| ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2 |
| ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3 |
| ; AVX1-NEXT: vpcmpgtw %xmm2, %xmm3, %xmm2 |
| ; AVX1-NEXT: vpcmpgtw %xmm1, %xmm0, %xmm0 |
| ; AVX1-NEXT: vpacksswb %xmm2, %xmm0, %xmm0 |
| ; AVX1-NEXT: vpmovmskb %xmm0, %ecx |
| ; AVX1-NEXT: xorl %eax, %eax |
| ; AVX1-NEXT: negl %ecx |
| ; AVX1-NEXT: sbbl %eax, %eax |
| ; AVX1-NEXT: # kill: def $ax killed $ax killed $eax |
| ; AVX1-NEXT: vzeroupper |
| ; AVX1-NEXT: retq |
| ; |
| ; AVX2-LABEL: test_v16i16_legal_sext: |
| ; AVX2: # %bb.0: |
| ; AVX2-NEXT: vpcmpgtw %ymm1, %ymm0, %ymm0 |
| ; AVX2-NEXT: vpmovmskb %ymm0, %ecx |
| ; AVX2-NEXT: xorl %eax, %eax |
| ; AVX2-NEXT: negl %ecx |
| ; AVX2-NEXT: sbbl %eax, %eax |
| ; AVX2-NEXT: # kill: def $ax killed $ax killed $eax |
| ; AVX2-NEXT: vzeroupper |
| ; AVX2-NEXT: retq |
| ; |
| ; AVX512-LABEL: test_v16i16_legal_sext: |
| ; AVX512: # %bb.0: |
| ; AVX512-NEXT: vpcmpgtw %ymm1, %ymm0, %k0 |
| ; AVX512-NEXT: vpmovm2b %k0, %xmm0 |
| ; AVX512-NEXT: vpmovmskb %xmm0, %ecx |
| ; AVX512-NEXT: xorl %eax, %eax |
| ; AVX512-NEXT: negl %ecx |
| ; AVX512-NEXT: sbbl %eax, %eax |
| ; AVX512-NEXT: # kill: def $ax killed $ax killed $eax |
| ; AVX512-NEXT: vzeroupper |
| ; AVX512-NEXT: retq |
| %c = icmp sgt <16 x i16> %a0, %a1 |
| %s = sext <16 x i1> %c to <16 x i8> |
| %r = call i8 @llvm.vector.reduce.or.v16i8(<16 x i8> %s) |
| %x = sext i8 %r to i16 |
| ret i16 %x |
| } |
| |
| define i8 @test_v16i8_sext(<16 x i8> %a0, <16 x i8> %a1) { |
| ; SSE-LABEL: test_v16i8_sext: |
| ; SSE: # %bb.0: |
| ; SSE-NEXT: pcmpgtb %xmm1, %xmm0 |
| ; SSE-NEXT: pmovmskb %xmm0, %ecx |
| ; SSE-NEXT: xorl %eax, %eax |
| ; SSE-NEXT: negl %ecx |
| ; SSE-NEXT: sbbl %eax, %eax |
| ; SSE-NEXT: # kill: def $al killed $al killed $eax |
| ; SSE-NEXT: retq |
| ; |
| ; AVX-LABEL: test_v16i8_sext: |
| ; AVX: # %bb.0: |
| ; AVX-NEXT: vpcmpgtb %xmm1, %xmm0, %xmm0 |
| ; AVX-NEXT: vpmovmskb %xmm0, %ecx |
| ; AVX-NEXT: xorl %eax, %eax |
| ; AVX-NEXT: negl %ecx |
| ; AVX-NEXT: sbbl %eax, %eax |
| ; AVX-NEXT: # kill: def $al killed $al killed $eax |
| ; AVX-NEXT: retq |
| %c = icmp sgt <16 x i8> %a0, %a1 |
| %s = sext <16 x i1> %c to <16 x i8> |
| %r = call i8 @llvm.vector.reduce.or.v16i8(<16 x i8> %s) |
| ret i8 %r |
| } |
| |
| define i8 @test_v32i8_sext(<32 x i8> %a0, <32 x i8> %a1) { |
| ; SSE-LABEL: test_v32i8_sext: |
| ; SSE: # %bb.0: |
| ; SSE-NEXT: pcmpgtb %xmm3, %xmm1 |
| ; SSE-NEXT: pcmpgtb %xmm2, %xmm0 |
| ; SSE-NEXT: por %xmm1, %xmm0 |
| ; SSE-NEXT: pmovmskb %xmm0, %ecx |
| ; SSE-NEXT: xorl %eax, %eax |
| ; SSE-NEXT: negl %ecx |
| ; SSE-NEXT: sbbl %eax, %eax |
| ; SSE-NEXT: # kill: def $al killed $al killed $eax |
| ; SSE-NEXT: retq |
| ; |
| ; AVX1-LABEL: test_v32i8_sext: |
| ; AVX1: # %bb.0: |
| ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2 |
| ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3 |
| ; AVX1-NEXT: vpcmpgtb %xmm2, %xmm3, %xmm2 |
| ; AVX1-NEXT: vpcmpgtb %xmm1, %xmm0, %xmm0 |
| ; AVX1-NEXT: vpor %xmm2, %xmm0, %xmm0 |
| ; AVX1-NEXT: vpmovmskb %xmm0, %ecx |
| ; AVX1-NEXT: xorl %eax, %eax |
| ; AVX1-NEXT: negl %ecx |
| ; AVX1-NEXT: sbbl %eax, %eax |
| ; AVX1-NEXT: # kill: def $al killed $al killed $eax |
| ; AVX1-NEXT: vzeroupper |
| ; AVX1-NEXT: retq |
| ; |
| ; AVX2-LABEL: test_v32i8_sext: |
| ; AVX2: # %bb.0: |
| ; AVX2-NEXT: vpcmpgtb %ymm1, %ymm0, %ymm0 |
| ; AVX2-NEXT: vpmovmskb %ymm0, %ecx |
| ; AVX2-NEXT: xorl %eax, %eax |
| ; AVX2-NEXT: negl %ecx |
| ; AVX2-NEXT: sbbl %eax, %eax |
| ; AVX2-NEXT: # kill: def $al killed $al killed $eax |
| ; AVX2-NEXT: vzeroupper |
| ; AVX2-NEXT: retq |
| ; |
| ; AVX512-LABEL: test_v32i8_sext: |
| ; AVX512: # %bb.0: |
| ; AVX512-NEXT: vpcmpgtb %ymm1, %ymm0, %ymm0 |
| ; AVX512-NEXT: vpmovmskb %ymm0, %ecx |
| ; AVX512-NEXT: xorl %eax, %eax |
| ; AVX512-NEXT: negl %ecx |
| ; AVX512-NEXT: sbbl %eax, %eax |
| ; AVX512-NEXT: # kill: def $al killed $al killed $eax |
| ; AVX512-NEXT: vzeroupper |
| ; AVX512-NEXT: retq |
| %c = icmp sgt <32 x i8> %a0, %a1 |
| %s = sext <32 x i1> %c to <32 x i8> |
| %r = call i8 @llvm.vector.reduce.or.v32i8(<32 x i8> %s) |
| ret i8 %r |
| } |
| |
| define i1 @bool_reduction_v2f64(<2 x double> %x, <2 x double> %y) { |
| ; SSE-LABEL: bool_reduction_v2f64: |
| ; SSE: # %bb.0: |
| ; SSE-NEXT: cmpltpd %xmm0, %xmm1 |
| ; SSE-NEXT: movmskpd %xmm1, %eax |
| ; SSE-NEXT: testl %eax, %eax |
| ; SSE-NEXT: setne %al |
| ; SSE-NEXT: retq |
| ; |
| ; AVX1OR2-LABEL: bool_reduction_v2f64: |
| ; AVX1OR2: # %bb.0: |
| ; AVX1OR2-NEXT: vcmpltpd %xmm0, %xmm1, %xmm0 |
| ; AVX1OR2-NEXT: vtestpd %xmm0, %xmm0 |
| ; AVX1OR2-NEXT: setne %al |
| ; AVX1OR2-NEXT: retq |
| ; |
| ; AVX512-LABEL: bool_reduction_v2f64: |
| ; AVX512: # %bb.0: |
| ; AVX512-NEXT: vcmpltpd %xmm0, %xmm1, %k0 |
| ; AVX512-NEXT: kmovd %k0, %eax |
| ; AVX512-NEXT: testb %al, %al |
| ; AVX512-NEXT: setne %al |
| ; AVX512-NEXT: retq |
| %a = fcmp ogt <2 x double> %x, %y |
| %b = bitcast <2 x i1> %a to i2 |
| %c = icmp ne i2 %b, 0 |
| ret i1 %c |
| } |
| |
| define i1 @bool_reduction_v4f32(<4 x float> %x, <4 x float> %y) { |
| ; SSE-LABEL: bool_reduction_v4f32: |
| ; SSE: # %bb.0: |
| ; SSE-NEXT: cmpeqps %xmm1, %xmm0 |
| ; SSE-NEXT: movmskps %xmm0, %eax |
| ; SSE-NEXT: testl %eax, %eax |
| ; SSE-NEXT: setne %al |
| ; SSE-NEXT: retq |
| ; |
| ; AVX1OR2-LABEL: bool_reduction_v4f32: |
| ; AVX1OR2: # %bb.0: |
| ; AVX1OR2-NEXT: vcmpeqps %xmm1, %xmm0, %xmm0 |
| ; AVX1OR2-NEXT: vtestps %xmm0, %xmm0 |
| ; AVX1OR2-NEXT: setne %al |
| ; AVX1OR2-NEXT: retq |
| ; |
| ; AVX512-LABEL: bool_reduction_v4f32: |
| ; AVX512: # %bb.0: |
| ; AVX512-NEXT: vcmpeqps %xmm1, %xmm0, %k0 |
| ; AVX512-NEXT: kmovd %k0, %eax |
| ; AVX512-NEXT: testb %al, %al |
| ; AVX512-NEXT: setne %al |
| ; AVX512-NEXT: retq |
| %a = fcmp oeq <4 x float> %x, %y |
| %b = bitcast <4 x i1> %a to i4 |
| %c = icmp ne i4 %b, 0 |
| ret i1 %c |
| } |
| |
| define i1 @bool_reduction_v4f64(<4 x double> %x, <4 x double> %y) { |
| ; SSE-LABEL: bool_reduction_v4f64: |
| ; SSE: # %bb.0: |
| ; SSE-NEXT: cmplepd %xmm1, %xmm3 |
| ; SSE-NEXT: cmplepd %xmm0, %xmm2 |
| ; SSE-NEXT: shufps {{.*#+}} xmm2 = xmm2[0,2],xmm3[0,2] |
| ; SSE-NEXT: movmskps %xmm2, %eax |
| ; SSE-NEXT: testl %eax, %eax |
| ; SSE-NEXT: setne %al |
| ; SSE-NEXT: retq |
| ; |
| ; AVX1OR2-LABEL: bool_reduction_v4f64: |
| ; AVX1OR2: # %bb.0: |
| ; AVX1OR2-NEXT: vcmplepd %ymm0, %ymm1, %ymm0 |
| ; AVX1OR2-NEXT: vtestpd %ymm0, %ymm0 |
| ; AVX1OR2-NEXT: setne %al |
| ; AVX1OR2-NEXT: vzeroupper |
| ; AVX1OR2-NEXT: retq |
| ; |
| ; AVX512-LABEL: bool_reduction_v4f64: |
| ; AVX512: # %bb.0: |
| ; AVX512-NEXT: vcmplepd %ymm0, %ymm1, %k0 |
| ; AVX512-NEXT: kmovd %k0, %eax |
| ; AVX512-NEXT: testb %al, %al |
| ; AVX512-NEXT: setne %al |
| ; AVX512-NEXT: vzeroupper |
| ; AVX512-NEXT: retq |
| %a = fcmp oge <4 x double> %x, %y |
| %b = bitcast <4 x i1> %a to i4 |
| %c = icmp ne i4 %b, 0 |
| ret i1 %c |
| } |
| |
| define i1 @bool_reduction_v8f32(<8 x float> %x, <8 x float> %y) { |
| ; SSE-LABEL: bool_reduction_v8f32: |
| ; SSE: # %bb.0: |
| ; SSE-NEXT: cmpneqps %xmm3, %xmm1 |
| ; SSE-NEXT: cmpneqps %xmm2, %xmm0 |
| ; SSE-NEXT: packssdw %xmm1, %xmm0 |
| ; SSE-NEXT: pmovmskb %xmm0, %eax |
| ; SSE-NEXT: testl %eax, %eax |
| ; SSE-NEXT: setne %al |
| ; SSE-NEXT: retq |
| ; |
| ; AVX1OR2-LABEL: bool_reduction_v8f32: |
| ; AVX1OR2: # %bb.0: |
| ; AVX1OR2-NEXT: vcmpneqps %ymm1, %ymm0, %ymm0 |
| ; AVX1OR2-NEXT: vtestps %ymm0, %ymm0 |
| ; AVX1OR2-NEXT: setne %al |
| ; AVX1OR2-NEXT: vzeroupper |
| ; AVX1OR2-NEXT: retq |
| ; |
| ; AVX512-LABEL: bool_reduction_v8f32: |
| ; AVX512: # %bb.0: |
| ; AVX512-NEXT: vcmpneqps %ymm1, %ymm0, %k0 |
| ; AVX512-NEXT: kmovd %k0, %eax |
| ; AVX512-NEXT: testb %al, %al |
| ; AVX512-NEXT: setne %al |
| ; AVX512-NEXT: vzeroupper |
| ; AVX512-NEXT: retq |
| %a = fcmp une <8 x float> %x, %y |
| %b = bitcast <8 x i1> %a to i8 |
| %c = icmp ne i8 %b, 0 |
| ret i1 %c |
| } |
| |
| define i1 @bool_reduction_v2i64(<2 x i64> %x, <2 x i64> %y) { |
| ; SSE2-LABEL: bool_reduction_v2i64: |
| ; SSE2: # %bb.0: |
| ; SSE2-NEXT: pcmpeqd %xmm1, %xmm0 |
| ; SSE2-NEXT: movmskps %xmm0, %eax |
| ; SSE2-NEXT: xorl $15, %eax |
| ; SSE2-NEXT: setne %al |
| ; SSE2-NEXT: retq |
| ; |
| ; SSE42-LABEL: bool_reduction_v2i64: |
| ; SSE42: # %bb.0: |
| ; SSE42-NEXT: pxor %xmm1, %xmm0 |
| ; SSE42-NEXT: ptest %xmm0, %xmm0 |
| ; SSE42-NEXT: setne %al |
| ; SSE42-NEXT: retq |
| ; |
| ; AVX-LABEL: bool_reduction_v2i64: |
| ; AVX: # %bb.0: |
| ; AVX-NEXT: vpxor %xmm1, %xmm0, %xmm0 |
| ; AVX-NEXT: vptest %xmm0, %xmm0 |
| ; AVX-NEXT: setne %al |
| ; AVX-NEXT: retq |
| %a = icmp ne <2 x i64> %x, %y |
| %b = bitcast <2 x i1> %a to i2 |
| %c = icmp ne i2 %b, 0 |
| ret i1 %c |
| } |
| |
| define i1 @bool_reduction_v4i32(<4 x i32> %x, <4 x i32> %y) { |
| ; SSE2-LABEL: bool_reduction_v4i32: |
| ; SSE2: # %bb.0: |
| ; SSE2-NEXT: movdqa {{.*#+}} xmm2 = [2147483648,2147483648,2147483648,2147483648] |
| ; SSE2-NEXT: pxor %xmm2, %xmm1 |
| ; SSE2-NEXT: pxor %xmm2, %xmm0 |
| ; SSE2-NEXT: pcmpgtd %xmm1, %xmm0 |
| ; SSE2-NEXT: movmskps %xmm0, %eax |
| ; SSE2-NEXT: testl %eax, %eax |
| ; SSE2-NEXT: setne %al |
| ; SSE2-NEXT: retq |
| ; |
| ; SSE42-LABEL: bool_reduction_v4i32: |
| ; SSE42: # %bb.0: |
| ; SSE42-NEXT: pminud %xmm0, %xmm1 |
| ; SSE42-NEXT: pxor %xmm0, %xmm1 |
| ; SSE42-NEXT: ptest %xmm1, %xmm1 |
| ; SSE42-NEXT: setne %al |
| ; SSE42-NEXT: retq |
| ; |
| ; AVX1OR2-LABEL: bool_reduction_v4i32: |
| ; AVX1OR2: # %bb.0: |
| ; AVX1OR2-NEXT: vpminud %xmm1, %xmm0, %xmm1 |
| ; AVX1OR2-NEXT: vpxor %xmm1, %xmm0, %xmm0 |
| ; AVX1OR2-NEXT: vptest %xmm0, %xmm0 |
| ; AVX1OR2-NEXT: setne %al |
| ; AVX1OR2-NEXT: retq |
| ; |
| ; AVX512-LABEL: bool_reduction_v4i32: |
| ; AVX512: # %bb.0: |
| ; AVX512-NEXT: vpcmpnleud %xmm1, %xmm0, %k0 |
| ; AVX512-NEXT: kmovd %k0, %eax |
| ; AVX512-NEXT: testb %al, %al |
| ; AVX512-NEXT: setne %al |
| ; AVX512-NEXT: retq |
| %a = icmp ugt <4 x i32> %x, %y |
| %b = bitcast <4 x i1> %a to i4 |
| %c = icmp ne i4 %b, 0 |
| ret i1 %c |
| } |
| |
| define i1 @bool_reduction_v8i16(<8 x i16> %x, <8 x i16> %y) { |
| ; SSE-LABEL: bool_reduction_v8i16: |
| ; SSE: # %bb.0: |
| ; SSE-NEXT: pcmpgtw %xmm0, %xmm1 |
| ; SSE-NEXT: pmovmskb %xmm1, %eax |
| ; SSE-NEXT: testl %eax, %eax |
| ; SSE-NEXT: setne %al |
| ; SSE-NEXT: retq |
| ; |
| ; AVX1OR2-LABEL: bool_reduction_v8i16: |
| ; AVX1OR2: # %bb.0: |
| ; AVX1OR2-NEXT: vpcmpgtw %xmm0, %xmm1, %xmm0 |
| ; AVX1OR2-NEXT: vpmovmskb %xmm0, %eax |
| ; AVX1OR2-NEXT: testl %eax, %eax |
| ; AVX1OR2-NEXT: setne %al |
| ; AVX1OR2-NEXT: retq |
| ; |
| ; AVX512-LABEL: bool_reduction_v8i16: |
| ; AVX512: # %bb.0: |
| ; AVX512-NEXT: vpcmpgtw %xmm0, %xmm1, %k0 |
| ; AVX512-NEXT: kmovd %k0, %eax |
| ; AVX512-NEXT: testb %al, %al |
| ; AVX512-NEXT: setne %al |
| ; AVX512-NEXT: retq |
| %a = icmp slt <8 x i16> %x, %y |
| %b = bitcast <8 x i1> %a to i8 |
| %c = icmp ne i8 %b, 0 |
| ret i1 %c |
| } |
| |
| define i1 @bool_reduction_v16i8(<16 x i8> %x, <16 x i8> %y) { |
| ; SSE-LABEL: bool_reduction_v16i8: |
| ; SSE: # %bb.0: |
| ; SSE-NEXT: pcmpgtb %xmm1, %xmm0 |
| ; SSE-NEXT: pmovmskb %xmm0, %eax |
| ; SSE-NEXT: testl %eax, %eax |
| ; SSE-NEXT: setne %al |
| ; SSE-NEXT: retq |
| ; |
| ; AVX1OR2-LABEL: bool_reduction_v16i8: |
| ; AVX1OR2: # %bb.0: |
| ; AVX1OR2-NEXT: vpcmpgtb %xmm1, %xmm0, %xmm0 |
| ; AVX1OR2-NEXT: vpmovmskb %xmm0, %eax |
| ; AVX1OR2-NEXT: testl %eax, %eax |
| ; AVX1OR2-NEXT: setne %al |
| ; AVX1OR2-NEXT: retq |
| ; |
| ; AVX512-LABEL: bool_reduction_v16i8: |
| ; AVX512: # %bb.0: |
| ; AVX512-NEXT: vpcmpgtb %xmm1, %xmm0, %k0 |
| ; AVX512-NEXT: kortestw %k0, %k0 |
| ; AVX512-NEXT: setne %al |
| ; AVX512-NEXT: retq |
| %a = icmp sgt <16 x i8> %x, %y |
| %b = bitcast <16 x i1> %a to i16 |
| %c = icmp ne i16 %b, 0 |
| ret i1 %c |
| } |
| |
| define i1 @bool_reduction_v4i64(<4 x i64> %x, <4 x i64> %y) { |
| ; SSE2-LABEL: bool_reduction_v4i64: |
| ; SSE2: # %bb.0: |
| ; SSE2-NEXT: movdqa {{.*#+}} xmm4 = [2147483648,2147483648] |
| ; SSE2-NEXT: pxor %xmm4, %xmm1 |
| ; SSE2-NEXT: pxor %xmm4, %xmm3 |
| ; SSE2-NEXT: movdqa %xmm3, %xmm5 |
| ; SSE2-NEXT: pcmpgtd %xmm1, %xmm5 |
| ; SSE2-NEXT: pxor %xmm4, %xmm0 |
| ; SSE2-NEXT: pxor %xmm4, %xmm2 |
| ; SSE2-NEXT: movdqa %xmm2, %xmm4 |
| ; SSE2-NEXT: pcmpgtd %xmm0, %xmm4 |
| ; SSE2-NEXT: movdqa %xmm4, %xmm6 |
| ; SSE2-NEXT: shufps {{.*#+}} xmm6 = xmm6[0,2],xmm5[0,2] |
| ; SSE2-NEXT: pcmpeqd %xmm1, %xmm3 |
| ; SSE2-NEXT: pcmpeqd %xmm0, %xmm2 |
| ; SSE2-NEXT: shufps {{.*#+}} xmm2 = xmm2[1,3],xmm3[1,3] |
| ; SSE2-NEXT: andps %xmm6, %xmm2 |
| ; SSE2-NEXT: shufps {{.*#+}} xmm4 = xmm4[1,3],xmm5[1,3] |
| ; SSE2-NEXT: orps %xmm2, %xmm4 |
| ; SSE2-NEXT: movmskps %xmm4, %eax |
| ; SSE2-NEXT: testl %eax, %eax |
| ; SSE2-NEXT: setne %al |
| ; SSE2-NEXT: retq |
| ; |
| ; SSE42-LABEL: bool_reduction_v4i64: |
| ; SSE42: # %bb.0: |
| ; SSE42-NEXT: pcmpgtq %xmm1, %xmm3 |
| ; SSE42-NEXT: pcmpgtq %xmm0, %xmm2 |
| ; SSE42-NEXT: packssdw %xmm3, %xmm2 |
| ; SSE42-NEXT: movmskps %xmm2, %eax |
| ; SSE42-NEXT: testl %eax, %eax |
| ; SSE42-NEXT: setne %al |
| ; SSE42-NEXT: retq |
| ; |
| ; AVX1-LABEL: bool_reduction_v4i64: |
| ; AVX1: # %bb.0: |
| ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm2 |
| ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm3 |
| ; AVX1-NEXT: vpcmpgtq %xmm2, %xmm3, %xmm2 |
| ; AVX1-NEXT: vpcmpgtq %xmm0, %xmm1, %xmm0 |
| ; AVX1-NEXT: vpor %xmm2, %xmm0, %xmm0 |
| ; AVX1-NEXT: vtestpd %xmm0, %xmm0 |
| ; AVX1-NEXT: setne %al |
| ; AVX1-NEXT: vzeroupper |
| ; AVX1-NEXT: retq |
| ; |
| ; AVX2-LABEL: bool_reduction_v4i64: |
| ; AVX2: # %bb.0: |
| ; AVX2-NEXT: vpcmpgtq %ymm0, %ymm1, %ymm0 |
| ; AVX2-NEXT: vtestpd %ymm0, %ymm0 |
| ; AVX2-NEXT: setne %al |
| ; AVX2-NEXT: vzeroupper |
| ; AVX2-NEXT: retq |
| ; |
| ; AVX512-LABEL: bool_reduction_v4i64: |
| ; AVX512: # %bb.0: |
| ; AVX512-NEXT: vpcmpgtq %ymm0, %ymm1, %k0 |
| ; AVX512-NEXT: kmovd %k0, %eax |
| ; AVX512-NEXT: testb %al, %al |
| ; AVX512-NEXT: setne %al |
| ; AVX512-NEXT: vzeroupper |
| ; AVX512-NEXT: retq |
| %a = icmp slt <4 x i64> %x, %y |
| %b = bitcast <4 x i1> %a to i4 |
| %c = icmp ne i4 %b, 0 |
| ret i1 %c |
| } |
| |
| define i1 @bool_reduction_v8i32(<8 x i32> %x, <8 x i32> %y) { |
| ; SSE2-LABEL: bool_reduction_v8i32: |
| ; SSE2: # %bb.0: |
| ; SSE2-NEXT: movdqa {{.*#+}} xmm4 = [2147483648,2147483648,2147483648,2147483648] |
| ; SSE2-NEXT: pxor %xmm4, %xmm3 |
| ; SSE2-NEXT: pxor %xmm4, %xmm1 |
| ; SSE2-NEXT: pcmpgtd %xmm3, %xmm1 |
| ; SSE2-NEXT: pxor %xmm4, %xmm2 |
| ; SSE2-NEXT: pxor %xmm4, %xmm0 |
| ; SSE2-NEXT: pcmpgtd %xmm2, %xmm0 |
| ; SSE2-NEXT: packssdw %xmm1, %xmm0 |
| ; SSE2-NEXT: packsswb %xmm0, %xmm0 |
| ; SSE2-NEXT: pmovmskb %xmm0, %eax |
| ; SSE2-NEXT: xorb $-1, %al |
| ; SSE2-NEXT: setne %al |
| ; SSE2-NEXT: retq |
| ; |
| ; SSE42-LABEL: bool_reduction_v8i32: |
| ; SSE42: # %bb.0: |
| ; SSE42-NEXT: pminud %xmm1, %xmm3 |
| ; SSE42-NEXT: pcmpeqd %xmm1, %xmm3 |
| ; SSE42-NEXT: pminud %xmm0, %xmm2 |
| ; SSE42-NEXT: pcmpeqd %xmm0, %xmm2 |
| ; SSE42-NEXT: packssdw %xmm3, %xmm2 |
| ; SSE42-NEXT: pmovmskb %xmm2, %eax |
| ; SSE42-NEXT: testl %eax, %eax |
| ; SSE42-NEXT: setne %al |
| ; SSE42-NEXT: retq |
| ; |
| ; AVX1-LABEL: bool_reduction_v8i32: |
| ; AVX1: # %bb.0: |
| ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2 |
| ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3 |
| ; AVX1-NEXT: vpminud %xmm2, %xmm3, %xmm2 |
| ; AVX1-NEXT: vpcmpeqd %xmm2, %xmm3, %xmm2 |
| ; AVX1-NEXT: vpminud %xmm1, %xmm0, %xmm1 |
| ; AVX1-NEXT: vpcmpeqd %xmm1, %xmm0, %xmm0 |
| ; AVX1-NEXT: vpor %xmm2, %xmm0, %xmm0 |
| ; AVX1-NEXT: vtestps %xmm0, %xmm0 |
| ; AVX1-NEXT: setne %al |
| ; AVX1-NEXT: vzeroupper |
| ; AVX1-NEXT: retq |
| ; |
| ; AVX2-LABEL: bool_reduction_v8i32: |
| ; AVX2: # %bb.0: |
| ; AVX2-NEXT: vpminud %ymm1, %ymm0, %ymm1 |
| ; AVX2-NEXT: vpcmpeqd %ymm1, %ymm0, %ymm0 |
| ; AVX2-NEXT: vtestps %ymm0, %ymm0 |
| ; AVX2-NEXT: setne %al |
| ; AVX2-NEXT: vzeroupper |
| ; AVX2-NEXT: retq |
| ; |
| ; AVX512-LABEL: bool_reduction_v8i32: |
| ; AVX512: # %bb.0: |
| ; AVX512-NEXT: vpcmpleud %ymm1, %ymm0, %k0 |
| ; AVX512-NEXT: kmovd %k0, %eax |
| ; AVX512-NEXT: testb %al, %al |
| ; AVX512-NEXT: setne %al |
| ; AVX512-NEXT: vzeroupper |
| ; AVX512-NEXT: retq |
| %a = icmp ule <8 x i32> %x, %y |
| %b = bitcast <8 x i1> %a to i8 |
| %c = icmp ne i8 %b, 0 |
| ret i1 %c |
| } |
| |
| define i1 @bool_reduction_v16i16(<16 x i16> %x, <16 x i16> %y) { |
| ; SSE-LABEL: bool_reduction_v16i16: |
| ; SSE: # %bb.0: |
| ; SSE-NEXT: pcmpeqw %xmm3, %xmm1 |
| ; SSE-NEXT: pcmpeqw %xmm2, %xmm0 |
| ; SSE-NEXT: packsswb %xmm1, %xmm0 |
| ; SSE-NEXT: pmovmskb %xmm0, %eax |
| ; SSE-NEXT: testl %eax, %eax |
| ; SSE-NEXT: setne %al |
| ; SSE-NEXT: retq |
| ; |
| ; AVX1-LABEL: bool_reduction_v16i16: |
| ; AVX1: # %bb.0: |
| ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2 |
| ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3 |
| ; AVX1-NEXT: vpcmpeqw %xmm2, %xmm3, %xmm2 |
| ; AVX1-NEXT: vpcmpeqw %xmm1, %xmm0, %xmm0 |
| ; AVX1-NEXT: vpacksswb %xmm2, %xmm0, %xmm0 |
| ; AVX1-NEXT: vpmovmskb %xmm0, %eax |
| ; AVX1-NEXT: testl %eax, %eax |
| ; AVX1-NEXT: setne %al |
| ; AVX1-NEXT: vzeroupper |
| ; AVX1-NEXT: retq |
| ; |
| ; AVX2-LABEL: bool_reduction_v16i16: |
| ; AVX2: # %bb.0: |
| ; AVX2-NEXT: vpcmpeqw %ymm1, %ymm0, %ymm0 |
| ; AVX2-NEXT: vpmovmskb %ymm0, %eax |
| ; AVX2-NEXT: testl %eax, %eax |
| ; AVX2-NEXT: setne %al |
| ; AVX2-NEXT: vzeroupper |
| ; AVX2-NEXT: retq |
| ; |
| ; AVX512-LABEL: bool_reduction_v16i16: |
| ; AVX512: # %bb.0: |
| ; AVX512-NEXT: vpcmpeqw %ymm1, %ymm0, %k0 |
| ; AVX512-NEXT: kortestw %k0, %k0 |
| ; AVX512-NEXT: setne %al |
| ; AVX512-NEXT: vzeroupper |
| ; AVX512-NEXT: retq |
| %a = icmp eq <16 x i16> %x, %y |
| %b = bitcast <16 x i1> %a to i16 |
| %c = icmp ne i16 %b, 0 |
| ret i1 %c |
| } |
| |
| define i1 @bool_reduction_v32i8(<32 x i8> %x, <32 x i8> %y) { |
| ; SSE-LABEL: bool_reduction_v32i8: |
| ; SSE: # %bb.0: |
| ; SSE-NEXT: pcmpeqb %xmm3, %xmm1 |
| ; SSE-NEXT: pcmpeqb %xmm2, %xmm0 |
| ; SSE-NEXT: por %xmm1, %xmm0 |
| ; SSE-NEXT: pmovmskb %xmm0, %eax |
| ; SSE-NEXT: testl %eax, %eax |
| ; SSE-NEXT: setne %al |
| ; SSE-NEXT: retq |
| ; |
| ; AVX1-LABEL: bool_reduction_v32i8: |
| ; AVX1: # %bb.0: |
| ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2 |
| ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3 |
| ; AVX1-NEXT: vpcmpeqb %xmm2, %xmm3, %xmm2 |
| ; AVX1-NEXT: vpcmpeqb %xmm1, %xmm0, %xmm0 |
| ; AVX1-NEXT: vpor %xmm2, %xmm0, %xmm0 |
| ; AVX1-NEXT: vpmovmskb %xmm0, %eax |
| ; AVX1-NEXT: testl %eax, %eax |
| ; AVX1-NEXT: setne %al |
| ; AVX1-NEXT: vzeroupper |
| ; AVX1-NEXT: retq |
| ; |
| ; AVX2-LABEL: bool_reduction_v32i8: |
| ; AVX2: # %bb.0: |
| ; AVX2-NEXT: vpcmpeqb %ymm1, %ymm0, %ymm0 |
| ; AVX2-NEXT: vpmovmskb %ymm0, %eax |
| ; AVX2-NEXT: testl %eax, %eax |
| ; AVX2-NEXT: setne %al |
| ; AVX2-NEXT: vzeroupper |
| ; AVX2-NEXT: retq |
| ; |
| ; AVX512-LABEL: bool_reduction_v32i8: |
| ; AVX512: # %bb.0: |
| ; AVX512-NEXT: vpcmpeqb %ymm1, %ymm0, %k0 |
| ; AVX512-NEXT: kortestd %k0, %k0 |
| ; AVX512-NEXT: setne %al |
| ; AVX512-NEXT: vzeroupper |
| ; AVX512-NEXT: retq |
| %a = icmp eq <32 x i8> %x, %y |
| %b = bitcast <32 x i1> %a to i32 |
| %c = icmp ne i32 %b, 0 |
| ret i1 %c |
| } |
| |
| define {i32, i1} @test_v16i8_muti_uses(<16 x i8> %x, <16 x i8>%y, <16 x i8> %z) { |
| ; SSE-LABEL: test_v16i8_muti_uses: |
| ; SSE: # %bb.0: |
| ; SSE-NEXT: pcmpeqb %xmm1, %xmm0 |
| ; SSE-NEXT: pcmpeqb %xmm1, %xmm2 |
| ; SSE-NEXT: pmovmskb %xmm0, %ecx |
| ; SSE-NEXT: pmovmskb %xmm2, %eax |
| ; SSE-NEXT: shll $16, %eax |
| ; SSE-NEXT: orl %ecx, %eax |
| ; SSE-NEXT: sete %dl |
| ; SSE-NEXT: retq |
| ; |
| ; AVX1-LABEL: test_v16i8_muti_uses: |
| ; AVX1: # %bb.0: |
| ; AVX1-NEXT: vpcmpeqb %xmm1, %xmm0, %xmm0 |
| ; AVX1-NEXT: vpcmpeqb %xmm1, %xmm2, %xmm1 |
| ; AVX1-NEXT: vpmovmskb %xmm0, %ecx |
| ; AVX1-NEXT: vpmovmskb %xmm1, %eax |
| ; AVX1-NEXT: shll $16, %eax |
| ; AVX1-NEXT: orl %ecx, %eax |
| ; AVX1-NEXT: sete %dl |
| ; AVX1-NEXT: retq |
| ; |
| ; AVX2-LABEL: test_v16i8_muti_uses: |
| ; AVX2: # %bb.0: |
| ; AVX2-NEXT: vpcmpeqb %xmm1, %xmm0, %xmm0 |
| ; AVX2-NEXT: vpcmpeqb %xmm1, %xmm2, %xmm1 |
| ; AVX2-NEXT: vinserti128 $1, %xmm1, %ymm0, %ymm0 |
| ; AVX2-NEXT: vpmovmskb %ymm0, %eax |
| ; AVX2-NEXT: testl %eax, %eax |
| ; AVX2-NEXT: sete %dl |
| ; AVX2-NEXT: vzeroupper |
| ; AVX2-NEXT: retq |
| ; |
| ; AVX512-LABEL: test_v16i8_muti_uses: |
| ; AVX512: # %bb.0: |
| ; AVX512-NEXT: vpcmpeqb %xmm1, %xmm0, %k0 |
| ; AVX512-NEXT: vpcmpeqb %xmm1, %xmm2, %k1 |
| ; AVX512-NEXT: kunpckwd %k0, %k1, %k0 |
| ; AVX512-NEXT: kortestd %k0, %k0 |
| ; AVX512-NEXT: kmovd %k0, %eax |
| ; AVX512-NEXT: sete %dl |
| ; AVX512-NEXT: retq |
| %t1 = icmp eq <16 x i8> %x, %y |
| %t2 = icmp eq <16 x i8> %z, %y |
| %a = shufflevector <16 x i1> %t1, <16 x i1> %t2, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, 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> |
| %b = bitcast <32 x i1> %a to i32 |
| %c = icmp eq i32 %b, 0 |
| %r1 = insertvalue {i32, i1} poison, i32 %b, 0 |
| %r2 = insertvalue {i32, i1} %r1, i1 %c, 1 |
| ret {i32, i1} %r2 |
| } |
| |
| ; PR59867 |
| define i1 @select_v2i8(ptr %s0, ptr %s1) { |
| ; SSE2-LABEL: select_v2i8: |
| ; SSE2: # %bb.0: |
| ; SSE2-NEXT: movzwl (%rdi), %eax |
| ; SSE2-NEXT: movd %eax, %xmm0 |
| ; SSE2-NEXT: movzwl (%rsi), %eax |
| ; SSE2-NEXT: movd %eax, %xmm1 |
| ; SSE2-NEXT: pcmpeqb %xmm0, %xmm1 |
| ; SSE2-NEXT: punpcklbw {{.*#+}} xmm1 = xmm1[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7] |
| ; SSE2-NEXT: pshuflw {{.*#+}} xmm0 = xmm1[0,0,1,1,4,5,6,7] |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,0,1,1] |
| ; SSE2-NEXT: movmskpd %xmm0, %eax |
| ; SSE2-NEXT: testl %eax, %eax |
| ; SSE2-NEXT: setne %al |
| ; SSE2-NEXT: retq |
| ; |
| ; SSE42-LABEL: select_v2i8: |
| ; SSE42: # %bb.0: |
| ; SSE42-NEXT: movzwl (%rdi), %eax |
| ; SSE42-NEXT: movd %eax, %xmm0 |
| ; SSE42-NEXT: movzwl (%rsi), %eax |
| ; SSE42-NEXT: movd %eax, %xmm1 |
| ; SSE42-NEXT: pcmpeqb %xmm0, %xmm1 |
| ; SSE42-NEXT: pmovsxbq %xmm1, %xmm0 |
| ; SSE42-NEXT: movmskpd %xmm0, %eax |
| ; SSE42-NEXT: testl %eax, %eax |
| ; SSE42-NEXT: setne %al |
| ; SSE42-NEXT: retq |
| ; |
| ; AVX1OR2-LABEL: select_v2i8: |
| ; AVX1OR2: # %bb.0: |
| ; AVX1OR2-NEXT: movzwl (%rdi), %eax |
| ; AVX1OR2-NEXT: vmovd %eax, %xmm0 |
| ; AVX1OR2-NEXT: movzwl (%rsi), %eax |
| ; AVX1OR2-NEXT: vmovd %eax, %xmm1 |
| ; AVX1OR2-NEXT: vpcmpeqb %xmm1, %xmm0, %xmm0 |
| ; AVX1OR2-NEXT: vpmovsxbq %xmm0, %xmm0 |
| ; AVX1OR2-NEXT: vtestpd %xmm0, %xmm0 |
| ; AVX1OR2-NEXT: setne %al |
| ; AVX1OR2-NEXT: retq |
| ; |
| ; AVX512-LABEL: select_v2i8: |
| ; AVX512: # %bb.0: |
| ; AVX512-NEXT: movzwl (%rdi), %eax |
| ; AVX512-NEXT: vmovd %eax, %xmm0 |
| ; AVX512-NEXT: movzwl (%rsi), %eax |
| ; AVX512-NEXT: vmovd %eax, %xmm1 |
| ; AVX512-NEXT: vpcmpeqb %xmm1, %xmm0, %k0 |
| ; AVX512-NEXT: kmovd %k0, %eax |
| ; AVX512-NEXT: testb $3, %al |
| ; AVX512-NEXT: setne %al |
| ; AVX512-NEXT: retq |
| %v0 = load <2 x i8>, ptr %s0, align 1 |
| %v1 = load <2 x i8>, ptr %s1, align 1 |
| %cmp = icmp eq <2 x i8> %v0, %v1 |
| %cmp0 = extractelement <2 x i1> %cmp, i32 0 |
| %cmp1 = extractelement <2 x i1> %cmp, i32 1 |
| %res = select i1 %cmp0, i1 true, i1 %cmp1 |
| ret i1 %res |
| } |