diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index c30a222..c7823ff 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -39,6 +39,7 @@
 #include <algorithm>
 #include <cmath>
 #include <iostream>
+#include <algorithm>
 using namespace llvm;
 
 namespace {
@@ -132,7 +133,8 @@
       // Replace the old value with the new one.
       ++NodesCombined;
       DEBUG(std::cerr << "\nReplacing "; TLO.Old.Val->dump();
-            std::cerr << "\nWith: "; TLO.New.Val->dump(&DAG));
+            std::cerr << "\nWith: "; TLO.New.Val->dump(&DAG);
+            std::cerr << '\n');
 
       std::vector<SDNode*> NowDead;
       DAG.ReplaceAllUsesOfValueWith(TLO.Old, TLO.New, NowDead);
@@ -237,7 +239,31 @@
     SDOperand BuildSDIV(SDNode *N);
     SDOperand BuildUDIV(SDNode *N);
     SDNode *MatchRotate(SDOperand LHS, SDOperand RHS);
-    bool isNotAlias(SDOperand Ptr1, SDOperand Ptr2);
+    
+    /// FindBaseOffset - Return true if we can determine base and offset
+    /// information from a given pointer operand.  Provides base and offset as a
+    /// result.
+    static bool FindBaseOffset(SDOperand Ptr,
+                               SDOperand &Object, int64_t &Offset);
+    
+    /// isAlias - Return true if there is the possibility that the two addresses
+    /// overlap.
+    static bool isAlias(SDOperand Ptr1, int64_t Size1, SDOperand SrcValue1,
+                        SDOperand Ptr2, int64_t Size2, SDOperand SrcValue2);
+    
+    /// FindAliasInfo - Extracts the relevant alias information from the memory
+    /// node.
+    static void FindAliasInfo(SDNode *N,
+                           SDOperand &Ptr, int64_t &Size, SDOperand &SrcValue);
+    
+    /// hasChain - Return true if Op has a chain.  Provides chain if present.
+    ///
+    static bool hasChain(SDOperand Op, SDOperand &Chain);
+ 
+    /// FindBetterChain - Walk up chain skipping non-aliasing memory nodes,
+    /// looking for a better chain.
+    SDOperand FindBetterChain(SDNode *N, SDOperand Chain);
+    
 public:
     DAGCombiner(SelectionDAG &D)
       : DAG(D), TLI(D.getTargetLoweringInfo()), AfterLegalize(false) {}
