[LLVM][IR] Use splat syntax when printing ConstantExpr based splats. (#116856)
[llvm-project.git] / llvm / test / Transforms / Attributor / nounwind.ll
blob8ea812ce42a83774f853e84193f21ec3c83f3747
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
2 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal  -attributor-annotate-decl-cs  -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
3 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
5 ; TEST 1
6 define i32 @foo1() {
7 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
8 ; CHECK-LABEL: define {{[^@]+}}@foo1
9 ; CHECK-SAME: () #[[ATTR0:[0-9]+]] {
10 ; CHECK-NEXT:    ret i32 1
12   ret i32 1
15 declare void @unknown()
16 define void @foo2() nounwind {
17 ; CHECK: Function Attrs: nounwind
18 ; CHECK-LABEL: define {{[^@]+}}@foo2
19 ; CHECK-SAME: () #[[ATTR1:[0-9]+]] {
20 ; CHECK-NEXT:    call void @unknown()
21 ; CHECK-NEXT:    ret void
23   call void @unknown()
24   ret void
27 ; TEST 2
28 define i32 @scc1_foo() {
29 ; TUNIT: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
30 ; TUNIT-LABEL: define {{[^@]+}}@scc1_foo
31 ; TUNIT-SAME: () #[[ATTR2:[0-9]+]] {
32 ; TUNIT-NEXT:    ret i32 1
34 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
35 ; CGSCC-LABEL: define {{[^@]+}}@scc1_foo
36 ; CGSCC-SAME: () #[[ATTR0]] {
37 ; CGSCC-NEXT:    ret i32 1
39   %1 = call i32 @scc1_bar()
40   ret i32 1
44 ; TEST 3
45 define i32 @scc1_bar() {
46 ; TUNIT: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
47 ; TUNIT-LABEL: define {{[^@]+}}@scc1_bar
48 ; TUNIT-SAME: () #[[ATTR2]] {
49 ; TUNIT-NEXT:    ret i32 1
51 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
52 ; CGSCC-LABEL: define {{[^@]+}}@scc1_bar
53 ; CGSCC-SAME: () #[[ATTR0]] {
54 ; CGSCC-NEXT:    ret i32 1
56   %1 = call i32 @scc1_foo()
57   ret i32 1
60 declare i32 @non_nounwind()
62 ; TEST 4
63 define void @call_non_nounwind(){
64 ; CHECK-LABEL: define {{[^@]+}}@call_non_nounwind() {
65 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call i32 @non_nounwind()
66 ; CHECK-NEXT:    ret void
68   tail call i32 @non_nounwind()
69   ret void
72 ; TEST 5 - throw
73 ; int maybe_throw(bool canThrow) {
74 ;   if (canThrow)
75 ;     throw;
76 ;   else
77 ;     return -1;
78 ; }
80 define i32 @maybe_throw(i1 zeroext %0) {
81 ; CHECK-LABEL: define {{[^@]+}}@maybe_throw
82 ; CHECK-SAME: (i1 noundef zeroext [[TMP0:%.*]]) {
83 ; CHECK-NEXT:    br i1 [[TMP0]], label [[TMP2:%.*]], label [[TMP3:%.*]]
84 ; CHECK:       2:
85 ; CHECK-NEXT:    tail call void @__cxa_rethrow()
86 ; CHECK-NEXT:    unreachable
87 ; CHECK:       3:
88 ; CHECK-NEXT:    ret i32 -1
90   br i1 %0, label %2, label %3
92 2:                                                ; preds = %1
93   tail call void @__cxa_rethrow() #1
94   unreachable
96 3:                                                ; preds = %1
97   ret i32 -1
100 declare void @__cxa_rethrow()
102 ; TEST 6 - catch
103 ; int catch_thing() {
104 ;   try {
105 ;       int a = doThing(true);
106 ;   }
107 ;   catch(...) { return -1; }
108 ;   return 1;
109 ; }
111 define i32 @catch_thing() personality ptr @__gxx_personality_v0 {
112 ; CHECK-LABEL: define {{[^@]+}}@catch_thing() personality ptr @__gxx_personality_v0 {
113 ; CHECK-NEXT:    invoke void @__cxa_rethrow()
114 ; CHECK-NEXT:            to label [[TMP1:%.*]] unwind label [[TMP2:%.*]]
115 ; CHECK:       1:
116 ; CHECK-NEXT:    unreachable
117 ; CHECK:       2:
118 ; CHECK-NEXT:    [[TMP3:%.*]] = landingpad { ptr, i32 }
119 ; CHECK-NEXT:            catch ptr null
120 ; CHECK-NEXT:    [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP3]], 0
121 ; CHECK-NEXT:    [[TMP5:%.*]] = tail call ptr @__cxa_begin_catch(ptr [[TMP4]])
122 ; CHECK-NEXT:    tail call void @__cxa_end_catch()
123 ; CHECK-NEXT:    ret i32 -1
125   invoke void @__cxa_rethrow() #1
126   to label %1 unwind label %2
128 1:                                                ; preds = %0
129   unreachable
131 2:                                                ; preds = %0
132   %3 = landingpad { ptr, i32 }
133   catch ptr null
134   %4 = extractvalue { ptr, i32 } %3, 0
135   %5 = tail call ptr @__cxa_begin_catch(ptr %4) #2
136   tail call void @__cxa_end_catch()
137   ret i32 -1
140 define i32 @catch_thing_user() {
141 ; TUNIT-LABEL: define {{[^@]+}}@catch_thing_user() {
142 ; TUNIT-NEXT:    [[CATCH_THING_CALL:%.*]] = call i32 @catch_thing()
143 ; TUNIT-NEXT:    ret i32 -1
145 ; CGSCC-LABEL: define {{[^@]+}}@catch_thing_user() {
146 ; CGSCC-NEXT:    [[CATCH_THING_CALL:%.*]] = call noundef i32 @catch_thing()
147 ; CGSCC-NEXT:    ret i32 [[CATCH_THING_CALL]]
149   %catch_thing_call = call i32 @catch_thing()
150   ret i32 %catch_thing_call
153 define void @two_potential_callees_pos1(i1 %c) {
154 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
155 ; TUNIT-LABEL: define {{[^@]+}}@two_potential_callees_pos1
156 ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
157 ; TUNIT-NEXT:    ret void
159 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn
160 ; CGSCC-LABEL: define {{[^@]+}}@two_potential_callees_pos1
161 ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] {
162 ; CGSCC-NEXT:    [[FP:%.*]] = select i1 [[C]], ptr @foo1, ptr @scc1_foo
163 ; CGSCC-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[FP]], @scc1_foo
164 ; CGSCC-NEXT:    br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]
165 ; CGSCC:       2:
166 ; CGSCC-NEXT:    call void @scc1_foo()
167 ; CGSCC-NEXT:    br label [[TMP6:%.*]]
168 ; CGSCC:       3:
169 ; CGSCC-NEXT:    br i1 true, label [[TMP4:%.*]], label [[TMP5:%.*]]
170 ; CGSCC:       4:
171 ; CGSCC-NEXT:    call void @foo1()
172 ; CGSCC-NEXT:    br label [[TMP6]]
173 ; CGSCC:       5:
174 ; CGSCC-NEXT:    unreachable
175 ; CGSCC:       6:
176 ; CGSCC-NEXT:    ret void
178   %fp = select i1 %c, ptr @foo1, ptr @scc1_foo
179   call void %fp()
180   ret void
182 define void @two_potential_callees_pos2(i1 %c) {
183 ; CHECK: Function Attrs: nounwind
184 ; CHECK-LABEL: define {{[^@]+}}@two_potential_callees_pos2
185 ; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
186 ; CHECK-NEXT:    [[FP:%.*]] = select i1 [[C]], ptr @foo2, ptr @scc1_foo
187 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[FP]], @scc1_foo
188 ; CHECK-NEXT:    br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]
189 ; CHECK:       2:
190 ; CHECK-NEXT:    call void @scc1_foo()
191 ; CHECK-NEXT:    br label [[TMP6:%.*]]
192 ; CHECK:       3:
193 ; CHECK-NEXT:    br i1 true, label [[TMP4:%.*]], label [[TMP5:%.*]]
194 ; CHECK:       4:
195 ; CHECK-NEXT:    call void @foo2()
196 ; CHECK-NEXT:    br label [[TMP6]]
197 ; CHECK:       5:
198 ; CHECK-NEXT:    unreachable
199 ; CHECK:       6:
200 ; CHECK-NEXT:    ret void
202   %fp = select i1 %c, ptr @foo2, ptr @scc1_foo
203   call void %fp()
204   ret void
206 define void @two_potential_callees_neg(i1 %c) {
207 ; CHECK-LABEL: define {{[^@]+}}@two_potential_callees_neg
208 ; CHECK-SAME: (i1 [[C:%.*]]) {
209 ; CHECK-NEXT:    [[FP:%.*]] = select i1 [[C]], ptr @foo1, ptr @non_nounwind
210 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[FP]], @non_nounwind
211 ; CHECK-NEXT:    br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]
212 ; CHECK:       2:
213 ; CHECK-NEXT:    call void @non_nounwind()
214 ; CHECK-NEXT:    br label [[TMP6:%.*]]
215 ; CHECK:       3:
216 ; CHECK-NEXT:    br i1 true, label [[TMP4:%.*]], label [[TMP5:%.*]]
217 ; CHECK:       4:
218 ; CHECK-NEXT:    call void @foo1()
219 ; CHECK-NEXT:    br label [[TMP6]]
220 ; CHECK:       5:
221 ; CHECK-NEXT:    unreachable
222 ; CHECK:       6:
223 ; CHECK-NEXT:    ret void
225   %fp = select i1 %c, ptr @foo1, ptr @non_nounwind
226   call void %fp()
227   ret void
230 declare i32 @__gxx_personality_v0(...)
232 declare ptr @__cxa_begin_catch(ptr)
234 declare void @__cxa_end_catch()
236 ; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
237 ; TUNIT: attributes #[[ATTR1]] = { nounwind }
238 ; TUNIT: attributes #[[ATTR2]] = { mustprogress nofree nosync nounwind willreturn memory(none) }
240 ; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
241 ; CGSCC: attributes #[[ATTR1]] = { nounwind }
242 ; CGSCC: attributes #[[ATTR2]] = { mustprogress nofree nosync nounwind willreturn }