[llvm] 81cdd35 - [ValueTracking] Add support for `xor`/`disjoint or` in `isKnownNonZero`
Noah Goldstein via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 10 11:14:07 PDT 2024
Author: Noah Goldstein
Date: 2024-04-10T13:13:43-05:00
New Revision: 81cdd35c0c8db22bfdd1f06cb2118d17fd99fc07
URL: https://github.com/llvm/llvm-project/commit/81cdd35c0c8db22bfdd1f06cb2118d17fd99fc07
DIFF: https://github.com/llvm/llvm-project/commit/81cdd35c0c8db22bfdd1f06cb2118d17fd99fc07.diff
LOG: [ValueTracking] Add support for `xor`/`disjoint or` in `isKnownNonZero`
Handles cases like `X ^ Y == X` / `X disjoint| Y == X`.
Both of these cases have identical logic to the existing `add` case,
so just converting the `add` code to a more general helper.
Proofs: https://alive2.llvm.org/ce/z/Htm7pe
Closes #87706
Added:
Modified:
llvm/lib/Analysis/ValueTracking.cpp
llvm/test/Transforms/InstSimplify/icmp.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index f3ea73b2f0ec4d..3a10de72a27562 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -3207,20 +3207,33 @@ getInvertibleOperands(const Operator *Op1,
return std::nullopt;
}
-/// Return true if V2 == V1 + X, where X is known non-zero.
-static bool isAddOfNonZero(const Value *V1, const Value *V2, unsigned Depth,
- const SimplifyQuery &Q) {
+/// Return true if V1 == (binop V2, X), where X is known non-zero.
+/// Only handle a small subset of binops where (binop V2, X) with non-zero X
+/// implies V2 != V1.
+static bool isModifyingBinopOfNonZero(const Value *V1, const Value *V2,
+ unsigned Depth, const SimplifyQuery &Q) {
const BinaryOperator *BO = dyn_cast<BinaryOperator>(V1);
- if (!BO || BO->getOpcode() != Instruction::Add)
+ if (!BO)
return false;
- Value *Op = nullptr;
- if (V2 == BO->getOperand(0))
- Op = BO->getOperand(1);
- else if (V2 == BO->getOperand(1))
- Op = BO->getOperand(0);
- else
- return false;
- return isKnownNonZero(Op, Depth + 1, Q);
+ switch (BO->getOpcode()) {
+ default:
+ break;
+ case Instruction::Or:
+ if (!cast<PossiblyDisjointInst>(V1)->isDisjoint())
+ break;
+ [[fallthrough]];
+ case Instruction::Xor:
+ case Instruction::Add:
+ Value *Op = nullptr;
+ if (V2 == BO->getOperand(0))
+ Op = BO->getOperand(1);
+ else if (V2 == BO->getOperand(1))
+ Op = BO->getOperand(0);
+ else
+ return false;
+ return isKnownNonZero(Op, Depth + 1, Q);
+ }
+ return false;
}
/// Return true if V2 == V1 * C, where V1 is known non-zero, C is not 0/1 and
@@ -3380,7 +3393,8 @@ static bool isKnownNonEqual(const Value *V1, const Value *V2, unsigned Depth,
};
}
- if (isAddOfNonZero(V1, V2, Depth, Q) || isAddOfNonZero(V2, V1, Depth, Q))
+ if (isModifyingBinopOfNonZero(V1, V2, Depth, Q) ||
+ isModifyingBinopOfNonZero(V2, V1, Depth, Q))
return true;
if (isNonEqualMul(V1, V2, Depth, Q) || isNonEqualMul(V2, V1, Depth, Q))
diff --git a/llvm/test/Transforms/InstSimplify/icmp.ll b/llvm/test/Transforms/InstSimplify/icmp.ll
index 530dc16144eba9..c94922197096f2 100644
--- a/llvm/test/Transforms/InstSimplify/icmp.ll
+++ b/llvm/test/Transforms/InstSimplify/icmp.ll
@@ -359,12 +359,7 @@ define i1 @non_eq_xor_common_op_fail(i8 %x, i8 %y, i8 %ww, i8 %a) {
define i1 @non_eq_disjoint_or(i8 %x, i8 %yy, i8 %w) {
; CHECK-LABEL: @non_eq_disjoint_or(
-; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1
-; CHECK-NEXT: [[LHS:%.*]] = add i8 [[X:%.*]], [[W:%.*]]
-; CHECK-NEXT: [[VAL:%.*]] = or disjoint i8 [[Y]], [[W]]
-; CHECK-NEXT: [[RHS:%.*]] = add i8 [[X]], [[VAL]]
-; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[LHS]], [[RHS]]
-; CHECK-NEXT: ret i1 [[R]]
+; CHECK-NEXT: ret i1 false
;
%y = add nuw i8 %yy, 1
%lhs = add i8 %x, %w
@@ -393,12 +388,7 @@ define i1 @non_eq_or_fail(i8 %x, i8 %yy, i8 %w) {
define i1 @non_eq_xor(i8 %x, i8 %yy, i8 %w) {
; CHECK-LABEL: @non_eq_xor(
-; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1
-; CHECK-NEXT: [[LHS:%.*]] = add i8 [[X:%.*]], [[W:%.*]]
-; CHECK-NEXT: [[VAL:%.*]] = xor i8 [[Y]], [[W]]
-; CHECK-NEXT: [[RHS:%.*]] = add i8 [[X]], [[VAL]]
-; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[LHS]], [[RHS]]
-; CHECK-NEXT: ret i1 [[R]]
+; CHECK-NEXT: ret i1 false
;
%y = add nuw i8 %yy, 1
%lhs = add i8 %x, %w
More information about the llvm-commits
mailing list