diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index f2b23d7..96456aa 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -221,7 +221,6 @@
     SDOperand visitBRCOND(SDNode *N);
     SDOperand visitBR_CC(SDNode *N);
     SDOperand visitLOAD(SDNode *N);
-    SDOperand visitLOADX(SDNode *N);
     SDOperand visitSTORE(SDNode *N);
     SDOperand visitINSERT_VECTOR_ELT(SDNode *N);
     SDOperand visitVINSERT_VECTOR_ELT(SDNode *N);
@@ -499,7 +498,6 @@
   case ISD::BRCOND:             return visitBRCOND(N);
   case ISD::BR_CC:              return visitBR_CC(N);
   case ISD::LOAD:               return visitLOAD(N);
-  case ISD::LOADX:              return visitLOADX(N);
   case ISD::STORE:              return visitSTORE(N);
   case ISD::INSERT_VECTOR_ELT:  return visitINSERT_VECTOR_ELT(N);
   case ISD::VINSERT_VECTOR_ELT: return visitVINSERT_VECTOR_ELT(N);
@@ -1078,14 +1076,15 @@
     return SDOperand(N, 0);
   // fold (zext_inreg (extload x)) -> (zextload x)
   if (ISD::isEXTLoad(N0.Val)) {
-    MVT::ValueType EVT = cast<VTSDNode>(N0.getOperand(3))->getVT();
+    LoadSDNode *LN0 = cast<LoadSDNode>(N0);
+    MVT::ValueType EVT = LN0->getLoadVT();
     // 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 (TLI.MaskedValueIsZero(N1, ~0ULL << MVT::getSizeInBits(EVT)) &&
         (!AfterLegalize || TLI.isLoadXLegal(ISD::ZEXTLOAD, EVT))) {
-      SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, N0.getOperand(0),
-                                         N0.getOperand(1), N0.getOperand(2),
-                                         EVT);
+      SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(),
+                                         LN0->getBasePtr(), LN0->getSrcValue(),
+                                         LN0->getSrcValueOffset(), EVT);
       AddToWorkList(N);
       CombineTo(N0.Val, ExtLoad, ExtLoad.getValue(1));
       return SDOperand(N, 0);   // Return N so it doesn't get rechecked!
@@ -1093,14 +1092,15 @@
   }
   // fold (zext_inreg (sextload x)) -> (zextload x) iff load has one use
   if (ISD::isSEXTLoad(N0.Val) && N0.hasOneUse()) {
-    MVT::ValueType EVT = cast<VTSDNode>(N0.getOperand(3))->getVT();
+    LoadSDNode *LN0 = cast<LoadSDNode>(N0);
+    MVT::ValueType EVT = LN0->getLoadVT();
     // 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 (TLI.MaskedValueIsZero(N1, ~0ULL << MVT::getSizeInBits(EVT)) &&
         (!AfterLegalize || TLI.isLoadXLegal(ISD::ZEXTLOAD, EVT))) {
-      SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, N0.getOperand(0),
-                                         N0.getOperand(1), N0.getOperand(2),
-                                         EVT);
+      SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(),
+                                         LN0->getBasePtr(), LN0->getSrcValue(),
+                                         LN0->getSrcValueOffset(), EVT);
       AddToWorkList(N);
       CombineTo(N0.Val, ExtLoad, ExtLoad.getValue(1));
       return SDOperand(N, 0);   // Return N so it doesn't get rechecked!
@@ -1109,41 +1109,41 @@
   
   // fold (and (load x), 255) -> (zextload x, i8)
   // fold (and (extload x, i16), 255) -> (zextload x, i8)
-  if (N1C &&
-      (N0.getOpcode() == ISD::LOAD || ISD::isEXTLoad(N0.Val) ||
-       ISD::isZEXTLoad(N0.Val)) &&
-      N0.hasOneUse()) {
-    MVT::ValueType EVT, LoadedVT;
-    if (N1C->getValue() == 255)
-      EVT = MVT::i8;
-    else if (N1C->getValue() == 65535)
-      EVT = MVT::i16;
-    else if (N1C->getValue() == ~0U)
-      EVT = MVT::i32;
-    else
-      EVT = MVT::Other;
+  if (N1C && N0.getOpcode() == ISD::LOAD) {
+    LoadSDNode *LN0 = cast<LoadSDNode>(N0);
+    if (LN0->getExtensionType() != ISD::SEXTLOAD &&
+        N0.hasOneUse()) {
+      MVT::ValueType EVT, LoadedVT;
+      if (N1C->getValue() == 255)
+        EVT = MVT::i8;
+      else if (N1C->getValue() == 65535)
+        EVT = MVT::i16;
+      else if (N1C->getValue() == ~0U)
+        EVT = MVT::i32;
+      else
+        EVT = MVT::Other;
     
-    LoadedVT = N0.getOpcode() == ISD::LOAD ? VT :
-                           cast<VTSDNode>(N0.getOperand(3))->getVT();
-    if (EVT != MVT::Other && LoadedVT > EVT &&
-        (!AfterLegalize || TLI.isLoadXLegal(ISD::ZEXTLOAD, EVT))) {
-      MVT::ValueType PtrType = N0.getOperand(1).getValueType();
-      // For big endian targets, we need to add an offset to the pointer to load
-      // the correct bytes.  For little endian systems, we merely need to read
-      // fewer bytes from the same pointer.
-      unsigned PtrOff =
-        (MVT::getSizeInBits(LoadedVT) - MVT::getSizeInBits(EVT)) / 8;
-      SDOperand NewPtr = N0.getOperand(1);
-      if (!TLI.isLittleEndian())
-        NewPtr = DAG.getNode(ISD::ADD, PtrType, NewPtr,
-                             DAG.getConstant(PtrOff, PtrType));
-      AddToWorkList(NewPtr.Val);
-      SDOperand Load =
-        DAG.getExtLoad(ISD::ZEXTLOAD, VT, N0.getOperand(0), NewPtr,
-                       N0.getOperand(2), EVT);
-      AddToWorkList(N);
-      CombineTo(N0.Val, Load, Load.getValue(1));
-      return SDOperand(N, 0);   // Return N so it doesn't get rechecked!
+      LoadedVT = LN0->getLoadVT();
+      if (EVT != MVT::Other && LoadedVT > EVT &&
+          (!AfterLegalize || TLI.isLoadXLegal(ISD::ZEXTLOAD, EVT))) {
+        MVT::ValueType PtrType = N0.getOperand(1).getValueType();
+        // For big endian targets, we need to add an offset to the pointer to
+        // load the correct bytes.  For little endian systems, we merely need to
+        // read fewer bytes from the same pointer.
+        unsigned PtrOff =
+          (MVT::getSizeInBits(LoadedVT) - MVT::getSizeInBits(EVT)) / 8;
+        SDOperand NewPtr = LN0->getBasePtr();
+        if (!TLI.isLittleEndian())
+          NewPtr = DAG.getNode(ISD::ADD, PtrType, NewPtr,
+                               DAG.getConstant(PtrOff, PtrType));
+        AddToWorkList(NewPtr.Val);
+        SDOperand Load =
+          DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(), NewPtr,
+                         LN0->getSrcValue(), LN0->getSrcValueOffset(), EVT);
+        AddToWorkList(N);
+        CombineTo(N0.Val, Load, Load.getValue(1));
+        return SDOperand(N, 0);   // Return N so it doesn't get rechecked!
+      }
     }
   }
   
@@ -1857,10 +1857,12 @@
   }
   
   // fold (sext (load x)) -> (sext (truncate (sextload x)))
-  if (N0.getOpcode() == ISD::LOAD && N0.hasOneUse() &&
+  if (ISD::isNON_EXTLoad(N0.Val) && N0.hasOneUse() &&
       (!AfterLegalize||TLI.isLoadXLegal(ISD::SEXTLOAD, N0.getValueType()))){
-    SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, N0.getOperand(0),
-                                       N0.getOperand(1), N0.getOperand(2),
+    LoadSDNode *LN0 = cast<LoadSDNode>(N0);
+    SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, LN0->getChain(),
+                                       LN0->getBasePtr(), LN0->getSrcValue(),
+                                       LN0->getSrcValueOffset(),
                                        N0.getValueType());
     CombineTo(N, ExtLoad);
     CombineTo(N0.Val, DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad),
@@ -1871,9 +1873,11 @@
   // fold (sext (sextload x)) -> (sext (truncate (sextload x)))
   // fold (sext ( extload x)) -> (sext (truncate (sextload x)))
   if ((ISD::isSEXTLoad(N0.Val) || ISD::isEXTLoad(N0.Val)) && N0.hasOneUse()) {
-    MVT::ValueType EVT = cast<VTSDNode>(N0.getOperand(3))->getVT();
-    SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, N0.getOperand(0),
-                                       N0.getOperand(1), N0.getOperand(2), EVT);
+    LoadSDNode *LN0 = cast<LoadSDNode>(N0);
+    MVT::ValueType EVT = LN0->getLoadVT();
+    SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, LN0->getChain(),
+                                       LN0->getBasePtr(), LN0->getSrcValue(),
+                                       LN0->getSrcValueOffset(), EVT);
     CombineTo(N, ExtLoad);
     CombineTo(N0.Val, DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad),
               ExtLoad.getValue(1));
