[llvm] [ValueTracking] X ^ Y != 0 if X != Y (PR #146975)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Jul 5 08:00:45 PDT 2025
https://github.com/AZero13 updated https://github.com/llvm/llvm-project/pull/146975
>From aa21780c91e16425617d31a7b494025714d3b0d1 Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Sat, 5 Jul 2025 10:59:29 -0400
Subject: [PATCH 1/2] Pre-commit test (NFC)
---
.../test/Transforms/InstCombine/ctpop-cttz.ll | 21 +++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/ctpop-cttz.ll b/llvm/test/Transforms/InstCombine/ctpop-cttz.ll
index 4c5d7a7dc011b..b469a82a2af23 100644
--- a/llvm/test/Transforms/InstCombine/ctpop-cttz.ll
+++ b/llvm/test/Transforms/InstCombine/ctpop-cttz.ll
@@ -127,3 +127,24 @@ define <2 x i32> @ctpop3v_poison(<2 x i32> %0) {
%5 = tail call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %4)
ret <2 x i32> %5
}
+
+define i32 @ctpop_xor(i32 %x, i32 %y) {
+; CHECK-LABEL: @ctpop_xor(
+; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: br i1 [[CMP_NOT]], label [[FALSE:%.*]], label [[TRUE:%.*]]
+; CHECK: true:
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]]
+; CHECK-NEXT: [[RET:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[XOR]])
+; CHECK-NEXT: ret i32 [[RET]]
+; CHECK: false:
+; CHECK-NEXT: ret i32 0
+;
+ %cmp = icmp ne i32 %x, %y
+ br i1 %cmp, label %true, label %false
+true:
+ %xor = xor i32 %x, %y
+ %ret = call i32 @llvm.ctpop.i32(i32 %xor)
+ ret i32 %ret
+false:
+ ret i32 0
+}
>From 5b0e3a731d00559a508e0ff57649e61c9f3f6ac4 Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Thu, 3 Jul 2025 19:55:09 -0400
Subject: [PATCH 2/2] [ValueTracking] X ^ Y != 0 if X != Y.
It goes without saying that for x ^ y to be 0, x and y must be equal.
---
llvm/lib/Analysis/ValueTracking.cpp | 4 +++-
llvm/test/Transforms/InstCombine/ctpop-cttz.ll | 2 +-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 09745ed6eac6a..1c4412e4b5db7 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -3043,7 +3043,9 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
// (X ^ (X != 0)) is non zero
if (matchOpWithOpEqZero(I->getOperand(0), I->getOperand(1)))
return true;
- break;
+ // X ^ Y != 0 if X != Y.
+ return isKnownNonEqual(I->getOperand(0), I->getOperand(1), DemandedElts, Q,
+ Depth);
case Instruction::Or:
// (X | (X != 0)) is non zero
if (matchOpWithOpEqZero(I->getOperand(0), I->getOperand(1)))
diff --git a/llvm/test/Transforms/InstCombine/ctpop-cttz.ll b/llvm/test/Transforms/InstCombine/ctpop-cttz.ll
index b469a82a2af23..a1f0f01e2c470 100644
--- a/llvm/test/Transforms/InstCombine/ctpop-cttz.ll
+++ b/llvm/test/Transforms/InstCombine/ctpop-cttz.ll
@@ -134,7 +134,7 @@ define i32 @ctpop_xor(i32 %x, i32 %y) {
; CHECK-NEXT: br i1 [[CMP_NOT]], label [[FALSE:%.*]], label [[TRUE:%.*]]
; CHECK: true:
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]]
-; CHECK-NEXT: [[RET:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[XOR]])
+; CHECK-NEXT: [[RET:%.*]] = call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 [[XOR]])
; CHECK-NEXT: ret i32 [[RET]]
; CHECK: false:
; CHECK-NEXT: ret i32 0
More information about the llvm-commits
mailing list