summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorStepan Dyatkovskiy <stpworld@narod.ru>2014-01-27 09:18:31 +0000
committerStepan Dyatkovskiy <stpworld@narod.ru>2014-01-27 09:18:31 +0000
commit157bb42e2790fa0a3331a5510bfe5a5e43377c58 (patch)
tree5d183ac00936d5395ffaf46edbe20f4d08f1bd4a /llvm/lib
parent067f54718f32ee5ccc5c0a2a65399e7ad4b9f314 (diff)
downloadbcm5719-llvm-157bb42e2790fa0a3331a5510bfe5a5e43377c58.tar.gz
bcm5719-llvm-157bb42e2790fa0a3331a5510bfe5a5e43377c58.zip
Fix for PR18102.
Issue outcomes from DAGCombiner::MergeConsequtiveStores, more precisely from mem-ops sequence sorting. Consider, how MergeConsequtiveStores works for next example: store i8 1, a[0] store i8 2, a[1] store i8 3, a[1] ; a[1] again. return ; DAG starts here 1. Method will collect all the 3 stores. 2. It sorts them by distance from the base pointer (farthest with highest index). 3. It takes first consecutive non-overlapping stores and (if possible) replaces them with a single store instruction. The point is, we can't determine here which 'store' instruction would be the second after sorting ('store 2' or 'store 3'). It happens that 'store 3' would be the second, and 'store 2' would be the third. So after merging we have the next result: store i16 (1 | 3 << 8), base ; is a[0] but bit-casted to i16 store i8 2, a[1] So actually we swapped 'store 3' and 'store 2' and got wrong contents in a[1]. Fix: In sort routine just also take into account mem-op sequence number. llvm-svn: 200201
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp5
1 files changed, 4 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index b95a6c1198d..97c19d0e9b1 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -8761,7 +8761,10 @@ struct MemOpLink {
// base ptr.
struct ConsecutiveMemoryChainSorter {
bool operator()(MemOpLink LHS, MemOpLink RHS) {
- return LHS.OffsetFromBase < RHS.OffsetFromBase;
+ return
+ LHS.OffsetFromBase < RHS.OffsetFromBase ||
+ (LHS.OffsetFromBase == RHS.OffsetFromBase &&
+ LHS.SequenceNum > RHS.SequenceNum);
}
};
OpenPOWER on IntegriCloud