diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2011-06-02 21:24:42 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2011-06-02 21:24:42 +0000 |
commit | 70d893e84b0de21205ad042c6c00148d0e3cd74e (patch) | |
tree | f07f97f31afbffebe6158cd2fea7067a6eba3299 /test/Transforms/MemCpyOpt | |
parent | cf4cc84738abc5f63a05b0956e756c66c519ded5 (diff) | |
download | llvm-70d893e84b0de21205ad042c6c00148d0e3cd74e.tar.gz llvm-70d893e84b0de21205ad042c6c00148d0e3cd74e.tar.bz2 llvm-70d893e84b0de21205ad042c6c00148d0e3cd74e.tar.xz |
PR10067: Add missing safety check to call return transformation in MemCpyOpt::processStore. If something accesses the dest of the "copy" between the call and the copy, the performCallSlotOptzn transformation is not valid.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132485 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Transforms/MemCpyOpt')
-rw-r--r-- | test/Transforms/MemCpyOpt/2011-06-02-CallSlotOverwritten.ll | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/test/Transforms/MemCpyOpt/2011-06-02-CallSlotOverwritten.ll b/test/Transforms/MemCpyOpt/2011-06-02-CallSlotOverwritten.ll new file mode 100644 index 0000000000..132966ef6b --- /dev/null +++ b/test/Transforms/MemCpyOpt/2011-06-02-CallSlotOverwritten.ll @@ -0,0 +1,36 @@ +; RUN: opt < %s -basicaa -memcpyopt -S | FileCheck %s +; PR10067 +; Make sure the call+copy isn't optimized in such a way that +; %ret ends up with the wrong value. + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32" +target triple = "i386-apple-darwin10" + +%struct1 = type { i32, i32 } +%struct2 = type { %struct1, i8* } + +declare void @bar(%struct1* nocapture sret %agg.result) nounwind + +define i32 @foo() nounwind { + %x = alloca %struct1, align 8 + %y = alloca %struct2, align 8 + call void @bar(%struct1* sret %x) nounwind +; CHECK: call void @bar(%struct1* sret %x) + + %gepn1 = getelementptr inbounds %struct2* %y, i32 0, i32 0, i32 0 + store i32 0, i32* %gepn1, align 8 + %gepn2 = getelementptr inbounds %struct2* %y, i32 0, i32 0, i32 1 + store i32 0, i32* %gepn2, align 4 + + %bit1 = bitcast %struct1* %x to i64* + %bit2 = bitcast %struct2* %y to i64* + %load = load i64* %bit1, align 8 + store i64 %load, i64* %bit2, align 8 + +; CHECK: %load = load i64* %bit1, align 8 +; CHECK: store i64 %load, i64* %bit2, align 8 + + %gep1 = getelementptr %struct2* %y, i32 0, i32 0, i32 0 + %ret = load i32* %gep1 + ret i32 %ret +} |