@@ -1922,10 +1926,12 @@
   }
   
   // fold (zext (load x)) -> (zext (truncate (zextload x)))
-  if (N0.getOpcode() == ISD::LOAD && N0.hasOneUse() &&
+  if (ISD::isNON_EXTLoad(N0.Val) && N0.hasOneUse() &&
       (!AfterLegalize||TLI.isLoadXLegal(ISD::ZEXTLOAD, N0.getValueType()))) {
-    SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, N0.getOperand(0),
-                                       N0.getOperand(1), N0.getOperand(2),
+    LoadSDNode *LN0 = cast<LoadSDNode>(N0);
+    SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(),
+                                       LN0->getBasePtr(), LN0->getSrcValue(),
+                                       LN0->getSrcValueOffset(),
                                        N0.getValueType());
     CombineTo(N, ExtLoad);
     CombineTo(N0.Val, DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad),
@@ -1936,9 +1942,11 @@
   // fold (zext (zextload x)) -> (zext (truncate (zextload x)))
   // fold (zext ( extload x)) -> (zext (truncate (zextload x)))
   if ((ISD::isZEXTLoad(N0.Val) || ISD::isEXTLoad(N0.Val)) && N0.hasOneUse()) {
-    MVT::ValueType EVT = cast<VTSDNode>(N0.getOperand(3))->getVT();
-    SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, N0.getOperand(0),
-                                       N0.getOperand(1), N0.getOperand(2), EVT);
+    LoadSDNode *LN0 = cast<LoadSDNode>(N0);
+    MVT::ValueType EVT = LN0->getLoadVT();
+    SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(),
+                                       LN0->getBasePtr(), LN0->getSrcValue(),
+                                       LN0->getSrcValueOffset(), EVT);
     CombineTo(N, ExtLoad);
     CombineTo(N0.Val, DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad),
               ExtLoad.getValue(1));
@@ -1987,10 +1995,12 @@
   }
   
   // fold (aext (load x)) -> (aext (truncate (extload x)))
-  if (N0.getOpcode() == ISD::LOAD && N0.hasOneUse() &&
+  if (ISD::isNON_EXTLoad(N0.Val) && N0.hasOneUse() &&
       (!AfterLegalize||TLI.isLoadXLegal(ISD::EXTLOAD, N0.getValueType()))) {
-    SDOperand ExtLoad = DAG.getExtLoad(ISD::EXTLOAD, VT, N0.getOperand(0),
-                                       N0.getOperand(1), N0.getOperand(2),
+    LoadSDNode *LN0 = cast<LoadSDNode>(N0);
+    SDOperand ExtLoad = DAG.getExtLoad(ISD::EXTLOAD, VT, LN0->getChain(),
+                                       LN0->getBasePtr(), LN0->getSrcValue(),
+                                       LN0->getSrcValueOffset(),
                                        N0.getValueType());
     CombineTo(N, ExtLoad);
     CombineTo(N0.Val, DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad),
@@ -2001,12 +2011,14 @@
   // fold (aext (zextload x)) -> (aext (truncate (zextload x)))
   // fold (aext (sextload x)) -> (aext (truncate (sextload x)))
   // fold (aext ( extload x)) -> (aext (truncate (extload  x)))
-  if (N0.getOpcode() == ISD::LOADX && N0.hasOneUse()) {
-    MVT::ValueType EVT = cast<VTSDNode>(N0.getOperand(3))->getVT();
-    unsigned LType = N0.getConstantOperandVal(4);
-    SDOperand ExtLoad = DAG.getExtLoad((ISD::LoadExtType)LType, VT,
-                                       N0.getOperand(0), N0.getOperand(1),
-                                       N0.getOperand(2), EVT);
+  if (N0.getOpcode() == ISD::LOAD && !ISD::isNON_EXTLoad(N0.Val) &&
+      N0.hasOneUse()) {
+    LoadSDNode *LN0 = cast<LoadSDNode>(N0);
+    MVT::ValueType EVT = LN0->getLoadVT();
+    SDOperand ExtLoad = DAG.getExtLoad(LN0->getExtensionType(), VT,
+                                       LN0->getChain(), LN0->getBasePtr(),
+                                       LN0->getSrcValue(),
+                                       LN0->getSrcValueOffset(), EVT);
     CombineTo(N, ExtLoad);
     CombineTo(N0.Val, DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad),
               ExtLoad.getValue(1));
@@ -2057,22 +2069,24 @@
   
   // fold (sext_inreg (extload x)) -> (sextload x)
   if (ISD::isEXTLoad(N0.Val) && 
-      EVT == cast<VTSDNode>(N0.getOperand(3))->getVT() &&
+      EVT == cast<LoadSDNode>(N0)->getLoadVT() &&
       (!AfterLegalize || TLI.isLoadXLegal(ISD::SEXTLOAD, EVT))) {
-    SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, N0.getOperand(0),
-                                       N0.getOperand(1), N0.getOperand(2),
-                                       EVT);
+    LoadSDNode *LN0 = cast<LoadSDNode>(N0);
+    SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, LN0->getChain(),
+                                       LN0->getBasePtr(), LN0->getSrcValue(),
+                                       LN0->getSrcValueOffset(), EVT);
     CombineTo(N, ExtLoad);
     CombineTo(N0.Val, ExtLoad, ExtLoad.getValue(1));
     return SDOperand(N, 0);   // Return N so it doesn't get rechecked!
   }
   // fold (sext_inreg (zextload x)) -> (sextload x) iff load has one use
   if (ISD::isZEXTLoad(N0.Val) && N0.hasOneUse() &&
-      EVT == cast<VTSDNode>(N0.getOperand(3))->getVT() &&
+      EVT == cast<LoadSDNode>(N0)->getLoadVT() &&
       (!AfterLegalize || TLI.isLoadXLegal(ISD::SEXTLOAD, EVT))) {
-    SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, N0.getOperand(0),
-                                       N0.getOperand(1), N0.getOperand(2),
-                                       EVT);
+    LoadSDNode *LN0 = cast<LoadSDNode>(N0);
+    SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, LN0->getChain(),
+                                       LN0->getBasePtr(), LN0->getSrcValue(),
+                                       LN0->getSrcValueOffset(), EVT);
     CombineTo(N, ExtLoad);
     CombineTo(N0.Val, ExtLoad, ExtLoad.getValue(1));
     return SDOperand(N, 0);   // Return N so it doesn't get rechecked!
@@ -2108,20 +2122,22 @@
       return N0.getOperand(0);
   }
   // fold (truncate (load x)) -> (smaller load x)
