[llvm] [ValueTracking] Have sub and xor in KnownNonZero take the same exact path (PR #146975)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Jul 5 08:35:32 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 93bf56e68116daad627242f60cd3ff87aa90188e 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] Have sub and xor in KnownNonZero take the
same exact path
If x - y == 0, then x ^ y == 0. Therefore, we can do the exact same checks.
https://alive2.llvm.org/ce/z/MtBRoj
---
llvm/lib/Analysis/ValueTracking.cpp | 8 +++-----
llvm/test/Transforms/InstCombine/ctpop-cttz.ll | 2 +-
2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 09745ed6eac6a..5e80ddcfc0dd9 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -3036,14 +3036,12 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
return isKnownNonZero(TI->getOperand(0), DemandedElts, Q, Depth);
break;
+ // Iff x - y == 0, then x ^ y == 0
+ // Therefore we can do the same exact checks
+ case Instruction::Xor:
case Instruction::Sub:
return isNonZeroSub(DemandedElts, Q, BitWidth, I->getOperand(0),
I->getOperand(1), Depth);
- case Instruction::Xor:
- // (X ^ (X != 0)) is non zero
- if (matchOpWithOpEqZero(I->getOperand(0), I->getOperand(1)))
- return true;
- break;
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