Clean up DemandedBitsAreZero interface
[oota-llvm.git] / lib / CodeGen / SelectionDAG / DAGCombiner.cpp
index 0e061b90ace106c055e993da8fe218d955f1e14e..f1d0a9b5065efbddc5c664084fe13bbba310574d 100644 (file)
@@ -33,7 +33,6 @@
 // FIXME: divide by zero is currently left unfolded.  do we want to turn this
 //        into an undef?
 // FIXME: select ne (select cc, 1, 0), 0, true, false -> select cc, true, false
-// FIXME: reassociate (X+C)+Y  into (X+Y)+C  if the inner expression has one use
 // 
 //===----------------------------------------------------------------------===//
 
@@ -99,6 +98,17 @@ namespace {
       DAG.DeleteNode(N);
       return SDOperand(N, 0);
     }
+    
+    bool DemandedBitsAreZero(SDOperand Op, uint64_t DemandedMask) {
+      TargetLowering::TargetLoweringOpt TLO(DAG);
+      uint64_t KnownZero, KnownOne;
+      if (TLI.SimplifyDemandedBits(Op, DemandedMask, KnownZero, KnownOne, TLO)){
+        WorkList.push_back(Op.Val);
+        CombineTo(TLO.Old.Val, TLO.New);
+        return true;
+      }
+      return false;
+    }
 
     SDOperand CombineTo(SDNode *N, SDOperand Res) {
       std::vector<SDOperand> To;
@@ -146,14 +156,11 @@ namespace {
     SDOperand visitSELECT(SDNode *N);
     SDOperand visitSELECT_CC(SDNode *N);
     SDOperand visitSETCC(SDNode *N);
-    SDOperand visitADD_PARTS(SDNode *N);
-    SDOperand visitSUB_PARTS(SDNode *N);
     SDOperand visitSIGN_EXTEND(SDNode *N);
     SDOperand visitZERO_EXTEND(SDNode *N);
     SDOperand visitSIGN_EXTEND_INREG(SDNode *N);
     SDOperand visitTRUNCATE(SDNode *N);
     SDOperand visitBIT_CONVERT(SDNode *N);
-    
     SDOperand visitFADD(SDNode *N);
     SDOperand visitFSUB(SDNode *N);
     SDOperand visitFMUL(SDNode *N);
@@ -172,13 +179,11 @@ namespace {
     SDOperand visitBRCONDTWOWAY(SDNode *N);
     SDOperand visitBR_CC(SDNode *N);
     SDOperand visitBRTWOWAY_CC(SDNode *N);
-
     SDOperand visitLOAD(SDNode *N);
     SDOperand visitSTORE(SDNode *N);
 
-    SDOperand visitLOCATION(SDNode *N);
-    SDOperand visitDEBUGLOC(SDNode *N);
-
+    SDOperand ReassociateOps(unsigned Opc, SDOperand LHS, SDOperand RHS);
+    
     bool SimplifySelectOps(SDNode *SELECT, SDOperand LHS, SDOperand RHS);
     SDOperand SimplifySelect(SDOperand N0, SDOperand N1, SDOperand N2);
     SDOperand SimplifySelectCC(SDOperand N0, SDOperand N1, SDOperand N2, 
@@ -369,105 +374,6 @@ static mu magicu64(uint64_t d)
   return magu;
 }
 
-/// MaskedValueIsZero - Return true if 'Op & Mask' is known to be zero.  We use
-/// this predicate to simplify operations downstream.  Op and Mask are known to
-/// be the same type.
-static bool MaskedValueIsZero(const SDOperand &Op, uint64_t Mask,
-                              const TargetLowering &TLI) {
-  unsigned SrcBits;
-  if (Mask == 0) return true;
-  
-  // If we know the result of a setcc has the top bits zero, use this info.
-  switch (Op.getOpcode()) {
-  case ISD::Constant:
-    return (cast<ConstantSDNode>(Op)->getValue() & Mask) == 0;
-  case ISD::SETCC:
-    return ((Mask & 1) == 0) &&
-    TLI.getSetCCResultContents() == TargetLowering::ZeroOrOneSetCCResult;
-  case ISD::ZEXTLOAD:
-    SrcBits = MVT::getSizeInBits(cast<VTSDNode>(Op.getOperand(3))->getVT());
-    return (Mask & ((1ULL << SrcBits)-1)) == 0; // Returning only the zext bits.
-  case ISD::ZERO_EXTEND:
-    SrcBits = MVT::getSizeInBits(Op.getOperand(0).getValueType());
-    return MaskedValueIsZero(Op.getOperand(0),Mask & (~0ULL >> (64-SrcBits)),TLI);
-  case ISD::AssertZext:
-    SrcBits = MVT::getSizeInBits(cast<VTSDNode>(Op.getOperand(1))->getVT());
-    return (Mask & ((1ULL << SrcBits)-1)) == 0; // Returning only the zext bits.
-  case ISD::AND:
-    // If either of the operands has zero bits, the result will too.
-    if (MaskedValueIsZero(Op.getOperand(1), Mask, TLI) ||
-        MaskedValueIsZero(Op.getOperand(0), Mask, TLI))
-      return true;
-    // (X & C1) & C2 == 0   iff   C1 & C2 == 0.
-    if (ConstantSDNode *AndRHS = dyn_cast<ConstantSDNode>(Op.getOperand(1)))
-      return MaskedValueIsZero(Op.getOperand(0),AndRHS->getValue() & Mask, TLI);
-    return false;
-  case ISD::OR:
-  case ISD::XOR:
-    return MaskedValueIsZero(Op.getOperand(0), Mask, TLI) &&
-    MaskedValueIsZero(Op.getOperand(1), Mask, TLI);
-  case ISD::SELECT:
-    return MaskedValueIsZero(Op.getOperand(1), Mask, TLI) &&
-    MaskedValueIsZero(Op.getOperand(2), Mask, TLI);
-  case ISD::SELECT_CC:
-    return MaskedValueIsZero(Op.getOperand(2), Mask, TLI) &&
-    MaskedValueIsZero(Op.getOperand(3), Mask, TLI);
-  case ISD::SRL:
-    // (ushr X, C1) & C2 == 0   iff  X & (C2 << C1) == 0
-    if (ConstantSDNode *ShAmt = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
-      uint64_t NewVal = Mask << ShAmt->getValue();
-      SrcBits = MVT::getSizeInBits(Op.getValueType());
-      if (SrcBits != 64) NewVal &= (1ULL << SrcBits)-1;
-      return MaskedValueIsZero(Op.getOperand(0), NewVal, TLI);
-    }
-    return false;
-  case ISD::SHL:
-    // (ushl X, C1) & C2 == 0   iff  X & (C2 >> C1) == 0
-    if (ConstantSDNode *ShAmt = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
-      uint64_t NewVal = Mask >> ShAmt->getValue();
-      return MaskedValueIsZero(Op.getOperand(0), NewVal, TLI);
-    }
-    return false;
-  case ISD::ADD:
-    // (add X, Y) & C == 0 iff (X&C)|(Y&C) == 0 and all bits are low bits.
-    if ((Mask&(Mask+1)) == 0) {  // All low bits
-      if (MaskedValueIsZero(Op.getOperand(0), Mask, TLI) &&
-          MaskedValueIsZero(Op.getOperand(1), Mask, TLI))
-        return true;
-    }
-    break;
-  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:
-    // Bit counting instructions can not set the high bits of the result
-    // register.  The max number of bits sets depends on the input.
-    return (Mask & (MVT::getSizeInBits(Op.getValueType())*2-1)) == 0;
-  default:
-    if (Op.getOpcode() >= ISD::BUILTIN_OP_END)
-      return TLI.isMaskedValueZeroForTargetNode(Op, Mask, MaskedValueIsZero);
-    break;
-  }
-  return false;
-}
-
 // isSetCCEquivalent - Return true if this node is a setcc, or is a select_cc
 // that selects between the values 1 and 0, making it equivalent to a setcc.
 // Also, set the incoming LHS, RHS, and CC references to the appropriate 
@@ -517,6 +423,37 @@ static bool isCommutativeBinOp(unsigned Opcode) {
   }
 }
 
+SDOperand DAGCombiner::ReassociateOps(unsigned Opc, SDOperand N0, SDOperand N1){
+  MVT::ValueType VT = N0.getValueType();
+  // reassoc. (op (op x, c1), y) -> (op (op x, y), c1) iff x+c1 has one use
+  // reassoc. (op (op x, c1), c2) -> (op x, (op c1, c2))
+  if (N0.getOpcode() == Opc && isa<ConstantSDNode>(N0.getOperand(1))) {
+    if (isa<ConstantSDNode>(N1)) {
+      SDOperand OpNode = DAG.getNode(Opc, VT, N0.getOperand(1), N1);
+      WorkList.push_back(OpNode.Val);
+      return DAG.getNode(Opc, VT, OpNode, N0.getOperand(0));
+    } else if (N0.hasOneUse()) {
+      SDOperand OpNode = DAG.getNode(Opc, VT, N0.getOperand(0), N1);
+      WorkList.push_back(OpNode.Val);
+      return DAG.getNode(Opc, VT, OpNode, N0.getOperand(1));
+    }
+  }
+  // reassoc. (op y, (op x, c1)) -> (op (op x, y), c1) iff x+c1 has one use
+  // reassoc. (op c2, (op x, c1)) -> (op x, (op c1, c2))
+  if (N1.getOpcode() == Opc && isa<ConstantSDNode>(N1.getOperand(1))) {
+    if (isa<ConstantSDNode>(N0)) {
+      SDOperand OpNode = DAG.getNode(Opc, VT, N1.getOperand(1), N0);
+      WorkList.push_back(OpNode.Val);
+      return DAG.getNode(Opc, VT, OpNode, N1.getOperand(0));
+    } else if (N1.hasOneUse()) {
+      SDOperand OpNode = DAG.getNode(Opc, VT, N1.getOperand(0), N0);
+      WorkList.push_back(OpNode.Val);
+      return DAG.getNode(Opc, VT, OpNode, N1.getOperand(1));
+    }
+  }
+  return SDOperand();
+}
+
 void DAGCombiner::Run(bool RunningAfterLegalize) {
   // set the instance variable, so that the various visit routines may use it.
   AfterLegalize = RunningAfterLegalize;
@@ -608,8 +545,6 @@ SDOperand DAGCombiner::visit(SDNode *N) {
   case ISD::SELECT:             return visitSELECT(N);
   case ISD::SELECT_CC:          return visitSELECT_CC(N);
   case ISD::SETCC:              return visitSETCC(N);
-  case ISD::ADD_PARTS:          return visitADD_PARTS(N);
-  case ISD::SUB_PARTS:          return visitSUB_PARTS(N);
   case ISD::SIGN_EXTEND:        return visitSIGN_EXTEND(N);
   case ISD::ZERO_EXTEND:        return visitZERO_EXTEND(N);
   case ISD::SIGN_EXTEND_INREG:  return visitSIGN_EXTEND_INREG(N);
@@ -635,8 +570,6 @@ SDOperand DAGCombiner::visit(SDNode *N) {
   case ISD::BRTWOWAY_CC:        return visitBRTWOWAY_CC(N);
   case ISD::LOAD:               return visitLOAD(N);
   case ISD::STORE:              return visitSTORE(N);
-  case ISD::LOCATION:           return visitLOCATION(N);
-  case ISD::DEBUG_LOC:          return visitDEBUGLOC(N);
   }
   return SDOperand();
 }
@@ -686,25 +619,16 @@ SDOperand DAGCombiner::visitADD(SDNode *N) {
   // fold (add x, 0) -> x
   if (N1C && N1C->isNullValue())
     return N0;
-  // fold (add (add x, c1), c2) -> (add x, c1+c2)
-  if (N1C && N0.getOpcode() == ISD::ADD) {
-    ConstantSDNode *N00C = dyn_cast<ConstantSDNode>(N0.getOperand(0));
-    ConstantSDNode *N01C = dyn_cast<ConstantSDNode>(N0.getOperand(1));
-    if (N00C)
-      return DAG.getNode(ISD::ADD, VT, N0.getOperand(1),
-                         DAG.getConstant(N1C->getValue()+N00C->getValue(), VT));
-    if (N01C)
-      return DAG.getNode(ISD::ADD, VT, N0.getOperand(0),
-                         DAG.getConstant(N1C->getValue()+N01C->getValue(), VT));
-  }
-  
   // fold ((c1-A)+c2) -> (c1+c2)-A
   if (N1C && N0.getOpcode() == ISD::SUB)
     if (ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0.getOperand(0)))
       return DAG.getNode(ISD::SUB, VT,
                          DAG.getConstant(N1C->getValue()+N0C->getValue(), VT),
                          N0.getOperand(1));
-  
+  // reassociate add
+  SDOperand RADD = ReassociateOps(ISD::ADD, N0, N1);
+  if (RADD.Val != 0)
+    return RADD;
   // fold ((0-A) + B) -> B-A
   if (N0.getOpcode() == ISD::SUB && isa<ConstantSDNode>(N0.getOperand(0)) &&
       cast<ConstantSDNode>(N0.getOperand(0))->isNullValue())
@@ -777,19 +701,10 @@ SDOperand DAGCombiner::visitMUL(SDNode *N) {
                             DAG.getConstant(Log2_64(-N1C->getSignExtended()),
                                             TLI.getShiftAmountTy())));
   }
-  
-  
-  // fold (mul (mul x, c1), c2) -> (mul x, c1*c2)
-  if (N1C && N0.getOpcode() == ISD::MUL) {
-    ConstantSDNode *N00C = dyn_cast<ConstantSDNode>(N0.getOperand(0));
-    ConstantSDNode *N01C = dyn_cast<ConstantSDNode>(N0.getOperand(1));
-    if (N00C)
-      return DAG.getNode(ISD::MUL, VT, N0.getOperand(1),
-                         DAG.getConstant(N1C->getValue()*N00C->getValue(), VT));
-    if (N01C)
-      return DAG.getNode(ISD::MUL, VT, N0.getOperand(0),
-                         DAG.getConstant(N1C->getValue()*N01C->getValue(), VT));
-  }
+  // reassociate mul
+  SDOperand RMUL = ReassociateOps(ISD::MUL, N0, N1);
+  if (RMUL.Val != 0)
+    return RMUL;
   return SDOperand();
 }
 