-  if (N0.getOpcode() == ISD::LOAD && N0.hasOneUse()) {
+  if (ISD::isNON_EXTLoad(N0.Val) && N0.hasOneUse()) {
     assert(MVT::getSizeInBits(N0.getValueType()) > MVT::getSizeInBits(VT) &&
            "Cannot truncate to larger type!");
+    LoadSDNode *LN0 = cast<LoadSDNode>(N0);
     MVT::ValueType PtrType = N0.getOperand(1).getValueType();
     // For big endian targets, we need to add an offset to the pointer to load
     // the correct bytes.  For little endian systems, we merely need to read
     // fewer bytes from the same pointer.
     uint64_t PtrOff = 
       (MVT::getSizeInBits(N0.getValueType()) - MVT::getSizeInBits(VT)) / 8;
-    SDOperand NewPtr = TLI.isLittleEndian() ? N0.getOperand(1) : 
-      DAG.getNode(ISD::ADD, PtrType, N0.getOperand(1),
+    SDOperand NewPtr = TLI.isLittleEndian() ? LN0->getBasePtr() : 
+      DAG.getNode(ISD::ADD, PtrType, LN0->getBasePtr(),
                   DAG.getConstant(PtrOff, PtrType));
     AddToWorkList(NewPtr.Val);
-    SDOperand Load = DAG.getLoad(VT, N0.getOperand(0), NewPtr,N0.getOperand(2));
+    SDOperand Load = DAG.getLoad(VT, LN0->getChain(), NewPtr,
+                                 LN0->getSrcValue(), LN0->getSrcValueOffset());
     AddToWorkList(N);
     CombineTo(N0.Val, Load, Load.getValue(1));
     return SDOperand(N, 0);   // Return N so it doesn't get rechecked!
@@ -2145,9 +2161,10 @@
   // fold (conv (load x)) -> (load (conv*)x)
   // FIXME: These xforms need to know that the resultant load doesn't need a 
   // higher alignment than the original!
-  if (0 && N0.getOpcode() == ISD::LOAD && N0.hasOneUse()) {
-    SDOperand Load = DAG.getLoad(VT, N0.getOperand(0), N0.getOperand(1),
-                                 N0.getOperand(2));
+  if (0 && ISD::isNON_EXTLoad(N0.Val) && N0.hasOneUse()) {
+    LoadSDNode *LN0 = cast<LoadSDNode>(N0);
+    SDOperand Load = DAG.getLoad(VT, LN0->getChain(), LN0->getBasePtr(),
+                                 LN0->getSrcValue(), LN0->getSrcValueOffset());
     AddToWorkList(N);
     CombineTo(N0.Val, DAG.getNode(ISD::BIT_CONVERT, N0.getValueType(), Load),
               Load.getValue(1));
@@ -2517,10 +2534,12 @@
     return DAG.getNode(ISD::FP_EXTEND, VT, N0);
   
   // fold (fpext (load x)) -> (fpext (fpround (extload x)))
-  if (N0.getOpcode() == ISD::LOAD && N0.hasOneUse() &&
+  if (ISD::isNON_EXTLoad(N0.Val) && N0.hasOneUse() &&
       (!AfterLegalize||TLI.isLoadXLegal(ISD::EXTLOAD, N0.getValueType()))) {
-    SDOperand ExtLoad = DAG.getExtLoad(ISD::EXTLOAD, VT, N0.getOperand(0),
-                                       N0.getOperand(1), N0.getOperand(2),
+    LoadSDNode *LN0 = cast<LoadSDNode>(N0);
+    SDOperand ExtLoad = DAG.getExtLoad(ISD::EXTLOAD, VT, LN0->getChain(),
+                                       LN0->getBasePtr(), LN0->getSrcValue(),
+                                       LN0->getSrcValueOffset(),
                                        N0.getValueType());
     CombineTo(N, ExtLoad);
     CombineTo(N0.Val, DAG.getNode(ISD::FP_ROUND, N0.getValueType(), ExtLoad),
@@ -2616,15 +2635,18 @@
 }
 
 SDOperand DAGCombiner::visitLOAD(SDNode *N) {
-  SDOperand Chain    = N->getOperand(0);
-  SDOperand Ptr      = N->getOperand(1);
-  SDOperand SrcValue = N->getOperand(2);
+  LoadSDNode *LD  = cast<LoadSDNode>(N);
+  SDOperand Chain = LD->getChain();
+  SDOperand Ptr   = LD->getBasePtr();
   
   // If there are no uses of the loaded value, change uses of the chain value
   // into uses of the chain input (i.e. delete the dead load).
   if (N->hasNUsesOfValue(0, 0))
     return CombineTo(N, DAG.getNode(ISD::UNDEF, N->getValueType(0)), Chain);
   
+  if (!ISD::isNON_EXTLoad(N))
+    return SDOperand();
+
   // If this load is directly stored, replace the load value with the stored
   // value.
   // TODO: Handle store large -> read small portion.
@@ -2641,7 +2663,7 @@
     if (Chain != BetterChain) {
       // Replace the chain to void dependency.
       SDOperand ReplLoad = DAG.getLoad(N->getValueType(0), BetterChain, Ptr,
-                                       SrcValue);
+                                    LD->getSrcValue(), LD->getSrcValueOffset());
 
       // Create token factor to keep old chain connected.
       SDOperand Token = DAG.getNode(ISD::TokenFactor, MVT::Other,
@@ -2655,21 +2677,6 @@
   return SDOperand();
 }
 
-/// visitLOADX - Handle EXTLOAD/ZEXTLOAD/SEXTLOAD.
-SDOperand DAGCombiner::visitLOADX(SDNode *N) {
-  SDOperand Chain    = N->getOperand(0);
-  SDOperand Ptr      = N->getOperand(1);
-  SDOperand SrcValue = N->getOperand(2);
-  SDOperand EVT      = N->getOperand(3);
-  
-  // If there are no uses of the loaded value, change uses of the chain value
-  // into uses of the chain input (i.e. delete the dead load).
-  if (N->hasNUsesOfValue(0, 0))
-    return CombineTo(N, DAG.getNode(ISD::UNDEF, N->getValueType(0)), Chain);
-  
-  return SDOperand();
-}
-
 SDOperand DAGCombiner::visitSTORE(SDNode *N) {
   SDOperand Chain    = N->getOperand(0);
   SDOperand Value    = N->getOperand(1);
@@ -3268,47 +3275,49 @@
     // of two loads with a load through a select of the address to load from.
     // This triggers in things like "select bool X, 10.0, 123.0" after the FP
     // constants have been dropped into the constant pool.
-    if ((LHS.getOpcode() == ISD::LOAD ||
-         LHS.getOpcode() == ISD::LOADX ) &&
+    if (LHS.getOpcode() == ISD::LOAD &&
         // Token chains must be identical.
-        LHS.getOperand(0) == RHS.getOperand(0) &&
-        // If this is an EXTLOAD, the VT's must match.
-        (LHS.getOpcode() == ISD::LOAD ||
-         LHS.getOperand(3) == RHS.getOperand(3))) {
-      // FIXME: this conflates two src values, discarding one.  This is not
-      // the right thing to do, but nothing uses srcvalues now.  When they do,
-      // turn SrcValue into a list of locations.
-      SDOperand Addr;
-      if (TheSelect->getOpcode() == ISD::SELECT)
-        Addr = DAG.getNode(ISD::SELECT, LHS.getOperand(1).getValueType(),
-                           TheSelect->getOperand(0), LHS.getOperand(1),
-                           RHS.getOperand(1));
-      else
-        Addr = DAG.getNode(ISD::SELECT_CC, LHS.getOperand(1).getValueType(),
-                           TheSelect->getOperand(0),
-                           TheSelect->getOperand(1), 
-                           LHS.getOperand(1), RHS.getOperand(1),
-                           TheSelect->getOperand(4));
+        LHS.getOperand(0) == RHS.getOperand(0)) {
+      LoadSDNode *LLD = cast<LoadSDNode>(LHS);
+      LoadSDNode *RLD = cast<LoadSDNode>(RHS);
+
+      // If this is an EXTLOAD, the VT's must match.
+      if (LLD->getLoadVT() == RLD->getLoadVT()) {
+        // FIXME: this conflates two src values, discarding one.  This is not
+        // the right thing to do, but nothing uses srcvalues now.  When they do,
+        // turn SrcValue into a list of locations.
+        SDOperand Addr;
+        if (TheSelect->getOpcode() == ISD::SELECT)
+          Addr = DAG.getNode(ISD::SELECT, LLD->getBasePtr().getValueType(),
+                             TheSelect->getOperand(0), LLD->getBasePtr(),
+                             RLD->getBasePtr());
+        else
+          Addr = DAG.getNode(ISD::SELECT_CC, LLD->getBasePtr().getValueType(),
+                             TheSelect->getOperand(0),
+                             TheSelect->getOperand(1), 
+                             LLD->getBasePtr(), RLD->getBasePtr(),
+                             TheSelect->getOperand(4));
       
-      SDOperand Load;
-      if (LHS.getOpcode() == ISD::LOAD)
-        Load = DAG.getLoad(TheSelect->getValueType(0), LHS.getOperand(0),
-                           Addr, LHS.getOperand(2));
-      else {
-        unsigned LType = LHS.getConstantOperandVal(4);
-        Load = DAG.getExtLoad((ISD::LoadExtType)LType,
-                              TheSelect->getValueType(0),
-                              LHS.getOperand(0), Addr, LHS.getOperand(2),
-                              cast<VTSDNode>(LHS.getOperand(3))->getVT());
+        SDOperand Load;
+        if (LLD->getExtensionType() == ISD::NON_EXTLOAD)
+          Load = DAG.getLoad(TheSelect->getValueType(0), LLD->getChain(),
+                             Addr,LLD->getSrcValue(), LLD->getSrcValueOffset());
+        else {
+          Load = DAG.getExtLoad(LLD->getExtensionType(),
+                                TheSelect->getValueType(0),
+                                LLD->getChain(), Addr, LLD->getSrcValue(),
+                                LLD->getSrcValueOffset(),
+                                LLD->getLoadVT());
+        }
+        // Users of the select now use the result of the load.
+        CombineTo(TheSelect, Load);
+      
+        // Users of the old loads now use the new load's chain.  We know the
+        // old-load value is dead now.
+        CombineTo(LHS.Val, Load.getValue(0), Load.getValue(1));
+        CombineTo(RHS.Val, Load.getValue(0), Load.getValue(1));
+        return true;
       }
-      // Users of the select now use the result of the load.
-      CombineTo(TheSelect, Load);
-      
-      // Users of the old loads now use the new load's chain.  We know the
-      // old-load value is dead now.
-      CombineTo(LHS.Val, Load.getValue(0), Load.getValue(1));
-      CombineTo(RHS.Val, Load.getValue(0), Load.getValue(1));
-      return true;
     }
   }
   
@@ -3965,10 +3974,12 @@
 
 /// FindAliasInfo - Extracts the relevant alias information from the memory
 /// node.  Returns true if the operand was a load.
-static bool FindAliasInfo(SDNode *N,
-                          SDOperand &Ptr, int64_t &Size, SDOperand &SrcValue) {
+static bool FindAliasInfo(SDNode *N, SDOperand &Ptr, int64_t &Size,
+                          SDOperand &SrcValue, SelectionDAG &DAG) {
   switch (N->getOpcode()) {
   case ISD::LOAD:
+    if (!ISD::isNON_EXTLoad(N))
+      return false;
     Ptr = N->getOperand(1);
     Size = MVT::getSizeInBits(N->getValueType(0)) >> 3;
     SrcValue = N->getOperand(2);
@@ -3997,7 +4008,7 @@
   SDOperand Ptr;
   int64_t Size;
   SDOperand SrcValue;
-  bool IsLoad = FindAliasInfo(N, Ptr, Size, SrcValue);
+  bool IsLoad = FindAliasInfo(N, Ptr, Size, SrcValue, DAG);
 
   // Starting off.
   Chains.push_back(OriginalChain);
@@ -4024,7 +4035,7 @@
       SDOperand OpPtr;
       int64_t OpSize;
       SDOperand OpSrcValue;
-      bool IsOpLoad = FindAliasInfo(Chain.Val, OpPtr, OpSize, OpSrcValue);
+      bool IsOpLoad = FindAliasInfo(Chain.Val, OpPtr, OpSize, OpSrcValue, DAG);
       
       // If chain is alias then stop here.
       if (!(IsLoad && IsOpLoad) &&
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 71f1c24..a3adb55 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -808,10 +808,9 @@
       SDOperand CPIdx = DAG.getConstantPool(LLVMC, TLI.getPointerTy());
       if (Extend) {
         Result = DAG.getExtLoad(ISD::EXTLOAD, MVT::f64, DAG.getEntryNode(),
-                                CPIdx, DAG.getSrcValue(NULL), MVT::f32);
+                                CPIdx, NULL, 0, MVT::f32);
       } else {
-        Result = DAG.getLoad(VT, DAG.getEntryNode(), CPIdx,
-                             DAG.getSrcValue(NULL));
+        Result = DAG.getLoad(VT, DAG.getEntryNode(), CPIdx, NULL, 0);
       }
     }
     break;
@@ -941,7 +940,7 @@
       // Store the scalar value.
       Ch = DAG.getStore(Ch, Tmp2, StackPtr2, DAG.getSrcValue(NULL));
       // Load the updated vector.
-      Result = DAG.getLoad(VT, Ch, StackPtr, DAG.getSrcValue(NULL));
+      Result = DAG.getLoad(VT, Ch, StackPtr, NULL, 0);
       break;
     }
     }
@@ -1335,104 +1334,106 @@
     }
     break;
   case ISD::LOAD: {
-    Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
-    Tmp2 = LegalizeOp(Node->getOperand(1));  // Legalize the pointer.
+    LoadSDNode *LD = cast<LoadSDNode>(Node);
+    Tmp1 = LegalizeOp(LD->getChain());   // Legalize the chain.
+    Tmp2 = LegalizeOp(LD->getBasePtr()); // Legalize the base pointer.
 
-    MVT::ValueType VT = Node->getValueType(0);
-    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Node->getOperand(2));
-    Tmp3 = Result.getValue(0);
-    Tmp4 = Result.getValue(1);
+    ISD::LoadExtType ExtType = LD->getExtensionType();
+    if (ExtType == ISD::NON_EXTLOAD) {
+      MVT::ValueType VT = Node->getValueType(0);
+      Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, LD->getOffset());
+      Tmp3 = Result.getValue(0);
+      Tmp4 = Result.getValue(1);
     
-    switch (TLI.getOperationAction(Node->getOpcode(), VT)) {
-    default: assert(0 && "This action is not supported yet!");
-    case TargetLowering::Legal: break;
-    case TargetLowering::Custom:
-      Tmp1 = TLI.LowerOperation(Tmp3, DAG);
-      if (Tmp1.Val) {
-        Tmp3 = LegalizeOp(Tmp1);
-        Tmp4 = LegalizeOp(Tmp1.getValue(1));
-      }
-      break;
-    case TargetLowering::Promote: {
-      // Only promote a load of vector type to another.
-      assert(MVT::isVector(VT) && "Cannot promote this load!");
-      // Change base type to a different vector type.
-      MVT::ValueType NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VT);
-
-      Tmp1 = DAG.getLoad(NVT, Tmp1, Tmp2, Node->getOperand(2));
-      Tmp3 = LegalizeOp(DAG.getNode(ISD::BIT_CONVERT, VT, Tmp1));
-      Tmp4 = LegalizeOp(Tmp1.getValue(1));
-      break;
-    }
-    }
-    // Since loads produce two values, make sure to remember that we 
-    // legalized both of them.
-    AddLegalizedOperand(SDOperand(Node, 0), Tmp3);
-    AddLegalizedOperand(SDOperand(Node, 1), Tmp4);
-    return Op.ResNo ? Tmp4 : Tmp3;
-  }
-  case ISD::LOADX: {
-    Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
-    Tmp2 = LegalizeOp(Node->getOperand(1));  // Legalize the pointer.
-
-    MVT::ValueType SrcVT = cast<VTSDNode>(Node->getOperand(3))->getVT();
-    unsigned LType = cast<ConstantSDNode>(Node->getOperand(4))->getValue();
-    switch (TLI.getLoadXAction(LType, SrcVT)) {
-    default: assert(0 && "This action is not supported yet!");
-    case TargetLowering::Promote:
-      assert(SrcVT == MVT::i1 && "Can only promote LOADX from i1 -> i8!");
-      Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Node->getOperand(2),
-                                      DAG.getValueType(MVT::i8),
-                                      Node->getOperand(4));
-      Tmp1 = Result.getValue(0);
-      Tmp2 = Result.getValue(1);
-      break;
-    case TargetLowering::Custom:
-      isCustom = true;
-      // FALLTHROUGH
-    case TargetLowering::Legal:
-      Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Node->getOperand(2),
-                                      Node->getOperand(3), Node->getOperand(4));
-      Tmp1 = Result.getValue(0);
-      Tmp2 = Result.getValue(1);
-      
-      if (isCustom) {
-        Tmp3 = TLI.LowerOperation(Result, DAG);
-        if (Tmp3.Val) {
-          Tmp1 = LegalizeOp(Tmp3);
-          Tmp2 = LegalizeOp(Tmp3.getValue(1));
+      switch (TLI.getOperationAction(Node->getOpcode(), VT)) {
+      default: assert(0 && "This action is not supported yet!");
+      case TargetLowering::Legal: break;
+      case TargetLowering::Custom:
+        Tmp1 = TLI.LowerOperation(Tmp3, DAG);
+        if (Tmp1.Val) {
+          Tmp3 = LegalizeOp(Tmp1);
+          Tmp4 = LegalizeOp(Tmp1.getValue(1));
         }
-      }
-      break;
-    case TargetLowering::Expand:
-      // f64 = EXTLOAD f32 should expand to LOAD, FP_EXTEND
-      if (SrcVT == MVT::f32 && Node->getValueType(0) == MVT::f64) {
-        SDOperand Load = DAG.getLoad(SrcVT, Tmp1, Tmp2, Node->getOperand(2));
-        Result = DAG.getNode(ISD::FP_EXTEND, Node->getValueType(0), Load);
-        Tmp1 = LegalizeOp(Result);  // Relegalize new nodes.
-        Tmp2 = LegalizeOp(Load.getValue(1));
+        break;
+      case TargetLowering::Promote: {
+        // Only promote a load of vector type to another.
+        assert(MVT::isVector(VT) && "Cannot promote this load!");
+        // Change base type to a different vector type.
+        MVT::ValueType NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VT);
+
+        Tmp1 = DAG.getLoad(NVT, Tmp1, Tmp2, LD->getSrcValue(),
+                           LD->getSrcValueOffset());
+        Tmp3 = LegalizeOp(DAG.getNode(ISD::BIT_CONVERT, VT, Tmp1));
+        Tmp4 = LegalizeOp(Tmp1.getValue(1));
         break;
       }
-      assert(LType != ISD::EXTLOAD && "EXTLOAD should always be supported!");
-      // Turn the unsupported load into an EXTLOAD followed by an explicit
-      // zero/sign extend inreg.
-      Result = DAG.getExtLoad(ISD::EXTLOAD, Node->getValueType(0),
-                              Tmp1, Tmp2, Node->getOperand(2), SrcVT);
-      SDOperand ValRes;
-      if (LType == ISD::SEXTLOAD)
-        ValRes = DAG.getNode(ISD::SIGN_EXTEND_INREG, Result.getValueType(),
-                             Result, DAG.getValueType(SrcVT));
-      else
-        ValRes = DAG.getZeroExtendInReg(Result, SrcVT);
-      Tmp1 = LegalizeOp(ValRes);  // Relegalize new nodes.
-      Tmp2 = LegalizeOp(Result.getValue(1));  // Relegalize new nodes.
+      }
+      // Since loads produce two values, make sure to remember that we 
+      // legalized both of them.
+      AddLegalizedOperand(SDOperand(Node, 0), Tmp3);
+      AddLegalizedOperand(SDOperand(Node, 1), Tmp4);
+      return Op.ResNo ? Tmp4 : Tmp3;
+    } else {
+      MVT::ValueType SrcVT = LD->getLoadVT();
+      switch (TLI.getLoadXAction(ExtType, SrcVT)) {
+      default: assert(0 && "This action is not supported yet!");
+      case TargetLowering::Promote:
+        assert(SrcVT == MVT::i1 &&
+               "Can only promote extending LOAD from i1 -> i8!");
+        Result = DAG.getExtLoad(ExtType, Node->getValueType(0), Tmp1, Tmp2,
+                                LD->getSrcValue(), LD->getSrcValueOffset(),
+                                MVT::i8);
+      Tmp1 = Result.getValue(0);
+      Tmp2 = Result.getValue(1);
       break;
+      case TargetLowering::Custom:
+        isCustom = true;
+        // FALLTHROUGH
+      case TargetLowering::Legal:
+        Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, LD->getOffset());
+        Tmp1 = Result.getValue(0);
+        Tmp2 = Result.getValue(1);
+      
+        if (isCustom) {
+          Tmp3 = TLI.LowerOperation(Result, DAG);
+          if (Tmp3.Val) {
+            Tmp1 = LegalizeOp(Tmp3);
+            Tmp2 = LegalizeOp(Tmp3.getValue(1));
+          }
+        }
+        break;
+      case TargetLowering::Expand:
+        // f64 = EXTLOAD f32 should expand to LOAD, FP_EXTEND
+        if (SrcVT == MVT::f32 && Node->getValueType(0) == MVT::f64) {
+          SDOperand Load = DAG.getLoad(SrcVT, Tmp1, Tmp2, LD->getSrcValue(),
+                                       LD->getSrcValueOffset());
+          Result = DAG.getNode(ISD::FP_EXTEND, Node->getValueType(0), Load);
+          Tmp1 = LegalizeOp(Result);  // Relegalize new nodes.
+          Tmp2 = LegalizeOp(Load.getValue(1));
+          break;
+        }
+        assert(ExtType != ISD::EXTLOAD && "EXTLOAD should always be supported!");
+        // Turn the unsupported load into an EXTLOAD followed by an explicit
+        // zero/sign extend inreg.
+        Result = DAG.getExtLoad(ISD::EXTLOAD, Node->getValueType(0),
+                                Tmp1, Tmp2, LD->getSrcValue(),
+                                LD->getSrcValueOffset(), SrcVT);
+        SDOperand ValRes;
+        if (ExtType == ISD::SEXTLOAD)
+          ValRes = DAG.getNode(ISD::SIGN_EXTEND_INREG, Result.getValueType(),
+                               Result, DAG.getValueType(SrcVT));
+        else
+          ValRes = DAG.getZeroExtendInReg(Result, SrcVT);
+        Tmp1 = LegalizeOp(ValRes);  // Relegalize new nodes.
+        Tmp2 = LegalizeOp(Result.getValue(1));  // Relegalize new nodes.
+        break;
+      }
+      // Since loads produce two values, make sure to remember that we legalized
+      // both of them.
+      AddLegalizedOperand(SDOperand(Node, 0), Tmp1);
+      AddLegalizedOperand(SDOperand(Node, 1), Tmp2);
+      return Op.ResNo ? Tmp2 : Tmp1;
     }
-    // Since loads produce two values, make sure to remember that we legalized
-    // both of them.
-    AddLegalizedOperand(SDOperand(Node, 0), Tmp1);
-    AddLegalizedOperand(SDOperand(Node, 1), Tmp2);
-    return Op.ResNo ? Tmp2 : Tmp1;
   }
   case ISD::EXTRACT_ELEMENT: {
     MVT::ValueType OpTy = Node->getOperand(0).getValueType();
@@ -2387,8 +2388,9 @@
       }
       break;
     case TargetLowering::Expand: {
+      SrcValueSDNode *SV = cast<SrcValueSDNode>(Node->getOperand(2));
       SDOperand VAList = DAG.getLoad(TLI.getPointerTy(), Tmp1, Tmp2,
-                                     Node->getOperand(2));
+                                     SV->getValue(), SV->getOffset());
       // Increment the pointer, VAList, to the next vaarg
       Tmp3 = DAG.getNode(ISD::ADD, TLI.getPointerTy(), VAList, 
                          DAG.getConstant(MVT::getSizeInBits(VT)/8, 
@@ -2396,7 +2398,7 @@
       // Store the incremented VAList to the legalized pointer
       Tmp3 = DAG.getStore(VAList.getValue(1), Tmp3, Tmp2,  Node->getOperand(2));
       // Load the actual argument out of the pointer VAList
-      Result = DAG.getLoad(VT, Tmp3, VAList, DAG.getSrcValue(0));
+      Result = DAG.getLoad(VT, Tmp3, VAList, NULL, 0);
       Tmp1 = LegalizeOp(Result.getValue(1));
       Result = LegalizeOp(Result);
       break;
@@ -2430,7 +2432,10 @@
     case TargetLowering::Expand:
       // This defaults to loading a pointer from the input and storing it to the
       // output, returning the chain.
-      Tmp4 = DAG.getLoad(TLI.getPointerTy(), Tmp1, Tmp3, Node->getOperand(3));
+      SrcValueSDNode *SVD = cast<SrcValueSDNode>(Node->getOperand(3));
+      SrcValueSDNode *SVS = cast<SrcValueSDNode>(Node->getOperand(4));
+      Tmp4 = DAG.getLoad(TLI.getPointerTy(), Tmp1, Tmp3, SVD->getValue(),
+                         SVD->getOffset());
       Result = DAG.getStore(Tmp4.getValue(1), Tmp4, Tmp2, Node->getOperand(4));
       break;
     }
@@ -2874,8 +2879,7 @@
                              Node->getOperand(0), StackSlot,
                              DAG.getSrcValue(NULL), DAG.getValueType(ExtraVT));
         Result = DAG.getExtLoad(ISD::EXTLOAD, Node->getValueType(0),
-                                Result, StackSlot, DAG.getSrcValue(NULL),
-                                ExtraVT);
+                                Result, StackSlot, NULL, 0, ExtraVT);
       } else {
         assert(0 && "Unknown op");
       }
@@ -3212,8 +3216,9 @@
       Tmp3 = DAG.getVAArg(VT, Tmp1, Tmp2, Node->getOperand(2));
       Result = TLI.CustomPromoteOperation(Tmp3, DAG);
     } else {
+      SrcValueSDNode *SV = cast<SrcValueSDNode>(Node->getOperand(2));
       SDOperand VAList = DAG.getLoad(TLI.getPointerTy(), Tmp1, Tmp2,
-                                     Node->getOperand(2));
+                                     SV->getValue(), SV->getOffset());
       // Increment the pointer, VAList, to the next vaarg
       Tmp3 = DAG.getNode(ISD::ADD, TLI.getPointerTy(), VAList, 
                          DAG.getConstant(MVT::getSizeInBits(VT)/8, 
@@ -3221,28 +3226,20 @@
       // Store the incremented VAList to the legalized pointer
       Tmp3 = DAG.getStore(VAList.getValue(1), Tmp3, Tmp2, Node->getOperand(2));
       // Load the actual argument out of the pointer VAList
-      Result = DAG.getExtLoad(ISD::EXTLOAD, NVT, Tmp3, VAList,
-                              DAG.getSrcValue(0), VT);
+      Result = DAG.getExtLoad(ISD::EXTLOAD, NVT, Tmp3, VAList, NULL, 0, VT);
     }
     // Remember that we legalized the chain.
     AddLegalizedOperand(Op.getValue(1), LegalizeOp(Result.getValue(1)));
     break;
 
-  case ISD::LOAD:
-    Result = DAG.getExtLoad(ISD::EXTLOAD, NVT, Node->getOperand(0),
-                            Node->getOperand(1), Node->getOperand(2), VT);
+  case ISD::LOAD: {
+    LoadSDNode *LD = cast<LoadSDNode>(Node);
+    Result = DAG.getExtLoad(ISD::EXTLOAD, NVT, LD->getChain(), LD->getBasePtr(),
+                            LD->getSrcValue(), LD->getSrcValueOffset(), VT);
     // Remember that we legalized the chain.
     AddLegalizedOperand(Op.getValue(1), LegalizeOp(Result.getValue(1)));
     break;
-  case ISD::LOADX:
-    Result =
-      DAG.getExtLoad((ISD::LoadExtType)Node->getConstantOperandVal(4),
-                     NVT, Node->getOperand(0), Node->getOperand(1),
-                     Node->getOperand(2),
-                     cast<VTSDNode>(Node->getOperand(3))->getVT());
-    // Remember that we legalized the chain.
-    AddLegalizedOperand(Op.getValue(1), LegalizeOp(Result.getValue(1)));
-    break;
+  }
   case ISD::SELECT:
     Tmp2 = PromoteOp(Node->getOperand(1));   // Legalize the op0
     Tmp3 = PromoteOp(Node->getOperand(2));   // Legalize the op1
@@ -3370,7 +3367,7 @@
                     DAG.getConstant(EltSize, Idx.getValueType()));
   StackPtr = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx, StackPtr);
   
-  return DAG.getLoad(Op.getValueType(), Ch, StackPtr, DAG.getSrcValue(NULL));
+  return DAG.getLoad(Op.getValueType(), Ch, StackPtr, NULL, 0);
 }
 
 
@@ -3508,7 +3505,7 @@
   SDOperand Store = DAG.getStore(DAG.getEntryNode(),
                                  SrcOp, FIPtr, DAG.getSrcValue(NULL));
   // Result is a load from the stack slot.
-  return DAG.getLoad(DestVT, Store, FIPtr, DAG.getSrcValue(0));
+  return DAG.getLoad(DestVT, Store, FIPtr, NULL, 0);
 }
 
 SDOperand SelectionDAGLegalize::ExpandSCALAR_TO_VECTOR(SDNode *Node) {
@@ -3517,7 +3514,7 @@
   SDOperand StackPtr = CreateStackTemporary(Node->getValueType(0));
   SDOperand Ch = DAG.getStore(DAG.getEntryNode(), Node->getOperand(0), StackPtr,
                               DAG.getSrcValue(NULL));
-  return DAG.getLoad(Node->getValueType(0), Ch, StackPtr,DAG.getSrcValue(NULL));
+  return DAG.getLoad(Node->getValueType(0), Ch, StackPtr, NULL, 0);
 }
 
 
