Teach ReturnInst lowering about aggregate return values.
[oota-llvm.git] / lib / CodeGen / SelectionDAG / SelectionDAGISel.cpp
index 01f00f459f1ee9bb697624b35f04b1d9087c9331..2671cc3cbb7be89ab9c7ec92d8efe9be39b53c31 100644 (file)
 #include <algorithm>
 using namespace llvm;
 
+static cl::opt<bool>
+EnableValueProp("enable-value-prop", cl::Hidden, cl::init(false));
+
+
 #ifndef NDEBUG
 static cl::opt<bool>
 ViewISelDAGs("view-isel-dags", cl::Hidden,
@@ -87,28 +91,77 @@ defaultListDAGScheduler("default", "  Best scheduler for the target",
 
 namespace { struct SDISelAsmOperandInfo; }
 
+/// ComputeLinearIndex - Given an LLVM IR aggregate type and a sequence
+/// insertvalue or extractvalue indices that identify a member, return
+/// the linearized index of the start of the member.
+///
+static unsigned ComputeLinearIndex(const TargetLowering &TLI, const Type *Ty,
+                                   const unsigned *Indices,
+                                   const unsigned *IndicesEnd,
+                                   unsigned CurIndex = 0) {
+  // Base case: We're done.
+  if (Indices && Indices == IndicesEnd)
+    return CurIndex;
+
+  // Given a struct type, recursively traverse the elements.
+  if (const StructType *STy = dyn_cast<StructType>(Ty)) {
+    for (StructType::element_iterator EB = STy->element_begin(),
+                                      EI = EB,
+                                      EE = STy->element_end();
+        EI != EE; ++EI) {
+      if (Indices && *Indices == unsigned(EI - EB))
+        return ComputeLinearIndex(TLI, *EI, Indices+1, IndicesEnd, CurIndex);
+      CurIndex = ComputeLinearIndex(TLI, *EI, 0, 0, CurIndex);
+    }
+  }
+  // Given an array type, recursively traverse the elements.
+  else if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
+    const Type *EltTy = ATy->getElementType();
+    for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i) {
+      if (Indices && *Indices == i)
+        return ComputeLinearIndex(TLI, EltTy, Indices+1, IndicesEnd, CurIndex);
+      CurIndex = ComputeLinearIndex(TLI, EltTy, 0, 0, CurIndex);
+    }
+  }
+  // We haven't found the type we're looking for, so keep searching.
+  return CurIndex + 1;
+}
+
 /// ComputeValueVTs - Given an LLVM IR type, compute a sequence of
 /// MVTs that represent all the individual underlying
 /// non-aggregate types that comprise it.
+///
+/// If Offsets is non-null, it points to a vector to be filled in
+/// with the in-memory offsets of each of the individual values.
+///
 static void ComputeValueVTs(const TargetLowering &TLI, const Type *Ty,
-                            SmallVectorImpl<MVT> &ValueVTs) {
+                            SmallVectorImpl<MVT> &ValueVTs,
+                            SmallVectorImpl<uint64_t> *Offsets = 0,
+                            uint64_t StartingOffset = 0) {
   // Given a struct type, recursively traverse the elements.
   if (const StructType *STy = dyn_cast<StructType>(Ty)) {
-    for (StructType::element_iterator EI = STy->element_begin(),
-                                      EB = STy->element_end();
-        EI != EB; ++EI)
-      ComputeValueVTs(TLI, *EI, ValueVTs);
+    const StructLayout *SL = TLI.getTargetData()->getStructLayout(STy);
+    for (StructType::element_iterator EB = STy->element_begin(),
+                                      EI = EB,
+                                      EE = STy->element_end();
+         EI != EE; ++EI)
+      ComputeValueVTs(TLI, *EI, ValueVTs, Offsets,
+                      StartingOffset + SL->getElementOffset(EI - EB));
     return;
   }
   // Given an array type, recursively traverse the elements.
   if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
     const Type *EltTy = ATy->getElementType();
+    uint64_t EltSize = TLI.getTargetData()->getABITypeSize(EltTy);
     for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i)
-      ComputeValueVTs(TLI, EltTy, ValueVTs);
+      ComputeValueVTs(TLI, EltTy, ValueVTs, Offsets,
+                      StartingOffset + i * EltSize);
     return;
   }
   // Base case: we can get an MVT for this LLVM IR type.
   ValueVTs.push_back(TLI.getValueType(Ty));
+  if (Offsets)
+    Offsets->push_back(StartingOffset);
 }
 
 namespace {
@@ -271,6 +324,16 @@ namespace llvm {
       assert(R == 0 && "Already initialized this value register!");
       return R = CreateRegForValue(V);
     }
+    
+    struct LiveOutInfo {
+      unsigned NumSignBits;
+      APInt KnownOne, KnownZero;
+      LiveOutInfo() : NumSignBits(0) {}
+    };
+    
+    /// LiveOutRegInfo - Information about live out vregs, indexed by their
+    /// register number offset by 'FirstVirtualRegister'.
+    std::vector<LiveOutInfo> LiveOutRegInfo;
   };
 }
 
@@ -594,10 +657,6 @@ public:
 
   void setCurrentBasicBlock(MachineBasicBlock *MBB) { CurMBB = MBB; }
 
