diff options
| author | Andrew Kaylor <andrew.kaylor@intel.com> | 2015-11-23 19:16:15 +0000 |
|---|---|---|
| committer | Andrew Kaylor <andrew.kaylor@intel.com> | 2015-11-23 19:16:15 +0000 |
| commit | d0430e85808b2ef6f71d0383b201d608b0d1955a (patch) | |
| tree | ff21895c1aad8e5a1efd0813d7172603f42f7130 /llvm/test/Transforms/CodeGenPrepare | |
| parent | f6857223c9fd534825cd8307b9cb37ada230ec83 (diff) | |
| download | bcm5719-llvm-d0430e85808b2ef6f71d0383b201d608b0d1955a.tar.gz bcm5719-llvm-d0430e85808b2ef6f71d0383b201d608b0d1955a.zip | |
[WinEH] Fix problem where CodeGenPrepare incorrectly sinks a bitcast into an EH pad.
Differential Revision: http://reviews.llvm.org/D14842
llvm-svn: 253902
Diffstat (limited to 'llvm/test/Transforms/CodeGenPrepare')
| -rw-r--r-- | llvm/test/Transforms/CodeGenPrepare/catchpad-phi-cast.ll | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/llvm/test/Transforms/CodeGenPrepare/catchpad-phi-cast.ll b/llvm/test/Transforms/CodeGenPrepare/catchpad-phi-cast.ll new file mode 100644 index 00000000000..998ca7069c8 --- /dev/null +++ b/llvm/test/Transforms/CodeGenPrepare/catchpad-phi-cast.ll @@ -0,0 +1,59 @@ +; RUN: opt -codegenprepare -S < %s | FileCheck %s + +; The following target lines are needed for the test to exercise what it should. +; Without these lines, CodeGenPrepare does not try to sink the bitcasts. +target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-windows-msvc" + +declare i32 @__CxxFrameHandler3(...) + +declare void @f() + +declare void @g(i8*) + +; CodeGenPrepare will want to sink these bitcasts, but it selects the catchpad +; blocks as the place to which the bitcast should be sunk. Since catchpads +; do not allow non-phi instructions before the terminator, this isn't possible. + +; CHECK-LABEL: @test( +define void @test(i32* %addr) personality i32 (...)* @__CxxFrameHandler3 { +; CHECK: entry: +; CHECK-NEXT: %x = getelementptr i32, i32* %addr, i32 1 +; CHECK-NEXT: %p1 = bitcast i32* %x to i8* +entry: + %x = getelementptr i32, i32* %addr, i32 1 + %p1 = bitcast i32* %x to i8* + invoke void @f() + to label %invoke.cont unwind label %catch1 + +; CHECK: invoke.cont: +; CHECK-NEXT: %y = getelementptr i32, i32* %addr, i32 2 +; CHECK-NEXT: %p2 = bitcast i32* %y to i8* +invoke.cont: + %y = getelementptr i32, i32* %addr, i32 2 + %p2 = bitcast i32* %y to i8* + invoke void @f() + to label %done unwind label %catch2 + +done: + ret void + +catch1: + %cp1 = catchpad [] to label %catch.dispatch unwind label %catchend1 + +catch2: + %cp2 = catchpad [] to label %catch.dispatch unwind label %catchend2 + +; CHECK: catch.dispatch: +; CHECK-NEXT: %p = phi i8* [ %p1, %catch1 ], [ %p2, %catch2 ] +catch.dispatch: + %p = phi i8* [ %p1, %catch1 ], [ %p2, %catch2 ] + call void @g(i8* %p) + unreachable + +catchend1: + catchendpad unwind to caller + +catchend2: + catchendpad unwind to caller +} |

