160 lines · plain
1; RUN: opt -mtriple=x86_64-linux-gnu -dwarf-eh-prepare -simplifycfg-require-and-preserve-domtree=1 -run-twice < %s -S | FileCheck %s2; 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 %s3 4; Check basic functionality of IR-to-IR DWARF EH preparation. This should5; eliminate resumes. This pass requires a TargetMachine, so we put it under X866; and provide an x86 triple.7 8@int_typeinfo = global i8 09 10declare void @might_throw()11declare void @cleanup()12 13define i32 @simple_cleanup_catch() personality ptr @__gxx_personality_v0 {14 invoke void @might_throw()15 to label %cont unwind label %lpad16 17; CHECK-LABEL: define i32 @simple_cleanup_catch()18; CHECK: invoke void @might_throw()19 20cont:21 ret i32 022 23; CHECK: ret i32 024 25lpad:26 %ehvals = landingpad { ptr, i32 }27 cleanup28 catch ptr @int_typeinfo29 %ehptr = extractvalue { ptr, i32 } %ehvals, 030 %ehsel = extractvalue { ptr, i32 } %ehvals, 131 call void @cleanup()32 %int_sel = call i32 @llvm.eh.typeid.for(ptr @int_typeinfo)33 %int_match = icmp eq i32 %ehsel, %int_sel34 br i1 %int_match, label %catch_int, label %eh.resume35 36; CHECK: lpad:37; CHECK: landingpad { ptr, i32 }38; CHECK: call void @cleanup()39; CHECK: call i32 @llvm.eh.typeid.for40; CHECK: br i141 42catch_int:43 ret i32 144 45; CHECK: catch_int:46; CHECK: ret i32 147 48eh.resume:49 %tmp_ehvals = insertvalue { ptr, i32 } undef, ptr %ehptr, 050 %new_ehvals = insertvalue { ptr, i32 } %tmp_ehvals, i32 %ehsel, 151 resume { ptr, i32 } %new_ehvals52 53; CHECK: eh.resume:54; CHECK-NEXT: call void @_Unwind_Resume(ptr %ehptr)55}56 57 58define i32 @catch_no_resume() personality ptr @__gxx_personality_v0 {59 invoke void @might_throw()60 to label %cont unwind label %lpad61 62cont:63 ret i32 064 65lpad:66 %ehvals = landingpad { ptr, i32 }67 catch ptr @int_typeinfo68 %ehptr = extractvalue { ptr, i32 } %ehvals, 069 %ehsel = extractvalue { ptr, i32 } %ehvals, 170 %int_sel = call i32 @llvm.eh.typeid.for(ptr @int_typeinfo)71 %int_match = icmp eq i32 %ehsel, %int_sel72 br i1 %int_match, label %catch_int, label %eh.resume73 74catch_int:75 ret i32 176 77eh.resume:78 %tmp_ehvals = insertvalue { ptr, i32 } undef, ptr %ehptr, 079 %new_ehvals = insertvalue { ptr, i32 } %tmp_ehvals, i32 %ehsel, 180 resume { ptr, i32 } %new_ehvals81}82 83; Check that we can prune the unreachable resume instruction.84 85; CHECK-LABEL: define i32 @catch_no_resume() personality ptr @__gxx_personality_v0 {86; CHECK: invoke void @might_throw()87; CHECK: ret i32 088; CHECK: lpad:89; CHECK: landingpad { ptr, i32 }90; CHECK-NOT: br i191; CHECK: ret i32 192; CHECK-NOT: call void @_Unwind_Resume93; CHECK: {{^[}]}}94 95 96define i32 @catch_cleanup_merge() personality ptr @__gxx_personality_v0 {97 invoke void @might_throw()98 to label %inner_invoke unwind label %outer_lpad99inner_invoke:100 invoke void @might_throw()101 to label %cont unwind label %inner_lpad102cont:103 ret i32 0104 105outer_lpad:106 %ehvals1 = landingpad { ptr, i32 }107 catch ptr @int_typeinfo108 br label %catch.dispatch109 110inner_lpad:111 %ehvals2 = landingpad { ptr, i32 }112 cleanup113 catch ptr @int_typeinfo114 call void @cleanup()115 br label %catch.dispatch116 117catch.dispatch:118 %ehvals = phi { ptr, i32 } [ %ehvals1, %outer_lpad ], [ %ehvals2, %inner_lpad ]119 %ehptr = extractvalue { ptr, i32 } %ehvals, 0120 %ehsel = extractvalue { ptr, i32 } %ehvals, 1121 %int_sel = call i32 @llvm.eh.typeid.for(ptr @int_typeinfo)122 %int_match = icmp eq i32 %ehsel, %int_sel123 br i1 %int_match, label %catch_int, label %eh.resume124 125catch_int:126 ret i32 1127 128eh.resume:129 %tmp_ehvals = insertvalue { ptr, i32 } undef, ptr %ehptr, 0130 %new_ehvals = insertvalue { ptr, i32 } %tmp_ehvals, i32 %ehsel, 1131 resume { ptr, i32 } %new_ehvals132}133 134; We can't prune this merge because one landingpad is a cleanup pad.135 136; CHECK-LABEL: define i32 @catch_cleanup_merge()137; CHECK: invoke void @might_throw()138; CHECK: invoke void @might_throw()139; CHECK: ret i32 0140;141; CHECK: outer_lpad:142; CHECK: landingpad { ptr, i32 }143; CHECK: br label %catch.dispatch144;145; CHECK: inner_lpad:146; CHECK: landingpad { ptr, i32 }147; CHECK: call void @cleanup()148; CHECK: br label %catch.dispatch149;150; CHECK: catch.dispatch:151; CHECK: call i32 @llvm.eh.typeid.for152; CHECK: br i1153; CHECK: catch_int:154; CHECK: ret i32 1155; CHECK: eh.resume:156; CHECK-NEXT: call void @_Unwind_Resume(ptr %ehptr)157 158declare i32 @__gxx_personality_v0(...)159declare i32 @llvm.eh.typeid.for(ptr)160