1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals
2 ; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
5 declare void @llvm.foo(i32) nounwind
6 declare void @ProcessCLRException()
8 define void @test1() personality ptr @ProcessCLRException {
11 ; CHECK-NEXT: invoke void @f()
12 ; CHECK-NEXT: to label [[EXIT:%.*]] unwind label [[EXN_DISPATCH:%.*]]
13 ; CHECK: exn.dispatch:
14 ; CHECK-NEXT: [[CS:%.*]] = catchswitch within none [label %pad1] unwind to caller
16 ; CHECK-NEXT: [[CP1:%.*]] = catchpad within [[CS]] [i32 1]
17 ; CHECK-NEXT: call void @llvm.foo(i32 1)
18 ; CHECK-NEXT: catchret from [[CP1]] to label [[EXIT]]
20 ; CHECK-NEXT: ret void
24 to label %exit unwind label %exn.dispatch
26 %cs = catchswitch within none [label %pad1, label %pad2] unwind to caller
28 %cp1 = catchpad within %cs [i32 1]
29 call void @llvm.foo(i32 1)
30 catchret from %cp1 to label %exit
32 %cp2 = catchpad within %cs [i32 2]
37 ; Remove unreachble catch2, leave catch1 as-is
39 ; Remove both catchpads and the catchswitch from exn.dispatch
40 define void @test2() personality ptr @ProcessCLRException {
41 ; CHECK-LABEL: @test2(
43 ; CHECK-NEXT: call void @f()
44 ; CHECK-NEXT: invoke void @f()
45 ; CHECK-NEXT: to label [[VIA_CATCHSWITCH:%.*]] unwind label [[CLEANUP_INNER:%.*]]
46 ; CHECK: cleanup.inner:
47 ; CHECK-NEXT: [[CP_INNER:%.*]] = cleanuppad within none []
48 ; CHECK-NEXT: call void @llvm.foo(i32 0)
49 ; CHECK-NEXT: cleanupret from [[CP_INNER]] unwind to caller
50 ; CHECK: via.catchswitch:
51 ; CHECK-NEXT: invoke void @f()
52 ; CHECK-NEXT: to label [[EXIT:%.*]] unwind label [[DISPATCH_INNER:%.*]]
53 ; CHECK: dispatch.inner:
54 ; CHECK-NEXT: [[CS_INNER:%.*]] = catchswitch within none [label %pad.inner] unwind to caller
56 ; CHECK-NEXT: [[CATCH_INNER:%.*]] = catchpad within [[CS_INNER]] [i32 0]
57 ; CHECK-NEXT: call void @llvm.foo(i32 1)
58 ; CHECK-NEXT: catchret from [[CATCH_INNER]] to label [[EXIT]]
60 ; CHECK-NEXT: ret void
64 to label %via.cleanup unwind label %exn.dispatch
67 to label %via.catchswitch unwind label %cleanup.inner
69 %cp.inner = cleanuppad within none []
70 call void @llvm.foo(i32 0)
71 cleanupret from %cp.inner unwind label %exn.dispatch
74 to label %exit unwind label %dispatch.inner
76 %cs.inner = catchswitch within none [label %pad.inner] unwind label %exn.dispatch
78 %catch.inner = catchpad within %cs.inner [i32 0]
79 call void @llvm.foo(i32 1)
80 catchret from %catch.inner to label %exit
82 %cs = catchswitch within none [label %pad1, label %pad2] unwind to caller
84 catchpad within %cs [i32 1]
87 catchpad within %cs [i32 2]
93 ; Same as @test2, but exn.dispatch catchswitch has an unwind dest that
94 ; preds need to be reidrected to
95 define void @test3() personality ptr @ProcessCLRException {
96 ; CHECK-LABEL: @test3(
98 ; CHECK-NEXT: invoke void @f()
99 ; CHECK-NEXT: to label [[VIA_CLEANUP:%.*]] unwind label [[CLEANUP:%.*]]
100 ; CHECK: via.cleanup:
101 ; CHECK-NEXT: invoke void @f()
102 ; CHECK-NEXT: to label [[VIA_CATCHSWITCH:%.*]] unwind label [[CLEANUP_INNER:%.*]]
103 ; CHECK: cleanup.inner:
104 ; CHECK-NEXT: [[CP_INNER:%.*]] = cleanuppad within none []
105 ; CHECK-NEXT: call void @llvm.foo(i32 0)
106 ; CHECK-NEXT: cleanupret from [[CP_INNER]] unwind label [[CLEANUP]]
107 ; CHECK: via.catchswitch:
108 ; CHECK-NEXT: invoke void @f()
109 ; CHECK-NEXT: to label [[EXIT:%.*]] unwind label [[DISPATCH_INNER:%.*]]
110 ; CHECK: dispatch.inner:
111 ; CHECK-NEXT: [[CS_INNER:%.*]] = catchswitch within none [label %pad.inner] unwind label [[CLEANUP]]
113 ; CHECK-NEXT: [[CATCH_INNER:%.*]] = catchpad within [[CS_INNER]] [i32 0]
114 ; CHECK-NEXT: call void @llvm.foo(i32 1)
115 ; CHECK-NEXT: catchret from [[CATCH_INNER]] to label [[EXIT]]
117 ; CHECK-NEXT: [[CP:%.*]] = cleanuppad within none []
118 ; CHECK-NEXT: call void @llvm.foo(i32 0)
119 ; CHECK-NEXT: cleanupret from [[CP]] unwind to caller
121 ; CHECK-NEXT: ret void
125 to label %via.cleanup unwind label %exn.dispatch
128 to label %via.catchswitch unwind label %cleanup.inner
130 %cp.inner = cleanuppad within none []
131 call void @llvm.foo(i32 0)
132 cleanupret from %cp.inner unwind label %exn.dispatch
135 to label %exit unwind label %dispatch.inner
137 %cs.inner = catchswitch within none [label %pad.inner] unwind label %exn.dispatch
139 %catch.inner = catchpad within %cs.inner [i32 0]
140 call void @llvm.foo(i32 1)
141 catchret from %catch.inner to label %exit
143 %cs = catchswitch within none [label %pad1, label %pad2] unwind label %cleanup
145 catchpad within %cs [i32 1]
148 catchpad within %cs [i32 2]
151 %cp = cleanuppad within none []
152 call void @llvm.foo(i32 0)
153 cleanupret from %cp unwind to caller
158 ; CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind }