[WinEH] Simplify unreachable catchpads
[oota-llvm.git] / test / Transforms / SimplifyCFG / empty-catchpad.ll
1 ; RUN: opt < %s -simplifycfg -S | FileCheck %s
2
3 declare void @f()
4 declare void @llvm.foo(i32) nounwind
5 declare void @ProcessCLRException()
6
7 define void @test1() personality void ()* @ProcessCLRException {
8 entry:
9   invoke void @f()
10     to label %exit unwind label %exn.dispatch
11 exn.dispatch:
12   %cs = catchswitch within none [label %pad1, label %pad2] unwind to caller
13 pad1:
14   %cp1 = catchpad within %cs [i32 1]
15   call void @llvm.foo(i32 1)
16   catchret from %cp1 to label %exit
17 pad2:
18   %cp2 = catchpad within %cs [i32 2]
19   unreachable
20 exit:
21   ret void
22 }
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
26 ; CHECK-NOT: catchpad
27 ; CHECK: %cp1 = catchpad within %cs [i32 1]
28 ; CHECK-NOT: catchpad
29
30 ; Remove both catchpads and the catchswitch from exn.dispatch
31 ; CHECK-LABEL: define void @test2()
32 define void @test2() personality void ()* @ProcessCLRException {
33 entry:
34   invoke void @f()
35     to label %via.cleanup unwind label %exn.dispatch
36   ; CHECK-NOT: invoke
37   ; CHECK: call void @f()
38 via.cleanup:
39   invoke void @f()
40     to label %via.catchswitch unwind label %cleanup.inner
41 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
46 via.catchswitch:
47   invoke void @f()
48     to label %exit unwind label %dispatch.inner
49 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
52 pad.inner:
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
57 exn.dispatch:
58   %cs = catchswitch within none [label %pad1, label %pad2] unwind to caller
59   ; CHECK-NOT: catchswitch within
60   ; CHECK-NOT: catchpad
61 pad1:
62   catchpad within %cs [i32 1]
63   unreachable
64 pad2:
65   catchpad within %cs [i32 2]
66   unreachable
67 exit:
68   ret void
69 }
70
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 {
75 entry:
76   invoke void @f()
77     to label %via.cleanup unwind label %exn.dispatch
78   ; CHECK: invoke void @f()
79   ; CHECK-NEXT: to label %via.cleanup unwind label %cleanup
80 via.cleanup:
81   invoke void @f()
82     to label %via.catchswitch unwind label %cleanup.inner
83 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
88 via.catchswitch:
89   invoke void @f()
90     to label %exit unwind label %dispatch.inner
91 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
94 pad.inner:
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
99 exn.dispatch:
100   %cs = catchswitch within none [label %pad1, label %pad2] unwind label %cleanup
101   ; CHECK-NOT: catchswitch within
102   ; CHECK-NOT: catchpad
103 pad1:
104   catchpad within %cs [i32 1]
105   unreachable
106 pad2:
107   catchpad within %cs [i32 2]
108   unreachable
109 cleanup:
110   %cp = cleanuppad within none []
111   call void @llvm.foo(i32 0)
112   cleanupret from %cp unwind to caller
113 exit:
114   ret void
115 }