diff options
| author | David Majnemer <david.majnemer@gmail.com> | 2016-05-26 19:24:24 +0000 |
|---|---|---|
| committer | David Majnemer <david.majnemer@gmail.com> | 2016-05-26 19:24:24 +0000 |
| commit | d99068d26db69f2cdaba0ad02a6bd92512f04b60 (patch) | |
| tree | ef3d5a5ff2988cdfe75cbc90f0cb34972aea0a9a /llvm/test | |
| parent | 23c12ca9226c297771ba5fefa0f047e9e2450d7b (diff) | |
| download | bcm5719-llvm-d99068d26db69f2cdaba0ad02a6bd92512f04b60.tar.gz bcm5719-llvm-d99068d26db69f2cdaba0ad02a6bd92512f04b60.zip | |
[MemCpyOpt] Don't perform callslot optimization across may-throw calls
An exception could prevent a store from occurring but MemCpyOpt's
callslot optimization would fire anyway, causing the store to occur.
This fixes PR27849.
llvm-svn: 270892
Diffstat (limited to 'llvm/test')
| -rw-r--r-- | llvm/test/Transforms/MemCpyOpt/callslot_throw.ll | 34 | ||||
| -rw-r--r-- | llvm/test/Transforms/MemCpyOpt/loadstore-sret.ll | 2 |
2 files changed, 35 insertions, 1 deletions
diff --git a/llvm/test/Transforms/MemCpyOpt/callslot_throw.ll b/llvm/test/Transforms/MemCpyOpt/callslot_throw.ll new file mode 100644 index 00000000000..1aa4c92efc7 --- /dev/null +++ b/llvm/test/Transforms/MemCpyOpt/callslot_throw.ll @@ -0,0 +1,34 @@ +; RUN: opt -S -memcpyopt < %s | FileCheck %s +declare void @may_throw(i32* nocapture %x) + +; CHECK-LABEL: define void @test1( +define void @test1(i32* nocapture noalias dereferenceable(4) %x) { +entry: + %t = alloca i32, align 4 + call void @may_throw(i32* nonnull %t) + %load = load i32, i32* %t, align 4 + store i32 %load, i32* %x, align 4 +; CHECK: %[[t:.*]] = alloca i32, align 4 +; CHECK-NEXT: call void @may_throw(i32* {{.*}} %[[t]]) +; CHECK-NEXT: %[[load:.*]] = load i32, i32* %[[t]], align 4 +; CHECK-NEXT: store i32 %[[load]], i32* %x, align 4 + ret void +} + +declare void @always_throws() + +; CHECK-LABEL: define void @test2( +define void @test2(i32* nocapture noalias dereferenceable(4) %x) { +entry: + %t = alloca i32, align 4 + call void @may_throw(i32* nonnull %t) nounwind + %load = load i32, i32* %t, align 4 + call void @always_throws() + store i32 %load, i32* %x, align 4 +; CHECK: %[[t:.*]] = alloca i32, align 4 +; CHECK-NEXT: call void @may_throw(i32* {{.*}} %[[t]]) +; CHECK-NEXT: %[[load:.*]] = load i32, i32* %[[t]], align 4 +; CHECK-NEXT: call void @always_throws() +; CHECK-NEXT: store i32 %[[load]], i32* %x, align 4 + ret void +} diff --git a/llvm/test/Transforms/MemCpyOpt/loadstore-sret.ll b/llvm/test/Transforms/MemCpyOpt/loadstore-sret.ll index 55cbe59651f..4c6136cf625 100644 --- a/llvm/test/Transforms/MemCpyOpt/loadstore-sret.ll +++ b/llvm/test/Transforms/MemCpyOpt/loadstore-sret.ll @@ -22,4 +22,4 @@ _ZNSt8auto_ptrIiED1Ev.exit: ret void } -declare void @_Z3barv(%"class.std::auto_ptr"* nocapture sret) +declare void @_Z3barv(%"class.std::auto_ptr"* nocapture sret) nounwind |

