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