1; RUN: opt < %s -function-attrs -S | FileCheck %s
2
3; TEST 1
4; CHECK: Function Attrs: norecurse nounwind readnone
5; CHECK-NEXT: define i32 @foo1()
6define i32 @foo1() {
7  ret i32 1
8}
9
10; TEST 2
11; CHECK: Function Attrs: nounwind readnone
12; CHECK-NEXT: define i32 @scc1_foo()
13define i32 @scc1_foo() {
14  %1 = call i32 @scc1_bar()
15  ret i32 1
16}
17
18
19; TEST 3
20; CHECK: Function Attrs: nounwind readnone
21; CHECK-NEXT: define i32 @scc1_bar()
22define i32 @scc1_bar() {
23  %1 = call i32 @scc1_foo()
24  ret i32 1
25}
26
27; CHECK: declare i32 @non_nounwind()
28declare i32 @non_nounwind()
29
30; TEST 4
31; CHECK: define void @call_non_nounwind() {
32define void @call_non_nounwind(){
33    tail call i32 @non_nounwind()
34    ret void
35}
36
37; TEST 5 - throw
38; int maybe_throw(bool canThrow) {
39;   if (canThrow)
40;     throw;
41;   else
42;     return -1;
43; }
44
45; CHECK: define i32 @maybe_throw(i1 zeroext %0)
46define i32 @maybe_throw(i1 zeroext %0) {
47  br i1 %0, label %2, label %3
48
492:                                                ; preds = %1
50  tail call void @__cxa_rethrow() #1
51  unreachable
52
533:                                                ; preds = %1
54  ret i32 -1
55}
56
57declare void @__cxa_rethrow()
58
59; TEST 6 - catch
60; int catch_thing() {
61;   try {
62;       int a = doThing(true);
63;   }
64;   catch(...) { return -1; }
65;   return 1;
66; }
67
68; CHECK: define i32 @catch_thing()
69define i32 @catch_thing() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
70  invoke void @__cxa_rethrow() #1
71          to label %1 unwind label %2
72
731:                                                ; preds = %0
74  unreachable
75
762:                                                ; preds = %0
77  %3 = landingpad { i8*, i32 }
78          catch i8* null
79  %4 = extractvalue { i8*, i32 } %3, 0
80  %5 = tail call i8* @__cxa_begin_catch(i8* %4) #2
81  tail call void @__cxa_end_catch()
82  ret i32 -1
83}
84
85define i32 @catch_thing_user() {
86  %catch_thing_call = call i32 @catch_thing()
87  ret i32 %catch_thing_call
88}
89
90
91declare i32 @__gxx_personality_v0(...)
92
93declare i8* @__cxa_begin_catch(i8*)
94
95declare void @__cxa_end_catch()
96