@@ -12,11 +12,23 @@ define i32 @foo1() {
12
12
ret i32 1
13
13
}
14
14
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
22
+ ;
23
+ call void @unknown ()
24
+ ret void
25
+ }
26
+
15
27
; TEST 2
16
28
define i32 @scc1_foo () {
17
29
; TUNIT: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
18
30
; TUNIT-LABEL: define {{[^@]+}}@scc1_foo
19
- ; TUNIT-SAME: () #[[ATTR1 :[0-9]+]] {
31
+ ; TUNIT-SAME: () #[[ATTR2 :[0-9]+]] {
20
32
; TUNIT-NEXT: ret i32 1
21
33
;
22
34
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
@@ -33,7 +45,7 @@ define i32 @scc1_foo() {
33
45
define i32 @scc1_bar () {
34
46
; TUNIT: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
35
47
; TUNIT-LABEL: define {{[^@]+}}@scc1_bar
36
- ; TUNIT-SAME: () #[[ATTR1 ]] {
48
+ ; TUNIT-SAME: () #[[ATTR2 ]] {
37
49
; TUNIT-NEXT: ret i32 1
38
50
;
39
51
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
@@ -138,6 +150,94 @@ define i32 @catch_thing_user() {
138
150
ret i32 %catch_thing_call
139
151
}
140
152
153
+ define void @two_potential_callees_pos1 (i1 %c ) {
154
+ ; TUNIT: Function Attrs: norecurse
155
+ ; TUNIT-LABEL: define {{[^@]+}}@two_potential_callees_pos1
156
+ ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR3:[0-9]+]] {
157
+ ; TUNIT-NEXT: [[FP:%.*]] = select i1 [[C]], ptr @foo1, ptr @scc1_foo
158
+ ; TUNIT-NEXT: [[TMP1:%.*]] = icmp eq ptr [[FP]], @scc1_foo
159
+ ; TUNIT-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]
160
+ ; TUNIT: 2:
161
+ ; TUNIT-NEXT: call void @scc1_foo()
162
+ ; TUNIT-NEXT: br label [[TMP6:%.*]]
163
+ ; TUNIT: 3:
164
+ ; TUNIT-NEXT: br i1 true, label [[TMP4:%.*]], label [[TMP5:%.*]]
165
+ ; TUNIT: 4:
166
+ ; TUNIT-NEXT: call void @foo1()
167
+ ; TUNIT-NEXT: br label [[TMP6]]
168
+ ; TUNIT: 5:
169
+ ; TUNIT-NEXT: unreachable
170
+ ; TUNIT: 6:
171
+ ; TUNIT-NEXT: ret void
172
+ ;
173
+ ; CGSCC-LABEL: define {{[^@]+}}@two_potential_callees_pos1
174
+ ; CGSCC-SAME: (i1 [[C:%.*]]) {
175
+ ; CGSCC-NEXT: [[FP:%.*]] = select i1 [[C]], ptr @foo1, ptr @scc1_foo
176
+ ; CGSCC-NEXT: [[TMP1:%.*]] = icmp eq ptr [[FP]], @scc1_foo
177
+ ; CGSCC-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]
178
+ ; CGSCC: 2:
179
+ ; CGSCC-NEXT: call void @scc1_foo()
180
+ ; CGSCC-NEXT: br label [[TMP6:%.*]]
181
+ ; CGSCC: 3:
182
+ ; CGSCC-NEXT: br i1 true, label [[TMP4:%.*]], label [[TMP5:%.*]]
183
+ ; CGSCC: 4:
184
+ ; CGSCC-NEXT: call void @foo1()
185
+ ; CGSCC-NEXT: br label [[TMP6]]
186
+ ; CGSCC: 5:
187
+ ; CGSCC-NEXT: unreachable
188
+ ; CGSCC: 6:
189
+ ; CGSCC-NEXT: ret void
190
+ ;
191
+ %fp = select i1 %c , ptr @foo1 , ptr @scc1_foo
192
+ call void %fp ()
193
+ ret void
194
+ }
195
+ define void @two_potential_callees_pos2 (i1 %c ) {
196
+ ; CHECK-LABEL: define {{[^@]+}}@two_potential_callees_pos2
197
+ ; CHECK-SAME: (i1 [[C:%.*]]) {
198
+ ; CHECK-NEXT: [[FP:%.*]] = select i1 [[C]], ptr @foo2, ptr @scc1_foo
199
+ ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq ptr [[FP]], @scc1_foo
200
+ ; CHECK-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]
201
+ ; CHECK: 2:
202
+ ; CHECK-NEXT: call void @scc1_foo()
203
+ ; CHECK-NEXT: br label [[TMP6:%.*]]
204
+ ; CHECK: 3:
205
+ ; CHECK-NEXT: br i1 true, label [[TMP4:%.*]], label [[TMP5:%.*]]
206
+ ; CHECK: 4:
207
+ ; CHECK-NEXT: call void @foo2()
208
+ ; CHECK-NEXT: br label [[TMP6]]
209
+ ; CHECK: 5:
210
+ ; CHECK-NEXT: unreachable
211
+ ; CHECK: 6:
212
+ ; CHECK-NEXT: ret void
213
+ ;
214
+ %fp = select i1 %c , ptr @foo2 , ptr @scc1_foo
215
+ call void %fp ()
216
+ ret void
217
+ }
218
+ define void @two_potential_callees_neg (i1 %c ) {
219
+ ; CHECK-LABEL: define {{[^@]+}}@two_potential_callees_neg
220
+ ; CHECK-SAME: (i1 [[C:%.*]]) {
221
+ ; CHECK-NEXT: [[FP:%.*]] = select i1 [[C]], ptr @foo1, ptr @non_nounwind
222
+ ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq ptr [[FP]], @non_nounwind
223
+ ; CHECK-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]
224
+ ; CHECK: 2:
225
+ ; CHECK-NEXT: call void @non_nounwind()
226
+ ; CHECK-NEXT: br label [[TMP6:%.*]]
227
+ ; CHECK: 3:
228
+ ; CHECK-NEXT: br i1 true, label [[TMP4:%.*]], label [[TMP5:%.*]]
229
+ ; CHECK: 4:
230
+ ; CHECK-NEXT: call void @foo1()
231
+ ; CHECK-NEXT: br label [[TMP6]]
232
+ ; CHECK: 5:
233
+ ; CHECK-NEXT: unreachable
234
+ ; CHECK: 6:
235
+ ; CHECK-NEXT: ret void
236
+ ;
237
+ %fp = select i1 %c , ptr @foo1 , ptr @non_nounwind
238
+ call void %fp ()
239
+ ret void
240
+ }
141
241
142
242
declare i32 @__gxx_personality_v0 (...)
143
243
@@ -146,7 +246,10 @@ declare ptr @__cxa_begin_catch(ptr)
146
246
declare void @__cxa_end_catch ()
147
247
;.
148
248
; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
149
- ; TUNIT: attributes #[[ATTR1]] = { mustprogress nofree nosync nounwind willreturn memory(none) }
249
+ ; TUNIT: attributes #[[ATTR1]] = { nounwind }
250
+ ; TUNIT: attributes #[[ATTR2]] = { mustprogress nofree nosync nounwind willreturn memory(none) }
251
+ ; TUNIT: attributes #[[ATTR3]] = { norecurse }
150
252
;.
151
253
; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
254
+ ; CGSCC: attributes #[[ATTR1]] = { nounwind }
152
255
;.
0 commit comments