diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index c7da77c..e3d8c80 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -2737,83 +2737,89 @@
   } else
     return false;
 
-  if ((Ptr.getOpcode() == ISD::ADD || Ptr.getOpcode() == ISD::SUB) &&
-      Ptr.Val->use_size() > 1) {
-    SDOperand BasePtr;
-    SDOperand Offset;
-    ISD::MemIndexedMode AM = ISD::UNINDEXED;
-    if (TLI.getPreIndexedAddressParts(N, BasePtr, Offset, AM, DAG)) {
-      // Try turning it into a pre-indexed load / store except when
-      // 1) If N is a store and the ptr is either the same as or is a
-      //    predecessor of the value being stored.
-      // 2) Another use of base ptr is a predecessor of N. If ptr is folded
-      //    that would create a cycle.
-      // 3) All uses are load / store ops that use it as base ptr.
+  // If the pointer is not an add/sub, or if it doesn't have multiple uses, bail
+  // out.  There is no reason to make this a preinc/predec.
+  if ((Ptr.getOpcode() != ISD::ADD && Ptr.getOpcode() != ISD::SUB) ||
+      Ptr.Val->hasOneUse())
+    return false;
 
-      // Checking #1.
-      if (!isLoad) {
-        SDOperand Val = cast<StoreSDNode>(N)->getValue();
-        if (Val == Ptr || Ptr.Val->isPredecessor(Val.Val))
-          return false;
-      }
+  // Ask the target to do addressing mode selection.
+  SDOperand BasePtr;
+  SDOperand Offset;
+  ISD::MemIndexedMode AM = ISD::UNINDEXED;
+  if (!TLI.getPreIndexedAddressParts(N, BasePtr, Offset, AM, DAG))
+    return false;
+  
+  // Try turning it into a pre-indexed load / store except when
+  // 1) If N is a store and the ptr is either the same as or is a
+  //    predecessor of the value being stored.
+  // 2) Another use of base ptr is a predecessor of N. If ptr is folded
+  //    that would create a cycle.
+  // 3) All uses are load / store ops that use it as base ptr.
 
-      // Now check for #2 and #3.
-      bool RealUse = false;
-      for (SDNode::use_iterator I = Ptr.Val->use_begin(),
-             E = Ptr.Val->use_end(); I != E; ++I) {
-        SDNode *Use = *I;
-        if (Use == N)
-          continue;
-        if (Use->isPredecessor(N))
-          return false;
-
-        if (!((Use->getOpcode() == ISD::LOAD &&
-               cast<LoadSDNode>(Use)->getBasePtr() == Ptr) ||
-              (Use->getOpcode() == ISD::STORE) &&
-              cast<StoreSDNode>(Use)->getBasePtr() == Ptr))
-          RealUse = true;
-      }
-      if (!RealUse)
-        return false;
-
-      SDOperand Result = isLoad
-        ? DAG.getIndexedLoad(SDOperand(N,0), BasePtr, Offset, AM)
-        : DAG.getIndexedStore(SDOperand(N,0), BasePtr, Offset, AM);
-      ++PreIndexedNodes;
-      ++NodesCombined;
-      DEBUG(std::cerr << "\nReplacing.4 "; N->dump();
-            std::cerr << "\nWith: "; Result.Val->dump(&DAG);
-            std::cerr << '\n');
-      std::vector<SDNode*> NowDead;
-      if (isLoad) {
-        DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), Result.getValue(0),
-                                      NowDead);
-        DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 1), Result.getValue(2),
-                                      NowDead);
-      } else {
-        DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), Result.getValue(1),
-                                      NowDead);
-      }
-
-      // Nodes can end up on the worklist more than once.  Make sure we do
-      // not process a node that has been replaced.
-      for (unsigned i = 0, e = NowDead.size(); i != e; ++i)
-        removeFromWorkList(NowDead[i]);
-      // Finally, since the node is now dead, remove it from the graph.
-      DAG.DeleteNode(N);
-
-      // Replace the uses of Ptr with uses of the updated base value.
-      DAG.ReplaceAllUsesOfValueWith(Ptr, Result.getValue(isLoad ? 1 : 0),
-                                    NowDead);
-      removeFromWorkList(Ptr.Val);
-      for (unsigned i = 0, e = NowDead.size(); i != e; ++i)
-        removeFromWorkList(NowDead[i]);
-      DAG.DeleteNode(Ptr.Val);
-
-      return true;
-    }
+  // Checking #1.
+  if (!isLoad) {
+    SDOperand Val = cast<StoreSDNode>(N)->getValue();
+    if (Val == Ptr || Ptr.Val->isPredecessor(Val.Val))
+      return false;
   }
