implement CodeGen/PowerPC/div-2.ll:test2-4 by propagating zero bits through
authorChris Lattner <sabre@nondot.org>
Fri, 7 Oct 2005 15:30:32 +0000 (15:30 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 7 Oct 2005 15:30:32 +0000 (15:30 +0000)
C-X's

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

lib/CodeGen/SelectionDAG/DAGCombiner.cpp
lib/CodeGen/SelectionDAG/SelectionDAG.cpp

index 86ee932eab2650f46d6dd6edde1995c539d7c72f..e037f2e13c3ee54dda0f19ef49d52c2333f14dce 100644 (file)
@@ -205,6 +205,24 @@ static bool MaskedValueIsZero(const SDOperand &Op, uint64_t Mask,
       return MaskedValueIsZero(Op.getOperand(0), NewVal, TLI);
     }
     return false;
+  case ISD::SUB:
+    if (ConstantSDNode *CLHS = dyn_cast<ConstantSDNode>(Op.getOperand(0))) {
+      // We know that the top bits of C-X are clear if X contains less bits
+      // than C (i.e. no wrap-around can happen).  For example, 20-X is
+      // positive if we can prove that X is >= 0 and < 16.
+      unsigned Bits = MVT::getSizeInBits(CLHS->getValueType(0));
+      if ((CLHS->getValue() & (1 << (Bits-1))) == 0) {  // sign bit clear
+        unsigned NLZ = CountLeadingZeros_64(CLHS->getValue()+1);
+        uint64_t MaskV = (1ULL << (63-NLZ))-1;
+        if (MaskedValueIsZero(Op.getOperand(1), ~MaskV, TLI)) {
+          // High bits are clear this value is known to be >= C.
+          unsigned NLZ2 = CountLeadingZeros_64(CLHS->getValue());
+          if ((Mask & ((1ULL << (64-NLZ2))-1)) == 0)
+            return true;
+        }
+      }
+    }
+    break;
   case ISD::CTTZ:
   case ISD::CTLZ:
   case ISD::CTPOP:
index acb44fb1ac7411ee7eb31524bba1a0054b0adaef..6e171d1251ba2226ef1758dc51d4a261b2eeef7b 100644 (file)
@@ -639,6 +639,24 @@ static bool MaskedValueIsZero(const SDOperand &Op, uint64_t Mask,
       return MaskedValueIsZero(Op.getOperand(0), NewVal, TLI);
     }
     return false;
+  case ISD::SUB:
+    if (ConstantSDNode *CLHS = dyn_cast<ConstantSDNode>(Op.getOperand(0))) {
+      // We know that the top bits of C-X are clear if X contains less bits
+      // than C (i.e. no wrap-around can happen).  For example, 20-X is
+      // positive if we can prove that X is >= 0 and < 16.
+      unsigned Bits = MVT::getSizeInBits(CLHS->getValueType(0));
+      if ((CLHS->getValue() & (1 << (Bits-1))) == 0) {  // sign bit clear
+        unsigned NLZ = CountLeadingZeros_64(CLHS->getValue()+1);
+        uint64_t MaskV = (1ULL << (63-NLZ))-1;
+        if (MaskedValueIsZero(Op.getOperand(1), ~MaskV, TLI)) {
+          // High bits are clear this value is known to be >= C.
+          unsigned NLZ2 = CountLeadingZeros_64(CLHS->getValue());
+          if ((Mask & ((1ULL << (64-NLZ2))-1)) == 0)
+            return true;
+        }
+      }
+    }
+    break;
   case ISD::CTTZ:
   case ISD::CTLZ:
   case ISD::CTPOP:
@@ -1563,8 +1581,12 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
     // udiv instead.  Handles (X&15) /s 4 -> X&15 >> 2
     uint64_t SignBit = 1ULL << (MVT::getSizeInBits(VT)-1);
     if (MaskedValueIsZero(N2, SignBit, TLI) &&
-        MaskedValueIsZero(N1, SignBit, TLI))
+        MaskedValueIsZero(N1, SignBit, TLI)) {
+      std::cerr << "SDIV [[";
+      N1.Val->dump(); std::cerr << "]]  [[";
+      N2.Val->dump(); std::cerr << "]] -> udiv\n";
       return getNode(ISD::UDIV, VT, N1, N2);
+    }
     break;
   }