xref: /aosp_15_r20/external/llvm/test/Transforms/Inline/invoke-combine-clauses.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt %s -inline -S | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker
3*9880d681SAndroid Build Coastguard Workerdeclare void @external_func()
4*9880d681SAndroid Build Coastguard Workerdeclare void @abort()
5*9880d681SAndroid Build Coastguard Worker
6*9880d681SAndroid Build Coastguard Worker@exception_inner = external global i8
7*9880d681SAndroid Build Coastguard Worker@exception_outer = external global i8
8*9880d681SAndroid Build Coastguard Worker@condition = external global i1
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Worker
11*9880d681SAndroid Build Coastguard Worker; Check for a bug in which multiple "resume" instructions in the
12*9880d681SAndroid Build Coastguard Worker; inlined function caused "catch i8* @exception_outer" to appear
13*9880d681SAndroid Build Coastguard Worker; multiple times in the resulting landingpad.
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard Workerdefine internal void @inner_multiple_resume() personality i8* null {
16*9880d681SAndroid Build Coastguard Worker  invoke void @external_func()
17*9880d681SAndroid Build Coastguard Worker      to label %cont unwind label %lpad
18*9880d681SAndroid Build Coastguard Workercont:
19*9880d681SAndroid Build Coastguard Worker  ret void
20*9880d681SAndroid Build Coastguard Workerlpad:
21*9880d681SAndroid Build Coastguard Worker  %lp = landingpad i32
22*9880d681SAndroid Build Coastguard Worker      catch i8* @exception_inner
23*9880d681SAndroid Build Coastguard Worker  %cond = load i1, i1* @condition
24*9880d681SAndroid Build Coastguard Worker  br i1 %cond, label %resume1, label %resume2
25*9880d681SAndroid Build Coastguard Workerresume1:
26*9880d681SAndroid Build Coastguard Worker  resume i32 1
27*9880d681SAndroid Build Coastguard Workerresume2:
28*9880d681SAndroid Build Coastguard Worker  resume i32 2
29*9880d681SAndroid Build Coastguard Worker}
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Workerdefine void @outer_multiple_resume() personality i8* null {
32*9880d681SAndroid Build Coastguard Worker  invoke void @inner_multiple_resume()
33*9880d681SAndroid Build Coastguard Worker      to label %cont unwind label %lpad
34*9880d681SAndroid Build Coastguard Workercont:
35*9880d681SAndroid Build Coastguard Worker  ret void
36*9880d681SAndroid Build Coastguard Workerlpad:
37*9880d681SAndroid Build Coastguard Worker  %lp = landingpad i32
38*9880d681SAndroid Build Coastguard Worker      catch i8* @exception_outer
39*9880d681SAndroid Build Coastguard Worker  resume i32 %lp
40*9880d681SAndroid Build Coastguard Worker}
41*9880d681SAndroid Build Coastguard Worker; CHECK: define void @outer_multiple_resume()
42*9880d681SAndroid Build Coastguard Worker; CHECK: %lp.i = landingpad
43*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: catch i8* @exception_inner
44*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: catch i8* @exception_outer
45*9880d681SAndroid Build Coastguard Worker; Check that there isn't another "catch" clause:
46*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: load
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Worker
49*9880d681SAndroid Build Coastguard Worker; Check for a bug in which having a "resume" and a "call" in the
50*9880d681SAndroid Build Coastguard Worker; inlined function caused "catch i8* @exception_outer" to appear
51*9880d681SAndroid Build Coastguard Worker; multiple times in the resulting landingpad.
52*9880d681SAndroid Build Coastguard Worker
53*9880d681SAndroid Build Coastguard Workerdefine internal void @inner_resume_and_call() personality i8* null {
54*9880d681SAndroid Build Coastguard Worker  call void @external_func()
55*9880d681SAndroid Build Coastguard Worker  invoke void @external_func()
56*9880d681SAndroid Build Coastguard Worker      to label %cont unwind label %lpad
57*9880d681SAndroid Build Coastguard Workercont:
58*9880d681SAndroid Build Coastguard Worker  ret void
59*9880d681SAndroid Build Coastguard Workerlpad:
60*9880d681SAndroid Build Coastguard Worker  %lp = landingpad i32
61*9880d681SAndroid Build Coastguard Worker      catch i8* @exception_inner
62*9880d681SAndroid Build Coastguard Worker  resume i32 %lp
63*9880d681SAndroid Build Coastguard Worker}
64*9880d681SAndroid Build Coastguard Worker
65*9880d681SAndroid Build Coastguard Workerdefine void @outer_resume_and_call() personality i8* null {
66*9880d681SAndroid Build Coastguard Worker  invoke void @inner_resume_and_call()
67*9880d681SAndroid Build Coastguard Worker      to label %cont unwind label %lpad
68*9880d681SAndroid Build Coastguard Workercont:
69*9880d681SAndroid Build Coastguard Worker  ret void
70*9880d681SAndroid Build Coastguard Workerlpad:
71*9880d681SAndroid Build Coastguard Worker  %lp = landingpad i32
72*9880d681SAndroid Build Coastguard Worker      catch i8* @exception_outer
73*9880d681SAndroid Build Coastguard Worker  resume i32 %lp
74*9880d681SAndroid Build Coastguard Worker}
75*9880d681SAndroid Build Coastguard Worker; CHECK: define void @outer_resume_and_call()
76*9880d681SAndroid Build Coastguard Worker; CHECK: %lp.i = landingpad
77*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: catch i8* @exception_inner
78*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: catch i8* @exception_outer
79*9880d681SAndroid Build Coastguard Worker; Check that there isn't another "catch" clause:
80*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: br
81*9880d681SAndroid Build Coastguard Worker
82*9880d681SAndroid Build Coastguard Worker
83*9880d681SAndroid Build Coastguard Worker; Check what happens if the inlined function contains an "invoke" but
84*9880d681SAndroid Build Coastguard Worker; no "resume".  In this case, the inlined landingpad does not need to
85*9880d681SAndroid Build Coastguard Worker; include the "catch i8* @exception_outer" clause from the outer
86*9880d681SAndroid Build Coastguard Worker; function (since the outer function's landingpad will not be
87*9880d681SAndroid Build Coastguard Worker; reachable), but it's OK to include this clause.
88*9880d681SAndroid Build Coastguard Worker
89*9880d681SAndroid Build Coastguard Workerdefine internal void @inner_no_resume_or_call() personality i8* null {
90*9880d681SAndroid Build Coastguard Worker  invoke void @external_func()
91*9880d681SAndroid Build Coastguard Worker      to label %cont unwind label %lpad
92*9880d681SAndroid Build Coastguard Workercont:
93*9880d681SAndroid Build Coastguard Worker  ret void
94*9880d681SAndroid Build Coastguard Workerlpad:
95*9880d681SAndroid Build Coastguard Worker  %lp = landingpad i32
96*9880d681SAndroid Build Coastguard Worker      catch i8* @exception_inner
97*9880d681SAndroid Build Coastguard Worker  ; A landingpad might have no "resume" if a C++ destructor aborts.
98*9880d681SAndroid Build Coastguard Worker  call void @abort() noreturn nounwind
99*9880d681SAndroid Build Coastguard Worker  unreachable
100*9880d681SAndroid Build Coastguard Worker}
101*9880d681SAndroid Build Coastguard Worker
102*9880d681SAndroid Build Coastguard Workerdefine void @outer_no_resume_or_call() personality i8* null {
103*9880d681SAndroid Build Coastguard Worker  invoke void @inner_no_resume_or_call()
104*9880d681SAndroid Build Coastguard Worker      to label %cont unwind label %lpad
105*9880d681SAndroid Build Coastguard Workercont:
106*9880d681SAndroid Build Coastguard Worker  ret void
107*9880d681SAndroid Build Coastguard Workerlpad:
108*9880d681SAndroid Build Coastguard Worker  %lp = landingpad i32
109*9880d681SAndroid Build Coastguard Worker      catch i8* @exception_outer
110*9880d681SAndroid Build Coastguard Worker  resume i32 %lp
111*9880d681SAndroid Build Coastguard Worker}
112*9880d681SAndroid Build Coastguard Worker; CHECK: define void @outer_no_resume_or_call()
113*9880d681SAndroid Build Coastguard Worker; CHECK: %lp.i = landingpad
114*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: catch i8* @exception_inner
115*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: catch i8* @exception_outer
116*9880d681SAndroid Build Coastguard Worker; Check that there isn't another "catch" clause:
117*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @abort()
118