-  return false;
+
+  // Now check for #2 and #3.
+  bool RealUse = false;
+  for (SDNode::use_iterator I = Ptr.Val->use_begin(),
+         E = Ptr.Val->use_end(); I != E; ++I) {
+    SDNode *Use = *I;
+    if (Use == N)
+      continue;
+    if (Use->isPredecessor(N))
+      return false;
+
+    if (!((Use->getOpcode() == ISD::LOAD &&
+           cast<LoadSDNode>(Use)->getBasePtr() == Ptr) ||
+          (Use->getOpcode() == ISD::STORE) &&
+          cast<StoreSDNode>(Use)->getBasePtr() == Ptr))
+      RealUse = true;
+  }
+  if (!RealUse)
+    return false;
+
+  SDOperand Result;
+  if (isLoad)
+    Result = DAG.getIndexedLoad(SDOperand(N,0), BasePtr, Offset, AM);
+  else
+    Result = DAG.getIndexedStore(SDOperand(N,0), BasePtr, Offset, AM);
+  ++PreIndexedNodes;
+  ++NodesCombined;
+  DEBUG(std::cerr << "\nReplacing.4 "; N->dump();
+        std::cerr << "\nWith: "; Result.Val->dump(&DAG);
+        std::cerr << '\n');
+  std::vector<SDNode*> NowDead;
+  if (isLoad) {
+    DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), Result.getValue(0),
+                                  NowDead);
+    DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 1), Result.getValue(2),
+                                  NowDead);
+  } else {
+    DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), Result.getValue(1),
+                                  NowDead);
+  }
+
+  // Nodes can end up on the worklist more than once.  Make sure we do
+  // not process a node that has been replaced.
+  for (unsigned i = 0, e = NowDead.size(); i != e; ++i)
+    removeFromWorkList(NowDead[i]);
+  // Finally, since the node is now dead, remove it from the graph.
+  DAG.DeleteNode(N);
+
+  // Replace the uses of Ptr with uses of the updated base value.
+  DAG.ReplaceAllUsesOfValueWith(Ptr, Result.getValue(isLoad ? 1 : 0),
+                                NowDead);
+  removeFromWorkList(Ptr.Val);
+  for (unsigned i = 0, e = NowDead.size(); i != e; ++i)
+    removeFromWorkList(NowDead[i]);
+  DAG.DeleteNode(Ptr.Val);
+
+  return true;
 }
 
 /// CombineToPostIndexedLoadStore - Try combine a load / store with a
@@ -2844,99 +2850,100 @@
   } else
     return false;
 
