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 | 5da0ff41d7d43e246081f9379b8dec91364624d1 (patch) | |
| tree | d8872b8a8dd06d78a828967f4e163c284f6f102a /llvm/test/Transforms/MemCpyOpt | |
| parent | 8a742f5f379146fd695e7fd8600e0ce84df21a30 (diff) | |
| download | bcm5719-llvm-5da0ff41d7d43e246081f9379b8dec91364624d1.tar.gz bcm5719-llvm-5da0ff41d7d43e246081f9379b8dec91364624d1.zip | |
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.
llvm-svn: 132485
Diffstat (limited to 'llvm/test/Transforms/MemCpyOpt')
| -rw-r--r-- | llvm/test/Transforms/MemCpyOpt/2011-06-02-CallSlotOverwritten.ll | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/llvm/test/Transforms/MemCpyOpt/2011-06-02-CallSlotOverwritten.ll b/llvm/test/Transforms/MemCpyOpt/2011-06-02-CallSlotOverwritten.ll new file mode 100644 index 00000000000..132966ef6b9 --- /dev/null +++ b/llvm/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 +} |