@@ -3581,8 +3578,7 @@
     }
     Constant *CP = ConstantPacked::get(CV);
     SDOperand CPIdx = DAG.getConstantPool(CP, TLI.getPointerTy());
-    return DAG.getLoad(VT, DAG.getEntryNode(), CPIdx,
-                       DAG.getSrcValue(NULL));
+    return DAG.getLoad(VT, DAG.getEntryNode(), CPIdx, NULL, 0);
   }
   
   if (SplatValue.Val) {   // Splat of one value?
@@ -3677,7 +3673,7 @@
     StoreChain = DAG.getEntryNode();
   
   // Result is a load from the stack slot.
-  return DAG.getLoad(VT, StoreChain, FIPtr, DAG.getSrcValue(0));
+  return DAG.getLoad(VT, StoreChain, FIPtr, NULL, 0);
 }
 
 /// CreateStackTemporary - Create a stack temporary, suitable for holding the
@@ -3933,12 +3929,11 @@
     CPIdx = DAG.getNode(ISD::ADD, TLI.getPointerTy(), CPIdx, CstOffset);
     SDOperand FudgeInReg;
     if (DestTy == MVT::f32)
-      FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx,
-                               DAG.getSrcValue(NULL));
+      FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx, NULL, 0);
     else {
       assert(DestTy == MVT::f64 && "Unexpected conversion");
       FudgeInReg = DAG.getExtLoad(ISD::EXTLOAD, MVT::f64, DAG.getEntryNode(),
-                                  CPIdx, DAG.getSrcValue(NULL), MVT::f32);
+                                  CPIdx, NULL, 0, MVT::f32);
     }
     return DAG.getNode(ISD::FADD, DestTy, SignedConv, FudgeInReg);
   }
