1 ; RUN: opt -mtriple=x86_64-linux-gnu -dwarf-eh-prepare -simplifycfg-require-and-preserve-domtree=1 -run-twice < %s -S | FileCheck %s
2 ; RUN: opt -mtriple=x86_64-linux-gnu -passes=dwarf-eh-prepare -codegen-opt-level=2 -simplifycfg-require-and-preserve-domtree=1 -run-twice < %s -S | FileCheck %s
4 ; Check basic functionality of IR-to-IR DWARF EH preparation. This should
5 ; eliminate resumes. This pass requires a TargetMachine, so we put it under X86
6 ; and provide an x86 triple.
8 @int_typeinfo = global i8 0
10 declare void @might_throw()
11 declare void @cleanup()
13 define i32 @simple_cleanup_catch() personality ptr @__gxx_personality_v0 {
14 invoke void @might_throw()
15 to label %cont unwind label %lpad
17 ; CHECK-LABEL: define i32 @simple_cleanup_catch()
18 ; CHECK: invoke void @might_throw()
26 %ehvals = landingpad { ptr, i32 }
28 catch ptr @int_typeinfo
29 %ehptr = extractvalue { ptr, i32 } %ehvals, 0
30 %ehsel = extractvalue { ptr, i32 } %ehvals, 1
32 %int_sel = call i32 @llvm.eh.typeid.for(ptr @int_typeinfo)
33 %int_match = icmp eq i32 %ehsel, %int_sel
34 br i1 %int_match, label %catch_int, label %eh.resume
37 ; CHECK: landingpad { ptr, i32 }
38 ; CHECK: call void @cleanup()
39 ; CHECK: call i32 @llvm.eh.typeid.for
49 %tmp_ehvals = insertvalue { ptr, i32 } undef, ptr %ehptr, 0
50 %new_ehvals = insertvalue { ptr, i32 } %tmp_ehvals, i32 %ehsel, 1
51 resume { ptr, i32 } %new_ehvals
54 ; CHECK-NEXT: call void @_Unwind_Resume(ptr %ehptr)
58 define i32 @catch_no_resume() personality ptr @__gxx_personality_v0 {
59 invoke void @might_throw()
60 to label %cont unwind label %lpad
66 %ehvals = landingpad { ptr, i32 }
67 catch ptr @int_typeinfo
68 %ehptr = extractvalue { ptr, i32 } %ehvals, 0
69 %ehsel = extractvalue { ptr, i32 } %ehvals, 1
70 %int_sel = call i32 @llvm.eh.typeid.for(ptr @int_typeinfo)
71 %int_match = icmp eq i32 %ehsel, %int_sel
72 br i1 %int_match, label %catch_int, label %eh.resume
78 %tmp_ehvals = insertvalue { ptr, i32 } undef, ptr %ehptr, 0
79 %new_ehvals = insertvalue { ptr, i32 } %tmp_ehvals, i32 %ehsel, 1
80 resume { ptr, i32 } %new_ehvals
83 ; Check that we can prune the unreachable resume instruction.
85 ; CHECK-LABEL: define i32 @catch_no_resume() personality ptr @__gxx_personality_v0 {
86 ; CHECK: invoke void @might_throw()
89 ; CHECK: landingpad { ptr, i32 }
92 ; CHECK-NOT: call void @_Unwind_Resume
96 define i32 @catch_cleanup_merge() personality ptr @__gxx_personality_v0 {
97 invoke void @might_throw()
98 to label %inner_invoke unwind label %outer_lpad
100 invoke void @might_throw()
101 to label %cont unwind label %inner_lpad
106 %ehvals1 = landingpad { ptr, i32 }
107 catch ptr @int_typeinfo
108 br label %catch.dispatch
111 %ehvals2 = landingpad { ptr, i32 }
113 catch ptr @int_typeinfo
115 br label %catch.dispatch
118 %ehvals = phi { ptr, i32 } [ %ehvals1, %outer_lpad ], [ %ehvals2, %inner_lpad ]
119 %ehptr = extractvalue { ptr, i32 } %ehvals, 0
120 %ehsel = extractvalue { ptr, i32 } %ehvals, 1
121 %int_sel = call i32 @llvm.eh.typeid.for(ptr @int_typeinfo)
122 %int_match = icmp eq i32 %ehsel, %int_sel
123 br i1 %int_match, label %catch_int, label %eh.resume
129 %tmp_ehvals = insertvalue { ptr, i32 } undef, ptr %ehptr, 0
130 %new_ehvals = insertvalue { ptr, i32 } %tmp_ehvals, i32 %ehsel, 1
131 resume { ptr, i32 } %new_ehvals
134 ; We can't prune this merge because one landingpad is a cleanup pad.
136 ; CHECK-LABEL: define i32 @catch_cleanup_merge()
137 ; CHECK: invoke void @might_throw()
138 ; CHECK: invoke void @might_throw()
142 ; CHECK: landingpad { ptr, i32 }
143 ; CHECK: br label %catch.dispatch
146 ; CHECK: landingpad { ptr, i32 }
147 ; CHECK: call void @cleanup()
148 ; CHECK: br label %catch.dispatch
150 ; CHECK: catch.dispatch:
151 ; CHECK: call i32 @llvm.eh.typeid.for
156 ; CHECK-NEXT: call void @_Unwind_Resume(ptr %ehptr)
158 declare i32 @__gxx_personality_v0(...)
159 declare i32 @llvm.eh.typeid.for(ptr)