summaryrefslogtreecommitdiffstats
path: root/llvm/test/Transforms
diff options
context:
space:
mode:
authorJoseph Tremoulet <jotrem@microsoft.com>2016-01-05 02:37:41 +0000
committerJoseph Tremoulet <jotrem@microsoft.com>2016-01-05 02:37:41 +0000
commit0d808888c141971d8750cf151029db2131aca5a1 (patch)
tree6ae5b882e591073377b1e1689d1a1c941c8d7068 /llvm/test/Transforms
parent869be0a4a6ba22cdedcefad13bcad8bbcb39e273 (diff)
downloadbcm5719-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.ll115
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
+}
OpenPOWER on IntegriCloud