@@ -4017,8 +4012,7 @@
     // store the hi of the constructed double - biased exponent
     SDOperand Store2=DAG.getStore(Store1, InitialHi, Hi, DAG.getSrcValue(NULL));
     // load the constructed double
-    SDOperand Load = DAG.getLoad(MVT::f64, Store2, StackSlot,
-                               DAG.getSrcValue(NULL));
+    SDOperand Load = DAG.getLoad(MVT::f64, Store2, StackSlot, NULL, 0);
     // FP constant to bias correct the final result
     SDOperand Bias = DAG.getConstantFP(isSigned ?
                                             BitsToDouble(0x4330000080000000ULL)
@@ -4066,13 +4060,12 @@
   CPIdx = DAG.getNode(ISD::ADD, TLI.getPointerTy(), CPIdx, CstOffset);
   SDOperand FudgeInReg;
   if (DestVT == MVT::f32)
-    FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx,
-                             DAG.getSrcValue(NULL));
+    FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx, NULL, 0);
   else {
     assert(DestVT == MVT::f64 && "Unexpected conversion");
     FudgeInReg = LegalizeOp(DAG.getExtLoad(ISD::EXTLOAD, MVT::f64,
                                            DAG.getEntryNode(), CPIdx,
-                                           DAG.getSrcValue(NULL), MVT::f32));
+                                           NULL, 0, MVT::f32));
   }
 
   return DAG.getNode(ISD::FADD, DestVT, Tmp1, FudgeInReg);