-  if (Ptr.Val->use_size() > 1) {
-    for (SDNode::use_iterator I = Ptr.Val->use_begin(),
-           E = Ptr.Val->use_end(); I != E; ++I) {
-      SDNode *Op = *I;
-      if (Op == N ||
-          (Op->getOpcode() != ISD::ADD && Op->getOpcode() != ISD::SUB))
+  if (!Ptr.Val->hasOneUse())
+    return false;
+  
+  for (SDNode::use_iterator I = Ptr.Val->use_begin(),
+         E = Ptr.Val->use_end(); I != E; ++I) {
+    SDNode *Op = *I;
+    if (Op == N ||
+        (Op->getOpcode() != ISD::ADD && Op->getOpcode() != ISD::SUB))
+      continue;
+
+    SDOperand BasePtr;
+    SDOperand Offset;
+    ISD::MemIndexedMode AM = ISD::UNINDEXED;
+    if (TLI.getPostIndexedAddressParts(N, Op, BasePtr, Offset, AM, DAG)) {
+      if (Ptr == Offset)
+        std::swap(BasePtr, Offset);
+      if (Ptr != BasePtr)
         continue;
 
-      SDOperand BasePtr;
-      SDOperand Offset;
-      ISD::MemIndexedMode AM = ISD::UNINDEXED;
-      if (TLI.getPostIndexedAddressParts(N, Op, BasePtr, Offset, AM, DAG)) {
-        if (Ptr == Offset)
-          std::swap(BasePtr, Offset);
-        if (Ptr != BasePtr)
+      // Try turning it into a post-indexed load / store except when
+      // 1) All uses are load / store ops that use it as base ptr.
+      // 2) Op must be independent of N, i.e. Op is neither a predecessor
+      //    nor a successor of N. Otherwise, if Op is folded that would
+      //    create a cycle.
+
+      // Check for #1.
+      bool TryNext = false;
+      for (SDNode::use_iterator II = BasePtr.Val->use_begin(),
+             EE = BasePtr.Val->use_end(); II != EE; ++II) {
+        SDNode *Use = *II;
+        if (Use == Ptr.Val)
           continue;
 
-        // Try turning it into a post-indexed load / store except when
-        // 1) All uses are load / store ops that use it as base ptr.
-        // 2) Op must be independent of N, i.e. Op is neither a predecessor
-        //    nor a successor of N. Otherwise, if Op is folded that would
-        //    create a cycle.
+        // If all the uses are load / store addresses, then don't do the
+        // transformation.
+        if (Use->getOpcode() == ISD::ADD || Use->getOpcode() == ISD::SUB){
+          bool RealUse = false;
+          for (SDNode::use_iterator III = Use->use_begin(),
+                 EEE = Use->use_end(); III != EEE; ++III) {
+            SDNode *UseUse = *III;
+            if (!((UseUse->getOpcode() == ISD::LOAD &&
+                   cast<LoadSDNode>(UseUse)->getBasePtr().Val == Use) ||
+                  (UseUse->getOpcode() == ISD::STORE) &&
+                  cast<StoreSDNode>(UseUse)->getBasePtr().Val == Use))
+              RealUse = true;
+          }
 
-        // Check for #1.
-        bool TryNext = false;
-        for (SDNode::use_iterator II = BasePtr.Val->use_begin(),
-               EE = BasePtr.Val->use_end(); II != EE; ++II) {
-          SDNode *Use = *II;
-          if (Use == Ptr.Val)
-            continue;
-
-          // If all the uses are load / store addresses, then don't do the
-          // transformation.
-          if (Use->getOpcode() == ISD::ADD || Use->getOpcode() == ISD::SUB){
-            bool RealUse = false;
-            for (SDNode::use_iterator III = Use->use_begin(),
-                   EEE = Use->use_end(); III != EEE; ++III) {
-              SDNode *UseUse = *III;
-              if (!((UseUse->getOpcode() == ISD::LOAD &&
-                     cast<LoadSDNode>(UseUse)->getBasePtr().Val == Use) ||
-                    (UseUse->getOpcode() == ISD::STORE) &&
-                    cast<StoreSDNode>(UseUse)->getBasePtr().Val == Use))
-                RealUse = true;
-            }
-
-            if (!RealUse) {
-              TryNext = true;
-              break;
-            }
+          if (!RealUse) {
+            TryNext = true;
+            break;
           }
         }
-        if (TryNext)
-          continue;
+      }
+      if (TryNext)
+        continue;
 
-        // Check for #2
-        if (!Op->isPredecessor(N) && !N->isPredecessor(Op)) {
-          SDOperand Result = isLoad
-            ? DAG.getIndexedLoad(SDOperand(N,0), BasePtr, Offset, AM)
-            : DAG.getIndexedStore(SDOperand(N,0), BasePtr, Offset, AM);
-          ++PostIndexedNodes;
-          ++NodesCombined;
-          DEBUG(std::cerr << "\nReplacing.5 "; N->dump();
-                std::cerr << "\nWith: "; Result.Val->dump(&DAG);
-                std::cerr << '\n');
-          std::vector<SDNode*> NowDead;
-          if (isLoad) {
-            DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), Result.getValue(0),
-                                          NowDead);
-            DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 1), Result.getValue(2),
-                                          NowDead);
-          } else {
-            DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), Result.getValue(1),
-                                          NowDead);
-          }
-
-          // Nodes can end up on the worklist more than once.  Make sure we do
-          // not process a node that has been replaced.
-          for (unsigned i = 0, e = NowDead.size(); i != e; ++i)
-            removeFromWorkList(NowDead[i]);
-          // Finally, since the node is now dead, remove it from the graph.
-          DAG.DeleteNode(N);
-
-          // Replace the uses of Use with uses of the updated base value.
-          DAG.ReplaceAllUsesOfValueWith(SDOperand(Op, 0),
-                                        Result.getValue(isLoad ? 1 : 0),
+      // Check for #2
+      if (!Op->isPredecessor(N) && !N->isPredecessor(Op)) {
+        SDOperand Result = isLoad
+          ? DAG.getIndexedLoad(SDOperand(N,0), BasePtr, Offset, AM)
+          : DAG.getIndexedStore(SDOperand(N,0), BasePtr, Offset, AM);
+        ++PostIndexedNodes;
+        ++NodesCombined;
+        DEBUG(std::cerr << "\nReplacing.5 "; N->dump();
+              std::cerr << "\nWith: "; Result.Val->dump(&DAG);
+              std::cerr << '\n');
+        std::vector<SDNode*> NowDead;
+        if (isLoad) {
+          DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), Result.getValue(0),
                                         NowDead);
-          removeFromWorkList(Op);
-          for (unsigned i = 0, e = NowDead.size(); i != e; ++i)
-            removeFromWorkList(NowDead[i]);
-          DAG.DeleteNode(Op);
-
-          return true;
+          DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 1), Result.getValue(2),
+                                        NowDead);
+        } else {
+          DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), Result.getValue(1),
+                                        NowDead);
         }
+
+        // Nodes can end up on the worklist more than once.  Make sure we do
+        // not process a node that has been replaced.
+        for (unsigned i = 0, e = NowDead.size(); i != e; ++i)
+          removeFromWorkList(NowDead[i]);
+        // Finally, since the node is now dead, remove it from the graph.
+        DAG.DeleteNode(N);
+
+        // Replace the uses of Use with uses of the updated base value.
+        DAG.ReplaceAllUsesOfValueWith(SDOperand(Op, 0),
+                                      Result.getValue(isLoad ? 1 : 0),
+                                      NowDead);
+        removeFromWorkList(Op);
+        for (unsigned i = 0, e = NowDead.size(); i != e; ++i)
+          removeFromWorkList(NowDead[i]);
+        DAG.DeleteNode(Op);
+
+        return true;
       }
     }
   }