@@ -812,11 +727,11 @@ SDOperand DAGCombiner::visitSDIV(SDNode *N) {
   // If we know the sign bits of both operands are zero, strength reduce to a
   // udiv instead.  Handles (X&15) /s 4 -> X&15 >> 2
   uint64_t SignBit = 1ULL << (MVT::getSizeInBits(VT)-1);
-  if (MaskedValueIsZero(N1, SignBit, TLI) &&
-      MaskedValueIsZero(N0, SignBit, TLI))
+  if (TLI.MaskedValueIsZero(N1, SignBit) &&
+      TLI.MaskedValueIsZero(N0, SignBit))
     return DAG.getNode(ISD::UDIV, N1.getValueType(), N0, N1);
-  // fold (sdiv X, pow2) -> (add (sra X, log(pow2)), (srl X, sizeof(X)-1))
-  if (N1C && N1C->getValue() && !TLI.isIntDivCheap() && 
+  // fold (sdiv X, pow2) -> simple ops after legalize
+  if (N1C && N1C->getValue() && !TLI.isIntDivCheap() &&
       (isPowerOf2_64(N1C->getSignExtended()) || 
        isPowerOf2_64(-N1C->getSignExtended()))) {
     // If dividing by powers of two is cheap, then don't perform the following
@@ -825,15 +740,21 @@ SDOperand DAGCombiner::visitSDIV(SDNode *N) {
       return SDOperand();
     int64_t pow2 = N1C->getSignExtended();
     int64_t abs2 = pow2 > 0 ? pow2 : -pow2;
-    SDOperand SRL = DAG.getNode(ISD::SRL, VT, N0,
+    unsigned lg2 = Log2_64(abs2);
+    // Splat the sign bit into the register
+    SDOperand SGN = DAG.getNode(ISD::SRA, VT, N0,
                                 DAG.getConstant(MVT::getSizeInBits(VT)-1,
                                                 TLI.getShiftAmountTy()));
-    WorkList.push_back(SRL.Val);
-    SDOperand SGN = DAG.getNode(ISD::ADD, VT, N0, SRL);
     WorkList.push_back(SGN.Val);
-    SDOperand SRA = DAG.getNode(ISD::SRA, VT, SGN, 
-                                DAG.getConstant(Log2_64(abs2),
+    // Add (N0 < 0) ? abs2 - 1 : 0;
+    SDOperand SRL = DAG.getNode(ISD::SRL, VT, SGN,
+                                DAG.getConstant(MVT::getSizeInBits(VT)-lg2,
                                                 TLI.getShiftAmountTy()));
+    SDOperand ADD = DAG.getNode(ISD::ADD, VT, N0, SRL);
+    WorkList.push_back(SRL.Val);
+    WorkList.push_back(ADD.Val);    // Divide by pow2
+    SDOperand SRA = DAG.getNode(ISD::SRA, VT, ADD,
+                                DAG.getConstant(lg2, TLI.getShiftAmountTy()));
     // If we're dividing by a positive value, we're done.  Otherwise, we must
     // negate the result.
     if (pow2 > 0)
@@ -863,15 +784,27 @@ SDOperand DAGCombiner::visitUDIV(SDNode *N) {
     return DAG.getNode(ISD::UDIV, VT, N0, N1);
   // fold (udiv x, (1 << c)) -> x >>u c
   if (N1C && isPowerOf2_64(N1C->getValue()))
-    return DAG.getNode(ISD::SRL, N->getValueType(0), N0,
+    return DAG.getNode(ISD::SRL, VT, N0, 
                        DAG.getConstant(Log2_64(N1C->getValue()),
                                        TLI.getShiftAmountTy()));
+  // fold (udiv x, (shl c, y)) -> x >>u (log2(c)+y) iff c is power of 2
+  if (N1.getOpcode() == ISD::SHL) {
+    if (ConstantSDNode *SHC = dyn_cast<ConstantSDNode>(N1.getOperand(0))) {
+      if (isPowerOf2_64(SHC->getValue())) {
+        MVT::ValueType ADDVT = N1.getOperand(1).getValueType();
+        SDOperand Add = DAG.getNode(ISD::ADD, ADDVT, N1.getOperand(1),
+                                    DAG.getConstant(Log2_64(SHC->getValue()),
+                                                    ADDVT));
+        WorkList.push_back(Add.Val);
+        return DAG.getNode(ISD::SRL, VT, N0, Add);
+      }
+    }
+  }
   // fold (udiv x, c) -> alternate
   if (N1C && N1C->getValue() && !TLI.isIntDivCheap()) {
     SDOperand Op = BuildUDIV(N);
     if (Op.Val) return Op;
   }
-      
   return SDOperand();
 }
 
@@ -888,8 +821,8 @@ SDOperand DAGCombiner::visitSREM(SDNode *N) {
   // If we know the sign bits of both operands are zero, strength reduce to a
   // urem instead.  Handles (X & 0x0FFFFFFF) %s 16 -> X&15
   uint64_t SignBit = 1ULL << (MVT::getSizeInBits(VT)-1);
-  if (MaskedValueIsZero(N1, SignBit, TLI) &&
-      MaskedValueIsZero(N0, SignBit, TLI))
+  if (TLI.MaskedValueIsZero(N1, SignBit) &&
+      TLI.MaskedValueIsZero(N0, SignBit))
     return DAG.getNode(ISD::UREM, VT, N0, N1);
   return SDOperand();
 }
@@ -907,6 +840,16 @@ SDOperand DAGCombiner::visitUREM(SDNode *N) {
   // fold (urem x, pow2) -> (and x, pow2-1)
   if (N1C && !N1C->isNullValue() && isPowerOf2_64(N1C->getValue()))
     return DAG.getNode(ISD::AND, VT, N0, DAG.getConstant(N1C->getValue()-1,VT));
+  // fold (urem x, (shl pow2, y)) -> (and x, (add (shl pow2, y), -1))
+  if (N1.getOpcode() == ISD::SHL) {
+    if (ConstantSDNode *SHC = dyn_cast<ConstantSDNode>(N1.getOperand(0))) {
+      if (isPowerOf2_64(SHC->getValue())) {
+        SDOperand Add = DAG.getNode(ISD::ADD, VT, N1,DAG.getConstant(~0ULL,VT));
+        WorkList.push_back(Add.Val);
+        return DAG.getNode(ISD::AND, VT, N0, Add);
+      }
+    }
+  }
   return SDOperand();
 }
 
@@ -959,35 +902,30 @@ SDOperand DAGCombiner::visitAND(SDNode *N) {
   if (N1C && N1C->isAllOnesValue())
     return N0;
   // if (and x, c) is known to be zero, return 0
-  if (N1C && MaskedValueIsZero(SDOperand(N, 0), ~0ULL >> (64-OpSizeInBits),TLI))
+  if (N1C && TLI.MaskedValueIsZero(SDOperand(N, 0), MVT::getIntVTBitMask(VT)))
     return DAG.getConstant(0, VT);
-  // fold (and x, c) -> x iff (x & ~c) == 0
-  if (N1C && MaskedValueIsZero(N0,~N1C->getValue() & (~0ULL>>(64-OpSizeInBits)),
-                               TLI))
-    return N0;
-  // fold (and (and x, c1), c2) -> (and x, c1^c2)
-  if (N1C && N0.getOpcode() == ISD::AND) {
-    ConstantSDNode *N00C = dyn_cast<ConstantSDNode>(N0.getOperand(0));
-    ConstantSDNode *N01C = dyn_cast<ConstantSDNode>(N0.getOperand(1));
-    if (N00C)
-      return DAG.getNode(ISD::AND, VT, N0.getOperand(1),
-                         DAG.getConstant(N1C->getValue()&N00C->getValue(), VT));
-    if (N01C)
-      return DAG.getNode(ISD::AND, VT, N0.getOperand(0),
-                         DAG.getConstant(N1C->getValue()&N01C->getValue(), VT));
-  }
-  // fold (and (sign_extend_inreg x, i16 to i32), 1) -> (and x, 1)
-  if (N1C && N0.getOpcode() == ISD::SIGN_EXTEND_INREG) {
-    unsigned ExtendBits =
-        MVT::getSizeInBits(cast<VTSDNode>(N0.getOperand(1))->getVT());
-    if (ExtendBits == 64 || ((N1C->getValue() & (~0ULL << ExtendBits)) == 0))
-      return DAG.getNode(ISD::AND, VT, N0.getOperand(0), N1);
-  }
+  // reassociate and
+  SDOperand RAND = ReassociateOps(ISD::AND, N0, N1);
+  if (RAND.Val != 0)
+    return RAND;
   // fold (and (or x, 0xFFFF), 0xFF) -> 0xFF
   if (N1C && N0.getOpcode() == ISD::OR)
     if (ConstantSDNode *ORI = dyn_cast<ConstantSDNode>(N0.getOperand(1)))
       if ((ORI->getValue() & N1C->getValue()) == N1C->getValue())
         return N1;
+  // fold (and (any_ext V), c) -> (zero_ext V) if 'and' only clears top bits.
+  if (N1C && N0.getOpcode() == ISD::ANY_EXTEND) {
+    unsigned InBits = MVT::getSizeInBits(N0.getOperand(0).getValueType());
+    if (TLI.MaskedValueIsZero(N0.getOperand(0),
+                              ~N1C->getValue() & ((1ULL << InBits)-1))) {
+      // We actually want to replace all uses of the any_extend with the
+      // zero_extend, to avoid duplicating things.  This will later cause this
+      // AND to be folded.
+      CombineTo(N0.Val, DAG.getNode(ISD::ZERO_EXTEND, N0.getValueType(),
+                                    N0.getOperand(0)));
+      return SDOperand();
+    }
+  }
   // fold (and (setcc x), (setcc y)) -> (setcc (and x, y))
   if (isSetCCEquivalent(N0, LL, LR, CC0) && isSetCCEquivalent(N1, RL, RR, CC1)){
     ISD::CondCode Op0 = cast<CondCodeSDNode>(CC0)->get();
@@ -1045,26 +983,16 @@ SDOperand DAGCombiner::visitAND(SDNode *N) {
     WorkList.push_back(ANDNode.Val);
     return DAG.getNode(N0.getOpcode(), VT, ANDNode, N0.getOperand(1));
   }
+  // fold (and (sign_extend_inreg x, i16 to i32), 1) -> (and x, 1)
   // fold (and (sra)) -> (and (srl)) when possible.
-  if (N0.getOpcode() == ISD::SRA && N0.Val->hasOneUse()) {
-    if (ConstantSDNode *N01C = dyn_cast<ConstantSDNode>(N0.getOperand(1))) {
-      // If the RHS of the AND has zeros where the sign bits of the SRA will
-      // land, turn the SRA into an SRL.
-      if (MaskedValueIsZero(N1, (~0ULL << (OpSizeInBits-N01C->getValue())) &
-                            (~0ULL>>(64-OpSizeInBits)), TLI)) {
-        WorkList.push_back(N);
-        CombineTo(N0.Val, DAG.getNode(ISD::SRL, VT, N0.getOperand(0),
-                                      N0.getOperand(1)));
-        return SDOperand();
-      }
-    }
-  }
+  if (DemandedBitsAreZero(SDOperand(N, 0), MVT::getIntVTBitMask(VT)))
+    return SDOperand();
   // fold (zext_inreg (extload x)) -> (zextload x)
   if (N0.getOpcode() == ISD::EXTLOAD) {
     MVT::ValueType EVT = cast<VTSDNode>(N0.getOperand(3))->getVT();
     // If we zero all the possible extended bits, then we can turn this into
     // a zextload if we are running before legalize or the operation is legal.
-    if (MaskedValueIsZero(N1, ~0ULL << MVT::getSizeInBits(EVT), TLI) &&
+    if (TLI.MaskedValueIsZero(N1, ~0ULL << MVT::getSizeInBits(EVT)) &&
         (!AfterLegalize || TLI.isOperationLegal(ISD::ZEXTLOAD, EVT))) {
       SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, N0.getOperand(0),
                                          N0.getOperand(1), N0.getOperand(2),
@@ -1079,7 +1007,7 @@ SDOperand DAGCombiner::visitAND(SDNode *N) {
     MVT::ValueType EVT = cast<VTSDNode>(N0.getOperand(3))->getVT();
     // If we zero all the possible extended bits, then we can turn this into
     // a zextload if we are running before legalize or the operation is legal.
-    if (MaskedValueIsZero(N1, ~0ULL << MVT::getSizeInBits(EVT), TLI) &&
+    if (TLI.MaskedValueIsZero(N1, ~0ULL << MVT::getSizeInBits(EVT)) &&
         (!AfterLegalize || TLI.isOperationLegal(ISD::ZEXTLOAD, EVT))) {
       SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, N0.getOperand(0),
                                          N0.getOperand(1), N0.getOperand(2),
@@ -1114,22 +1042,16 @@ SDOperand DAGCombiner::visitOR(SDNode *N) {
   if (N1C && N1C->isAllOnesValue())
     return N1;
   // fold (or x, c) -> c iff (x & ~c) == 0
-  if (N1C && MaskedValueIsZero(N0,~N1C->getValue() & (~0ULL>>(64-OpSizeInBits)),
-                               TLI))
+  if (N1C && 
+      TLI.MaskedValueIsZero(N0,~N1C->getValue() & (~0ULL>>(64-OpSizeInBits))))
     return N1;
-  // fold (or (or x, c1), c2) -> (or x, c1|c2)
-  if (N1C && N0.getOpcode() == ISD::OR) {
-    ConstantSDNode *N00C = dyn_cast<ConstantSDNode>(N0.getOperand(0));
-    ConstantSDNode *N01C = dyn_cast<ConstantSDNode>(N0.getOperand(1));
-    if (N00C)
-      return DAG.getNode(ISD::OR, VT, N0.getOperand(1),
-                         DAG.getConstant(N1C->getValue()|N00C->getValue(), VT));
-    if (N01C)
-      return DAG.getNode(ISD::OR, VT, N0.getOperand(0),
-                         DAG.getConstant(N1C->getValue()|N01C->getValue(), VT));
-  } else if (N1C && N0.getOpcode() == ISD::AND && N0.Val->hasOneUse() &&
+  // reassociate or
+  SDOperand ROR = ReassociateOps(ISD::OR, N0, N1);
+  if (ROR.Val != 0)
+    return ROR;
+  // Canonicalize (or (and X, c1), c2) -> (and (or X, c2), c1|c2)
+  if (N1C && N0.getOpcode() == ISD::AND && N0.Val->hasOneUse() &&
              isa<ConstantSDNode>(N0.getOperand(1))) {
-    // Canonicalize (or (and X, c1), c2) -> (and (or X, c2), c1|c2)
     ConstantSDNode *C1 = cast<ConstantSDNode>(N0.getOperand(1));
     return DAG.getNode(ISD::AND, VT, DAG.getNode(ISD::OR, VT, N0.getOperand(0),
                                                  N1),
@@ -1180,6 +1102,16 @@ SDOperand DAGCombiner::visitOR(SDNode *N) {
     WorkList.push_back(ORNode.Val);
     return DAG.getNode(ISD::ZERO_EXTEND, VT, ORNode);
   }
+  // fold (or (shl/srl/sra x), (shl/srl/sra y)) -> (shl/srl/sra (or x, y))
+  if (((N0.getOpcode() == ISD::SHL && N1.getOpcode() == ISD::SHL) ||
+       (N0.getOpcode() == ISD::SRL && N1.getOpcode() == ISD::SRL) ||
+       (N0.getOpcode() == ISD::SRA && N1.getOpcode() == ISD::SRA)) &&
+      N0.getOperand(1) == N1.getOperand(1)) {
+    SDOperand ORNode = DAG.getNode(ISD::OR, N0.getOperand(0).getValueType(),
+                                   N0.getOperand(0), N1.getOperand(0));
+    WorkList.push_back(ORNode.Val);
+    return DAG.getNode(N0.getOpcode(), VT, ORNode, N0.getOperand(1));
+  }
   // canonicalize shl to left side in a shl/srl pair, to match rotate
   if (N0.getOpcode() == ISD::SRL && N1.getOpcode() == ISD::SHL)
     std::swap(N0, N1);
@@ -1236,6 +1168,10 @@ SDOperand DAGCombiner::visitXOR(SDNode *N) {
   // fold (xor x, 0) -> x
   if (N1C && N1C->isNullValue())
     return N0;
+  // reassociate xor
+  SDOperand RXOR = ReassociateOps(ISD::XOR, N0, N1);
+  if (RXOR.Val != 0)
+    return RXOR;
   // fold !(x cc y) -> (x !cc y)
   if (N1C && N1C->getValue() == 1 && isSetCCEquivalent(N0, LHS, RHS, CC)) {
     bool isInt = MVT::isInteger(LHS.getValueType());
@@ -1295,6 +1231,16 @@ SDOperand DAGCombiner::visitXOR(SDNode *N) {
     WorkList.push_back(XORNode.Val);
     return DAG.getNode(ISD::ZERO_EXTEND, VT, XORNode);
   }
+  // fold (xor (shl/srl/sra x), (shl/srl/sra y)) -> (shl/srl/sra (xor x, y))
+  if (((N0.getOpcode() == ISD::SHL && N1.getOpcode() == ISD::SHL) ||
+       (N0.getOpcode() == ISD::SRL && N1.getOpcode() == ISD::SRL) ||
+       (N0.getOpcode() == ISD::SRA && N1.getOpcode() == ISD::SRA)) &&
+      N0.getOperand(1) == N1.getOperand(1)) {
+    SDOperand XORNode = DAG.getNode(ISD::XOR, N0.getOperand(0).getValueType(),
+                                    N0.getOperand(0), N1.getOperand(0));
+    WorkList.push_back(XORNode.Val);
+    return DAG.getNode(N0.getOpcode(), VT, XORNode, N0.getOperand(1));
+  }
   return SDOperand();
 }
 
@@ -1319,8 +1265,10 @@ SDOperand DAGCombiner::visitSHL(SDNode *N) {
   if (N1C && N1C->isNullValue())
     return N0;
   // if (shl x, c) is known to be zero, return 0
-  if (N1C && MaskedValueIsZero(SDOperand(N, 0), ~0ULL >> (64-OpSizeInBits),TLI))
+  if (TLI.MaskedValueIsZero(SDOperand(N, 0), MVT::getIntVTBitMask(VT)))
     return DAG.getConstant(0, VT);
+  if (DemandedBitsAreZero(SDOperand(N,0), MVT::getIntVTBitMask(VT)))
+    return SDOperand();
   // fold (shl (shl x, c1), c2) -> 0 or (shl x, c1+c2)
   if (N1C && N0.getOpcode() == ISD::SHL && 
       N0.getOperand(1).getOpcode() == ISD::Constant) {
@@ -1359,7 +1307,6 @@ SDOperand DAGCombiner::visitSRA(SDNode *N) {
   ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
   ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
   MVT::ValueType VT = N0.getValueType();
-  unsigned OpSizeInBits = MVT::getSizeInBits(VT);
   
   // fold (sra c1, c2) -> c1>>c2
   if (N0C && N1C)
@@ -1371,13 +1318,29 @@ SDOperand DAGCombiner::visitSRA(SDNode *N) {
   if (N0C && N0C->isAllOnesValue())
     return N0;
   // fold (sra x, c >= size(x)) -> undef
-  if (N1C && N1C->getValue() >= OpSizeInBits)
+  if (N1C && N1C->getValue() >= MVT::getSizeInBits(VT))
     return DAG.getNode(ISD::UNDEF, VT);
   // fold (sra x, 0) -> x
   if (N1C && N1C->isNullValue())
     return N0;
+  // fold (sra (shl x, c1), c1) -> sext_inreg for some c1 and target supports
+  // sext_inreg.
+  if (N1C && N0.getOpcode() == ISD::SHL && N1 == N0.getOperand(1)) {
+    unsigned LowBits = MVT::getSizeInBits(VT) - (unsigned)N1C->getValue();
+    MVT::ValueType EVT;
+    switch (LowBits) {
+    default: EVT = MVT::Other; break;
+    case  1: EVT = MVT::i1;    break;
+    case  8: EVT = MVT::i8;    break;
+    case 16: EVT = MVT::i16;   break;
+    case 32: EVT = MVT::i32;   break;
+    }
+    if (EVT > MVT::Other && TLI.isOperationLegal(ISD::SIGN_EXTEND_INREG, EVT))
+      return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, N0.getOperand(0),
+                         DAG.getValueType(EVT));
+  }
   // If the sign bit is known to be zero, switch this to a SRL.
-  if (MaskedValueIsZero(N0, (1ULL << (OpSizeInBits-1)), TLI))
+  if (TLI.MaskedValueIsZero(N0, MVT::getIntVTSignBit(VT)))
     return DAG.getNode(ISD::SRL, VT, N0, N1);
   return SDOperand();
 }
@@ -1403,7 +1366,7 @@ SDOperand DAGCombiner::visitSRL(SDNode *N) {
   if (N1C && N1C->isNullValue())
     return N0;
   // if (srl x, c) is known to be zero, return 0
-  if (N1C && MaskedValueIsZero(SDOperand(N, 0), ~0ULL >> (64-OpSizeInBits),TLI))
+  if (N1C && TLI.MaskedValueIsZero(SDOperand(N, 0), ~0ULL >> (64-OpSizeInBits)))
     return DAG.getConstant(0, VT);
   // fold (srl (srl x, c1), c2) -> 0 or (srl x, c1+c2)
   if (N1C && N0.getOpcode() == ISD::SRL && 
@@ -1495,14 +1458,20 @@ SDOperand DAGCombiner::visitSELECT(SDNode *N) {
   // fold X ? Y : X --> X ? Y : 0 --> X & Y
   if (MVT::i1 == VT && N0 == N2)
     return DAG.getNode(ISD::AND, VT, N0, N1);
-  
   // If we can fold this based on the true/false value, do so.
   if (SimplifySelectOps(N, N1, N2))
     return SDOperand();
-  
   // fold selects based on a setcc into other things, such as min/max/abs
   if (N0.getOpcode() == ISD::SETCC)
-    return SimplifySelect(N0, N1, N2);
+    // FIXME:
+    // Check against MVT::Other for SELECT_CC, which is a workaround for targets
+    // having to say they don't support SELECT_CC on every type the DAG knows
+    // about, since there is no way to mark an opcode illegal at all value types
+    if (TLI.isOperationLegal(ISD::SELECT_CC, MVT::Other))
+      return DAG.getNode(ISD::SELECT_CC, VT, N0.getOperand(0), N0.getOperand(1),
+                         N1, N2, N0.getOperand(2));
+    else
+      return SimplifySelect(N0, N1, N2);
   return SDOperand();
 }
 
@@ -1538,46 +1507,6 @@ SDOperand DAGCombiner::visitSETCC(SDNode *N) {
                        cast<CondCodeSDNode>(N->getOperand(2))->get());
 }
 
-SDOperand DAGCombiner::visitADD_PARTS(SDNode *N) {
-  SDOperand LHSLo = N->getOperand(0);
-  SDOperand RHSLo = N->getOperand(2);
-  MVT::ValueType VT = LHSLo.getValueType();
-  
-  // fold (a_Hi, 0) + (b_Hi, b_Lo) -> (b_Hi + a_Hi, b_Lo)
-  if (MaskedValueIsZero(LHSLo, (1ULL << MVT::getSizeInBits(VT))-1, TLI)) {
-    SDOperand Hi = DAG.getNode(ISD::ADD, VT, N->getOperand(1),
-                               N->getOperand(3));
-    WorkList.push_back(Hi.Val);
-    CombineTo(N, RHSLo, Hi);
-    return SDOperand();
-  }
-  // fold (a_Hi, a_Lo) + (b_Hi, 0) -> (a_Hi + b_Hi, a_Lo)
-  if (MaskedValueIsZero(RHSLo, (1ULL << MVT::getSizeInBits(VT))-1, TLI)) {
-    SDOperand Hi = DAG.getNode(ISD::ADD, VT, N->getOperand(1),
-                               N->getOperand(3));
-    WorkList.push_back(Hi.Val);
-    CombineTo(N, LHSLo, Hi);
-    return SDOperand();
-  }
-  return SDOperand();
-}
-
-SDOperand DAGCombiner::visitSUB_PARTS(SDNode *N) {
-  SDOperand LHSLo = N->getOperand(0);
-  SDOperand RHSLo = N->getOperand(2);
-  MVT::ValueType VT = LHSLo.getValueType();
-  
-  // fold (a_Hi, a_Lo) - (b_Hi, 0) -> (a_Hi - b_Hi, a_Lo)
-  if (MaskedValueIsZero(RHSLo, (1ULL << MVT::getSizeInBits(VT))-1, TLI)) {
-    SDOperand Hi = DAG.getNode(ISD::SUB, VT, N->getOperand(1),
-                               N->getOperand(3));
-    WorkList.push_back(Hi.Val);
-    CombineTo(N, LHSLo, Hi);
-    return SDOperand();
-  }
-  return SDOperand();
-}
-
 SDOperand DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
   SDOperand N0 = N->getOperand(0);
   ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
@@ -1704,9 +1633,8 @@ SDOperand DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) {
         TargetLowering::ZeroOrNegativeOneSetCCResult)
     return N0;
   // fold (sext_in_reg x) -> (zext_in_reg x) if the sign bit is zero
-  if (MaskedValueIsZero(N0, 1ULL << (EVTBits-1), TLI))
-    return DAG.getNode(ISD::AND, N0.getValueType(), N0,
-                       DAG.getConstant(~0ULL >> (64-EVTBits), VT));
+  if (TLI.MaskedValueIsZero(N0, 1ULL << (EVTBits-1)))
+    return DAG.getZeroExtendInReg(N0, EVT);
   // fold (sext_in_reg (srl x)) -> sra x
   if (N0.getOpcode() == ISD::SRL && 
       N0.getOperand(1).getOpcode() == ISD::Constant &&
@@ -2026,6 +1954,13 @@ SDOperand DAGCombiner::visitBRCOND(SDNode *N) {
   // unconditional branch
   if (N1C && N1C->getValue() == 1)
     return DAG.getNode(ISD::BR, MVT::Other, Chain, N2);
+  // fold a brcond with a setcc condition into a BR_CC node if BR_CC is legal
+  // on the target.
+  if (N1.getOpcode() == ISD::SETCC && 
+      TLI.isOperationLegal(ISD::BR_CC, MVT::Other)) {
+    return DAG.getNode(ISD::BR_CC, MVT::Other, Chain, N1.getOperand(2),
+                       N1.getOperand(0), N1.getOperand(1), N2);
+  }
   return SDOperand();
 }
 
@@ -2042,6 +1977,19 @@ SDOperand DAGCombiner::visitBRCONDTWOWAY(SDNode *N) {
   // unconditional branch to false mbb
   if (N1C && N1C->isNullValue())
     return DAG.getNode(ISD::BR, MVT::Other, Chain, N3);
+  // fold a brcondtwoway with a setcc condition into a BRTWOWAY_CC node if 
+  // BRTWOWAY_CC is legal on the target.
+  if (N1.getOpcode() == ISD::SETCC && 
+      TLI.isOperationLegal(ISD::BRTWOWAY_CC, MVT::Other)) {
+    std::vector<SDOperand> Ops;
+    Ops.push_back(Chain);
+    Ops.push_back(N1.getOperand(2));
+    Ops.push_back(N1.getOperand(0));
+    Ops.push_back(N1.getOperand(1));
+    Ops.push_back(N2);
+    Ops.push_back(N3);
+    return DAG.getNode(ISD::BRTWOWAY_CC, MVT::Other, Ops);
+  }
   return SDOperand();
 }
 
@@ -2155,35 +2103,6 @@ SDOperand DAGCombiner::visitSTORE(SDNode *N) {
   return SDOperand();
 }
 
-SDOperand DAGCombiner::visitLOCATION(SDNode *N) {
-  SDOperand Chain    = N->getOperand(0);
-  
-  // Remove redundant locations (last one holds)
-  if (Chain.getOpcode() == ISD::LOCATION && Chain.hasOneUse()) {
-    return DAG.getNode(ISD::LOCATION, MVT::Other, Chain.getOperand(0),
-                                                  N->getOperand(1),
-                                                  N->getOperand(2),
-                                                  N->getOperand(3),
-                                                  N->getOperand(4));
-  }
-  
-  return SDOperand();
-}
-
-SDOperand DAGCombiner::visitDEBUGLOC(SDNode *N) {
-  SDOperand Chain    = N->getOperand(0);
-  
-  // Remove redundant debug locations (last one holds)
-  if (Chain.getOpcode() == ISD::DEBUG_LOC && Chain.hasOneUse()) {
-    return DAG.getNode(ISD::DEBUG_LOC, MVT::Other, Chain.getOperand(0),
-                                                   N->getOperand(1),
-                                                   N->getOperand(2),
-                                                   N->getOperand(3));
-  }
-  
-  return SDOperand();
-}
-
 SDOperand DAGCombiner::SimplifySelect(SDOperand N0, SDOperand N1, SDOperand N2){
   assert(N0.getOpcode() ==ISD::SETCC && "First argument must be a SetCC node!");
   
@@ -2537,6 +2456,32 @@ SDOperand DAGCombiner::SimplifySetCC(MVT::ValueType VT, SDOperand N0,
                             DAG.getConstant(C1 & (~0ULL>>(64-ExtSrcTyBits)), 
                                             ExtDstTy),
                             Cond);
+      } else if ((N1C->getValue() == 0 || N1C->getValue() == 1) &&
+                 (Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
+                 (N0.getOpcode() == ISD::XOR ||
+                  (N0.getOpcode() == ISD::AND && 
+                   N0.getOperand(0).getOpcode() == ISD::XOR &&
+                   N0.getOperand(1) == N0.getOperand(0).getOperand(1))) &&
+                 isa<ConstantSDNode>(N0.getOperand(1)) &&
+                 cast<ConstantSDNode>(N0.getOperand(1))->getValue() == 1) {
+        // If this is (X^1) == 0/1, swap the RHS and eliminate the xor.  We can
+        // only do this if the top bits are known zero.
+        if (TLI.MaskedValueIsZero(N1, 
+                                  MVT::getIntVTBitMask(N0.getValueType())-1)) {
+          // Okay, get the un-inverted input value.
+          SDOperand Val;
+          if (N0.getOpcode() == ISD::XOR)
+            Val = N0.getOperand(0);
+          else {
+            assert(N0.getOpcode() == ISD::AND && 
+                   N0.getOperand(0).getOpcode() == ISD::XOR);
+            // ((X^1)&1)^1 -> X & 1
+            Val = DAG.getNode(ISD::AND, N0.getValueType(),
+                              N0.getOperand(0).getOperand(0), N0.getOperand(1));
+          }
+          return DAG.getSetCC(VT, Val, N1,
+                              Cond == ISD::SETEQ ? ISD::SETNE : ISD::SETEQ);
+        }
       }
       
       uint64_t MinVal, MaxVal;
@@ -2676,19 +2621,36 @@ SDOperand DAGCombiner::SimplifySetCC(MVT::ValueType VT, SDOperand N0,
             return DAG.getSetCC(VT, N0.getOperand(0), N1.getOperand(1), Cond);
         }
       }
-
-      // Turn (X^C1) == C2 into X == C1^C2 iff X&~C1 = 0.  Common for condcodes.
-      if (N0.getOpcode() == ISD::XOR)
-        if (ConstantSDNode *XORC = dyn_cast<ConstantSDNode>(N0.getOperand(1)))
-          if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(N1)) {
+      
+      if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(N1)) {
+        if (ConstantSDNode *LHSR = dyn_cast<ConstantSDNode>(N0.getOperand(1))) {
+          // Turn (X+C1) == C2 --> X == C2-C1
+          if (N0.getOpcode() == ISD::ADD && N0.Val->hasOneUse()) {
+            return DAG.getSetCC(VT, N0.getOperand(0),
+                              DAG.getConstant(RHSC->getValue()-LHSR->getValue(),
+                                N0.getValueType()), Cond);
+          }
+          
+          // Turn (X^C1) == C2 into X == C1^C2 iff X&~C1 = 0.
+          if (N0.getOpcode() == ISD::XOR)
             // If we know that all of the inverted bits are zero, don't bother
             // performing the inversion.
-            if (MaskedValueIsZero(N0.getOperand(0), ~XORC->getValue(), TLI))
+            if (TLI.MaskedValueIsZero(N0.getOperand(0), ~LHSR->getValue()))
               return DAG.getSetCC(VT, N0.getOperand(0),
-                              DAG.getConstant(XORC->getValue()^RHSC->getValue(),
+                              DAG.getConstant(LHSR->getValue()^RHSC->getValue(),
                                               N0.getValueType()), Cond);
+        }
+        
+        // Turn (C1-X) == C2 --> X == C1-C2
+        if (ConstantSDNode *SUBC = dyn_cast<ConstantSDNode>(N0.getOperand(0))) {
+          if (N0.getOpcode() == ISD::SUB && N0.Val->hasOneUse()) {
+            return DAG.getSetCC(VT, N0.getOperand(1),
+                             DAG.getConstant(SUBC->getValue()-RHSC->getValue(),
+                                             N0.getValueType()), Cond);
           }
-      
+        }          
+      }
+
       // Simplify (X+Z) == X -->  Z == 0
       if (N0.getOperand(0) == N1)
         return DAG.getSetCC(VT, N0.getOperand(1),