@@ -4420,26 +4413,57 @@
   }
     
   case ISD::LOAD: {
-    SDOperand Ch = Node->getOperand(0);   // Legalize the chain.
-    SDOperand Ptr = Node->getOperand(1);  // Legalize the pointer.
-    Lo = DAG.getLoad(NVT, Ch, Ptr, Node->getOperand(2));
+    LoadSDNode *LD = cast<LoadSDNode>(Node);
+    SDOperand Ch  = LD->getChain();    // Legalize the chain.
+    SDOperand Ptr = LD->getBasePtr();  // Legalize the pointer.
+    ISD::LoadExtType ExtType = LD->getExtensionType();
 
-    // Increment the pointer to the other half.
-    unsigned IncrementSize = MVT::getSizeInBits(Lo.getValueType())/8;
-    Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
-                      getIntPtrConstant(IncrementSize));
-    // FIXME: This creates a bogus srcvalue!
-    Hi = DAG.getLoad(NVT, Ch, Ptr, Node->getOperand(2));
+    if (ExtType == ISD::NON_EXTLOAD) {
+      Lo = DAG.getLoad(NVT, Ch, Ptr, LD->getSrcValue(), LD->getSrcValueOffset());
 
-    // Build a factor node to remember that this load is independent of the
-    // other one.
-    SDOperand TF = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
-                               Hi.getValue(1));
+      // Increment the pointer to the other half.
+      unsigned IncrementSize = MVT::getSizeInBits(Lo.getValueType())/8;
+      Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+                        getIntPtrConstant(IncrementSize));
+      // FIXME: This creates a bogus srcvalue!
+      Hi = DAG.getLoad(NVT, Ch, Ptr, LD->getSrcValue(), LD->getSrcValueOffset());
 
