[rtsan] Add fork/execve interceptors (#117198)
[llvm-project.git] / llvm / test / Transforms / Inline / invoke-combine-clauses.ll
blobec1dafe8b68a66f1a8c941d4b77f31dd6e3b0851
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()
5 declare void @abort()
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
19 cont:
20   ret void
21 lpad:
22   %lp = landingpad i32
23       catch ptr @exception_inner
24   %cond = load i1, ptr @condition
25   br i1 %cond, label %resume1, label %resume2
26 resume1:
27   resume i32 1
28 resume2:
29   resume i32 2
32 define void @outer_multiple_resume() personality ptr null {
33   invoke void @inner_multiple_resume()
34       to label %cont unwind label %lpad
35 cont:
36   ret void
37 lpad:
38   %lp = landingpad i32
39       catch ptr @exception_outer
40   resume i32 %lp
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:
47 ; CHECK-NEXT: load
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
58 cont:
59   ret void
60 lpad:
61   %lp = landingpad i32
62       catch ptr @exception_inner
63   resume i32 %lp
66 define void @outer_resume_and_call() personality ptr null {
67   invoke void @inner_resume_and_call()
68       to label %cont unwind label %lpad
69 cont:
70   ret void
71 lpad:
72   %lp = landingpad i32
73       catch ptr @exception_outer
74   resume i32 %lp
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:
81 ; CHECK-NEXT: br
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
93 cont:
94   ret void
95 lpad:
96   %lp = landingpad i32
97       catch ptr @exception_inner
98   ; A landingpad might have no "resume" if a C++ destructor aborts.
99   call void @abort() noreturn nounwind
100   unreachable
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
106 cont:
107   ret void
108 lpad:
109   %lp = landingpad i32
110       catch ptr @exception_outer
111   resume i32 %lp
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()