summaryrefslogtreecommitdiff
path: root/test
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
commitc628af024e7f1716161241e1e3fb7037b6a078fa (patch)
tree306f345521efeca1ff304a89fd9d8c2290bcc1ae /test
parent0afd0bc5facb63a96c706dc8a2468327ee3161da (diff)
downloadllvm-c628af024e7f1716161241e1e3fb7037b6a078fa.tar.gz
llvm-c628af024e7f1716161241e1e3fb7037b6a078fa.tar.bz2
llvm-c628af024e7f1716161241e1e3fb7037b6a078fa.tar.xz
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200201 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r--test/CodeGen/Generic/stores-merging.ll23
1 files changed, 23 insertions, 0 deletions
diff --git a/test/CodeGen/Generic/stores-merging.ll b/test/CodeGen/Generic/stores-merging.ll
new file mode 100644
index 0000000000..61dea08899
--- /dev/null
+++ b/test/CodeGen/Generic/stores-merging.ll
@@ -0,0 +1,23 @@
+; RUN: llc < %s | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+%structTy = type { i8, i32, i32 }
+
+@e = common global %structTy zeroinitializer, align 4
+
+; CHECK-LABEL: f
+define void @f() {
+entry:
+
+; CHECK: movabsq $528280977409, %rax
+; CHECK: movq %rax, e+4(%rip)
+; CHECK: movl $456, e+8(%rip)
+
+ store i32 1, i32* getelementptr inbounds (%structTy* @e, i64 0, i32 1), align 4
+ store i32 123, i32* getelementptr inbounds (%structTy* @e, i64 0, i32 2), align 4
+ store i32 456, i32* getelementptr inbounds (%structTy* @e, i64 0, i32 2), align 4
+ ret void
+}
+