-    // Remember that we legalized the chain.
-    AddLegalizedOperand(Op.getValue(1), LegalizeOp(TF));
-    if (!TLI.isLittleEndian())
-      std::swap(Lo, Hi);
+      // Build a factor node to remember that this load is independent of the
+      // other one.
+      SDOperand TF = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
+                                 Hi.getValue(1));
+
+      // Remember that we legalized the chain.
+      AddLegalizedOperand(Op.getValue(1), LegalizeOp(TF));
+      if (!TLI.isLittleEndian())
+        std::swap(Lo, Hi);
+    } else {
+      MVT::ValueType EVT = LD->getLoadVT();
+    
+      if (EVT == NVT)
+        Lo = DAG.getLoad(NVT, Ch, Ptr, LD->getSrcValue(),
+                         LD->getSrcValueOffset());
+      else
+        Lo = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, LD->getSrcValue(),
+                            LD->getSrcValueOffset(), EVT);
+    
+      // Remember that we legalized the chain.
+      AddLegalizedOperand(SDOperand(Node, 1), LegalizeOp(Lo.getValue(1)));
+
+      if (ExtType == ISD::SEXTLOAD) {
+        // The high part is obtained by SRA'ing all but one of the bits of the
+        // lo part.
+        unsigned LoSize = MVT::getSizeInBits(Lo.getValueType());
+        Hi = DAG.getNode(ISD::SRA, NVT, Lo,
+                         DAG.getConstant(LoSize-1, TLI.getShiftAmountTy()));
+      } else if (ExtType == ISD::ZEXTLOAD) {
+        // The high part is just a zero.
+        Hi = DAG.getConstant(0, NVT);
+      } else /* if (ExtType == ISD::EXTLOAD) */ {
+        // The high part is undefined.
+        Hi = DAG.getNode(ISD::UNDEF, NVT);
+      }
+    }
     break;
   }
   case ISD::AND:
@@ -4470,35 +4494,6 @@
                      Node->getOperand(1), TH, FH, Node->getOperand(4));
     break;
   }
-  case ISD::LOADX: {
-    SDOperand Chain = Node->getOperand(0);
-    SDOperand Ptr   = Node->getOperand(1);
-    MVT::ValueType EVT = cast<VTSDNode>(Node->getOperand(3))->getVT();
-    ISD::LoadExtType LType = (ISD::LoadExtType)Node->getConstantOperandVal(4);
-    
-    if (EVT == NVT)
-      Lo = DAG.getLoad(NVT, Chain, Ptr, Node->getOperand(2));
-    else
-      Lo = DAG.getExtLoad(LType, NVT, Chain, Ptr, Node->getOperand(2), EVT);
-    
-    // Remember that we legalized the chain.
-    AddLegalizedOperand(SDOperand(Node, 1), LegalizeOp(Lo.getValue(1)));
-
-    if (LType == ISD::SEXTLOAD) {
-      // The high part is obtained by SRA'ing all but one of the bits of the lo
-      // part.
-      unsigned LoSize = MVT::getSizeInBits(Lo.getValueType());
-      Hi = DAG.getNode(ISD::SRA, NVT, Lo, DAG.getConstant(LoSize-1,
-                                                          TLI.getShiftAmountTy()));
-    } else if (LType == ISD::ZEXTLOAD) {
-      // The high part is just a zero.
-      Hi = DAG.getConstant(0, NVT);
-    } else /* if (LType == ISD::EXTLOAD) */ {
-      // The high part is undefined.
-      Hi = DAG.getNode(ISD::UNDEF, NVT);
-    }
-    break;
-  }
   case ISD::ANY_EXTEND:
     // The low part is any extension of the input (which degenerates to a copy).
     Lo = DAG.getNode(ISD::ANY_EXTEND, NVT, Node->getOperand(0));
@@ -4995,7 +4990,8 @@
     SDOperand Ch = LegalizeOp(Node->getOperand(0));   // Legalize the chain.
     SDOperand Ptr = LegalizeOp(Node->getOperand(1));  // Legalize the pointer.
     
-    Result = DAG.getLoad(NewVT, Ch, Ptr, Node->getOperand(2));
+    SrcValueSDNode *SV = cast<SrcValueSDNode>(Node->getOperand(2));
+    Result = DAG.getLoad(NewVT, Ch, Ptr, SV->getValue(), SV->getOffset());
     
     // Remember that we legalized the chain.
     AddLegalizedOperand(Op.getValue(1), LegalizeOp(Result.getValue(1)));
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index e673175..2b7a9db 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -1460,14 +1460,66 @@
 
 SDOperand SelectionDAG::getLoad(MVT::ValueType VT,
                                 SDOperand Chain, SDOperand Ptr,
-                                SDOperand SV) {
+                                const Value *SV, int SVOffset,
+                                bool isVolatile) {
+  // FIXME: Alignment == 1 for now.
+  unsigned Alignment = 1;
   SDVTList VTs = getVTList(VT, MVT::Other);
-  
-  SelectionDAGCSEMap::NodeID ID(ISD::LOAD, VTs, Chain, Ptr, SV);
+  SDOperand Undef = getNode(ISD::UNDEF, VT);
+  SelectionDAGCSEMap::NodeID ID(ISD::LOAD, VTs, Chain, Ptr, Undef);
+  ID.AddInteger(ISD::UNINDEXED);
+  ID.AddInteger(ISD::NON_EXTLOAD);
+  ID.AddInteger(VT);
+  ID.AddPointer(SV);
+  ID.AddInteger(SVOffset);
+  ID.AddInteger(Alignment);
+  ID.AddInteger(isVolatile);
   void *IP = 0;
   if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
     return SDOperand(E, 0);
-  SDNode *N = new SDNode(ISD::LOAD, Chain, Ptr, SV);
+  SDNode *N = new LoadSDNode(Chain, Ptr, Undef, ISD::NON_EXTLOAD, VT,
+                             SV, SVOffset, Alignment, isVolatile);
+  N->setValueTypes(VTs);
+  CSEMap.InsertNode(N, IP);
+  AllNodes.push_back(N);
+  return SDOperand(N, 0);
+}
+
+SDOperand SelectionDAG::getExtLoad(ISD::LoadExtType ExtType, MVT::ValueType VT,
+                                   SDOperand Chain, SDOperand Ptr, const Value *SV,
+                                   int SVOffset, MVT::ValueType EVT,
+                                   bool isVolatile) {
+  // If they are asking for an extending load from/to the same thing, return a
+  // normal load.
+  if (VT == EVT)
+    ExtType = ISD::NON_EXTLOAD;
+
+  if (MVT::isVector(VT))
+    assert(EVT == MVT::getVectorBaseType(VT) && "Invalid vector extload!");
+  else
+    assert(EVT < VT && "Should only be an extending load, not truncating!");
+  assert((ExtType == ISD::EXTLOAD || MVT::isInteger(VT)) &&
+         "Cannot sign/zero extend a FP/Vector load!");
+  assert(MVT::isInteger(VT) == MVT::isInteger(EVT) &&
+         "Cannot convert from FP to Int or Int -> FP!");
+
+  // FIXME: Alignment == 1 for now.
+  unsigned Alignment = 1;
+  SDVTList VTs = getVTList(VT, MVT::Other);
+  SDOperand Undef = getNode(ISD::UNDEF, VT);
+  SelectionDAGCSEMap::NodeID ID(ISD::LOAD, VTs, Chain, Ptr, Undef);
+  ID.AddInteger(ISD::UNINDEXED);
+  ID.AddInteger(ExtType);
+  ID.AddInteger(EVT);
+  ID.AddPointer(SV);
+  ID.AddInteger(SVOffset);
+  ID.AddInteger(Alignment);
+  ID.AddInteger(isVolatile);
+  void *IP = 0;
+  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
+    return SDOperand(E, 0);
+  SDNode *N = new LoadSDNode(Chain, Ptr, Undef, ExtType, EVT, SV, SVOffset,
+                             Alignment, isVolatile);
   N->setValueTypes(VTs);
   CSEMap.InsertNode(N, IP);
   AllNodes.push_back(N);
@@ -1482,14 +1534,6 @@
   return getNode(ISD::VLOAD, getVTList(MVT::Vector, MVT::Other), Ops, 5);
 }
 
