diff options
author | Noah Goldstein <goldstein.w.n@gmail.com> | 2024-04-03 17:40:03 -0500 |
---|---|---|
committer | Noah Goldstein <goldstein.w.n@gmail.com> | 2024-04-10 13:13:43 -0500 |
commit | 0c57a2e4b4e5a6e5dda78a313fc8d8e3c91797f5 (patch) | |
tree | 4a7d8e54df0f4f74d3229376245d74a970913272 | |
parent | 195d278d502308655edb1e9ff1c6f0c9256d0d15 (diff) | |
download | llvm-0c57a2e4b4e5a6e5dda78a313fc8d8e3c91797f5.zip llvm-0c57a2e4b4e5a6e5dda78a313fc8d8e3c91797f5.tar.gz llvm-0c57a2e4b4e5a6e5dda78a313fc8d8e3c91797f5.tar.bz2 |
[ValueTracking] Add support for `xor`/`disjoint or` in `getInvertibleOperands`
This strengthens our `isKnownNonEqual` logic with some fairly
trivial cases.
Proofs: https://alive2.llvm.org/ce/z/4pxRTj
Closes #87705
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 15 | ||||
-rw-r--r-- | llvm/test/Transforms/InstSimplify/icmp.ll | 18 |
2 files changed, 16 insertions, 17 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 9f16eaf..f3ea73b 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -3106,7 +3106,20 @@ getInvertibleOperands(const Operator *Op1, switch (Op1->getOpcode()) { default: break; - case Instruction::Add: + case Instruction::Or: + if (!cast<PossiblyDisjointInst>(Op1)->isDisjoint() || + !cast<PossiblyDisjointInst>(Op2)->isDisjoint()) + break; + [[fallthrough]]; + case Instruction::Xor: + case Instruction::Add: { + Value *Other; + if (match(Op2, m_c_BinOp(m_Specific(Op1->getOperand(0)), m_Value(Other)))) + return std::make_pair(Op1->getOperand(1), Other); + if (match(Op2, m_c_BinOp(m_Specific(Op1->getOperand(1)), m_Value(Other)))) + return std::make_pair(Op1->getOperand(0), Other); + break; + } case Instruction::Sub: if (Op1->getOperand(0) == Op2->getOperand(0)) return getOperands(1); diff --git a/llvm/test/Transforms/InstSimplify/icmp.ll b/llvm/test/Transforms/InstSimplify/icmp.ll index a66f7cb..d1799098 100644 --- a/llvm/test/Transforms/InstSimplify/icmp.ll +++ b/llvm/test/Transforms/InstSimplify/icmp.ll @@ -281,14 +281,7 @@ define i1 @load_ptr_null_valid(ptr %p) null_pointer_is_valid { define i1 @non_eq_disjoint_or_common_op(i8 %x, i8 %y, i8 %ww, i8 %a) { ; CHECK-LABEL: @non_eq_disjoint_or_common_op( -; CHECK-NEXT: [[W:%.*]] = add nuw i8 [[WW:%.*]], 1 -; CHECK-NEXT: [[Z:%.*]] = add i8 [[Y:%.*]], [[W]] -; CHECK-NEXT: [[XY:%.*]] = or disjoint i8 [[X:%.*]], [[Y]] -; CHECK-NEXT: [[XZ:%.*]] = or disjoint i8 [[X]], [[Z]] -; CHECK-NEXT: [[AXY:%.*]] = add i8 [[A:%.*]], [[XY]] -; CHECK-NEXT: [[AXZ:%.*]] = add i8 [[A]], [[XZ]] -; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AXY]], [[AXZ]] -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 false ; %w = add nuw i8 %ww, 1 %z = add i8 %y, %w @@ -327,14 +320,7 @@ define i1 @non_eq_disjoint_or_common_op_fail(i8 %x, i8 %y, i8 %ww, i8 %a) { define i1 @non_eq_xor_common_op(i8 %x, i8 %y, i8 %ww, i8 %a) { ; CHECK-LABEL: @non_eq_xor_common_op( -; CHECK-NEXT: [[W:%.*]] = add nuw i8 [[WW:%.*]], 1 -; CHECK-NEXT: [[Z:%.*]] = add i8 [[Y:%.*]], [[W]] -; CHECK-NEXT: [[XY:%.*]] = xor i8 [[Y]], [[X:%.*]] -; CHECK-NEXT: [[XZ:%.*]] = xor i8 [[X]], [[Z]] -; CHECK-NEXT: [[AXY:%.*]] = add i8 [[A:%.*]], [[XY]] -; CHECK-NEXT: [[AXZ:%.*]] = add i8 [[A]], [[XZ]] -; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AXY]], [[AXZ]] -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 false ; %w = add nuw i8 %ww, 1 %z = add i8 %y, %w |