1 ; RUN: opt -mtriple=x86_64-linux-gnu -dwarfehprepare -simplifycfg-require-and-preserve-domtree=1 -run-twice < %s -S | FileCheck %s
3 ; Check basic functionality of IR-to-IR DWARF EH preparation. This should
4 ; eliminate resumes. This pass requires a TargetMachine, so we put it under X86
5 ; and provide an x86 triple.
7 @int_typeinfo = global i8 0
9 declare void @might_throw()
10 declare void @cleanup()
12 define i32 @simple_cleanup_catch() personality ptr @__gxx_personality_v0 {
13 invoke void @might_throw()
14 to label %cont unwind label %lpad
16 ; CHECK-LABEL: define i32 @simple_cleanup_catch()
17 ; CHECK: invoke void @might_throw()
25 %ehvals = landingpad { ptr, i32 }
27 catch ptr @int_typeinfo
28 %ehptr = extractvalue { ptr, i32 } %ehvals, 0
29 %ehsel = extractvalue { ptr, i32 } %ehvals, 1
31 %int_sel = call i32 @llvm.eh.typeid.for(ptr @int_typeinfo)
32 %int_match = icmp eq i32 %ehsel, %int_sel
33 br i1 %int_match, label %catch_int, label %eh.resume
36 ; CHECK: landingpad { ptr, i32 }
37 ; CHECK: call void @cleanup()
38 ; CHECK: call i32 @llvm.eh.typeid.for
48 %tmp_ehvals = insertvalue { ptr, i32 } undef, ptr %ehptr, 0
49 %new_ehvals = insertvalue { ptr, i32 } %tmp_ehvals, i32 %ehsel, 1
50 resume { ptr, i32 } %new_ehvals
53 ; CHECK-NEXT: call void @_Unwind_Resume(ptr %ehptr)
57 define i32 @catch_no_resume() personality ptr @__gxx_personality_v0 {
58 invoke void @might_throw()
59 to label %cont unwind label %lpad
65 %ehvals = landingpad { ptr, i32 }
66 catch ptr @int_typeinfo
67 %ehptr = extractvalue { ptr, i32 } %ehvals, 0
68 %ehsel = extractvalue { ptr, i32 } %ehvals, 1
69 %int_sel = call i32 @llvm.eh.typeid.for(ptr @int_typeinfo)
70 %int_match = icmp eq i32 %ehsel, %int_sel
71 br i1 %int_match, label %catch_int, label %eh.resume
77 %tmp_ehvals = insertvalue { ptr, i32 } undef, ptr %ehptr, 0
78 %new_ehvals = insertvalue { ptr, i32 } %tmp_ehvals, i32 %ehsel, 1
79 resume { ptr, i32 } %new_ehvals
82 ; Check that we can prune the unreachable resume instruction.
84 ; CHECK-LABEL: define i32 @catch_no_resume() personality ptr @__gxx_personality_v0 {
85 ; CHECK: invoke void @might_throw()
88 ; CHECK: landingpad { ptr, i32 }
91 ; CHECK-NOT: call void @_Unwind_Resume
95 define i32 @catch_cleanup_merge() personality ptr @__gxx_personality_v0 {
96 invoke void @might_throw()
97 to label %inner_invoke unwind label %outer_lpad
99 invoke void @might_throw()
100 to label %cont unwind label %inner_lpad
105 %ehvals1 = landingpad { ptr, i32 }
106 catch ptr @int_typeinfo
107 br label %catch.dispatch
110 %ehvals2 = landingpad { ptr, i32 }
112 catch ptr @int_typeinfo
114 br label %catch.dispatch
117 %ehvals = phi { ptr, i32 } [ %ehvals1, %outer_lpad ], [ %ehvals2, %inner_lpad ]
118 %ehptr = extractvalue { ptr, i32 } %ehvals, 0
119 %ehsel = extractvalue { ptr, i32 } %ehvals, 1
120 %int_sel = call i32 @llvm.eh.typeid.for(ptr @int_typeinfo)
121 %int_match = icmp eq i32 %ehsel, %int_sel
122 br i1 %int_match, label %catch_int, label %eh.resume
128 %tmp_ehvals = insertvalue { ptr, i32 } undef, ptr %ehptr, 0
129 %new_ehvals = insertvalue { ptr, i32 } %tmp_ehvals, i32 %ehsel, 1
130 resume { ptr, i32 } %new_ehvals
133 ; We can't prune this merge because one landingpad is a cleanup pad.
135 ; CHECK-LABEL: define i32 @catch_cleanup_merge()
136 ; CHECK: invoke void @might_throw()
137 ; CHECK: invoke void @might_throw()
141 ; CHECK: landingpad { ptr, i32 }
142 ; CHECK: br label %catch.dispatch
145 ; CHECK: landingpad { ptr, i32 }
146 ; CHECK: call void @cleanup()
147 ; CHECK: br label %catch.dispatch
149 ; CHECK: catch.dispatch:
150 ; CHECK: call i32 @llvm.eh.typeid.for
155 ; CHECK-NEXT: call void @_Unwind_Resume(ptr %ehptr)
157 declare i32 @__gxx_personality_v0(...)
158 declare i32 @llvm.eh.typeid.for(ptr)