diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 37d7731aa15..5659069178b 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -291,6 +291,10 @@ namespace { unsigned SrcValueAlign2, const MDNode *TBAAInfo2) const; + /// isAlias - Return true if there is any possibility that the two addresses + /// overlap. + bool isAlias(LSBaseSDNode *Op0, LSBaseSDNode *Op1); + /// FindAliasInfo - Extracts the relevant alias information from the memory /// node. Returns true if the operand was a load. bool FindAliasInfo(SDNode *N, @@ -7552,7 +7556,14 @@ bool DAGCombiner::MergeConsecutiveStores(StoreSDNode* St) { if (BasePtr.first.getOpcode() == ISD::UNDEF) return false; + // Save the LoadSDNodes that we find in the chain. + // We need to make sure that these nodes do not interfere with + // any of the store nodes. + SmallVector AliasLoadNodes; + + // Save the StoreSDNodes that we find in the chain. SmallVector StoreNodes; + // Walk up the chain and look for nodes with offsets from the same // base pointer. Stop when reaching an instruction with a different kind // or instruction which has a different base pointer. @@ -7596,8 +7607,26 @@ bool DAGCombiner::MergeConsecutiveStores(StoreSDNode* St) { // We found a potential memory operand to merge. StoreNodes.push_back(MemOpLink(Index, Ptr.second, Seq++)); - // Move up the chain to the next memory operation. - Index = dyn_cast(Index->getChain().getNode()); + // Find the next memory operand in the chain. If the next operand in the + // chain is a store then move up and continue the scan with the next + // memory operand. If the next operand is a load save it and use alias + // information to check if it interferes with anything. + SDNode *NextInChain = Index->getChain().getNode(); + while (1) { + if (isa(NextInChain)) { + // We found a store node. Use it for the next iteration. + Index = cast(NextInChain); + break; + } else if (LoadSDNode *Ldn = dyn_cast(NextInChain)) { + // Save the load node for later. Continue the scan. + AliasLoadNodes.push_back(Ldn); + NextInChain = Ldn->getChain().getNode(); + continue; + } else { + Index = NULL; + break; + } + } } // Check if there is anything to merge. @@ -7612,11 +7641,23 @@ bool DAGCombiner::MergeConsecutiveStores(StoreSDNode* St) { // store memory address. unsigned LastConsecutiveStore = 0; int64_t StartAddress = StoreNodes[0].OffsetFromBase; - for (unsigned i=1; i