[llvm] ISD::XOR has the same non-zero detection as ISD::SUB (PR #146980)

via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 5 09:40:49 PDT 2025


https://github.com/AZero13 updated https://github.com/llvm/llvm-project/pull/146980

>From 63e5cbc21733783d4397cb804a75894276b9a123 Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Sat, 5 Jul 2025 11:14:40 -0400
Subject: [PATCH 1/2] Pre-commit tests (NFC)

---
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp |  1 -
 llvm/test/CodeGen/X86/known-never-zero.ll     | 93 +++++++++++++++++++
 2 files changed, 93 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 2a3c8e2b011ad..d7dc3646e24fe 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -6016,7 +6016,6 @@ bool SelectionDAG::isKnownNeverZero(SDValue Op, unsigned Depth) const {
         return true;
     // TODO: There are a lot more cases we can prove for add.
     break;
-
   case ISD::SUB: {
     if (isNullConstant(Op.getOperand(0)))
       return isKnownNeverZero(Op.getOperand(1), Depth + 1);
diff --git a/llvm/test/CodeGen/X86/known-never-zero.ll b/llvm/test/CodeGen/X86/known-never-zero.ll
index 63336ffa7c6c8..45ec188fe79e7 100644
--- a/llvm/test/CodeGen/X86/known-never-zero.ll
+++ b/llvm/test/CodeGen/X86/known-never-zero.ll
@@ -1401,3 +1401,96 @@ define i32 @sext_maybe_zero(i16 %x) {
   %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
   ret i32 %r
 }
+
+define i32 @xor_known_nonzero_neg_case(i32 %xx) {
+; X86-LABEL: xor_known_nonzero_neg_case:
+; X86:       # %bb.0:
+; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT:    movl $256, %eax # imm = 0x100
+; X86-NEXT:    shll %cl, %eax
+; X86-NEXT:    rep bsfl %eax, %eax
+; X86-NEXT:    retl
+;
+; X64-LABEL: xor_known_nonzero_neg_case:
+; X64:       # %bb.0:
+; X64-NEXT:    movl %edi, %ecx
+; X64-NEXT:    movl $256, %eax # imm = 0x100
+; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
+; X64-NEXT:    shll %cl, %eax
+; X64-NEXT:    rep bsfl %eax, %eax
+; X64-NEXT:    retq
+  %x = shl nuw nsw i32 256, %xx
+  %z = xor i32 0, %x
+  %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
+  ret i32 %r
+}
+
+define i32 @xor_known_nonzero_ne_case(i32 %xx, i32 %yy) {
+; X86-LABEL: xor_known_nonzero_ne_case:
+; X86:       # %bb.0:
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    movl %eax, %ecx
+; X86-NEXT:    orl $64, %ecx
+; X86-NEXT:    andl $-65, %eax
+; X86-NEXT:    xorl %ecx, %eax
+; X86-NEXT:    rep bsfl %eax, %eax
+; X86-NEXT:    retl
+;
+; X64-LABEL: xor_known_nonzero_ne_case:
+; X64:       # %bb.0:
+; X64-NEXT:    movl %edi, %eax
+; X64-NEXT:    orl $64, %eax
+; X64-NEXT:    andl $-65, %edi
+; X64-NEXT:    xorl %eax, %edi
+; X64-NEXT:    rep bsfl %edi, %eax
+; X64-NEXT:    retq
+  %x = or i32 %xx, 64
+  %y = and i32 %xx, -65
+  %z = xor i32 %y, %x
+  %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
+  ret i32 %r
+}
+
+define i32 @xor_maybe_zero(i32 %x) {
+; X86-LABEL: xor_maybe_zero:
+; X86:       # %bb.0:
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    movl %eax, %ecx
+; X86-NEXT:    orl $64, %ecx
+; X86-NEXT:    xorl %eax, %ecx
+; X86-NEXT:    bsfl %ecx, %ecx
+; X86-NEXT:    movl $32, %eax
+; X86-NEXT:    cmovnel %ecx, %eax
+; X86-NEXT:    retl
+;
+; X64-LABEL: xor_maybe_zero:
+; X64:       # %bb.0:
+; X64-NEXT:    movl %edi, %ecx
+; X64-NEXT:    orl $64, %ecx
+; X64-NEXT:    xorl %edi, %ecx
+; X64-NEXT:    movl $32, %eax
+; X64-NEXT:    rep bsfl %ecx, %eax
+; X64-NEXT:    retq
+  %y = or i32 %x, 64
+  %z = xor i32 %y, %x
+  %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
+  ret i32 %r
+}
+
+define i32 @xor_maybe_zero2(i32 %x) {
+; X86-LABEL: xor_maybe_zero2:
+; X86:       # %bb.0:
+; X86-NEXT:    bsfl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT:    movl $32, %eax
+; X86-NEXT:    cmovnel %ecx, %eax
+; X86-NEXT:    retl
+;
+; X64-LABEL: xor_maybe_zero2:
+; X64:       # %bb.0:
+; X64-NEXT:    movl $32, %eax
+; X64-NEXT:    rep bsfl %edi, %eax
+; X64-NEXT:    retq
+  %z = xor i32 0, %x
+  %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)
+  ret i32 %r
+}

>From 5eae1c0dfa9cd230e4e07688337bd6f9707480f8 Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Sat, 5 Jul 2025 12:37:55 -0400
Subject: [PATCH 2/2] [SelectionDAG] ISD::XOR has the same non-zero detection
 as ISD::SUB

If X - Y != 0, then X ^ Y != 0
---
 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index d7dc3646e24fe..a01e34fa1b179 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -6016,6 +6016,9 @@ bool SelectionDAG::isKnownNeverZero(SDValue Op, unsigned Depth) const {
         return true;
     // TODO: There are a lot more cases we can prove for add.
     break;
+
+  // If X - Y != 0, then X ^ Y != 0
+  case ISD::XOR:
   case ISD::SUB: {
     if (isNullConstant(Op.getOperand(0)))
       return isKnownNeverZero(Op.getOperand(1), Depth + 1);



More information about the llvm-commits mailing list