Clean up DemandedBitsAreZero interface
[oota-llvm.git] / lib / CodeGen / SelectionDAG / DAGCombiner.cpp
index 6fd1fe4b789dcfef91e894dd87e1891becd37414..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, 
@@ -418,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;
@@ -509,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);
@@ -536,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();
 }
@@ -587,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())
@@ -678,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();
 }
 
@@ -716,8 +730,8 @@ SDOperand DAGCombiner::visitSDIV(SDNode *N) {
   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
@@ -726,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)
@@ -764,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();
 }
 
@@ -808,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();
 }
 
@@ -860,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 && TLI.MaskedValueIsZero(SDOperand(N, 0), ~0ULL >> (64-OpSizeInBits)))
+  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 && 
-      TLI.MaskedValueIsZero(N0, ~N1C->getValue() & (~0ULL>>(64-OpSizeInBits))))
-    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();
@@ -946,20 +983,10 @@ 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 (TLI.MaskedValueIsZero(N1, (~0ULL << (OpSizeInBits-N01C->getValue())) &
-                                (~0ULL>>(64-OpSizeInBits)))) {
-        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();
@@ -1018,19 +1045,13 @@ SDOperand DAGCombiner::visitOR(SDNode *N) {
   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),
@@ -1147,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());
@@ -1240,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 && TLI.MaskedValueIsZero(SDOperand(N, 0), ~0ULL >> (64-OpSizeInBits)))
+  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) {
@@ -1280,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)
@@ -1292,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 (TLI.MaskedValueIsZero(N0, (1ULL << (OpSizeInBits-1))))
+  if (TLI.MaskedValueIsZero(N0, MVT::getIntVTSignBit(VT)))
     return DAG.getNode(ISD::SRL, VT, N0, N1);
   return SDOperand();
 }
@@ -1465,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 (TLI.MaskedValueIsZero(LHSLo, (1ULL << MVT::getSizeInBits(VT))-1)) {
-    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 (TLI.MaskedValueIsZero(RHSLo, (1ULL << MVT::getSizeInBits(VT))-1)) {
-    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 (TLI.MaskedValueIsZero(RHSLo, (1ULL << MVT::getSizeInBits(VT))-1)) {
-    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);
@@ -1632,8 +1634,7 @@ SDOperand DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) {
     return N0;
   // fold (sext_in_reg x) -> (zext_in_reg x) if the sign bit is zero
   if (TLI.MaskedValueIsZero(N0, 1ULL << (EVTBits-1)))
-    return DAG.getNode(ISD::AND, N0.getValueType(), N0,
-                       DAG.getConstant(~0ULL >> (64-EVTBits), VT));
+    return DAG.getZeroExtendInReg(N0, EVT);
   // fold (sext_in_reg (srl x)) -> sra x
   if (N0.getOpcode() == ISD::SRL && 
       N0.getOperand(1).getOpcode() == ISD::Constant &&
@@ -2102,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!");
   
@@ -2484,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;
@@ -2623,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 (TLI.MaskedValueIsZero(N0.getOperand(0), ~XORC->getValue()))
+            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),