-  SDOperand getLoadFrom(const Type *Ty, SDOperand Ptr,
-                        const Value *SV, SDOperand Root,
-                        bool isVolatile, unsigned Alignment);
-
   SDOperand getValue(const Value *V);
 
   void setValue(const Value *V, SDOperand NewN) {
@@ -703,8 +762,8 @@ public:
   void visitInsertElement(User &I);
   void visitShuffleVector(User &I);
 
-  void visitExtractValue(User &I);
-  void visitInsertValue(User &I);
+  void visitExtractValue(ExtractValueInst &I);
+  void visitInsertValue(InsertValueInst &I);
 
   void visitGetElementPtr(User &I);
   void visitSelect(User &I);
@@ -863,7 +922,7 @@ static SDOperand getCopyFromParts(SelectionDAG &DAG,
 
   if (PartVT.isInteger() &&
       ValueVT.isInteger()) {
-    if (ValueVT.getSizeInBits() < PartVT.getSizeInBits()) {
+    if (ValueVT.bitsLT(PartVT)) {
       // For a truncate, see if we have any information to
       // indicate whether the truncated bits will always be
       // zero or sign-extension.
@@ -877,7 +936,7 @@ static SDOperand getCopyFromParts(SelectionDAG &DAG,
   }
 
   if (PartVT.isFloatingPoint() && ValueVT.isFloatingPoint()) {
-    if (ValueVT < Val.getValueType())
+    if (ValueVT.bitsLT(Val.getValueType()))
       // FP_ROUND's are always exact here.
       return DAG.getNode(ISD::FP_ROUND, ValueVT, Val,
                          DAG.getIntPtrConstant(1));
@@ -1083,7 +1142,8 @@ SDOperand SelectionDAGLowering::getValue(const Value *V) {
     if (ConstantFP *CFP = dyn_cast<ConstantFP>(C))
       return N = DAG.getConstantFP(CFP->getValueAPF(), VT);
     
-    if (isa<UndefValue>(C) && !isa<VectorType>(V->getType()))
+    if (isa<UndefValue>(C) && !isa<VectorType>(V->getType()) &&
+        !V->getType()->isAggregateType())
       return N = DAG.getNode(ISD::UNDEF, VT);
 
     if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
@@ -1093,6 +1153,67 @@ SDOperand SelectionDAGLowering::getValue(const Value *V) {
       return N1;
     }
     
+    if (isa<ConstantStruct>(C) || isa<ConstantArray>(C)) {
+      SmallVector<SDOperand, 4> Constants;
+      SmallVector<MVT, 4> ValueVTs;
+      for (User::const_op_iterator OI = C->op_begin(), OE = C->op_end();
+           OI != OE; ++OI) {
+        SDNode *Val = getValue(*OI).Val;
+        for (unsigned i = 0, e = Val->getNumValues(); i != e; ++i) {
+          Constants.push_back(SDOperand(Val, i));
+          ValueVTs.push_back(Val->getValueType(i));
+        }
+      }
+      return DAG.getNode(ISD::MERGE_VALUES,
+                         DAG.getVTList(&ValueVTs[0], ValueVTs.size()),
+                         &Constants[0], Constants.size());
+    }
+
+    if (const ArrayType *ATy = dyn_cast<ArrayType>(C->getType())) {
+      assert((isa<ConstantAggregateZero>(C) || isa<UndefValue>(C)) &&
+             "Unknown array constant!");
+      unsigned NumElts = ATy->getNumElements();
+      if (NumElts == 0)
+        return SDOperand(); // empty array
+      MVT EltVT = TLI.getValueType(ATy->getElementType());
+      SmallVector<SDOperand, 4> Constants(NumElts);
+      SmallVector<MVT, 4> ValueVTs(NumElts, EltVT);
+      for (unsigned i = 0, e = NumElts; i != e; ++i) {
+        if (isa<UndefValue>(C))
+          Constants[i] = DAG.getNode(ISD::UNDEF, EltVT);
+        else if (EltVT.isFloatingPoint())
+          Constants[i] = DAG.getConstantFP(0, EltVT);
+        else
+          Constants[i] = DAG.getConstant(0, EltVT);
+      }
+      return DAG.getNode(ISD::MERGE_VALUES,
+                         DAG.getVTList(&ValueVTs[0], ValueVTs.size()),
+                         &Constants[0], Constants.size());
+    }
+
+    if (const StructType *STy = dyn_cast<StructType>(C->getType())) {
+      assert((isa<ConstantAggregateZero>(C) || isa<UndefValue>(C)) &&
+             "Unknown struct constant!");
+      unsigned NumElts = STy->getNumElements();
+      if (NumElts == 0)
+        return SDOperand(); // empty struct
+      SmallVector<SDOperand, 4> Constants(NumElts);
+      SmallVector<MVT, 4> ValueVTs(NumElts);
+      for (unsigned i = 0, e = NumElts; i != e; ++i) {
+        MVT EltVT = TLI.getValueType(STy->getElementType(i));
+        ValueVTs[i] = EltVT;
+        if (isa<UndefValue>(C))
+          Constants[i] = DAG.getNode(ISD::UNDEF, EltVT);
+        else if (EltVT.isFloatingPoint())
+          Constants[i] = DAG.getConstantFP(0, EltVT);
+        else
+          Constants[i] = DAG.getConstant(0, EltVT);
+      }
+      return DAG.getNode(ISD::MERGE_VALUES,
+                         DAG.getVTList(&ValueVTs[0], ValueVTs.size()),
+                         &Constants[0], Constants.size());
+    }
+
     const VectorType *VecTy = cast<VectorType>(V->getType());
     unsigned NumElements = VecTy->getNumElements();
     
@@ -1149,32 +1270,38 @@ void SelectionDAGLowering::visitRet(ReturnInst &I) {
   NewValues.push_back(getControlRoot());
   for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {  
     SDOperand RetOp = getValue(I.getOperand(i));
-    MVT VT = RetOp.getValueType();
-
-    // FIXME: C calling convention requires the return type to be promoted to
-    // at least 32-bit. But this is not necessary for non-C calling conventions.
-    if (VT.isInteger()) {
-      MVT MinVT = TLI.getRegisterType(MVT::i32);
-      if (VT.getSizeInBits() < MinVT.getSizeInBits())
-        VT = MinVT;
-    }
-
-    unsigned NumParts = TLI.getNumRegisters(VT);
-    MVT PartVT = TLI.getRegisterType(VT);
-    SmallVector<SDOperand, 4> Parts(NumParts);
-    ISD::NodeType ExtendKind = ISD::ANY_EXTEND;
 
-    const Function *F = I.getParent()->getParent();
-    if (F->paramHasAttr(0, ParamAttr::SExt))
-      ExtendKind = ISD::SIGN_EXTEND;
-    else if (F->paramHasAttr(0, ParamAttr::ZExt))
-      ExtendKind = ISD::ZERO_EXTEND;
-
-    getCopyToParts(DAG, RetOp, &Parts[0], NumParts, PartVT, ExtendKind);
+    SmallVector<MVT, 4> ValueVTs;
+    ComputeValueVTs(TLI, I.getOperand(i)->getType(), ValueVTs);
+    for (unsigned j = 0, f = ValueVTs.size(); j != f; ++j) {
+      MVT VT = ValueVTs[j];
+
+      // FIXME: C calling convention requires the return type to be promoted to
+      // at least 32-bit. But this is not necessary for non-C calling conventions.
+      if (VT.isInteger()) {
+        MVT MinVT = TLI.getRegisterType(MVT::i32);
+        if (VT.bitsLT(MinVT))
+          VT = MinVT;
+      }
 
-    for (unsigned i = 0; i < NumParts; ++i) {
-      NewValues.push_back(Parts[i]);
-      NewValues.push_back(DAG.getArgFlags(ISD::ArgFlagsTy()));
+      unsigned NumParts = TLI.getNumRegisters(VT);
+      MVT PartVT = TLI.getRegisterType(VT);
+      SmallVector<SDOperand, 4> Parts(NumParts);
+      ISD::NodeType ExtendKind = ISD::ANY_EXTEND;
+  
+      const Function *F = I.getParent()->getParent();
+      if (F->paramHasAttr(0, ParamAttr::SExt))
+        ExtendKind = ISD::SIGN_EXTEND;
+      else if (F->paramHasAttr(0, ParamAttr::ZExt))
+        ExtendKind = ISD::ZERO_EXTEND;
+
+      getCopyToParts(DAG, SDOperand(RetOp.Val, RetOp.ResNo + j),
+                     &Parts[0], NumParts, PartVT, ExtendKind);
+
+      for (unsigned i = 0; i < NumParts; ++i) {
+        NewValues.push_back(Parts[i]);
+        NewValues.push_back(DAG.getArgFlags(ISD::ArgFlagsTy()));
+      }
     }
   }
   DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other,
@@ -1542,7 +1669,7 @@ void SelectionDAGLowering::visitJumpTableHeader(SelectionDAGISel::JumpTable &JT,
   // register so it can be used as an index into the jump table in a 
   // subsequent basic block.  This value may be smaller or larger than the
   // target's pointer type, and therefore require extension or truncating.
-  if (VT.getSizeInBits() > TLI.getPointerTy().getSizeInBits())
+  if (VT.bitsGT(TLI.getPointerTy()))
     SwitchOp = DAG.getNode(ISD::TRUNCATE, TLI.getPointerTy(), SUB);
   else
     SwitchOp = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), SUB);
@@ -1592,7 +1719,7 @@ void SelectionDAGLowering::visitBitTestHeader(SelectionDAGISel::BitTestBlock &B)
                                     ISD::SETUGT);
 
   SDOperand ShiftOp;
-  if (VT.getSizeInBits() > TLI.getShiftAmountTy().getSizeInBits())
+  if (VT.bitsGT(TLI.getShiftAmountTy()))
     ShiftOp = DAG.getNode(ISD::TRUNCATE, TLI.getShiftAmountTy(), SUB);
   else
     ShiftOp = DAG.getNode(ISD::ZERO_EXTEND, TLI.getShiftAmountTy(), SUB);
@@ -1635,12 +1762,11 @@ void SelectionDAGLowering::visitBitTestCase(MachineBasicBlock* NextMBB,
                                             unsigned Reg,
                                             SelectionDAGISel::BitTestCase &B) {
   // Emit bit tests and jumps
-  SDOperand SwitchVal = DAG.getCopyFromReg(getControlRoot(), Reg, TLI.getPointerTy());
+  SDOperand SwitchVal = DAG.getCopyFromReg(getControlRoot(), Reg, 
+                                           TLI.getPointerTy());
   
-  SDOperand AndOp = DAG.getNode(ISD::AND, TLI.getPointerTy(),
-                                SwitchVal,
-                                DAG.getConstant(B.Mask,
-                                                TLI.getPointerTy()));
+  SDOperand AndOp = DAG.getNode(ISD::AND, TLI.getPointerTy(), SwitchVal,
+                                DAG.getConstant(B.Mask, TLI.getPointerTy()));
   SDOperand AndCmp = DAG.getSetCC(TLI.getSetCCResultType(AndOp), AndOp,
                                   DAG.getConstant(0, TLI.getPointerTy()),
                                   ISD::SETNE);
@@ -2273,10 +2399,9 @@ void SelectionDAGLowering::visitShift(User &I, unsigned Opcode) {
   SDOperand Op1 = getValue(I.getOperand(0));
   SDOperand Op2 = getValue(I.getOperand(1));
   
-  if (TLI.getShiftAmountTy().getSizeInBits() <
-      Op2.getValueType().getSizeInBits())
+  if (TLI.getShiftAmountTy().bitsLT(Op2.getValueType()))
     Op2 = DAG.getNode(ISD::TRUNCATE, TLI.getShiftAmountTy(), Op2);
-  else if (TLI.getShiftAmountTy() > Op2.getValueType())
+  else if (TLI.getShiftAmountTy().bitsGT(Op2.getValueType()))
     Op2 = DAG.getNode(ISD::ANY_EXTEND, TLI.getShiftAmountTy(), Op2);
   
   setValue(&I, DAG.getNode(Opcode, Op1.getValueType(), Op1, Op2));
@@ -2498,7 +2623,7 @@ void SelectionDAGLowering::visitPtrToInt(User &I) {
   MVT SrcVT = N.getValueType();
   MVT DestVT = TLI.getValueType(I.getType());
   SDOperand Result;
-  if (DestVT.getSizeInBits() < SrcVT.getSizeInBits())
+  if (DestVT.bitsLT(SrcVT))
     Result = DAG.getNode(ISD::TRUNCATE, DestVT, N);
   else 
     // Note: ZERO_EXTEND can handle cases where the sizes are equal too
@@ -2512,7 +2637,7 @@ void SelectionDAGLowering::visitIntToPtr(User &I) {
   SDOperand N = getValue(I.getOperand(0));
   MVT SrcVT = N.getValueType();
   MVT DestVT = TLI.getValueType(I.getType());
-  if (DestVT.getSizeInBits() < SrcVT.getSizeInBits())
+  if (DestVT.bitsLT(SrcVT))
     setValue(&I, DAG.getNode(ISD::TRUNCATE, DestVT, N));
   else 
     // Note: ZERO_EXTEND can handle cases where the sizes are equal too
@@ -2560,14 +2685,72 @@ void SelectionDAGLowering::visitShuffleVector(User &I) {
                            V1, V2, Mask));
 }
 
-void SelectionDAGLowering::visitInsertValue(User &I) {
-  assert(0 && "insertvalue instruction not implemented");
-  abort();
+void SelectionDAGLowering::visitInsertValue(InsertValueInst &I) {
+  const Value *Op0 = I.getOperand(0);
+  const Value *Op1 = I.getOperand(1);
+  const Type *AggTy = I.getType();
+  const Type *ValTy = Op1->getType();
+  bool IntoUndef = isa<UndefValue>(Op0);
+  bool FromUndef = isa<UndefValue>(Op1);
+
+  unsigned LinearIndex = ComputeLinearIndex(TLI, AggTy,
+                                            I.idx_begin(), I.idx_end());
+
+  SmallVector<MVT, 4> AggValueVTs;
+  ComputeValueVTs(TLI, AggTy, AggValueVTs);
+  SmallVector<MVT, 4> ValValueVTs;
+  ComputeValueVTs(TLI, ValTy, ValValueVTs);
+
+  unsigned NumAggValues = AggValueVTs.size();
+  unsigned NumValValues = ValValueVTs.size();
+  SmallVector<SDOperand, 4> Values(NumAggValues);
+
+  SDOperand Agg = getValue(Op0);
+  SDOperand Val = getValue(Op1);
+  unsigned i = 0;
+  // Copy the beginning value(s) from the original aggregate.
+  for (; i != LinearIndex; ++i)
+    Values[i] = IntoUndef ? DAG.getNode(ISD::UNDEF, AggValueVTs[i]) :
+                SDOperand(Agg.Val, Agg.ResNo + i);
+  // Copy values from the inserted value(s).
+  for (; i != LinearIndex + NumValValues; ++i)
+    Values[i] = FromUndef ? DAG.getNode(ISD::UNDEF, AggValueVTs[i]) :
+                SDOperand(Val.Val, Val.ResNo + i - LinearIndex);
+  // Copy remaining value(s) from the original aggregate.
+  for (; i != NumAggValues; ++i)
+    Values[i] = IntoUndef ? DAG.getNode(ISD::UNDEF, AggValueVTs[i]) :
+                SDOperand(Agg.Val, Agg.ResNo + i);
+
+  setValue(&I, DAG.getNode(ISD::MERGE_VALUES,
+                           DAG.getVTList(&AggValueVTs[0], NumAggValues),
+                           &Values[0], NumAggValues));
 }
 
-void SelectionDAGLowering::visitExtractValue(User &I) {
-  assert(0 && "extractvalue instruction not implemented");
-  abort();
+void SelectionDAGLowering::visitExtractValue(ExtractValueInst &I) {
+  const Value *Op0 = I.getOperand(0);
+  const Type *AggTy = Op0->getType();
+  const Type *ValTy = I.getType();
+  bool OutOfUndef = isa<UndefValue>(Op0);
+
+  unsigned LinearIndex = ComputeLinearIndex(TLI, AggTy,
+                                            I.idx_begin(), I.idx_end());
+
+  SmallVector<MVT, 4> ValValueVTs;
+  ComputeValueVTs(TLI, ValTy, ValValueVTs);
+
+  unsigned NumValValues = ValValueVTs.size();
+  SmallVector<SDOperand, 4> Values(NumValValues);
+
+  SDOperand Agg = getValue(Op0);
+  // Copy out the selected value(s).
+  for (unsigned i = LinearIndex; i != LinearIndex + NumValValues; ++i)
+    Values[i - LinearIndex] =
+      OutOfUndef ? DAG.getNode(ISD::UNDEF, Agg.Val->getValueType(Agg.ResNo + i)) :
+                   SDOperand(Agg.Val, Agg.ResNo + i);
+
+  setValue(&I, DAG.getNode(ISD::MERGE_VALUES,
+                           DAG.getVTList(&ValValueVTs[0], NumValValues),
+                           &Values[0], NumValValues));
 }
 
 
@@ -2606,9 +2789,9 @@ void SelectionDAGLowering::visitGetElementPtr(User &I) {
 
       // If the index is smaller or larger than intptr_t, truncate or extend
       // it.
-      if (IdxN.getValueType() < N.getValueType()) {
+      if (IdxN.getValueType().bitsLT(N.getValueType())) {
         IdxN = DAG.getNode(ISD::SIGN_EXTEND, N.getValueType(), IdxN);
-      } else if (IdxN.getValueType() > N.getValueType())
+      } else if (IdxN.getValueType().bitsGT(N.getValueType()))
         IdxN = DAG.getNode(ISD::TRUNCATE, N.getValueType(), IdxN);
 
       // If this is a multiply by a power of two, turn it into a shl
@@ -2643,9 +2826,9 @@ void SelectionDAGLowering::visitAlloca(AllocaInst &I) {
 
   SDOperand AllocSize = getValue(I.getArraySize());
   MVT IntPtr = TLI.getPointerTy();
-  if (IntPtr < AllocSize.getValueType())
+  if (IntPtr.bitsLT(AllocSize.getValueType()))
     AllocSize = DAG.getNode(ISD::TRUNCATE, IntPtr, AllocSize);
-  else if (IntPtr > AllocSize.getValueType())
+  else if (IntPtr.bitsGT(AllocSize.getValueType()))
     AllocSize = DAG.getNode(ISD::ZERO_EXTEND, IntPtr, AllocSize);
 
   AllocSize = DAG.getNode(ISD::MUL, IntPtr, AllocSize,
@@ -2680,7 +2863,19 @@ void SelectionDAGLowering::visitAlloca(AllocaInst &I) {
 }
 
 void SelectionDAGLowering::visitLoad(LoadInst &I) {
-  SDOperand Ptr = getValue(I.getOperand(0));
+  const Value *SV = I.getOperand(0);
+  SDOperand Ptr = getValue(SV);
+
+  const Type *Ty = I.getType();
+  bool isVolatile = I.isVolatile();
+  unsigned Alignment = I.getAlignment();
+
+  SmallVector<MVT, 4> ValueVTs;
+  SmallVector<uint64_t, 4> Offsets;
+  ComputeValueVTs(TLI, Ty, ValueVTs, &Offsets);
+  unsigned NumValues = ValueVTs.size();
+  if (NumValues == 0)
+    return;
 
   SDOperand Root;
   if (I.isVolatile())
@@ -2690,33 +2885,58 @@ void SelectionDAGLowering::visitLoad(LoadInst &I) {
     Root = DAG.getRoot();
   }
 
-  setValue(&I, getLoadFrom(I.getType(), Ptr, I.getOperand(0),
-                           Root, I.isVolatile(), I.getAlignment()));
-}
-
-SDOperand SelectionDAGLowering::getLoadFrom(const Type *Ty, SDOperand Ptr,
-                                            const Value *SV, SDOperand Root,
-                                            bool isVolatile, 
-                                            unsigned Alignment) {
-  SDOperand L =
-    DAG.getLoad(TLI.getValueType(Ty), Root, Ptr, SV, 0, 
-                isVolatile, Alignment);
-
+  SmallVector<SDOperand, 4> Values(NumValues);
+  SmallVector<SDOperand, 4> Chains(NumValues);
+  MVT PtrVT = Ptr.getValueType();
+  for (unsigned i = 0; i != NumValues; ++i) {
+    SDOperand L = DAG.getLoad(ValueVTs[i], Root,
+                              DAG.getNode(ISD::ADD, PtrVT, Ptr,
+                                          DAG.getConstant(Offsets[i], PtrVT)),
+                              SV, Offsets[i],
+                              isVolatile, Alignment);
+    Values[i] = L;
+    Chains[i] = L.getValue(1);
+  }
+  
+  SDOperand Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
+                                &Chains[0], NumValues);
   if (isVolatile)
-    DAG.setRoot(L.getValue(1));
+    DAG.setRoot(Chain);
   else
-    PendingLoads.push_back(L.getValue(1));
-  
-  return L;
+    PendingLoads.push_back(Chain);
+
+  setValue(&I, DAG.getNode(ISD::MERGE_VALUES,
+                           DAG.getVTList(&ValueVTs[0], NumValues),
+                           &Values[0], NumValues));
 }
 
 
 void SelectionDAGLowering::visitStore(StoreInst &I) {
   Value *SrcV = I.getOperand(0);
   SDOperand Src = getValue(SrcV);
-  SDOperand Ptr = getValue(I.getOperand(1));
-  DAG.setRoot(DAG.getStore(getRoot(), Src, Ptr, I.getOperand(1), 0,
-                           I.isVolatile(), I.getAlignment()));
+  Value *PtrV = I.getOperand(1);
+  SDOperand Ptr = getValue(PtrV);
+
+  SmallVector<MVT, 4> ValueVTs;
+  SmallVector<uint64_t, 4> Offsets;
+  ComputeValueVTs(TLI, SrcV->getType(), ValueVTs, &Offsets);
+  unsigned NumValues = ValueVTs.size();
+  if (NumValues == 0)
+    return;
+
+  SDOperand Root = getRoot();
+  SmallVector<SDOperand, 4> Chains(NumValues);
+  MVT PtrVT = Ptr.getValueType();
+  bool isVolatile = I.isVolatile();
+  unsigned Alignment = I.getAlignment();
+  for (unsigned i = 0; i != NumValues; ++i)
+    Chains[i] = DAG.getStore(Root, SDOperand(Src.Val, Src.ResNo + i),
+                             DAG.getNode(ISD::ADD, PtrVT, Ptr,
+                                         DAG.getConstant(Offsets[i], PtrVT)),
+                             PtrV, Offsets[i],
+                             isVolatile, Alignment);
+
+  DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, &Chains[0], NumValues));
 }
 
 /// visitTargetIntrinsic - Lower a call of a target intrinsic to an INTRINSIC
@@ -3118,7 +3338,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
    case Intrinsic::eh_dwarf_cfa: {
      MVT VT = getValue(I.getOperand(1)).getValueType();
      SDOperand CfaArg;
-     if (VT.getSizeInBits() > TLI.getPointerTy().getSizeInBits())
+     if (VT.bitsGT(TLI.getPointerTy()))
        CfaArg = DAG.getNode(ISD::TRUNCATE,
                             TLI.getPointerTy(), getValue(I.getOperand(1)));
      else
@@ -3319,6 +3539,8 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
     return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_OR);
   case Intrinsic::atomic_load_xor:
     return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_XOR);
+  case Intrinsic::atomic_load_nand:
+    return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_NAND);
   case Intrinsic::atomic_load_min:
     return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_MIN);
   case Intrinsic::atomic_load_max:
@@ -3497,7 +3719,7 @@ void SelectionDAGLowering::visitGetResult(GetResultInst &I) {
 /// this value and returns the result as a ValueVT value.  This uses 
 /// Chain/Flag as the input and updates them for the output Chain/Flag.
 /// If the Flag pointer is NULL, no flag is used.
-SDOperand RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
+SDOperand RegsForValue::getCopyFromRegs(SelectionDAG &DAG, 
                                         SDOperand &Chain,
                                         SDOperand *Flag) const {
   // Assemble the legal parts into the final values.
@@ -3519,6 +3741,49 @@ SDOperand RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
         *Flag = P.getValue(2);
       }
       Chain = P.getValue(1);
+      
+      // If the source register was virtual and if we know something about it,
+      // add an assert node.
+      if (TargetRegisterInfo::isVirtualRegister(Regs[Part+i]) &&
+          RegisterVT.isInteger() && !RegisterVT.isVector()) {
+        unsigned SlotNo = Regs[Part+i]-TargetRegisterInfo::FirstVirtualRegister;
+        FunctionLoweringInfo &FLI = DAG.getFunctionLoweringInfo();
+        if (FLI.LiveOutRegInfo.size() > SlotNo) {
+          FunctionLoweringInfo::LiveOutInfo &LOI = FLI.LiveOutRegInfo[SlotNo];
+          
+          unsigned RegSize = RegisterVT.getSizeInBits();
+          unsigned NumSignBits = LOI.NumSignBits;
+          unsigned NumZeroBits = LOI.KnownZero.countLeadingOnes();
+          
+          // FIXME: We capture more information than the dag can represent.  For
+          // now, just use the tightest assertzext/assertsext possible.
+          bool isSExt = true;
+          MVT FromVT(MVT::Other);
+          if (NumSignBits == RegSize)
+            isSExt = true, FromVT = MVT::i1;   // ASSERT SEXT 1
+          else if (NumZeroBits >= RegSize-1)
+            isSExt = false, FromVT = MVT::i1;  // ASSERT ZEXT 1
+          else if (NumSignBits > RegSize-8)
+            isSExt = true, FromVT = MVT::i8;   // ASSERT SEXT 8
+          else if (NumZeroBits >= RegSize-9)
+            isSExt = false, FromVT = MVT::i8;  // ASSERT ZEXT 8
+          else if (NumSignBits > RegSize-16)
+            isSExt = true, FromVT = MVT::i16;   // ASSERT SEXT 16
+          else if (NumZeroBits >= RegSize-17)
+            isSExt = false, FromVT = MVT::i16;  // ASSERT ZEXT 16
+          else if (NumSignBits > RegSize-32)
+            isSExt = true, FromVT = MVT::i32;   // ASSERT SEXT 32
+          else if (NumZeroBits >= RegSize-33)
+            isSExt = false, FromVT = MVT::i32;  // ASSERT ZEXT 32
+          
+          if (FromVT != MVT::Other) {
+            P = DAG.getNode(isSExt ? ISD::AssertSext : ISD::AssertZext,
+                            RegisterVT, P, DAG.getValueType(FromVT));
+
+          }
+        }
+      }
+      
       Parts[Part+i] = P;
     }
   
@@ -3620,8 +3885,7 @@ isAllocatableRegister(unsigned Reg, MachineFunction &MF,
         // If we have already found this register in a different register class,
         // choose the one with the largest VT specified.  For example, on
         // PowerPC, we favor f64 register classes over f32.
-        if (FoundVT == MVT::Other || 
-            FoundVT.getSizeInBits() < (*I).getSizeInBits()) {
+        if (FoundVT == MVT::Other || FoundVT.bitsLT(*I)) {
           ThisVT = *I;
           break;
         }
@@ -4075,7 +4339,7 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
       // Copy the output from the appropriate register.  Find a register that
       // we can use.
       if (OpInfo.AssignedRegs.Regs.empty()) {
-        cerr << "Couldn't allocate output reg for contraint '"
+        cerr << "Couldn't allocate output reg for constraint '"
              << OpInfo.ConstraintCode << "'!\n";
         exit(1);
       }
@@ -4271,9 +4535,9 @@ void SelectionDAGLowering::visitMalloc(MallocInst &I) {
 
   MVT IntPtr = TLI.getPointerTy();
 
-  if (IntPtr < Src.getValueType())
+  if (IntPtr.bitsLT(Src.getValueType()))
     Src = DAG.getNode(ISD::TRUNCATE, IntPtr, Src);
-  else if (IntPtr > Src.getValueType())
+  else if (IntPtr.bitsGT(Src.getValueType()))
     Src = DAG.getNode(ISD::ZERO_EXTEND, IntPtr, Src);
 
   // Scale the source by the type size.
@@ -4367,47 +4631,53 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
   unsigned j = 1;
   for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end();
        I != E; ++I, ++j) {
-    MVT VT = getValueType(I->getType());
-    ISD::ArgFlagsTy Flags;
-    unsigned OriginalAlignment =
-      getTargetData()->getABITypeAlignment(I->getType());
-
-    if (F.paramHasAttr(j, ParamAttr::ZExt))
-      Flags.setZExt();
-    if (F.paramHasAttr(j, ParamAttr::SExt))
-      Flags.setSExt();
-    if (F.paramHasAttr(j, ParamAttr::InReg))
-      Flags.setInReg();
-    if (F.paramHasAttr(j, ParamAttr::StructRet))
-      Flags.setSRet();
-    if (F.paramHasAttr(j, ParamAttr::ByVal)) {
-      Flags.setByVal();
-      const PointerType *Ty = cast<PointerType>(I->getType());
-      const Type *ElementTy = Ty->getElementType();
-      unsigned FrameAlign = getByValTypeAlignment(ElementTy);
-      unsigned FrameSize  = getTargetData()->getABITypeSize(ElementTy);
-      // For ByVal, alignment should be passed from FE.  BE will guess if
-      // this info is not there but there are cases it cannot get right.
-      if (F.getParamAlignment(j))
-        FrameAlign = F.getParamAlignment(j);
-      Flags.setByValAlign(FrameAlign);
-      Flags.setByValSize(FrameSize);
-    }
-    if (F.paramHasAttr(j, ParamAttr::Nest))
-      Flags.setNest();
-    Flags.setOrigAlign(OriginalAlignment);
+    SmallVector<MVT, 4> ValueVTs;
+    ComputeValueVTs(*this, I->getType(), ValueVTs);
+    for (unsigned Value = 0, NumValues = ValueVTs.size();
+         Value != NumValues; ++Value) {
+      MVT VT = ValueVTs[Value];
+      const Type *ArgTy = VT.getTypeForMVT();
+      ISD::ArgFlagsTy Flags;
+      unsigned OriginalAlignment =
+        getTargetData()->getABITypeAlignment(ArgTy);
+
+      if (F.paramHasAttr(j, ParamAttr::ZExt))
+        Flags.setZExt();
+      if (F.paramHasAttr(j, ParamAttr::SExt))
+        Flags.setSExt();
+      if (F.paramHasAttr(j, ParamAttr::InReg))
+        Flags.setInReg();
+      if (F.paramHasAttr(j, ParamAttr::StructRet))
+        Flags.setSRet();
+      if (F.paramHasAttr(j, ParamAttr::ByVal)) {
+        Flags.setByVal();
+        const PointerType *Ty = cast<PointerType>(I->getType());
+        const Type *ElementTy = Ty->getElementType();
+        unsigned FrameAlign = getByValTypeAlignment(ElementTy);
+        unsigned FrameSize  = getTargetData()->getABITypeSize(ElementTy);
+        // For ByVal, alignment should be passed from FE.  BE will guess if
+        // this info is not there but there are cases it cannot get right.
+        if (F.getParamAlignment(j))
+          FrameAlign = F.getParamAlignment(j);
+        Flags.setByValAlign(FrameAlign);
+        Flags.setByValSize(FrameSize);
+      }
+      if (F.paramHasAttr(j, ParamAttr::Nest))
+        Flags.setNest();
+      Flags.setOrigAlign(OriginalAlignment);
 
-    MVT RegisterVT = getRegisterType(VT);
-    unsigned NumRegs = getNumRegisters(VT);
-    for (unsigned i = 0; i != NumRegs; ++i) {
-      RetVals.push_back(RegisterVT);
-      ISD::ArgFlagsTy MyFlags = Flags;
-      if (NumRegs > 1 && i == 0)
-        MyFlags.setSplit();
-      // if it isn't first piece, alignment must be 1
-      else if (i > 0)
-        MyFlags.setOrigAlign(1);
-      Ops.push_back(DAG.getArgFlags(MyFlags));
+      MVT RegisterVT = getRegisterType(VT);
+      unsigned NumRegs = getNumRegisters(VT);
+      for (unsigned i = 0; i != NumRegs; ++i) {
+        RetVals.push_back(RegisterVT);
+        ISD::ArgFlagsTy MyFlags = Flags;
+        if (NumRegs > 1 && i == 0)
+          MyFlags.setSplit();
+        // if it isn't first piece, alignment must be 1
+        else if (i > 0)
+          MyFlags.setOrigAlign(1);
+        Ops.push_back(DAG.getArgFlags(MyFlags));
+      }
     }
   }
 
@@ -4440,22 +4710,27 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
   unsigned Idx = 1;
   for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; 
       ++I, ++Idx) {
-    MVT VT = getValueType(I->getType());
-    MVT PartVT = getRegisterType(VT);
-
-    unsigned NumParts = getNumRegisters(VT);
-    SmallVector<SDOperand, 4> Parts(NumParts);
-    for (unsigned j = 0; j != NumParts; ++j)
-      Parts[j] = SDOperand(Result, i++);
-
-    ISD::NodeType AssertOp = ISD::DELETED_NODE;
-    if (F.paramHasAttr(Idx, ParamAttr::SExt))
-      AssertOp = ISD::AssertSext;
-    else if (F.paramHasAttr(Idx, ParamAttr::ZExt))
-      AssertOp = ISD::AssertZext;
-
-    Ops.push_back(getCopyFromParts(DAG, &Parts[0], NumParts, PartVT, VT,
-                                   AssertOp));
+    SmallVector<MVT, 4> ValueVTs;
+    ComputeValueVTs(*this, I->getType(), ValueVTs);
+    for (unsigned Value = 0, NumValues = ValueVTs.size();
+         Value != NumValues; ++Value) {
+      MVT VT = ValueVTs[Value];
+      MVT PartVT = getRegisterType(VT);
+
+      unsigned NumParts = getNumRegisters(VT);
+      SmallVector<SDOperand, 4> Parts(NumParts);
+      for (unsigned j = 0; j != NumParts; ++j)
+        Parts[j] = SDOperand(Result, i++);
+
+      ISD::NodeType AssertOp = ISD::DELETED_NODE;
+      if (F.paramHasAttr(Idx, ParamAttr::SExt))
+        AssertOp = ISD::AssertSext;
+      else if (F.paramHasAttr(Idx, ParamAttr::ZExt))
+        AssertOp = ISD::AssertZext;
+
+      Ops.push_back(getCopyFromParts(DAG, &Parts[0], NumParts, PartVT, VT,
+                                     AssertOp));
+    }
   }
   assert(i == NumArgRegs && "Argument register count mismatch!");
   return Ops;
@@ -4481,59 +4756,65 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
   
   // Handle all of the outgoing arguments.
   for (unsigned i = 0, e = Args.size(); i != e; ++i) {
-    MVT VT = getValueType(Args[i].Ty);
-    SDOperand Op = Args[i].Node;
-    ISD::ArgFlagsTy Flags;
-    unsigned OriginalAlignment =
-      getTargetData()->getABITypeAlignment(Args[i].Ty);
-
-    if (Args[i].isZExt)
-      Flags.setZExt();
-    if (Args[i].isSExt)
-      Flags.setSExt();
-    if (Args[i].isInReg)
-      Flags.setInReg();
-    if (Args[i].isSRet)
-      Flags.setSRet();
-    if (Args[i].isByVal) {
-      Flags.setByVal();
-      const PointerType *Ty = cast<PointerType>(Args[i].Ty);
-      const Type *ElementTy = Ty->getElementType();
-      unsigned FrameAlign = getByValTypeAlignment(ElementTy);
-      unsigned FrameSize  = getTargetData()->getABITypeSize(ElementTy);
-      // For ByVal, alignment should come from FE.  BE will guess if this
-      // info is not there but there are cases it cannot get right.
-      if (Args[i].Alignment)
-        FrameAlign = Args[i].Alignment;
-      Flags.setByValAlign(FrameAlign);
-      Flags.setByValSize(FrameSize);
-    }
-    if (Args[i].isNest)
-      Flags.setNest();
-    Flags.setOrigAlign(OriginalAlignment);
-
-    MVT PartVT = getRegisterType(VT);
-    unsigned NumParts = getNumRegisters(VT);
-    SmallVector<SDOperand, 4> Parts(NumParts);
-    ISD::NodeType ExtendKind = ISD::ANY_EXTEND;
-
-    if (Args[i].isSExt)
-      ExtendKind = ISD::SIGN_EXTEND;
-    else if (Args[i].isZExt)
-      ExtendKind = ISD::ZERO_EXTEND;
-
-    getCopyToParts(DAG, Op, &Parts[0], NumParts, PartVT, ExtendKind);
-
-    for (unsigned i = 0; i != NumParts; ++i) {
-      // if it isn't first piece, alignment must be 1
-      ISD::ArgFlagsTy MyFlags = Flags;
-      if (NumParts > 1 && i == 0)
-        MyFlags.setSplit();
-      else if (i != 0)
-        MyFlags.setOrigAlign(1);
-
-      Ops.push_back(Parts[i]);
-      Ops.push_back(DAG.getArgFlags(MyFlags));
+    SmallVector<MVT, 4> ValueVTs;
+    ComputeValueVTs(*this, Args[i].Ty, ValueVTs);
+    for (unsigned Value = 0, NumValues = ValueVTs.size();
+         Value != NumValues; ++Value) {
+      MVT VT = ValueVTs[Value];
+      const Type *ArgTy = VT.getTypeForMVT();
+      SDOperand Op = SDOperand(Args[i].Node.Val, Args[i].Node.ResNo + Value);
+      ISD::ArgFlagsTy Flags;
+      unsigned OriginalAlignment =
+        getTargetData()->getABITypeAlignment(ArgTy);
+
+      if (Args[i].isZExt)
+        Flags.setZExt();
+      if (Args[i].isSExt)
+        Flags.setSExt();
+      if (Args[i].isInReg)
+        Flags.setInReg();
+      if (Args[i].isSRet)
+        Flags.setSRet();
+      if (Args[i].isByVal) {
+        Flags.setByVal();
+        const PointerType *Ty = cast<PointerType>(Args[i].Ty);
+        const Type *ElementTy = Ty->getElementType();
+        unsigned FrameAlign = getByValTypeAlignment(ElementTy);
+        unsigned FrameSize  = getTargetData()->getABITypeSize(ElementTy);
+        // For ByVal, alignment should come from FE.  BE will guess if this
+        // info is not there but there are cases it cannot get right.
+        if (Args[i].Alignment)
+          FrameAlign = Args[i].Alignment;
+        Flags.setByValAlign(FrameAlign);
+        Flags.setByValSize(FrameSize);
+      }
+      if (Args[i].isNest)
+        Flags.setNest();
+      Flags.setOrigAlign(OriginalAlignment);
+
+      MVT PartVT = getRegisterType(VT);
+      unsigned NumParts = getNumRegisters(VT);
+      SmallVector<SDOperand, 4> Parts(NumParts);
+      ISD::NodeType ExtendKind = ISD::ANY_EXTEND;
+
+      if (Args[i].isSExt)
+        ExtendKind = ISD::SIGN_EXTEND;
+      else if (Args[i].isZExt)
+        ExtendKind = ISD::ZERO_EXTEND;
+
+      getCopyToParts(DAG, Op, &Parts[0], NumParts, PartVT, ExtendKind);
+
+      for (unsigned i = 0; i != NumParts; ++i) {
+        // if it isn't first piece, alignment must be 1
+        ISD::ArgFlagsTy MyFlags = Flags;
+        if (NumParts > 1 && i == 0)
+          MyFlags.setSplit();
+        else if (i != 0)
+          MyFlags.setOrigAlign(1);
+
+        Ops.push_back(Parts[i]);
+        Ops.push_back(DAG.getArgFlags(MyFlags));
+      }
     }
   }
   
@@ -4682,10 +4963,18 @@ LowerArguments(BasicBlock *LLVMBB, SelectionDAGLowering &SDL) {
 
   unsigned a = 0;
   for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end();
-       AI != E; ++AI, ++a)
+       AI != E; ++AI) {
+    SmallVector<MVT, 4> ValueVTs;
+    ComputeValueVTs(TLI, AI->getType(), ValueVTs);
+    unsigned NumValues = ValueVTs.size();
     if (!AI->use_empty()) {
-      SDL.setValue(AI, Args[a]);
-
+      SmallVector<MVT, 4> LegalValueVTs(NumValues);
+      for (unsigned VI = 0; VI != NumValues; ++VI) 
+        LegalValueVTs[VI] = Args[a + VI].getValueType();
+      SDL.setValue(AI, SDL.DAG.getNode(ISD::MERGE_VALUES,
+                                       SDL.DAG.getVTList(&LegalValueVTs[0],
+                                                         NumValues),
+                                       &Args[a], NumValues));
       // If this argument is live outside of the entry block, insert a copy from
       // whereever we got it to the vreg that other BB's will reference it as.
       DenseMap<const Value*, unsigned>::iterator VMI=FuncInfo.ValueMap.find(AI);
@@ -4693,6 +4982,8 @@ LowerArguments(BasicBlock *LLVMBB, SelectionDAGLowering &SDL) {
         SDL.CopyValueToVirtualRegister(AI, VMI->second);
       }
     }
+    a += NumValues;
+  }
 
   // Finally, if the target has anything special to do, allow it to do so.
   // FIXME: this should insert code into the DAG!
@@ -4983,6 +5274,61 @@ void SelectionDAGISel::BuildSelectionDAG(SelectionDAG &DAG, BasicBlock *LLVMBB,
   CheckDAGForTailCallsAndFixThem(DAG, TLI);
 }
 
+void SelectionDAGISel::ComputeLiveOutVRegInfo(SelectionDAG &DAG) {
+  SmallPtrSet<SDNode*, 128> VisitedNodes;
+  SmallVector<SDNode*, 128> Worklist;
+  
+  Worklist.push_back(DAG.getRoot().Val);
+  
+  APInt Mask;
+  APInt KnownZero;
+  APInt KnownOne;
+  
+  while (!Worklist.empty()) {
+    SDNode *N = Worklist.back();
+    Worklist.pop_back();
+    
+    // If we've already seen this node, ignore it.
+    if (!VisitedNodes.insert(N))
+      continue;
+    
+    // Otherwise, add all chain operands to the worklist.
+    for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
+      if (N->getOperand(i).getValueType() == MVT::Other)
+        Worklist.push_back(N->getOperand(i).Val);
+    
+    // If this is a CopyToReg with a vreg dest, process it.
+    if (N->getOpcode() != ISD::CopyToReg)
+      continue;
+    
+    unsigned DestReg = cast<RegisterSDNode>(N->getOperand(1))->getReg();
+    if (!TargetRegisterInfo::isVirtualRegister(DestReg))
+      continue;
+    
+    // Ignore non-scalar or non-integer values.
+    SDOperand Src = N->getOperand(2);
+    MVT SrcVT = Src.getValueType();
+    if (!SrcVT.isInteger() || SrcVT.isVector())
+      continue;
+    
+    unsigned NumSignBits = DAG.ComputeNumSignBits(Src);
+    Mask = APInt::getAllOnesValue(SrcVT.getSizeInBits());
+    DAG.ComputeMaskedBits(Src, Mask, KnownZero, KnownOne);
+    
+    // Only install this information if it tells us something.
+    if (NumSignBits != 1 || KnownZero != 0 || KnownOne != 0) {
+      DestReg -= TargetRegisterInfo::FirstVirtualRegister;
+      FunctionLoweringInfo &FLI = DAG.getFunctionLoweringInfo();
+      if (DestReg >= FLI.LiveOutRegInfo.size())
+        FLI.LiveOutRegInfo.resize(DestReg+1);
+      FunctionLoweringInfo::LiveOutInfo &LOI = FLI.LiveOutRegInfo[DestReg];
+      LOI.NumSignBits = NumSignBits;
+      LOI.KnownOne = NumSignBits;
+      LOI.KnownZero = NumSignBits;
+    }
+  }
+}
+
 void SelectionDAGISel::CodeGenAndEmitDAG(SelectionDAG &DAG) {
   DOUT << "Lowered selection DAG:\n";
   DEBUG(DAG.dump());
@@ -5011,6 +5357,9 @@ void SelectionDAGISel::CodeGenAndEmitDAG(SelectionDAG &DAG) {
   DEBUG(DAG.dump());
 
   if (ViewISelDAGs) DAG.viewGraph();
+  
+  if (EnableValueProp)  // FIXME: Only do this if !fast.
+    ComputeLiveOutVRegInfo(DAG);
 
   // Third, instruction select all of the operations to machine code, adding the
   // code to the MachineBasicBlock.
@@ -5024,7 +5373,8 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF,
                                         FunctionLoweringInfo &FuncInfo) {
   std::vector<std::pair<MachineInstr*, unsigned> > PHINodesToUpdate;
   {
-    SelectionDAG DAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
+    SelectionDAG DAG(TLI, MF, FuncInfo, 
+                     getAnalysisToUpdate<MachineModuleInfo>());
     CurDAG = &DAG;
   
     // First step, lower LLVM code to some DAG.  This DAG may use operations and
@@ -5058,7 +5408,8 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF,
   for (unsigned i = 0, e = BitTestCases.size(); i != e; ++i) {
     // Lower header first, if it wasn't already lowered
     if (!BitTestCases[i].Emitted) {
-      SelectionDAG HSDAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
+      SelectionDAG HSDAG(TLI, MF, FuncInfo, 
+                         getAnalysisToUpdate<MachineModuleInfo>());
       CurDAG = &HSDAG;
       SelectionDAGLowering HSDL(HSDAG, TLI, *AA, FuncInfo, GCI);
       // Set the current basic block to the mbb we wish to insert the code into
@@ -5071,7 +5422,8 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF,
     }    
 
     for (unsigned j = 0, ej = BitTestCases[i].Cases.size(); j != ej; ++j) {
-      SelectionDAG BSDAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
+      SelectionDAG BSDAG(TLI, MF, FuncInfo, 
+                         getAnalysisToUpdate<MachineModuleInfo>());
       CurDAG = &BSDAG;
       SelectionDAGLowering BSDL(BSDAG, TLI, *AA, FuncInfo, GCI);
       // Set the current basic block to the mbb we wish to insert the code into
@@ -5128,7 +5480,8 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF,
   for (unsigned i = 0, e = JTCases.size(); i != e; ++i) {
     // Lower header first, if it wasn't already lowered
     if (!JTCases[i].first.Emitted) {
-      SelectionDAG HSDAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
+      SelectionDAG HSDAG(TLI, MF, FuncInfo, 
+                         getAnalysisToUpdate<MachineModuleInfo>());
       CurDAG = &HSDAG;
       SelectionDAGLowering HSDL(HSDAG, TLI, *AA, FuncInfo, GCI);
       // Set the current basic block to the mbb we wish to insert the code into
@@ -5140,7 +5493,8 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF,
       CodeGenAndEmitDAG(HSDAG);
     }
     
-    SelectionDAG JSDAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
+    SelectionDAG JSDAG(TLI, MF, FuncInfo, 
+                       getAnalysisToUpdate<MachineModuleInfo>());
     CurDAG = &JSDAG;
     SelectionDAGLowering JSDL(JSDAG, TLI, *AA, FuncInfo, GCI);
     // Set the current basic block to the mbb we wish to insert the code into
@@ -5188,7 +5542,8 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF,
   // If we generated any switch lowering information, build and codegen any
   // additional DAGs necessary.
   for (unsigned i = 0, e = SwitchCases.size(); i != e; ++i) {
-    SelectionDAG SDAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
+    SelectionDAG SDAG(TLI, MF, FuncInfo, 
+                      getAnalysisToUpdate<MachineModuleInfo>());
     CurDAG = &SDAG;
     SelectionDAGLowering SDL(SDAG, TLI, *AA, FuncInfo, GCI);