xref: /llvm-project/llvm/test/Transforms/Inline/invoke_test-3.ll (revision 151602c7a9935558ca671b35359989b261045db0)
1; Test that any rethrown exceptions in an inlined function are automatically
2; turned into branches to the invoke destination.
3
4; RUN: opt < %s -passes=inline -S | FileCheck %s
5; RUN: opt < %s -passes='cgscc(inline)' -S | FileCheck %s
6; RUN: opt < %s -passes='module-inline' -S | FileCheck %s
7
8declare void @might_throw()
9
10define internal i32 @callee() personality ptr @__gxx_personality_v0 {
11entry:
12  invoke void @might_throw()
13      to label %cont unwind label %exc
14
15cont:
16  ret i32 0
17
18exc:
19 ; This just rethrows the exception!
20  %exn = landingpad {ptr, i32}
21         cleanup
22  resume { ptr, i32 } %exn
23}
24
25; caller returns true if might_throw throws an exception... which gets
26; propagated by callee.
27define i32 @caller() personality ptr @__gxx_personality_v0 {
28; CHECK-LABEL: define i32 @caller()
29entry:
30  %X = invoke i32 @callee()
31           to label %cont unwind label %Handler
32; CHECK-NOT: @callee
33; CHECK: invoke void @might_throw()
34; At this point we just check that the rest of the function does not 'resume'
35; at any point and instead the inlined resume is threaded into normal control
36; flow.
37; CHECK-NOT: resume
38
39cont:
40  ret i32 %X
41
42Handler:
43; This consumes an exception thrown by might_throw
44  %exn = landingpad {ptr, i32}
45         cleanup
46  ret i32 1
47}
48
49declare i32 @__gxx_personality_v0(...)
50