forked from OSchip/llvm-project
add a SelectionDAG method to check if no common bits are set in two nodes; NFCI
This was suggested in: http://reviews.llvm.org/D13956 and is a follow-on to: http://reviews.llvm.org/rL252515 http://reviews.llvm.org/rL252519 This lets us remove logically equivalent/duplicated code from DAGCombiner and X86ISelDAGToDAG. A corresponding function for IR instructions already exists in ValueTracking. llvm-svn: 252539
This commit is contained in:
parent
e68649279e
commit
533c10c651
|
@ -1217,6 +1217,10 @@ public:
|
|||
/// other positive zero.
|
||||
bool isEqualTo(SDValue A, SDValue B) const;
|
||||
|
||||
/// Return true if A and B have no common bits set. As an example, this can
|
||||
/// allow an 'add' to be transformed into an 'or'.
|
||||
bool haveNoCommonBitsSet(SDValue A, SDValue B) const;
|
||||
|
||||
/// Utility function used by legalize and lowering to
|
||||
/// "unroll" a vector operation by splitting out the scalars and operating
|
||||
/// on each element individually. If the ResNE is 0, fully unroll the vector
|
||||
|
|
|
@ -1743,22 +1743,9 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
|
|||
return SDValue(N, 0);
|
||||
|
||||
// fold (a+b) -> (a|b) iff a and b share no bits.
|
||||
if (VT.isInteger() && !VT.isVector()) {
|
||||
APInt LHSZero, LHSOne;
|
||||
APInt RHSZero, RHSOne;
|
||||
DAG.computeKnownBits(N0, LHSZero, LHSOne);
|
||||
|
||||
if (LHSZero.getBoolValue()) {
|
||||
DAG.computeKnownBits(N1, RHSZero, RHSOne);
|
||||
|
||||
// If all possibly-set bits on the LHS are clear on the RHS, return an OR.
|
||||
// If all possibly-set bits on the RHS are clear on the LHS, return an OR.
|
||||
if ((RHSZero & ~LHSZero) == ~LHSZero || (LHSZero & ~RHSZero) == ~RHSZero){
|
||||
if (!LegalOperations || TLI.isOperationLegal(ISD::OR, VT))
|
||||
if ((!LegalOperations || TLI.isOperationLegal(ISD::OR, VT)) &&
|
||||
VT.isInteger() && !VT.isVector() && DAG.haveNoCommonBitsSet(N0, N1))
|
||||
return DAG.getNode(ISD::OR, SDLoc(N), VT, N0, N1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fold (add x, shl(0 - y, n)) -> sub(x, shl(y, n))
|
||||
if (N1.getOpcode() == ISD::SHL && N1.getOperand(0).getOpcode() == ISD::SUB &&
|
||||
|
|
|
@ -2833,6 +2833,16 @@ bool SelectionDAG::isEqualTo(SDValue A, SDValue B) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool SelectionDAG::haveNoCommonBitsSet(SDValue A, SDValue B) const {
|
||||
assert(A.getValueType() == B.getValueType() &&
|
||||
"Values must have the same type");
|
||||
APInt AZero, AOne;
|
||||
APInt BZero, BOne;
|
||||
computeKnownBits(A, AZero, AOne);
|
||||
computeKnownBits(B, BZero, BOne);
|
||||
return (AZero | BZero).isAllOnesValue();
|
||||
}
|
||||
|
||||
/// getNode - Gets or creates the specified node.
|
||||
///
|
||||
SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, EVT VT) {
|
||||
|
|
|
@ -1338,29 +1338,17 @@ bool X86DAGToDAGISel::matchAddressRecursively(SDValue N, X86ISelAddressMode &AM,
|
|||
return false;
|
||||
break;
|
||||
|
||||
case ISD::OR: {
|
||||
// TODO: The bit-checking logic should be put into a helper function and
|
||||
// used by DAGCombiner.
|
||||
|
||||
case ISD::OR:
|
||||
// We want to look through a transform in InstCombine and DAGCombiner that
|
||||
// turns 'add' into 'or', so we can treat this 'or' exactly like an 'add'.
|
||||
APInt LHSZero, LHSOne;
|
||||
APInt RHSZero, RHSOne;
|
||||
CurDAG->computeKnownBits(N.getOperand(0), LHSZero, LHSOne);
|
||||
CurDAG->computeKnownBits(N.getOperand(1), RHSZero, RHSOne);
|
||||
|
||||
// If we know that there are no common bits set by the operands of this
|
||||
// 'or', it is equivalent to an 'add'. For example:
|
||||
// (or (and x, 1), (shl y, 3)) --> (add (and x, 1), (shl y, 3))
|
||||
// Example: (or (and x, 1), (shl y, 3)) --> (add (and x, 1), (shl y, 3))
|
||||
// An 'lea' can then be used to match the shift (multiply) and add:
|
||||
// and $1, %esi
|
||||
// lea (%rsi, %rdi, 8), %rax
|
||||
if ((LHSZero | RHSZero).isAllOnesValue())
|
||||
if (!matchAdd(N, AM, Depth))
|
||||
if (CurDAG->haveNoCommonBitsSet(N.getOperand(0), N.getOperand(1)) &&
|
||||
!matchAdd(N, AM, Depth))
|
||||
return false;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ISD::AND: {
|
||||
// Perform some heroic transforms on an and of a constant-count shift
|
||||
|
|
Loading…
Reference in New Issue