Index: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -12375,6 +12375,27 @@ return LHS.OffsetFromBase < RHS.OffsetFromBase; }); + // Store Merge attempts to merge the lowest stores. This generally + // works out as if successful, as the remaining stores are checked + // after the first collection of stores is merged. However, in the + // case that a non-mergeable store is found first, e.g., {p[-2], + // p[0], p[1], p[2], p[3]}, we would fail and miss the subsequent + // mergeable cases. To prevent this, we prune such stores from the + // front of StoreNodes here. + + unsigned StartIdx = 0; + while ((StartIdx + 1 < StoreNodes.size()) && + StoreNodes[StartIdx].OffsetFromBase + ElementSizeBytes != + StoreNodes[StartIdx + 1].OffsetFromBase) + ++StartIdx; + + // Bail if we don't have enough candidates to merge. + if (StartIdx + 1 >= StoreNodes.size()) + return false; + + if (StartIdx) + StoreNodes.erase(StoreNodes.begin(), StoreNodes.begin() + StartIdx); + // Scan the memory operations on the chain and find the first non-consecutive // store memory address. unsigned NumConsecutiveStores = 0; Index: llvm/trunk/test/CodeGen/AArch64/arm64-abi.ll =================================================================== --- llvm/trunk/test/CodeGen/AArch64/arm64-abi.ll +++ llvm/trunk/test/CodeGen/AArch64/arm64-abi.ll @@ -43,9 +43,7 @@ ; CHECK-LABEL: i8i16caller ; The 8th, 9th, 10th and 11th arguments are passed at sp, sp+2, sp+4, sp+5. ; They are i8, i16, i8 and i8. -; CHECK-DAG: strb {{w[0-9]+}}, [sp, #5] -; CHECK-DAG: strb {{w[0-9]+}}, [sp, #4] -; CHECK-DAG: strh {{w[0-9]+}}, [sp, #2] +; CHECK-DAG: stur {{w[0-9]+}}, [sp, #2] ; CHECK-DAG: strb {{w[0-9]+}}, [sp] ; CHECK: bl ; FAST-LABEL: i8i16caller Index: llvm/trunk/test/CodeGen/X86/MergeConsecutiveStores.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/MergeConsecutiveStores.ll +++ llvm/trunk/test/CodeGen/X86/MergeConsecutiveStores.ll @@ -596,14 +596,8 @@ store i8 3, i8* %p3 ret void ; CHECK-LABEL: almost_consecutive_stores -; CHECK-DAG: movb $0, (%rdi) -; CHECK-DAG: movb $1, 42(%rdi) -; CHECK-DAG: movb $2, 2(%rdi) -; CHECK-DAG: movb $3, 3(%rdi) +; CHECK-DAG: movb $0, (%rdi) +; CHECK-DAG: movb $1, 42(%rdi) +; CHECK-DAG: movw $770, 2(%rdi) ; CHECK: retq - -; We should able to merge the final two stores into a 16-bit store -; FIXMECHECK-DAG: movw $770, 2(%rdi) - - }