@@ -507,9 +533,6 @@
 }
 
 SDOperand DAGCombiner::visitTokenFactor(SDNode *N) {
-  SmallVector<SDOperand, 8> Ops;
-  bool Changed = false;
-
   // If the token factor has two operands and one is the entry token, replace
   // the token factor with the other operand.
   if (N->getNumOperands() == 2) {
@@ -520,23 +543,69 @@
       return N->getOperand(0);
   }
   
-  // fold (tokenfactor (tokenfactor)) -> tokenfactor
-  for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
+  SmallVector<SDNode *, 8> TFs;   // Set of token factor nodes.
+  SmallVector<SDOperand, 8> Ops;  // Ops for replacing token factor.
+
+  // Add this ndoe to the token factor set.
+  TFs.push_back(N);
+
+  // Separate token factors from other operands.
+  for (unsigned i = 0, ie = N->getNumOperands(); i != ie; ++i) {
     SDOperand Op = N->getOperand(i);
-    if (Op.getOpcode() == ISD::TokenFactor && Op.hasOneUse()) {
-      AddToWorkList(Op.Val);  // Remove dead node.
-      Changed = true;
-      for (unsigned j = 0, e = Op.getNumOperands(); j != e; ++j)
-        Ops.push_back(Op.getOperand(j));
-    } else if (i == 0 || N->getOperand(i) != N->getOperand(i-1)) {
+    if (Op.getOpcode() == ISD::TokenFactor)
+      TFs.push_back(Op.Val);
+    else if (Op.getOpcode() != ISD::EntryToken)
       Ops.push_back(Op);
-    } else {
-      // Deleted an operand that was the same as the last one.
-      Changed = true;
+  }
+  
+  // If there are token factor operands.
+  if (TFs.size() > 1) {
+    bool Changed = false; // If we should replace this token factor.
+    
+    // For each token factor.
+    for (unsigned j = 1, je = TFs.size(); j != je; ++j) {
+      SDNode *TF = TFs[j];
+      bool CanMerge = true; // Can we merge this token factor.
+      
+      if (CombinerAA) {
+        if (!TF->hasOneUse()) {
+          // Check to see if all users point to members of the token factor set.
+          for (SDNode::use_iterator UI = TF->use_begin(), UE = TF->use_end();
+               CanMerge && UI != UE; ++UI) {
+            SDNode *User = *UI;
+            CanMerge = User->getOpcode() == ISD::TokenFactor &&
+                       std::find(TFs.begin(), TFs.end(), User) != TFs.end();
+          }
+        }
+      } else {
+        CanMerge = TF->hasOneUse();
+      }
+      
+      // If it's valid to merge.
+      if (CanMerge) {
+        // Remove dead token factor node.
+        AddToWorkList(TF); 
+        
+        // Make sure we don't duplicate operands.
+        unsigned m = Ops.size(); // Number of prior operands.
+        for (unsigned l = 0, le = TF->getNumOperands(); l != le; ++l) {
+          SDOperand Op = TF->getOperand(l);
+          if (std::find(Ops.begin(), Ops.end(), Op) == Ops.end())
+            Ops.push_back(Op);
+        }
+        Changed = true;
+      } else  {
+        // Can't merge this token factor.
+        Ops.push_back(SDOperand(TF, 0));
+      }
+    }
+    
+    // If we've change things around then replace token factor.
+    if (Changed) {
+      return DAG.getNode(ISD::TokenFactor, MVT::Other, &Ops[0], Ops.size());
     }
   }
-  if (Changed)
-    return DAG.getNode(ISD::TokenFactor, MVT::Other, &Ops[0], Ops.size());
+  
   return SDOperand();
 }
 
@@ -2571,6 +2640,27 @@
       Chain.getOperand(1).getValueType() == N->getValueType(0))
     return CombineTo(N, Chain.getOperand(1), Chain);
   
+  if (CombinerAA) { 
+    // Walk up chain skipping non-aliasing memory nodes.
+    SDOperand BetterChain = FindBetterChain(N, Chain);
+    
+    // If the there is a better chain.
+    if (Chain != BetterChain) {
+      // Replace the chain to void dependency.
+      SDOperand ReplLoad = DAG.getLoad(N->getValueType(0), BetterChain, Ptr,
+                                       SrcValue);
+
+      // Replace uses with token.
+      CombineTo(N, ReplLoad.getValue(0), ReplLoad.getValue(1));
+      
+      // Old chain needs to be cleaned up.
+      AddToWorkList(Chain.Val);
+      
+      // Don't recombine on token.
+      return SDOperand(N, 0);
+    }
+  }
+
   return SDOperand();
 }
 
@@ -2589,27 +2679,6 @@
   return SDOperand();
 }
 
