Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -12844,7 +12844,19 @@ // Check if we found a legal integer type that creates a meaningful merge. if (LastLegalType < 2 && LastLegalVectorType < 2) { - StoreNodes.erase(StoreNodes.begin(), StoreNodes.begin() + 1); + // We have already checked that candidate stores are in order + // and of correct shape. While there is no mergable sequence + // from the beggining one may start later in the sequence. The + // only reason a merge of size N could have failed where + // another of the same size would not have does not is if the + // alignment has improved. Drop as many candidates as we can + // here. + unsigned NumSkip = 1; + while ((NumSkip < NumConsecutiveStores) && + (StoreNodes[NumSkip].MemNode->getAlignment() <= FirstStoreAlign)) + NumSkip++; + + StoreNodes.erase(StoreNodes.begin(), StoreNodes.begin() + NumSkip); continue; } @@ -12900,6 +12912,23 @@ NumStoresToMerge = i + 1; } + // Check if we found a legal integer type that creates a meaningful merge. + if (NumStoresToMerge < 2) { + // We have already checked that candidate stores are in order + // and of correct shape. While there is no mergable sequence + // from the beggining one may start later in the sequence. The + // only reason a merge of size N could have failed where + // another of the same size would not have does not is if the + // alignment has improved. Drop as many candidates as we can here. + unsigned NumSkip = 1; + while ((NumSkip < NumConsecutiveStores) && + (StoreNodes[NumSkip].MemNode->getAlignment() <= FirstStoreAlign)) + NumSkip++; + + StoreNodes.erase(StoreNodes.begin(), StoreNodes.begin() + NumSkip); + continue; + } + bool Merged = MergeStoresOfConstantsOrVecElts( StoreNodes, MemVT, NumStoresToMerge, false, true, false); if (!Merged) {