[llvm] d56af3e - [DAG] isKnownNeverZero - add computeKnownBits fallback DemandedElts handling and tests (#198691)

via llvm-commits llvm-commits at lists.llvm.org
Wed May 20 03:01:56 PDT 2026


Author: ShaofengWu
Date: 2026-05-20T10:01:50Z
New Revision: d56af3e634a78a2697c9362fe5974c82451177ab

URL: https://github.com/llvm/llvm-project/commit/d56af3e634a78a2697c9362fe5974c82451177ab
DIFF: https://github.com/llvm/llvm-project/commit/d56af3e634a78a2697c9362fe5974c82451177ab.diff

LOG: [DAG] isKnownNeverZero - add computeKnownBits fallback DemandedElts handling and tests (#198691)

Add DemandedElts to fallback cases in isKnownNeverZero
Fixes #183041 

Tests:
AND and XOR as fallback cases, can see the improvement after code updated.

Added: 
    

Modified: 
    llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
    llvm/test/CodeGen/X86/known-never-zero.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 9ded303419d9e..5c80c4c1b5bff 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -6698,7 +6698,7 @@ bool SelectionDAG::isKnownNeverZero(SDValue Op, const APInt &DemandedElts,
   }
   }
 
-  return computeKnownBits(Op, Depth).isNonZero();
+  return computeKnownBits(Op, DemandedElts, Depth).isNonZero();
 }
 
 bool SelectionDAG::cannotBeOrderedNegativeFP(SDValue Op) const {

diff  --git a/llvm/test/CodeGen/X86/known-never-zero.ll b/llvm/test/CodeGen/X86/known-never-zero.ll
index 496b97f9e17e1..d3cd6942752db 100644
--- a/llvm/test/CodeGen/X86/known-never-zero.ll
+++ b/llvm/test/CodeGen/X86/known-never-zero.ll
@@ -2867,3 +2867,149 @@ define i32 @test_sext_demanded_elts(<4 x i32> %a0, ptr %p) {
   ret i32 %res
 }
 
+; AND is one of fallback case for isKnownNeverZero
+define i32 @and_known_nonzero(i32 %x, i32 %y) {
+; X86-LABEL: and_known_nonzero:
+; X86:       # %bb.0:
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT:    orl $1, %ecx
+; X86-NEXT:    orl $1, %eax
+; X86-NEXT:    andl %ecx, %eax
+; X86-NEXT:    rep bsfl %eax, %eax
+; X86-NEXT:    retl
+;
+; X64-LABEL: and_known_nonzero:
+; X64:       # %bb.0:
+; X64-NEXT:    orl $1, %edi
+; X64-NEXT:    orl $1, %esi
+; X64-NEXT:    andl %edi, %esi
+; X64-NEXT:    rep bsfl %esi, %eax
+; X64-NEXT:    retq
+  %xx = or i32 %x, 1
+  %yy = or i32 %y, 1
+  %z = and i32 %xx, %yy
+  %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
+  ret i32 %r
+}
+
+define i32 @and_known_nonzero_vec(<4 x i32> %x, <4 x i32> %y, ptr %p) {
+; X86-LABEL: and_known_nonzero_vec:
+; X86:       # %bb.0:
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    movd {{.*#+}} xmm2 = [1,0,0,0]
+; X86-NEXT:    por %xmm2, %xmm0
+; X86-NEXT:    por %xmm2, %xmm1
+; X86-NEXT:    pand %xmm0, %xmm1
+; X86-NEXT:    movdqa %xmm1, (%eax)
+; X86-NEXT:    movd %xmm1, %eax
+; X86-NEXT:    rep bsfl %eax, %eax
+; X86-NEXT:    retl
+;
+; X64-LABEL: and_known_nonzero_vec:
+; X64:       # %bb.0:
+; X64-NEXT:    vpmovsxbq {{.*#+}} xmm2 = [1,0]
+; X64-NEXT:    vpor %xmm2, %xmm0, %xmm0
+; X64-NEXT:    vpor %xmm2, %xmm1, %xmm1
+; X64-NEXT:    vpand %xmm1, %xmm0, %xmm0
+; X64-NEXT:    vmovdqa %xmm0, (%rdi)
+; X64-NEXT:    vmovd %xmm0, %eax
+; X64-NEXT:    rep bsfl %eax, %eax
+; X64-NEXT:    retq
+  %xx = or <4 x i32> %x, <i32 1, i32 0, i32 0, i32 0>
+  %yy = or <4 x i32> %y, <i32 1, i32 0, i32 0, i32 0>
+  %z = and <4 x i32> %xx, %yy
+  store <4 x i32> %z, ptr %p
+  %e = extractelement <4 x i32> %z, i32 0
+  %r = call i32 @llvm.cttz.i32(i32 %e, i1 false)
+  ret i32 %r
+}
+
+define i32 @and_maybe_zero(i32 %x, i32 %y) {
+; X86-LABEL: and_maybe_zero:
+; X86:       # %bb.0:
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    bsfl %eax, %ecx
+; X86-NEXT:    movl $32, %eax
+; X86-NEXT:    cmovnel %ecx, %eax
+; X86-NEXT:    retl
+;
+; X64-LABEL: and_maybe_zero:
+; X64:       # %bb.0:
+; X64-NEXT:    andl %esi, %edi
+; X64-NEXT:    movl $32, %eax
+; X64-NEXT:    rep bsfl %edi, %eax
+; X64-NEXT:    retq
+  %z = and i32 %x, %y
+  %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
+  ret i32 %r
+}
+
+; XOR as fallback case for isKnownNeverZero
+define i32 @xor_known_nonzero(i32 %x) {
+; X86-LABEL: xor_known_nonzero:
+; X86:       # %bb.0:
+; X86-NEXT:    xorl %eax, %eax
+; X86-NEXT:    retl
+;
+; X64-LABEL: xor_known_nonzero:
+; X64:       # %bb.0:
+; X64-NEXT:    xorl %eax, %eax
+; X64-NEXT:    retq
+  %xx = and i32 %x, 0
+  %z = xor i32 %xx, 1
+  %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
+  ret i32 %r
+}
+
+define i32 @xor_known_nonzero_vec(<4 x i32> %x, <4 x i32> %y, ptr %p) {
+; X86-LABEL: xor_known_nonzero_vec:
+; X86:       # %bb.0:
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
+; X86-NEXT:    por {{\.?LCPI[0-9]+_[0-9]+}}, %xmm1
+; X86-NEXT:    pxor %xmm0, %xmm1
+; X86-NEXT:    movdqa %xmm1, (%eax)
+; X86-NEXT:    movd %xmm1, %eax
+; X86-NEXT:    rep bsfl %eax, %eax
+; X86-NEXT:    retl
+;
+; X64-LABEL: xor_known_nonzero_vec:
+; X64:       # %bb.0:
+; X64-NEXT:    vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
+; X64-NEXT:    vpor {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm1
+; X64-NEXT:    vpxor %xmm1, %xmm0, %xmm0
+; X64-NEXT:    vmovdqa %xmm0, (%rdi)
+; X64-NEXT:    vmovd %xmm0, %eax
+; X64-NEXT:    rep bsfl %eax, %eax
+; X64-NEXT:    retq
+  %xx = and <4 x i32> %x, <i32 0, i32 1, i32 1, i32 1>
+  %yy = or <4 x i32> %y, <i32 1, i32 0, i32 0, i32 0>
+  %z = xor <4 x i32> %xx, %yy
+  store <4 x i32> %z, ptr %p
+  %e = extractelement <4 x i32> %z, i32 0
+  %r = call i32 @llvm.cttz.i32(i32 %e, i1 false)
+  ret i32 %r
+}
+
+define i32 @xor_maybe_zero(i32 %x, i32 %y) {
+; X86-LABEL: xor_maybe_zero:
+; X86:       # %bb.0:
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    xorl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    bsfl %eax, %ecx
+; X86-NEXT:    movl $32, %eax
+; X86-NEXT:    cmovnel %ecx, %eax
+; X86-NEXT:    retl
+;
+; X64-LABEL: xor_maybe_zero:
+; X64:       # %bb.0:
+; X64-NEXT:    xorl %esi, %edi
+; X64-NEXT:    movl $32, %eax
+; X64-NEXT:    rep bsfl %edi, %eax
+; X64-NEXT:    retq
+  %z = xor i32 %x, %y
+  %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
+  ret i32 %r
+}


        


More information about the llvm-commits mailing list