-SDOperand SelectionDAG::getExtLoad(ISD::LoadExtType LType, MVT::ValueType VT,
-                                   SDOperand Chain, SDOperand Ptr, SDOperand SV,
-                                   MVT::ValueType EVT) {
-  SDOperand Ops[] = { Chain, Ptr, SV, getValueType(EVT),
-                      getConstant(LType, MVT::i32) };
-  return getNode(ISD::LOADX, getVTList(VT, MVT::Other), Ops, 5);
-}
-
 SDOperand SelectionDAG::getStore(SDOperand Chain, SDOperand Value,
                                  SDOperand Ptr, SDOperand SV) {
   SDVTList VTs = getVTList(MVT::Other);
@@ -1602,28 +1646,6 @@
     return getNode(Opcode, VTList.VTs[0], Ops, NumOps);
 
   switch (Opcode) {
-  case ISD::LOADX: {
-    MVT::ValueType EVT = cast<VTSDNode>(Ops[3])->getVT();
-    unsigned LType = cast<ConstantSDNode>(Ops[4])->getValue();
-    assert(NumOps == 5 && VTList.NumVTs == 2 && "Bad *EXTLOAD!");
-    // If they are asking for an extending load from/to the same thing, return a
-    // normal load.
-    if (VTList.VTs[0] == EVT)
-      return getLoad(VTList.VTs[0], Ops[0], Ops[1], Ops[2]);
-    if (MVT::isVector(VTList.VTs[0])) {
-      assert(EVT == MVT::getVectorBaseType(VTList.VTs[0]) &&
-             "Invalid vector extload!");
-    } else {
-      assert(EVT < VTList.VTs[0] &&
-             "Should only be an extending load, not truncating!");
-    }
-    assert((LType == ISD::EXTLOAD || MVT::isInteger(VTList.VTs[0])) &&
-           "Cannot sign/zero extend a FP/Vector load!");
-    assert(MVT::isInteger(VTList.VTs[0]) == MVT::isInteger(EVT) &&
-           "Cannot convert from FP to Int or Int -> FP!");
-    break;
-  }
-
   // FIXME: figure out how to safely handle things like
   // int foo(int x) { return 1 << (x & 255); }
   // int bar() { return foo(256); }
@@ -2545,7 +2567,6 @@
   case ISD::LOAD:               return "load";
   case ISD::STORE:              return "store";
   case ISD::VLOAD:              return "vload";
-  case ISD::LOADX:              return "loadx";
   case ISD::TRUNCSTORE:         return "truncstore";
   case ISD::VAARG:              return "vaarg";
   case ISD::VACOPY:             return "vacopy";
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 6d0f782..e17105c 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -460,7 +460,7 @@
   void setCurrentBasicBlock(MachineBasicBlock *MBB) { CurMBB = MBB; }
 
   SDOperand getLoadFrom(const Type *Ty, SDOperand Ptr,
-                        SDOperand SrcValue, SDOperand Root,
+                        const Value *SV, SDOperand Root,
                         bool isVolatile);
 
   SDOperand getIntPtrConstant(uint64_t Val) {
@@ -859,7 +859,7 @@
   SDOperand TAB = DAG.getJumpTable(JT.JTI,PTy);
   SDOperand ADD = DAG.getNode(ISD::ADD, PTy, IDX, TAB);
   SDOperand LD  = DAG.getLoad(isPIC ? MVT::i32 : PTy, Copy.getValue(1), ADD,
-                              DAG.getSrcValue(0));
+                              NULL, 0);
   if (isPIC) {
     // For Pic, the sequence is:
     // BRIND(load(Jumptable + index) + RelocBase)
@@ -1360,19 +1360,20 @@
     Root = DAG.getRoot();
   }
 
-  setValue(&I, getLoadFrom(I.getType(), Ptr, DAG.getSrcValue(I.getOperand(0)),
+  setValue(&I, getLoadFrom(I.getType(), Ptr, I.getOperand(0),
                            Root, I.isVolatile()));
 }
 
 SDOperand SelectionDAGLowering::getLoadFrom(const Type *Ty, SDOperand Ptr,
-                                            SDOperand SrcValue, SDOperand Root,
+                                            const Value *SV, SDOperand Root,
                                             bool isVolatile) {
   SDOperand L;
   if (const PackedType *PTy = dyn_cast<PackedType>(Ty)) {
     MVT::ValueType PVT = TLI.getValueType(PTy->getElementType());
-    L = DAG.getVecLoad(PTy->getNumElements(), PVT, Root, Ptr, SrcValue);
+    L = DAG.getVecLoad(PTy->getNumElements(), PVT, Root, Ptr,
+                       DAG.getSrcValue(SV));
   } else {
-    L = DAG.getLoad(TLI.getValueType(Ty), Root, Ptr, SrcValue);
+    L = DAG.getLoad(TLI.getValueType(Ty), Root, Ptr, SV, isVolatile);
   }
 
   if (isVolatile)
@@ -2909,7 +2910,7 @@
           } else {
             Value = DAG.getLoad(VT, getRoot(),
                         getMemBasePlusOffset(Op2, SrcOff, DAG, TLI),
-                        DAG.getSrcValue(I.getOperand(2), SrcOff));
+                        I.getOperand(2), SrcOff);
             Chain = Value.getValue(1);
             Store =
               DAG.getStore(Chain, Value,
diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 1c00c91..73cefc4 100644
--- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -552,9 +552,10 @@
     KnownOne  = 0;
     break;
   }
-  case ISD::LOADX: {
+  case ISD::LOAD: {
     if (ISD::isZEXTLoad(Op.Val)) {
-      MVT::ValueType VT = cast<VTSDNode>(Op.getOperand(3))->getVT();
+      LoadSDNode *LD = cast<LoadSDNode>(Op);
+      MVT::ValueType VT = LD->getLoadVT();
       KnownZero |= ~MVT::getIntVTBitMask(VT) & DemandedMask;
     }
     break;
@@ -892,9 +893,10 @@
     KnownOne  = 0;
     return;
   }
-  case ISD::LOADX: {
+  case ISD::LOAD: {
     if (ISD::isZEXTLoad(Op.Val)) {
-      MVT::ValueType VT = cast<VTSDNode>(Op.getOperand(3))->getVT();
+      LoadSDNode *LD = cast<LoadSDNode>(Op);
+      MVT::ValueType VT = LD->getLoadVT();
       KnownZero |= ~MVT::getIntVTBitMask(VT) & Mask;
     }
     return;
@@ -1197,15 +1199,16 @@
   }
   
   // Handle LOADX separately here. EXTLOAD case will fallthrough.
-  if (Op.getOpcode() == ISD::LOADX) {
-    unsigned LType = Op.getConstantOperandVal(4);
-    switch (LType) {
+  if (Op.getOpcode() == ISD::LOAD) {
+    LoadSDNode *LD = cast<LoadSDNode>(Op);
+    unsigned ExtType = LD->getExtensionType();
+    switch (ExtType) {
     default: break;
     case ISD::SEXTLOAD:    // '17' bits known
-      Tmp = MVT::getSizeInBits(cast<VTSDNode>(Op.getOperand(3))->getVT());
+      Tmp = MVT::getSizeInBits(LD->getLoadVT());
       return VTBits-Tmp+1;
     case ISD::ZEXTLOAD:    // '16' bits known
-      Tmp = MVT::getSizeInBits(cast<VTSDNode>(Op.getOperand(3))->getVT());
+      Tmp = MVT::getSizeInBits(LD->getLoadVT());
       return VTBits-Tmp;
     }
   }
