1 ; RUN: opt %s -passes='cgscc(inline)' -S | FileCheck %s
2 ; RUN: opt %s -passes='module-inline' -S | FileCheck %s
4 declare void @external_func()
7 @exception_inner = external global i8
8 @exception_outer = external global i8
9 @condition = external global i1
12 ; Check for a bug in which multiple "resume" instructions in the
13 ; inlined function caused "catch ptr @exception_outer" to appear
14 ; multiple times in the resulting landingpad.
16 define internal void @inner_multiple_resume() personality ptr null {
17 invoke void @external_func()
18 to label %cont unwind label %lpad
23 catch ptr @exception_inner
24 %cond = load i1, ptr @condition
25 br i1 %cond, label %resume1, label %resume2
32 define void @outer_multiple_resume() personality ptr null {
33 invoke void @inner_multiple_resume()
34 to label %cont unwind label %lpad
39 catch ptr @exception_outer
42 ; CHECK: define void @outer_multiple_resume()
43 ; CHECK: %lp.i = landingpad
44 ; CHECK-NEXT: catch ptr @exception_inner
45 ; CHECK-NEXT: catch ptr @exception_outer
46 ; Check that there isn't another "catch" clause:
50 ; Check for a bug in which having a "resume" and a "call" in the
51 ; inlined function caused "catch ptr @exception_outer" to appear
52 ; multiple times in the resulting landingpad.
54 define 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 %lpad
62 catch ptr @exception_inner
66 define void @outer_resume_and_call() personality ptr null {
67 invoke void @inner_resume_and_call()
68 to label %cont unwind label %lpad
73 catch ptr @exception_outer
76 ; CHECK: define void @outer_resume_and_call()
77 ; CHECK: %lp.i = landingpad
78 ; CHECK-NEXT: catch ptr @exception_inner
79 ; CHECK-NEXT: catch ptr @exception_outer
80 ; Check that there isn't another "catch" clause:
84 ; Check what happens if the inlined function contains an "invoke" but
85 ; no "resume". In this case, the inlined landingpad does not need to
86 ; include the "catch ptr @exception_outer" clause from the outer
87 ; function (since the outer function's landingpad will not be
88 ; reachable), but it's OK to include this clause.
90 define internal void @inner_no_resume_or_call() personality ptr null {
91 invoke void @external_func()
92 to label %cont unwind label %lpad
97 catch ptr @exception_inner
98 ; A landingpad might have no "resume" if a C++ destructor aborts.
99 call void @abort() noreturn nounwind
103 define void @outer_no_resume_or_call() personality ptr null {
104 invoke void @inner_no_resume_or_call()
105 to label %cont unwind label %lpad
110 catch ptr @exception_outer
113 ; CHECK: define void @outer_no_resume_or_call()
114 ; CHECK: %lp.i = landingpad
115 ; CHECK-NEXT: catch ptr @exception_inner
116 ; CHECK-NEXT: catch ptr @exception_outer
117 ; Check that there isn't another "catch" clause:
118 ; CHECK-NEXT: call void @abort()