1 ; RUN: opt < %s -simplifycfg -S | FileCheck %s
4 declare void @llvm.foo(i32) nounwind
5 declare void @ProcessCLRException()
7 define void @test1() personality void ()* @ProcessCLRException {
10 to label %exit unwind label %exn.dispatch
12 %cs = catchswitch within none [label %pad1, label %pad2] unwind to caller
14 %cp1 = catchpad within %cs [i32 1]
15 call void @llvm.foo(i32 1)
16 catchret from %cp1 to label %exit
18 %cp2 = catchpad within %cs [i32 2]
23 ; Remove unreachble catch2, leave catch1 as-is
24 ; CHECK-LABEL: define void @test1()
25 ; CHECK: %cs = catchswitch within none [label %pad1] unwind to caller
27 ; CHECK: %cp1 = catchpad within %cs [i32 1]
30 ; Remove both catchpads and the catchswitch from exn.dispatch
31 ; CHECK-LABEL: define void @test2()
32 define void @test2() personality void ()* @ProcessCLRException {
35 to label %via.cleanup unwind label %exn.dispatch
37 ; CHECK: call void @f()
40 to label %via.catchswitch unwind label %cleanup.inner
42 %cp.inner = cleanuppad within none []
43 call void @llvm.foo(i32 0)
44 cleanupret from %cp.inner unwind label %exn.dispatch
45 ; CHECK: cleanupret from %cp.inner unwind to caller
48 to label %exit unwind label %dispatch.inner
50 %cs.inner = catchswitch within none [label %pad.inner] unwind label %exn.dispatch
51 ; CHECK: %cs.inner = catchswitch within none [label %pad.inner] unwind to caller
53 %catch.inner = catchpad within %cs.inner [i32 0]
54 ; CHECK: %catch.inner = catchpad within %cs.inner
55 call void @llvm.foo(i32 1)
56 catchret from %catch.inner to label %exit
58 %cs = catchswitch within none [label %pad1, label %pad2] unwind to caller
59 ; CHECK-NOT: catchswitch within
62 catchpad within %cs [i32 1]
65 catchpad within %cs [i32 2]
71 ; Same as @test2, but exn.dispatch catchswitch has an unwind dest that
72 ; preds need to be reidrected to
73 ; CHECK-LABEL: define void @test3()
74 define void @test3() personality void ()* @ProcessCLRException {
77 to label %via.cleanup unwind label %exn.dispatch
78 ; CHECK: invoke void @f()
79 ; CHECK-NEXT: to label %via.cleanup unwind label %cleanup
82 to label %via.catchswitch unwind label %cleanup.inner
84 %cp.inner = cleanuppad within none []
85 call void @llvm.foo(i32 0)
86 cleanupret from %cp.inner unwind label %exn.dispatch
87 ; CHECK: cleanupret from %cp.inner unwind label %cleanup
90 to label %exit unwind label %dispatch.inner
92 %cs.inner = catchswitch within none [label %pad.inner] unwind label %exn.dispatch
93 ; CHECK: %cs.inner = catchswitch within none [label %pad.inner] unwind label %cleanup
95 %catch.inner = catchpad within %cs.inner [i32 0]
96 ; CHECK: %catch.inner = catchpad within %cs.inner
97 call void @llvm.foo(i32 1)
98 catchret from %catch.inner to label %exit
100 %cs = catchswitch within none [label %pad1, label %pad2] unwind label %cleanup
101 ; CHECK-NOT: catchswitch within
102 ; CHECK-NOT: catchpad
104 catchpad within %cs [i32 1]
107 catchpad within %cs [i32 2]
110 %cp = cleanuppad within none []
111 call void @llvm.foo(i32 0)
112 cleanupret from %cp unwind to caller