diff options
| author | Joseph Tremoulet <jotrem@microsoft.com> | 2016-01-05 02:37:41 +0000 |
|---|---|---|
| committer | Joseph Tremoulet <jotrem@microsoft.com> | 2016-01-05 02:37:41 +0000 |
| commit | 0d808888c141971d8750cf151029db2131aca5a1 (patch) | |
| tree | 6ae5b882e591073377b1e1689d1a1c941c8d7068 /llvm/test/Transforms | |
| parent | 869be0a4a6ba22cdedcefad13bcad8bbcb39e273 (diff) | |
| download | bcm5719-llvm-0d808888c141971d8750cf151029db2131aca5a1.tar.gz bcm5719-llvm-0d808888c141971d8750cf151029db2131aca5a1.zip | |
[WinEH] Simplify unreachable catchpads
Summary:
At least for CoreCLR, a catchpad which immediately executes an
`unreachable` instruction indicates that the exception can never have a
matching type, and so such catchpads can be removed, and so can their
catchswitches if the catchswitch becomes empty.
Reviewers: rnk, andrew.w.kaylor, majnemer
Subscribers: llvm-commits
Differential Revision: http://reviews.llvm.org/D15846
llvm-svn: 256809
Diffstat (limited to 'llvm/test/Transforms')
| -rw-r--r-- | llvm/test/Transforms/SimplifyCFG/empty-catchpad.ll | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/llvm/test/Transforms/SimplifyCFG/empty-catchpad.ll b/llvm/test/Transforms/SimplifyCFG/empty-catchpad.ll new file mode 100644 index 00000000000..2926cd3f7dc --- /dev/null +++ b/llvm/test/Transforms/SimplifyCFG/empty-catchpad.ll @@ -0,0 +1,115 @@ +; RUN: opt < %s -simplifycfg -S | FileCheck %s + +declare void @f() +declare void @llvm.foo(i32) nounwind +declare void @ProcessCLRException() + +define void @test1() personality void ()* @ProcessCLRException { +entry: + invoke void @f() + to label %exit unwind label %exn.dispatch +exn.dispatch: + %cs = catchswitch within none [label %pad1, label %pad2] unwind to caller +pad1: + %cp1 = catchpad within %cs [i32 1] + call void @llvm.foo(i32 1) + catchret from %cp1 to label %exit +pad2: + %cp2 = catchpad within %cs [i32 2] + unreachable +exit: + ret void +} +; Remove unreachble catch2, leave catch1 as-is +; CHECK-LABEL: define void @test1() +; CHECK: %cs = catchswitch within none [label %pad1] unwind to caller +; CHECK-NOT: catchpad +; CHECK: %cp1 = catchpad within %cs [i32 1] +; CHECK-NOT: catchpad + +; Remove both catchpads and the catchswitch from exn.dispatch +; CHECK-LABEL: define void @test2() +define void @test2() personality void ()* @ProcessCLRException { +entry: + invoke void @f() + to label %via.cleanup unwind label %exn.dispatch + ; CHECK-NOT: invoke + ; CHECK: call void @f() +via.cleanup: + invoke void @f() + to label %via.catchswitch unwind label %cleanup.inner +cleanup.inner: + %cp.inner = cleanuppad within none [] + call void @llvm.foo(i32 0) + cleanupret from %cp.inner unwind label %exn.dispatch + ; CHECK: cleanupret from %cp.inner unwind to caller +via.catchswitch: + invoke void @f() + to label %exit unwind label %dispatch.inner +dispatch.inner: + %cs.inner = catchswitch within none [label %pad.inner] unwind label %exn.dispatch + ; CHECK: %cs.inner = catchswitch within none [label %pad.inner] unwind to caller +pad.inner: + %catch.inner = catchpad within %cs.inner [i32 0] + ; CHECK: %catch.inner = catchpad within %cs.inner + call void @llvm.foo(i32 1) + catchret from %catch.inner to label %exit +exn.dispatch: + %cs = catchswitch within none [label %pad1, label %pad2] unwind to caller + ; CHECK-NOT: catchswitch within + ; CHECK-NOT: catchpad +pad1: + catchpad within %cs [i32 1] + unreachable +pad2: + catchpad within %cs [i32 2] + unreachable +exit: + ret void +} + +; Same as @test2, but exn.dispatch catchswitch has an unwind dest that +; preds need to be reidrected to +; CHECK-LABEL: define void @test3() +define void @test3() personality void ()* @ProcessCLRException { +entry: + invoke void @f() + to label %via.cleanup unwind label %exn.dispatch + ; CHECK: invoke void @f() + ; CHECK-NEXT: to label %via.cleanup unwind label %cleanup +via.cleanup: + invoke void @f() + to label %via.catchswitch unwind label %cleanup.inner +cleanup.inner: + %cp.inner = cleanuppad within none [] + call void @llvm.foo(i32 0) + cleanupret from %cp.inner unwind label %exn.dispatch + ; CHECK: cleanupret from %cp.inner unwind label %cleanup +via.catchswitch: + invoke void @f() + to label %exit unwind label %dispatch.inner +dispatch.inner: + %cs.inner = catchswitch within none [label %pad.inner] unwind label %exn.dispatch + ; CHECK: %cs.inner = catchswitch within none [label %pad.inner] unwind label %cleanup +pad.inner: + %catch.inner = catchpad within %cs.inner [i32 0] + ; CHECK: %catch.inner = catchpad within %cs.inner + call void @llvm.foo(i32 1) + catchret from %catch.inner to label %exit +exn.dispatch: + %cs = catchswitch within none [label %pad1, label %pad2] unwind label %cleanup + ; CHECK-NOT: catchswitch within + ; CHECK-NOT: catchpad +pad1: + catchpad within %cs [i32 1] + unreachable +pad2: + catchpad within %cs [i32 2] + unreachable +cleanup: + %cp = cleanuppad within none [] + call void @llvm.foo(i32 0) + cleanupret from %cp unwind to caller +exit: + ret void +} |

