119 lines · plain
1; RUN: opt %s -passes='cgscc(inline)' -S | FileCheck %s2; RUN: opt %s -passes='module-inline' -S | FileCheck %s3 4declare void @external_func()5declare void @abort()6 7@exception_inner = external global i88@exception_outer = external global i89@condition = external global i110 11 12; Check for a bug in which multiple "resume" instructions in the13; inlined function caused "catch ptr @exception_outer" to appear14; multiple times in the resulting landingpad.15 16define internal void @inner_multiple_resume() personality ptr null {17 invoke void @external_func()18 to label %cont unwind label %lpad19cont:20 ret void21lpad:22 %lp = landingpad i3223 catch ptr @exception_inner24 %cond = load i1, ptr @condition25 br i1 %cond, label %resume1, label %resume226resume1:27 resume i32 128resume2:29 resume i32 230}31 32define void @outer_multiple_resume() personality ptr null {33 invoke void @inner_multiple_resume()34 to label %cont unwind label %lpad35cont:36 ret void37lpad:38 %lp = landingpad i3239 catch ptr @exception_outer40 resume i32 %lp41}42; CHECK: define void @outer_multiple_resume()43; CHECK: %lp.i = landingpad44; CHECK-NEXT: catch ptr @exception_inner45; CHECK-NEXT: catch ptr @exception_outer46; Check that there isn't another "catch" clause:47; CHECK-NEXT: load48 49 50; Check for a bug in which having a "resume" and a "call" in the51; inlined function caused "catch ptr @exception_outer" to appear52; multiple times in the resulting landingpad.53 54define internal void @inner_resume_and_call() personality ptr null {55 call void @external_func()56 invoke void @external_func()57 to label %cont unwind label %lpad58cont:59 ret void60lpad:61 %lp = landingpad i3262 catch ptr @exception_inner63 resume i32 %lp64}65 66define void @outer_resume_and_call() personality ptr null {67 invoke void @inner_resume_and_call()68 to label %cont unwind label %lpad69cont:70 ret void71lpad:72 %lp = landingpad i3273 catch ptr @exception_outer74 resume i32 %lp75}76; CHECK: define void @outer_resume_and_call()77; CHECK: %lp.i = landingpad78; CHECK-NEXT: catch ptr @exception_inner79; CHECK-NEXT: catch ptr @exception_outer80; Check that there isn't another "catch" clause:81; CHECK-NEXT: br82 83 84; Check what happens if the inlined function contains an "invoke" but85; no "resume". In this case, the inlined landingpad does not need to86; include the "catch ptr @exception_outer" clause from the outer87; function (since the outer function's landingpad will not be88; reachable), but it's OK to include this clause.89 90define internal void @inner_no_resume_or_call() personality ptr null {91 invoke void @external_func()92 to label %cont unwind label %lpad93cont:94 ret void95lpad:96 %lp = landingpad i3297 catch ptr @exception_inner98 ; A landingpad might have no "resume" if a C++ destructor aborts.99 call void @abort() noreturn nounwind100 unreachable101}102 103define void @outer_no_resume_or_call() personality ptr null {104 invoke void @inner_no_resume_or_call()105 to label %cont unwind label %lpad106cont:107 ret void108lpad:109 %lp = landingpad i32110 catch ptr @exception_outer111 resume i32 %lp112}113; CHECK: define void @outer_no_resume_or_call()114; CHECK: %lp.i = landingpad115; CHECK-NEXT: catch ptr @exception_inner116; CHECK-NEXT: catch ptr @exception_outer117; Check that there isn't another "catch" clause:118; CHECK-NEXT: call void @abort()119