add a SelectionDAG method to check if no common bits are set in two nodes; NFCI
authorSanjay Patel <spatel@rotateright.com>
Mon, 9 Nov 2015 23:31:38 +0000 (23:31 +0000)
committerSanjay Patel <spatel@rotateright.com>
Mon, 9 Nov 2015 23:31:38 +0000 (23:31 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252539 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/SelectionDAG.h
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
lib/CodeGen/SelectionDAG/SelectionDAG.cpp
lib/Target/X86/X86ISelDAGToDAG.cpp

index f9a760fb2e47f204b364762879e694db61da396f..8dfdd9029946f5b06549e8625361daeb44cf0a93 100644 (file)
@@ -1217,6 +1217,10 @@ public:
   /// other positive zero.
   bool isEqualTo(SDValue A, SDValue B) const;
 
   /// 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
   /// 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
index a1ea6d829f63789eb41c8ca5141ef4b8d726fffc..2dd71bd4e7fe1b59cbe9776bd1868291e958d91f 100644 (file)
@@ -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.
     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))
-          return DAG.getNode(ISD::OR, SDLoc(N), VT, N0, N1);
-      }
-    }
-  }
+  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 &&
 
   // fold (add x, shl(0 - y, n)) -> sub(x, shl(y, n))
   if (N1.getOpcode() == ISD::SHL && N1.getOperand(0).getOpcode() == ISD::SUB &&
index 3e7f466d89d3a76d5b41446cca7e3360e14df3d6..90ab785b2a482fa29597a308757a07cc1ab6ff06 100644 (file)
@@ -2833,6 +2833,16 @@ bool SelectionDAG::isEqualTo(SDValue A, SDValue B) const {
   return false;
 }
 
   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) {
 /// getNode - Gets or creates the specified node.
 ///
 SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, EVT VT) {
index 0cbeda91cccec9ac209b8127d92ae615e3667888..868ae4e19e55b27d6d246c67ee8864d02401c8be 100644 (file)
@@ -1338,29 +1338,17 @@ bool X86DAGToDAGISel::matchAddressRecursively(SDValue N, X86ISelAddressMode &AM,
       return false;
     break;
 
       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'.
     // 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
     // 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))
-        return false;
-
+    if (CurDAG->haveNoCommonBitsSet(N.getOperand(0), N.getOperand(1)) &&
+        !matchAdd(N, AM, Depth))
+      return false;
     break;
     break;
-  }
 
   case ISD::AND: {
     // Perform some heroic transforms on an and of a constant-count shift
 
   case ISD::AND: {
     // Perform some heroic transforms on an and of a constant-count shift