-/// isNotAlias - Return true if we have definitive knowlege that the two
-/// addresses don't overlap.
-bool DAGCombiner::isNotAlias(SDOperand Ptr1, SDOperand Ptr2) {
-  // Mind the flag.
-  if (!CombinerAA) return false;
-  
-  // If they are the same then they must be aliases.
-  if (Ptr1 == Ptr2) return false;
-  
-  // If both operands are frame values (not the same location from above test)
-  // then they can't alias.
-  FrameIndexSDNode *FI1 = dyn_cast<FrameIndexSDNode>(Ptr1);
-  FrameIndexSDNode *FI2 = dyn_cast<FrameIndexSDNode>(Ptr2);
-  if (FI1 && FI2) {
-    return true;
-  }
-  
-  // Otherwise we don't know and have to play it safe.
-  return false;
-}
-
 SDOperand DAGCombiner::visitSTORE(SDNode *N) {
   SDOperand Chain    = N->getOperand(0);
   SDOperand Value    = N->getOperand(1);
@@ -2637,22 +2706,33 @@
   // If this is a store of a bit convert, store the input value.
   // FIXME: This needs to know that the resultant store does not need a 
   // higher alignment than the original.
-  if (0 && Value.getOpcode() == ISD::BIT_CONVERT)
+  if (Value.getOpcode() == ISD::BIT_CONVERT) {
     return DAG.getNode(ISD::STORE, MVT::Other, Chain, Value.getOperand(0),
                        Ptr, SrcValue);
-                       
-  // If the previous store is not an alias then break artificial chain.
-  if (Chain.getOpcode() == ISD::STORE && isNotAlias(Ptr, Chain.getOperand(2))) {
-    // Replace the chain to void dependency.
-    SDNode *PrevStore = Chain.Val;
-    SDOperand ReplStore = DAG.getNode(ISD::STORE, MVT::Other,
-                                     PrevStore->getOperand(0), Value, Ptr,
-                                     SrcValue);
-    // Create token to keep both stores around.
-    SDOperand Token = DAG.getNode(ISD::TokenFactor, MVT::Other,
-                      Chain, ReplStore);
-    // Replace uses with token.
-    return Token;
+  }
+  
+  if (CombinerAA) { 
+    // Walk up chain skipping non-aliasing memory nodes.
+    SDOperand BetterChain = FindBetterChain(N, Chain);
+    
+    // If the there is a better chain.
+    if (Chain != BetterChain) {
+      // Replace the chain to void dependency.
+      SDOperand ReplStore = DAG.getNode(ISD::STORE, MVT::Other,
+                                        BetterChain, Value, Ptr,
+                                        SrcValue);
+      // Create token to keep both nodes around.
+      SDOperand Token = DAG.getNode(ISD::TokenFactor, MVT::Other,
+                                    Chain, ReplStore);
+
+      // Make sure we merge token factors.
+      AddUsersToWorkList(N);
+      
+      // Old chain needs to be cleaned up.
+      AddToWorkList(Chain.Val);
+         
+      return Token;
+    }
   }
   
   return SDOperand();
@@ -3860,6 +3940,155 @@
   return S;
 }
 
+/// FindBaseOffset - Return true if we can determine base and offset information
+/// from a given pointer operand.  Provides base and offset as a result.
+bool DAGCombiner::FindBaseOffset(SDOperand Ptr,
+                                 SDOperand &Object, int64_t &Offset) {
+  
+  // Is it a frame variable, global or constant.
+  if (isa<FrameIndexSDNode>(Ptr) ||
+      isa<ConstantPoolSDNode>(Ptr) ||
+      isa<GlobalAddressSDNode>(Ptr)) {
+    Object = Ptr; Offset = 0;
+    return true;
+  } else if (Ptr.getOpcode() == ISD::ADD &&
+             FindBaseOffset(Ptr.getOperand(0), Object, Offset)) {
+    // If it's an add of an simple constant then include it in the offset.
+    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Ptr.getOperand(1))) {
+      Offset += C->getValue();
+      return true;
+    }
+  }
+                                 
+  return false;                               
+}
+
+/// isAlias - Return true if there is the possibility that the two addresses
+/// overlap.
+bool DAGCombiner::isAlias(SDOperand Ptr1, int64_t Size1,
+                          SDOperand SrcValue1,
+                          SDOperand Ptr2, int64_t Size2,
+                          SDOperand SrcValue2) {
+  // If they are the same then they must be aliases.
+  if (Ptr1 == Ptr2) return true;
+  
+  // Gather base offset information.  Objects can be frame variables, globals
+  // or constants.
+  SDOperand Object1, Object2;
+  int64_t Offset1, Offset2;
+  if (FindBaseOffset(Ptr1, Object1, Offset1) &&
+      FindBaseOffset(Ptr2, Object2, Offset2)) {
+    // If they have a different base address, then they can't alias.
+    if (Object1 != Object2) return false;
+    
+    // Check to see if the addresses overlap.
+    if ((Offset1 + Size1) <= Offset2 || (Offset2 + Size2) <= Offset1)
+      return false;
+  }
+  
+  // Otherwise we don't know and have to play it safe.
+  return true;
+}
+
+/// FindAliasInfo - Extracts the relevant alias information from the memory
+/// node.
+void DAGCombiner::FindAliasInfo(SDNode *N,
+                          SDOperand &Ptr, int64_t &Size, SDOperand &SrcValue) {
+  switch (N->getOpcode()) {
+  case ISD::LOAD:
+    Ptr = N->getOperand(1);
+    Size = MVT::getSizeInBits(N->getOperand(1).getValueType()) >> 3;
+    SrcValue = N->getOperand(2);
+    break;
+  case ISD::STORE:
+    Ptr = N->getOperand(2);
+    Size = MVT::getSizeInBits(N->getOperand(1).getValueType()) >> 3;
+    SrcValue = N->getOperand(3);
+    break;
+  default:
+    assert(0 && "getAliasInfo expected a memory op");
+  }
+}
+
+/// hasChain - Return true if Op has a chain.  Provides chain if present.
+///
+bool DAGCombiner::hasChain(SDOperand Op, SDOperand &Chain) {
+  if (Op.getNumOperands() == 0) return false;
+  Chain = Op.getOperand(0);
+  return Chain.getValueType() == MVT::Other;
+}
+
+/// FindBetterChain - Walk up chain skipping non-aliasing memory nodes, looking
+/// for a better chain.
+SDOperand DAGCombiner::FindBetterChain(SDNode *N, SDOperand Chain) {
+  // Get alias information for node.
+  SDOperand Ptr;
+  int64_t Size;
+  SDOperand SrcValue;
+  FindAliasInfo(N, Ptr, Size, SrcValue);
+
+  // While we don't encounter any aliasing memory nodes walk up chain.
+  while (true) {
+    switch (Chain.getOpcode()) {
+    case ISD::EntryToken:
+      // Entry token is ideal chain operand.
+      return Chain;
+    case ISD::LOAD:
+    case ISD::STORE: {
+      // Get alias information for chain.
+      SDOperand ChainPtr;
+      int64_t ChainSize;
+      SDOperand ChainSrcValue;
+      FindAliasInfo(Chain.Val, ChainPtr, ChainSize, ChainSrcValue);
+      
+      // If chain is alias then stop here, otherwise continue up chain.
+      if (isAlias(Ptr, Size, SrcValue, ChainPtr, ChainSize, ChainSrcValue))
+        return Chain;
+      else
+        Chain = Chain.getOperand(0);
+      
+      break;
+    }
+    case ISD::TokenFactor: {
+      // Continue up each of token factor operand and accumulate results in
+      // a new token factor.  CSE will handle duplicate elimination.
+      SmallVector<SDOperand, 8> Ops;  // Ops for replacing token factor.
+      bool Change = false;
+      
+      // For each token factor operand. 
+      for (unsigned i = 0, e = Chain.getNumOperands(); i != e; ++i) {
+        SDOperand Op = Chain.getOperand(i);
+        SDOperand OpChain = FindBetterChain(N, Op);
+        
+        // Make sure we don't duplicate an operand.
+        if (OpChain.getOpcode() != ISD::EntryToken &&
+            std::find(Ops.begin(), Ops.end(), OpChain) == Ops.end()) {
+          Ops.push_back(OpChain);
+        }
+        
+        // If we added a new operand.
+        Change = Change || Op != OpChain; 
+      }
+      
+      // If we have new operands.
+      if (Change) {
+        // Create a specialized token factor for this chain. getNode CSE will
+        // handle duplicates. If it's a single operand, getNode will just
+        // return the opernand instead of a new token factor.
+        return DAG.getNode(ISD::TokenFactor, MVT::Other, &Ops[0], Ops.size());
+      }
+      
+      // Leave things alone.
+      return Chain;
+    }
+    // For all other instructions we will just have to take what we can get.
+    default: return Chain;
+    }
+  }
+  
+  return Chain;
+}
+
 // SelectionDAG::Combine - This is the entry point for the file.
 //
 void SelectionDAG::Combine(bool RunningAfterLegalize) {
