[llvm] 9678936 - [DAGCombine] Fold (X & ~Y) | Y with truncated not
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Thu May 5 02:10:21 PDT 2022
Author: Nikita Popov
Date: 2022-05-05T11:10:11+02:00
New Revision: 9678936f180776db4ebd960fa2eb06b3a61bc94c
URL: https://github.com/llvm/llvm-project/commit/9678936f180776db4ebd960fa2eb06b3a61bc94c
DIFF: https://github.com/llvm/llvm-project/commit/9678936f180776db4ebd960fa2eb06b3a61bc94c.diff
LOG: [DAGCombine] Fold (X & ~Y) | Y with truncated not
This extends the (X & ~Y) | Y to X | Y fold to also work if ~Y is
a truncated not (when taking into account the mask X). This is
done by exporting the infrastructure added in D124856 and reusing
it here.
I've retained the old value of AllowUndefs=false, though probably
this can be switched to true with extra test coverage.
Differential Revision: https://reviews.llvm.org/D124930
Added:
Modified:
llvm/include/llvm/CodeGen/SelectionDAGNodes.h
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
llvm/test/CodeGen/X86/add-and-not.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
index 4683d6810bb86..51e80ebbcf0ee 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -1688,6 +1688,11 @@ SDValue peekThroughExtractSubvectors(SDValue V);
/// constant is canonicalized to be operand 1.
bool isBitwiseNot(SDValue V, bool AllowUndefs = false);
+/// If \p V is a bitwise not, returns the inverted operand. Otherwise returns
+/// an empty SDValue. Only bits set in \p Mask are required to be inverted,
+/// other bits may be arbitrary.
+SDValue getBitwiseNotOperand(SDValue V, SDValue Mask, bool AllowUndefs);
+
/// Returns the SDNode if it is a constant splat BuildVector or constant int.
ConstantSDNode *isConstOrConstSplat(SDValue N, bool AllowUndefs = false,
bool AllowTruncation = false);
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 679466be954ed..cf0a3a9ff0c1b 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -6814,11 +6814,14 @@ static SDValue visitORCommutative(
EVT VT = N0.getValueType();
if (N0.getOpcode() == ISD::AND) {
// fold (or (and X, (xor Y, -1)), Y) -> (or X, Y)
- if (isBitwiseNot(N0.getOperand(1)) && N0.getOperand(1).getOperand(0) == N1)
+ // TODO: Set AllowUndefs = true.
+ if (getBitwiseNotOperand(N0.getOperand(1), N0.getOperand(0),
+ /* AllowUndefs */ false) == N1)
return DAG.getNode(ISD::OR, SDLoc(N), VT, N0.getOperand(0), N1);
// fold (or (and (xor Y, -1), X), Y) -> (or X, Y)
- if (isBitwiseNot(N0.getOperand(0)) && N0.getOperand(0).getOperand(0) == N1)
+ if (getBitwiseNotOperand(N0.getOperand(0), N0.getOperand(1),
+ /* AllowUndefs */ false) == N1)
return DAG.getNode(ISD::OR, SDLoc(N), VT, N0.getOperand(1), N1);
}
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index da33d24d97289..b93c99db2e15a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -4685,8 +4685,8 @@ bool SelectionDAG::isEqualTo(SDValue A, SDValue B) const {
}
// Only bits set in Mask must be negated, other bits may be arbitrary.
-static SDValue getBitwiseNotOperand(SDValue V, SDValue Mask) {
- if (isBitwiseNot(V, true))
+SDValue llvm::getBitwiseNotOperand(SDValue V, SDValue Mask, bool AllowUndefs) {
+ if (isBitwiseNot(V, AllowUndefs))
return V.getOperand(0);
// Handle any_extend (not (truncate X)) pattern, where Mask only sets
@@ -4697,7 +4697,7 @@ static SDValue getBitwiseNotOperand(SDValue V, SDValue Mask) {
SDValue ExtArg = V.getOperand(0);
if (ExtArg.getScalarValueSizeInBits() >=
MaskC->getAPIntValue().getActiveBits() &&
- isBitwiseNot(ExtArg, true) &&
+ isBitwiseNot(ExtArg, AllowUndefs) &&
ExtArg.getOperand(0).getOpcode() == ISD::TRUNCATE &&
ExtArg.getOperand(0).getOperand(0).getValueType() == V.getValueType())
return ExtArg.getOperand(0).getOperand(0);
@@ -4709,7 +4709,8 @@ static bool haveNoCommonBitsSetCommutative(SDValue A, SDValue B) {
// Including degenerate case (X & ~M) op M
auto MatchNoCommonBitsPattern = [&](SDValue Not, SDValue Mask,
SDValue Other) {
- if (SDValue NotOperand = getBitwiseNotOperand(Not, Mask)) {
+ if (SDValue NotOperand =
+ getBitwiseNotOperand(Not, Mask, /* AllowUndefs */ true)) {
if (Other == NotOperand)
return true;
if (Other->getOpcode() == ISD::AND)
diff --git a/llvm/test/CodeGen/X86/add-and-not.ll b/llvm/test/CodeGen/X86/add-and-not.ll
index c0434b1a5b296..7fbdc1c8e6fdc 100644
--- a/llvm/test/CodeGen/X86/add-and-not.ll
+++ b/llvm/test/CodeGen/X86/add-and-not.ll
@@ -118,10 +118,8 @@ define i8 @add_and_xor_extra_use(i8 %x, i8 %y) nounwind {
define i64 @add_and_xor_const(i64 %x) {
; CHECK-LABEL: add_and_xor_const:
; CHECK: # %bb.0:
-; CHECK-NEXT: movl %edi, %eax
-; CHECK-NEXT: notl %eax
-; CHECK-NEXT: andl $1, %eax
-; CHECK-NEXT: orq %rdi, %rax
+; CHECK-NEXT: movq %rdi, %rax
+; CHECK-NEXT: orq $1, %rax
; CHECK-NEXT: retq
%xor = xor i64 %x, -1
%and = and i64 %xor, 1
@@ -145,10 +143,8 @@ define i64 @add_and_xor_const_wrong_op(i64 %x, i64 %y) {
define i64 @add_and_xor_const_explicit_trunc(i64 %x) {
; CHECK-LABEL: add_and_xor_const_explicit_trunc:
; CHECK: # %bb.0:
-; CHECK-NEXT: movl %edi, %eax
-; CHECK-NEXT: notl %eax
-; CHECK-NEXT: andl $1, %eax
-; CHECK-NEXT: orq %rdi, %rax
+; CHECK-NEXT: movq %rdi, %rax
+; CHECK-NEXT: orq $1, %rax
; CHECK-NEXT: retq
%trunc = trunc i64 %x to i32
%xor = xor i32 %trunc, -1
@@ -192,10 +188,8 @@ define i8* @gep_and_xor(i8* %a, i64 %m) {
define i8* @gep_and_xor_const(i8* %a) {
; CHECK-LABEL: gep_and_xor_const:
; CHECK: # %bb.0:
-; CHECK-NEXT: movl %edi, %eax
-; CHECK-NEXT: notl %eax
-; CHECK-NEXT: andl $1, %eax
-; CHECK-NEXT: orq %rdi, %rax
+; CHECK-NEXT: movq %rdi, %rax
+; CHECK-NEXT: orq $1, %rax
; CHECK-NEXT: retq
%old = ptrtoint i8* %a to i64
%old.not = and i64 %old, 1
More information about the llvm-commits
mailing list