[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / Attributor / nonnull.ll
blobd92b0233b133ad702e01d31361b55bc8d7ee1ccc
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
2 ; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal  -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=14 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
3 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal  -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=14 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
4 ; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
5 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
8 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
10 declare nonnull i8* @ret_nonnull()
11 declare void @llvm.assume(i1)
13 ; Return a pointer trivially nonnull (call return attribute)
14 define i8* @test1() {
15 ; CHECK-LABEL: define {{[^@]+}}@test1() {
16 ; CHECK-NEXT:    [[RET:%.*]] = call nonnull i8* @ret_nonnull()
17 ; CHECK-NEXT:    ret i8* [[RET]]
19   %ret = call i8* @ret_nonnull()
20   ret i8* %ret
23 ; Return a pointer trivially nonnull (argument attribute)
24 define i8* @test2(i8* nonnull %p) {
25 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
26 ; IS__TUNIT____-LABEL: define {{[^@]+}}@test2
27 ; IS__TUNIT____-SAME: (i8* nofree nonnull readnone returned "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR1:[0-9]+]] {
28 ; IS__TUNIT____-NEXT:    ret i8* [[P]]
30 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
31 ; IS__CGSCC____-LABEL: define {{[^@]+}}@test2
32 ; IS__CGSCC____-SAME: (i8* nofree nonnull readnone returned "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR1:[0-9]+]] {
33 ; IS__CGSCC____-NEXT:    ret i8* [[P]]
35   ret i8* %p
38 define i8* @test2A(i1 %c, i8* %ret) {
39 ; NOT_CGSCC_OPM: Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn
40 ; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test2A
41 ; NOT_CGSCC_OPM-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned "no-capture-maybe-returned" [[RET:%.*]]) #[[ATTR0:[0-9]+]] {
42 ; NOT_CGSCC_OPM-NEXT:    br i1 [[C]], label [[A:%.*]], label [[B:%.*]]
43 ; NOT_CGSCC_OPM:       A:
44 ; NOT_CGSCC_OPM-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR12:[0-9]+]] [ "nonnull"(i8* [[RET]]) ]
45 ; NOT_CGSCC_OPM-NEXT:    ret i8* [[RET]]
46 ; NOT_CGSCC_OPM:       B:
47 ; NOT_CGSCC_OPM-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR12]] [ "nonnull"(i8* [[RET]]) ]
48 ; NOT_CGSCC_OPM-NEXT:    ret i8* [[RET]]
50 ; IS__CGSCC_OPM: Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn
51 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test2A
52 ; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned "no-capture-maybe-returned" [[RET:%.*]]) #[[ATTR0:[0-9]+]] {
53 ; IS__CGSCC_OPM-NEXT:    br i1 [[C]], label [[A:%.*]], label [[B:%.*]]
54 ; IS__CGSCC_OPM:       A:
55 ; IS__CGSCC_OPM-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR13:[0-9]+]] [ "nonnull"(i8* [[RET]]) ]
56 ; IS__CGSCC_OPM-NEXT:    ret i8* [[RET]]
57 ; IS__CGSCC_OPM:       B:
58 ; IS__CGSCC_OPM-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR13]] [ "nonnull"(i8* [[RET]]) ]
59 ; IS__CGSCC_OPM-NEXT:    ret i8* [[RET]]
61   br i1 %c, label %A, label %B
63   call void @llvm.assume(i1 true) [ "nonnull"(i8* %ret) ]
64   ret i8* %ret
66   call void @llvm.assume(i1 true) [ "nonnull"(i8* %ret) ]
67   ret i8* %ret
70 define i8* @test2B(i1 %c, i8* %ret) {
71 ; NOT_CGSCC_OPM: Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn
72 ; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test2B
73 ; NOT_CGSCC_OPM-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[RET:%.*]]) #[[ATTR0]] {
74 ; NOT_CGSCC_OPM-NEXT:    br i1 [[C]], label [[A:%.*]], label [[B:%.*]]
75 ; NOT_CGSCC_OPM:       A:
76 ; NOT_CGSCC_OPM-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR12]] [ "dereferenceable"(i8* [[RET]], i32 4) ]
77 ; NOT_CGSCC_OPM-NEXT:    ret i8* [[RET]]
78 ; NOT_CGSCC_OPM:       B:
79 ; NOT_CGSCC_OPM-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR12]] [ "dereferenceable"(i8* [[RET]], i32 4) ]
80 ; NOT_CGSCC_OPM-NEXT:    ret i8* [[RET]]
82 ; IS__CGSCC_OPM: Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn
83 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test2B
84 ; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[RET:%.*]]) #[[ATTR0]] {
85 ; IS__CGSCC_OPM-NEXT:    br i1 [[C]], label [[A:%.*]], label [[B:%.*]]
86 ; IS__CGSCC_OPM:       A:
87 ; IS__CGSCC_OPM-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR13]] [ "dereferenceable"(i8* [[RET]], i32 4) ]
88 ; IS__CGSCC_OPM-NEXT:    ret i8* [[RET]]
89 ; IS__CGSCC_OPM:       B:
90 ; IS__CGSCC_OPM-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR13]] [ "dereferenceable"(i8* [[RET]], i32 4) ]
91 ; IS__CGSCC_OPM-NEXT:    ret i8* [[RET]]
93   br i1 %c, label %A, label %B
95   call void @llvm.assume(i1 true) [ "dereferenceable"(i8* %ret, i32 4) ]
96   ret i8* %ret
98   call void @llvm.assume(i1 true) [ "dereferenceable"(i8* %ret, i32 4) ]
99   ret i8* %ret
102 ; Given an SCC where one of the functions can not be marked nonnull,
103 ; can we still mark the other one which is trivially nonnull
104 define i8* @scc_binder(i1 %c) {
105 ; IS________OPM-LABEL: define {{[^@]+}}@scc_binder
106 ; IS________OPM-SAME: (i1 [[C:%.*]]) {
107 ; IS________OPM-NEXT:    br i1 [[C]], label [[REC:%.*]], label [[END:%.*]]
108 ; IS________OPM:       rec:
109 ; IS________OPM-NEXT:    [[TMP1:%.*]] = call i8* @test3(i1 [[C]])
110 ; IS________OPM-NEXT:    br label [[END]]
111 ; IS________OPM:       end:
112 ; IS________OPM-NEXT:    ret i8* null
114 ; IS________NPM-LABEL: define {{[^@]+}}@scc_binder
115 ; IS________NPM-SAME: (i1 [[C:%.*]]) {
116 ; IS________NPM-NEXT:    br i1 [[C]], label [[REC:%.*]], label [[END:%.*]]
117 ; IS________NPM:       rec:
118 ; IS________NPM-NEXT:    [[TMP1:%.*]] = call i8* @test3(i1 noundef [[C]])
119 ; IS________NPM-NEXT:    br label [[END]]
120 ; IS________NPM:       end:
121 ; IS________NPM-NEXT:    ret i8* null
123   br i1 %c, label %rec, label %end
124 rec:
125   call i8* @test3(i1 %c)
126   br label %end
127 end:
128   ret i8* null
131 define i8* @test3(i1 %c) {
132 ; CHECK-LABEL: define {{[^@]+}}@test3
133 ; CHECK-SAME: (i1 [[C:%.*]]) {
134 ; CHECK-NEXT:    [[TMP1:%.*]] = call i8* @scc_binder(i1 [[C]])
135 ; CHECK-NEXT:    [[RET:%.*]] = call nonnull i8* @ret_nonnull()
136 ; CHECK-NEXT:    ret i8* [[RET]]
138   call i8* @scc_binder(i1 %c)
139   %ret = call i8* @ret_nonnull()
140   ret i8* %ret
143 ; Given a mutual recursive set of functions, we can mark them
144 ; nonnull if neither can ever return null.  (In this case, they
145 ; just never return period.)
146 define i8* @test4_helper() {
147 ; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone willreturn
148 ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test4_helper
149 ; NOT_CGSCC_NPM-SAME: () #[[ATTR2:[0-9]+]] {
150 ; NOT_CGSCC_NPM-NEXT:    unreachable
152 ; IS__CGSCC_NPM: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
153 ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test4_helper
154 ; IS__CGSCC_NPM-SAME: () #[[ATTR2:[0-9]+]] {
155 ; IS__CGSCC_NPM-NEXT:    unreachable
157   %ret = call i8* @test4()
158   ret i8* %ret
161 define i8* @test4() {
162 ; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone willreturn
163 ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test4
164 ; NOT_CGSCC_NPM-SAME: () #[[ATTR2]] {
165 ; NOT_CGSCC_NPM-NEXT:    unreachable
167 ; IS__CGSCC_NPM: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
168 ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test4
169 ; IS__CGSCC_NPM-SAME: () #[[ATTR2]] {
170 ; IS__CGSCC_NPM-NEXT:    unreachable
172   %ret = call i8* @test4_helper()
173   ret i8* %ret
176 ; Given a mutual recursive set of functions which *can* return null
177 ; make sure we haven't marked them as nonnull.
178 define i8* @test5_helper(i1 %c) {
179 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
180 ; IS__TUNIT____-LABEL: define {{[^@]+}}@test5_helper
181 ; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
182 ; IS__TUNIT____-NEXT:    br i1 [[C]], label [[REC:%.*]], label [[END:%.*]]
183 ; IS__TUNIT____:       rec:
184 ; IS__TUNIT____-NEXT:    br label [[END]]
185 ; IS__TUNIT____:       end:
186 ; IS__TUNIT____-NEXT:    ret i8* null
188 ; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
189 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test5_helper
190 ; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR3:[0-9]+]] {
191 ; IS__CGSCC_OPM-NEXT:    br i1 [[C]], label [[REC:%.*]], label [[END:%.*]]
192 ; IS__CGSCC_OPM:       rec:
193 ; IS__CGSCC_OPM-NEXT:    br label [[END]]
194 ; IS__CGSCC_OPM:       end:
195 ; IS__CGSCC_OPM-NEXT:    ret i8* null
197 ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
198 ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test5_helper
199 ; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
200 ; IS__CGSCC_NPM-NEXT:    br i1 [[C]], label [[REC:%.*]], label [[END:%.*]]
201 ; IS__CGSCC_NPM:       rec:
202 ; IS__CGSCC_NPM-NEXT:    br label [[END]]
203 ; IS__CGSCC_NPM:       end:
204 ; IS__CGSCC_NPM-NEXT:    ret i8* null
206   br i1 %c, label %rec, label %end
207 rec:
208   %ret = call i8* @test5(i1 %c)
209   br label %end
210 end:
211   ret i8* null
214 define i8* @test5(i1 %c) {
215 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
216 ; IS__TUNIT____-LABEL: define {{[^@]+}}@test5
217 ; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
218 ; IS__TUNIT____-NEXT:    ret i8* null
220 ; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
221 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test5
222 ; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR3]] {
223 ; IS__CGSCC_OPM-NEXT:    ret i8* null
225 ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
226 ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test5
227 ; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
228 ; IS__CGSCC_NPM-NEXT:    ret i8* null
230   %ret = call i8* @test5_helper(i1 %c)
231   ret i8* %ret
234 ; Local analysis, but going through a self recursive phi
235 define i8* @test6a() {
237 ; NOT_CGSCC_OPM: Function Attrs: noreturn
238 ; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test6a
239 ; NOT_CGSCC_OPM-SAME: () #[[ATTR3:[0-9]+]] {
240 ; NOT_CGSCC_OPM-NEXT:  entry:
241 ; NOT_CGSCC_OPM-NEXT:    [[RET:%.*]] = call i8* @ret_nonnull()
242 ; NOT_CGSCC_OPM-NEXT:    br label [[LOOP:%.*]]
243 ; NOT_CGSCC_OPM:       loop:
244 ; NOT_CGSCC_OPM-NEXT:    unreachable
245 ; NOT_CGSCC_OPM:       exit:
246 ; NOT_CGSCC_OPM-NEXT:    unreachable
248 ; IS__CGSCC_OPM: Function Attrs: noreturn
249 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test6a
250 ; IS__CGSCC_OPM-SAME: () #[[ATTR4:[0-9]+]] {
251 ; IS__CGSCC_OPM-NEXT:  entry:
252 ; IS__CGSCC_OPM-NEXT:    [[RET:%.*]] = call i8* @ret_nonnull()
253 ; IS__CGSCC_OPM-NEXT:    br label [[LOOP:%.*]]
254 ; IS__CGSCC_OPM:       loop:
255 ; IS__CGSCC_OPM-NEXT:    unreachable
256 ; IS__CGSCC_OPM:       exit:
257 ; IS__CGSCC_OPM-NEXT:    unreachable
259 entry:
260   %ret = call i8* @ret_nonnull()
261   br label %loop
262 loop:
263   %phi = phi i8* [%ret, %entry], [%phi, %loop]
264   br i1 undef, label %loop, label %exit
265 exit:
266   ret i8* %phi
269 define i8* @test6b(i1 %c) {
270 ; CHECK-LABEL: define {{[^@]+}}@test6b
271 ; CHECK-SAME: (i1 [[C:%.*]]) {
272 ; CHECK-NEXT:  entry:
273 ; CHECK-NEXT:    [[RET:%.*]] = call nonnull i8* @ret_nonnull()
274 ; CHECK-NEXT:    br label [[LOOP:%.*]]
275 ; CHECK:       loop:
276 ; CHECK-NEXT:    [[PHI:%.*]] = phi i8* [ [[RET]], [[ENTRY:%.*]] ], [ [[PHI]], [[LOOP]] ]
277 ; CHECK-NEXT:    br i1 [[C]], label [[LOOP]], label [[EXIT:%.*]]
278 ; CHECK:       exit:
279 ; CHECK-NEXT:    ret i8* [[PHI]]
281 entry:
282   %ret = call i8* @ret_nonnull()
283   br label %loop
284 loop:
285   %phi = phi i8* [%ret, %entry], [%phi, %loop]
286   br i1 %c, label %loop, label %exit
287 exit:
288   ret i8* %phi
291 define i8* @test7(i8* %a) {
292 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
293 ; IS__TUNIT____-LABEL: define {{[^@]+}}@test7
294 ; IS__TUNIT____-SAME: (i8* nofree readnone returned "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] {
295 ; IS__TUNIT____-NEXT:    ret i8* [[A]]
297 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
298 ; IS__CGSCC____-LABEL: define {{[^@]+}}@test7
299 ; IS__CGSCC____-SAME: (i8* nofree readnone returned "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] {
300 ; IS__CGSCC____-NEXT:    ret i8* [[A]]
302   %b = getelementptr inbounds i8, i8* %a, i64 0
303   ret i8* %b
306 define i8* @test8(i8* %a) {
307 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
308 ; IS__TUNIT____-LABEL: define {{[^@]+}}@test8
309 ; IS__TUNIT____-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] {
310 ; IS__TUNIT____-NEXT:    [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 1
311 ; IS__TUNIT____-NEXT:    ret i8* [[B]]
313 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
314 ; IS__CGSCC____-LABEL: define {{[^@]+}}@test8
315 ; IS__CGSCC____-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] {
316 ; IS__CGSCC____-NEXT:    [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 1
317 ; IS__CGSCC____-NEXT:    ret i8* [[B]]
319   %b = getelementptr inbounds i8, i8* %a, i64 1
320   ret i8* %b
323 define i8* @test9(i8* %a, i64 %n) {
324 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
325 ; IS__TUNIT____-LABEL: define {{[^@]+}}@test9
326 ; IS__TUNIT____-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]], i64 [[N:%.*]]) #[[ATTR1]] {
327 ; IS__TUNIT____-NEXT:    [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 [[N]]
328 ; IS__TUNIT____-NEXT:    ret i8* [[B]]
330 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
331 ; IS__CGSCC____-LABEL: define {{[^@]+}}@test9
332 ; IS__CGSCC____-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]], i64 [[N:%.*]]) #[[ATTR1]] {
333 ; IS__CGSCC____-NEXT:    [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 [[N]]
334 ; IS__CGSCC____-NEXT:    ret i8* [[B]]
336   %b = getelementptr inbounds i8, i8* %a, i64 %n
337   ret i8* %b
340 ; ATTRIBUTOR_OPM: define i8* @test10
341 ; ATTRIBUTOR_NPM: define nonnull i8* @test10
342 define i8* @test10(i8* %a, i64 %n) {
343 ; NOT_CGSCC_OPM: Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn
344 ; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test10
345 ; NOT_CGSCC_OPM-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]], i64 [[N:%.*]]) #[[ATTR0]] {
346 ; NOT_CGSCC_OPM-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR12]]
347 ; NOT_CGSCC_OPM-NEXT:    [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 [[N]]
348 ; NOT_CGSCC_OPM-NEXT:    ret i8* [[B]]
350 ; IS__CGSCC_OPM: Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn
351 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test10
352 ; IS__CGSCC_OPM-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]], i64 [[N:%.*]]) #[[ATTR0]] {
353 ; IS__CGSCC_OPM-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR13]]
354 ; IS__CGSCC_OPM-NEXT:    [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 [[N]]
355 ; IS__CGSCC_OPM-NEXT:    ret i8* [[B]]
357   %cmp = icmp ne i64 %n, 0
358   call void @llvm.assume(i1 %cmp)
359   %b = getelementptr inbounds i8, i8* %a, i64 %n
360   ret i8* %b
363 ; TEST 11
364 ; char* test11(char *p) {
365 ;   return p? p: nonnull();
366 ; }
367 ; FIXME: missing nonnull
368 define i8* @test11(i8*) local_unnamed_addr {
369 ; CHECK-LABEL: define {{[^@]+}}@test11
370 ; CHECK-SAME: (i8* [[TMP0:%.*]]) local_unnamed_addr {
371 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null
372 ; CHECK-NEXT:    br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
373 ; CHECK:       3:
374 ; CHECK-NEXT:    [[TMP4:%.*]] = tail call i8* @ret_nonnull()
375 ; CHECK-NEXT:    br label [[TMP5]]
376 ; CHECK:       5:
377 ; CHECK-NEXT:    [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ]
378 ; CHECK-NEXT:    ret i8* [[TMP6]]
380   %2 = icmp eq i8* %0, null
381   br i1 %2, label %3, label %5
383 ; <label>:3:                                      ; preds = %1
384   %4 = tail call i8* @ret_nonnull()
385   br label %5
387 ; <label>:5:                                      ; preds = %3, %1
388   %6 = phi i8* [ %4, %3 ], [ %0, %1 ]
389   ret i8* %6
392 ; TEST 12
393 ; Simple CallSite Test
394 declare void @test12_helper(i8*)
395 define void @test12(i8* nonnull %a) {
396 ; CHECK-LABEL: define {{[^@]+}}@test12
397 ; CHECK-SAME: (i8* nonnull [[A:%.*]]) {
398 ; CHECK-NEXT:    tail call void @test12_helper(i8* nonnull [[A]])
399 ; CHECK-NEXT:    ret void
401   tail call void @test12_helper(i8* %a)
402   ret void
405 ; TEST 13
406 ; Simple Argument Tests
407 declare i8* @unknown()
408 define void @test13_helper() {
409 ; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test13_helper() {
410 ; NOT_CGSCC_OPM-NEXT:    [[NONNULLPTR:%.*]] = tail call nonnull i8* @ret_nonnull()
411 ; NOT_CGSCC_OPM-NEXT:    [[MAYBENULLPTR:%.*]] = tail call i8* @unknown()
412 ; NOT_CGSCC_OPM-NEXT:    tail call void @test13(i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]], i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]], i8* noalias nocapture nofree readnone [[MAYBENULLPTR]]) #[[ATTR4:[0-9]+]]
413 ; NOT_CGSCC_OPM-NEXT:    tail call void @test13(i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]], i8* noalias nocapture nofree readnone [[MAYBENULLPTR]], i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]]) #[[ATTR4]]
414 ; NOT_CGSCC_OPM-NEXT:    ret void
416 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test13_helper() {
417 ; IS__CGSCC_OPM-NEXT:    [[NONNULLPTR:%.*]] = tail call nonnull i8* @ret_nonnull()
418 ; IS__CGSCC_OPM-NEXT:    [[MAYBENULLPTR:%.*]] = tail call i8* @unknown()
419 ; IS__CGSCC_OPM-NEXT:    tail call void @test13(i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]], i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]], i8* noalias nocapture nofree readnone [[MAYBENULLPTR]]) #[[ATTR5:[0-9]+]]
420 ; IS__CGSCC_OPM-NEXT:    tail call void @test13(i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]], i8* noalias nocapture nofree readnone [[MAYBENULLPTR]], i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]]) #[[ATTR5]]
421 ; IS__CGSCC_OPM-NEXT:    ret void
423   %nonnullptr = tail call i8* @ret_nonnull()
424   %maybenullptr = tail call i8* @unknown()
425   tail call void @test13(i8* %nonnullptr, i8* %nonnullptr, i8* %maybenullptr)
426   tail call void @test13(i8* %nonnullptr, i8* %maybenullptr, i8* %nonnullptr)
427   ret void
429 define internal void @test13(i8* %a, i8* %b, i8* %c) {
431 ; NOT_CGSCC_OPM: Function Attrs: nounwind
432 ; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test13
433 ; NOT_CGSCC_OPM-SAME: (i8* noalias nocapture nofree nonnull readnone [[A:%.*]], i8* noalias nocapture nofree readnone [[B:%.*]], i8* noalias nocapture nofree readnone [[C:%.*]]) #[[ATTR4]] {
434 ; NOT_CGSCC_OPM-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[A]]) #[[ATTR4]]
435 ; NOT_CGSCC_OPM-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[B]]) #[[ATTR4]]
436 ; NOT_CGSCC_OPM-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[C]]) #[[ATTR4]]
437 ; NOT_CGSCC_OPM-NEXT:    ret void
439 ; IS__CGSCC_OPM: Function Attrs: nounwind
440 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test13
441 ; IS__CGSCC_OPM-SAME: (i8* noalias nocapture nofree nonnull readnone [[A:%.*]], i8* noalias nocapture nofree readnone [[B:%.*]], i8* noalias nocapture nofree readnone [[C:%.*]]) #[[ATTR5]] {
442 ; IS__CGSCC_OPM-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[A]]) #[[ATTR5]]
443 ; IS__CGSCC_OPM-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[B]]) #[[ATTR5]]
444 ; IS__CGSCC_OPM-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[C]]) #[[ATTR5]]
445 ; IS__CGSCC_OPM-NEXT:    ret void
447   call void @use_i8_ptr(i8* %a)
448   call void @use_i8_ptr(i8* %b)
449   call void @use_i8_ptr(i8* %c)
450   ret void
453 declare nonnull i8* @nonnull()
455 ; TEST 14
456 ; Complex propagation
457 ; Argument of f1, f2, f3 can be marked with nonnull.
459 ; * Argument
460 ; 1. In f1:bb6, %arg can be marked with nonnull because of the comparison in bb1
461 ; 2. Because f2 is internal function, f2(i32* %arg) -> @f2(i32* nonnull %arg)
462 ; 3. In f1:bb4 %tmp5 is nonnull and f3 is internal function.
463 ;    Then, f3(i32* %arg) -> @f3(i32* nonnull %arg)
464 ; 4. We get nonnull in whole f1 call sites so f1(i32* %arg) -> @f1(i32* nonnull %arg)
467 define internal i32* @f1(i32* %arg) {
468 ; FIXME: missing nonnull It should be nonnull @f1(i32* nonnull readonly %arg)
469 ; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind readonly
470 ; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@f1
471 ; NOT_CGSCC_OPM-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR5:[0-9]+]] {
472 ; NOT_CGSCC_OPM-NEXT:  bb:
473 ; NOT_CGSCC_OPM-NEXT:    [[TMP:%.*]] = icmp eq i32* [[ARG]], null
474 ; NOT_CGSCC_OPM-NEXT:    br i1 [[TMP]], label [[BB9:%.*]], label [[BB1:%.*]]
475 ; NOT_CGSCC_OPM:       bb1:
476 ; NOT_CGSCC_OPM-NEXT:    [[TMP2:%.*]] = load i32, i32* [[ARG]], align 4
477 ; NOT_CGSCC_OPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 0
478 ; NOT_CGSCC_OPM-NEXT:    br i1 [[TMP3]], label [[BB6:%.*]], label [[BB4:%.*]]
479 ; NOT_CGSCC_OPM:       bb4:
480 ; NOT_CGSCC_OPM-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i32, i32* [[ARG]], i64 1
481 ; NOT_CGSCC_OPM-NEXT:    [[TMP5B:%.*]] = tail call i32* @f3(i32* nofree nonnull readonly [[TMP5]]) #[[ATTR13:[0-9]+]]
482 ; NOT_CGSCC_OPM-NEXT:    [[TMP5C:%.*]] = getelementptr inbounds i32, i32* [[TMP5B]], i64 -1
483 ; NOT_CGSCC_OPM-NEXT:    br label [[BB9]]
484 ; NOT_CGSCC_OPM:       bb6:
485 ; NOT_CGSCC_OPM-NEXT:    [[TMP7:%.*]] = tail call i32* @f2(i32* nofree nonnull readonly align 4 dereferenceable(4) [[ARG]]) #[[ATTR13]]
486 ; NOT_CGSCC_OPM-NEXT:    ret i32* [[TMP7]]
487 ; NOT_CGSCC_OPM:       bb9:
488 ; NOT_CGSCC_OPM-NEXT:    [[TMP10:%.*]] = phi i32* [ [[TMP5C]], [[BB4]] ], [ inttoptr (i64 4 to i32*), [[BB:%.*]] ]
489 ; NOT_CGSCC_OPM-NEXT:    ret i32* [[TMP10]]
491 ; IS__CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind readonly
492 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f1
493 ; IS__CGSCC_OPM-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR6:[0-9]+]] {
494 ; IS__CGSCC_OPM-NEXT:  bb:
495 ; IS__CGSCC_OPM-NEXT:    [[TMP:%.*]] = icmp eq i32* [[ARG]], null
496 ; IS__CGSCC_OPM-NEXT:    br i1 [[TMP]], label [[BB9:%.*]], label [[BB1:%.*]]
497 ; IS__CGSCC_OPM:       bb1:
498 ; IS__CGSCC_OPM-NEXT:    [[TMP2:%.*]] = load i32, i32* [[ARG]], align 4
499 ; IS__CGSCC_OPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 0
500 ; IS__CGSCC_OPM-NEXT:    br i1 [[TMP3]], label [[BB6:%.*]], label [[BB4:%.*]]
501 ; IS__CGSCC_OPM:       bb4:
502 ; IS__CGSCC_OPM-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i32, i32* [[ARG]], i64 1
503 ; IS__CGSCC_OPM-NEXT:    [[TMP5B:%.*]] = tail call i32* @f3(i32* nofree nonnull readonly [[TMP5]]) #[[ATTR14:[0-9]+]]
504 ; IS__CGSCC_OPM-NEXT:    [[TMP5C:%.*]] = getelementptr inbounds i32, i32* [[TMP5B]], i64 -1
505 ; IS__CGSCC_OPM-NEXT:    br label [[BB9]]
506 ; IS__CGSCC_OPM:       bb6:
507 ; IS__CGSCC_OPM-NEXT:    [[TMP7:%.*]] = tail call i32* @f2(i32* nofree nonnull readonly align 4 dereferenceable(4) [[ARG]]) #[[ATTR14]]
508 ; IS__CGSCC_OPM-NEXT:    ret i32* [[TMP7]]
509 ; IS__CGSCC_OPM:       bb9:
510 ; IS__CGSCC_OPM-NEXT:    [[TMP10:%.*]] = phi i32* [ [[TMP5C]], [[BB4]] ], [ inttoptr (i64 4 to i32*), [[BB:%.*]] ]
511 ; IS__CGSCC_OPM-NEXT:    ret i32* [[TMP10]]
515   %tmp = icmp eq i32* %arg, null
516   br i1 %tmp, label %bb9, label %bb1
518 bb1:                                              ; preds = %bb
519   %tmp2 = load i32, i32* %arg, align 4
520   %tmp3 = icmp eq i32 %tmp2, 0
521   br i1 %tmp3, label %bb6, label %bb4
523 bb4:                                              ; preds = %bb1
524   %tmp5 = getelementptr inbounds i32, i32* %arg, i64 1
525   %tmp5b = tail call i32* @f3(i32* %tmp5)
526   %tmp5c = getelementptr inbounds i32, i32* %tmp5b, i64 -1
527   br label %bb9
529 bb6:                                              ; preds = %bb1
530   %tmp7 = tail call i32* @f2(i32* %arg)
531   ret i32* %tmp7
533 bb9:                                              ; preds = %bb4, %bb
534   %tmp10 = phi i32* [ %tmp5c, %bb4 ], [ inttoptr (i64 4 to i32*), %bb ]
535   ret i32* %tmp10
538 define internal i32* @f2(i32* %arg) {
539 ; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind readonly
540 ; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@f2
541 ; NOT_CGSCC_OPM-SAME: (i32* nofree nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR5]] {
542 ; NOT_CGSCC_OPM-NEXT:  bb:
543 ; NOT_CGSCC_OPM-NEXT:    [[TMP:%.*]] = tail call i32* @f1(i32* nofree nonnull readonly align 4 dereferenceable(4) [[ARG]]) #[[ATTR13]]
544 ; NOT_CGSCC_OPM-NEXT:    ret i32* [[TMP]]
546 ; IS__CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind readonly
547 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f2
548 ; IS__CGSCC_OPM-SAME: (i32* nofree nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR6]] {
549 ; IS__CGSCC_OPM-NEXT:  bb:
550 ; IS__CGSCC_OPM-NEXT:    [[TMP:%.*]] = tail call i32* @f1(i32* nofree nonnull readonly align 4 dereferenceable(4) [[ARG]]) #[[ATTR14]]
551 ; IS__CGSCC_OPM-NEXT:    ret i32* [[TMP]]
554   %tmp = tail call i32* @f1(i32* %arg)
555   ret i32* %tmp
558 define dso_local noalias i32* @f3(i32* %arg) {
559 ; FIXME: missing nonnull. It should be nonnull @f3(i32* nonnull readonly %arg)
560 ; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind readonly
561 ; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@f3
562 ; NOT_CGSCC_OPM-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR5]] {
563 ; NOT_CGSCC_OPM-NEXT:  bb:
564 ; NOT_CGSCC_OPM-NEXT:    [[TMP:%.*]] = call i32* @f1(i32* nofree readonly [[ARG]]) #[[ATTR13]]
565 ; NOT_CGSCC_OPM-NEXT:    ret i32* [[TMP]]
567 ; IS__CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind readonly
568 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f3
569 ; IS__CGSCC_OPM-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR6]] {
570 ; IS__CGSCC_OPM-NEXT:  bb:
571 ; IS__CGSCC_OPM-NEXT:    [[TMP:%.*]] = call i32* @f1(i32* nofree readonly [[ARG]]) #[[ATTR14]]
572 ; IS__CGSCC_OPM-NEXT:    ret i32* [[TMP]]
575 ; FIXME: missing nonnull. It should be @f1(i32* nonnull readonly %arg)
576   %tmp = call i32* @f1(i32* %arg)
577   ret i32* %tmp
580 ; TEST 15
581 define void @f15(i8* %arg) {
582 ; CHECK-LABEL: define {{[^@]+}}@f15
583 ; CHECK-SAME: (i8* noundef nonnull dereferenceable(4) [[ARG:%.*]]) {
584 ; CHECK-NEXT:    tail call void @use1(i8* noundef nonnull dereferenceable(4) [[ARG]])
585 ; CHECK-NEXT:    ret void
588   tail call void @use1(i8* dereferenceable(4) %arg)
589   ret void
592 declare void @fun0() #1
593 declare void @fun1(i8*) #1
594 declare void @fun2(i8*, i8*) #1
595 declare void @fun3(i8*, i8*, i8*) #1
596 ; TEST 16 simple path test
597 ; if(..)
598 ;   fun2(nonnull %a, nonnull %b)
599 ; else
600 ;   fun2(nonnull %a, %b)
601 ; We can say that %a is nonnull but %b is not.
602 define void @f16(i8* %a, i8 * %b, i8 %c) {
603 ; NOT_CGSCC_OPM: Function Attrs: nounwind willreturn
604 ; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@f16
605 ; NOT_CGSCC_OPM-SAME: (i8* nonnull [[A:%.*]], i8* [[B:%.*]], i8 [[C:%.*]]) #[[ATTR6:[0-9]+]] {
606 ; NOT_CGSCC_OPM-NEXT:    [[CMP:%.*]] = icmp eq i8 [[C]], 0
607 ; NOT_CGSCC_OPM-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
608 ; NOT_CGSCC_OPM:       if.then:
609 ; NOT_CGSCC_OPM-NEXT:    tail call void @fun2(i8* nonnull [[A]], i8* nonnull [[B]]) #[[ATTR6]]
610 ; NOT_CGSCC_OPM-NEXT:    ret void
611 ; NOT_CGSCC_OPM:       if.else:
612 ; NOT_CGSCC_OPM-NEXT:    tail call void @fun2(i8* nonnull [[A]], i8* [[B]]) #[[ATTR6]]
613 ; NOT_CGSCC_OPM-NEXT:    ret void
615 ; IS__CGSCC_OPM: Function Attrs: nounwind willreturn
616 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f16
617 ; IS__CGSCC_OPM-SAME: (i8* nonnull [[A:%.*]], i8* [[B:%.*]], i8 [[C:%.*]]) #[[ATTR7:[0-9]+]] {
618 ; IS__CGSCC_OPM-NEXT:    [[CMP:%.*]] = icmp eq i8 [[C]], 0
619 ; IS__CGSCC_OPM-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
620 ; IS__CGSCC_OPM:       if.then:
621 ; IS__CGSCC_OPM-NEXT:    tail call void @fun2(i8* nonnull [[A]], i8* nonnull [[B]]) #[[ATTR7]]
622 ; IS__CGSCC_OPM-NEXT:    ret void
623 ; IS__CGSCC_OPM:       if.else:
624 ; IS__CGSCC_OPM-NEXT:    tail call void @fun2(i8* nonnull [[A]], i8* [[B]]) #[[ATTR7]]
625 ; IS__CGSCC_OPM-NEXT:    ret void
627   %cmp = icmp eq i8 %c, 0
628   br i1 %cmp, label %if.then, label %if.else
629 if.then:
630   tail call void @fun2(i8* nonnull %a, i8* nonnull %b)
631   ret void
632 if.else:
633   tail call void @fun2(i8* nonnull %a, i8* %b)
634   ret void
636 ; TEST 17 explore child BB test
637 ; if(..)
638 ;    ... (willreturn & nounwind)
639 ; else
640 ;    ... (willreturn & nounwind)
641 ; fun1(nonnull %a)
642 ; We can say that %a is nonnull
643 define void @f17(i8* %a, i8 %c) {
645 ; NOT_CGSCC_OPM: Function Attrs: nounwind willreturn
646 ; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@f17
647 ; NOT_CGSCC_OPM-SAME: (i8* nonnull [[A:%.*]], i8 [[C:%.*]]) #[[ATTR6]] {
648 ; NOT_CGSCC_OPM-NEXT:    [[CMP:%.*]] = icmp eq i8 [[C]], 0
649 ; NOT_CGSCC_OPM-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
650 ; NOT_CGSCC_OPM:       if.then:
651 ; NOT_CGSCC_OPM-NEXT:    tail call void @fun0() #[[ATTR6]]
652 ; NOT_CGSCC_OPM-NEXT:    br label [[CONT:%.*]]
653 ; NOT_CGSCC_OPM:       if.else:
654 ; NOT_CGSCC_OPM-NEXT:    tail call void @fun0() #[[ATTR6]]
655 ; NOT_CGSCC_OPM-NEXT:    br label [[CONT]]
656 ; NOT_CGSCC_OPM:       cont:
657 ; NOT_CGSCC_OPM-NEXT:    tail call void @fun1(i8* nonnull [[A]]) #[[ATTR6]]
658 ; NOT_CGSCC_OPM-NEXT:    ret void
660 ; IS__CGSCC_OPM: Function Attrs: nounwind willreturn
661 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f17
662 ; IS__CGSCC_OPM-SAME: (i8* nonnull [[A:%.*]], i8 [[C:%.*]]) #[[ATTR7]] {
663 ; IS__CGSCC_OPM-NEXT:    [[CMP:%.*]] = icmp eq i8 [[C]], 0
664 ; IS__CGSCC_OPM-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
665 ; IS__CGSCC_OPM:       if.then:
666 ; IS__CGSCC_OPM-NEXT:    tail call void @fun0() #[[ATTR7]]
667 ; IS__CGSCC_OPM-NEXT:    br label [[CONT:%.*]]
668 ; IS__CGSCC_OPM:       if.else:
669 ; IS__CGSCC_OPM-NEXT:    tail call void @fun0() #[[ATTR7]]
670 ; IS__CGSCC_OPM-NEXT:    br label [[CONT]]
671 ; IS__CGSCC_OPM:       cont:
672 ; IS__CGSCC_OPM-NEXT:    tail call void @fun1(i8* nonnull [[A]]) #[[ATTR7]]
673 ; IS__CGSCC_OPM-NEXT:    ret void
675   %cmp = icmp eq i8 %c, 0
676   br i1 %cmp, label %if.then, label %if.else
677 if.then:
678   tail call void @fun0()
679   br label %cont
680 if.else:
681   tail call void @fun0()
682   br label %cont
683 cont:
684   tail call void @fun1(i8* nonnull %a)
685   ret void
687 ; TEST 18 More complex test
688 ; if(..)
689 ;    ... (willreturn & nounwind)
690 ; else
691 ;    ... (willreturn & nounwind)
692 ; if(..)
693 ;    ... (willreturn & nounwind)
694 ; else
695 ;    ... (willreturn & nounwind)
696 ; fun1(nonnull %a)
698 define void @f18(i8* %a, i8* %b, i8 %c) {
699 ; NOT_CGSCC_OPM: Function Attrs: nounwind willreturn
700 ; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@f18
701 ; NOT_CGSCC_OPM-SAME: (i8* nonnull [[A:%.*]], i8* [[B:%.*]], i8 [[C:%.*]]) #[[ATTR6]] {
702 ; NOT_CGSCC_OPM-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[C]], 0
703 ; NOT_CGSCC_OPM-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
704 ; NOT_CGSCC_OPM:       if.then:
705 ; NOT_CGSCC_OPM-NEXT:    tail call void @fun0() #[[ATTR6]]
706 ; NOT_CGSCC_OPM-NEXT:    br label [[CONT:%.*]]
707 ; NOT_CGSCC_OPM:       if.else:
708 ; NOT_CGSCC_OPM-NEXT:    tail call void @fun0() #[[ATTR6]]
709 ; NOT_CGSCC_OPM-NEXT:    br label [[CONT]]
710 ; NOT_CGSCC_OPM:       cont:
711 ; NOT_CGSCC_OPM-NEXT:    [[CMP2:%.*]] = icmp eq i8 [[C]], 1
712 ; NOT_CGSCC_OPM-NEXT:    br i1 [[CMP2]], label [[CONT_THEN:%.*]], label [[CONT_ELSE:%.*]]
713 ; NOT_CGSCC_OPM:       cont.then:
714 ; NOT_CGSCC_OPM-NEXT:    tail call void @fun1(i8* nonnull [[B]]) #[[ATTR6]]
715 ; NOT_CGSCC_OPM-NEXT:    br label [[CONT2:%.*]]
716 ; NOT_CGSCC_OPM:       cont.else:
717 ; NOT_CGSCC_OPM-NEXT:    tail call void @fun0() #[[ATTR6]]
718 ; NOT_CGSCC_OPM-NEXT:    br label [[CONT2]]
719 ; NOT_CGSCC_OPM:       cont2:
720 ; NOT_CGSCC_OPM-NEXT:    tail call void @fun1(i8* nonnull [[A]]) #[[ATTR6]]
721 ; NOT_CGSCC_OPM-NEXT:    ret void
723 ; IS__CGSCC_OPM: Function Attrs: nounwind willreturn
724 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f18
725 ; IS__CGSCC_OPM-SAME: (i8* nonnull [[A:%.*]], i8* [[B:%.*]], i8 [[C:%.*]]) #[[ATTR7]] {
726 ; IS__CGSCC_OPM-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[C]], 0
727 ; IS__CGSCC_OPM-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
728 ; IS__CGSCC_OPM:       if.then:
729 ; IS__CGSCC_OPM-NEXT:    tail call void @fun0() #[[ATTR7]]
730 ; IS__CGSCC_OPM-NEXT:    br label [[CONT:%.*]]
731 ; IS__CGSCC_OPM:       if.else:
732 ; IS__CGSCC_OPM-NEXT:    tail call void @fun0() #[[ATTR7]]
733 ; IS__CGSCC_OPM-NEXT:    br label [[CONT]]
734 ; IS__CGSCC_OPM:       cont:
735 ; IS__CGSCC_OPM-NEXT:    [[CMP2:%.*]] = icmp eq i8 [[C]], 1
736 ; IS__CGSCC_OPM-NEXT:    br i1 [[CMP2]], label [[CONT_THEN:%.*]], label [[CONT_ELSE:%.*]]
737 ; IS__CGSCC_OPM:       cont.then:
738 ; IS__CGSCC_OPM-NEXT:    tail call void @fun1(i8* nonnull [[B]]) #[[ATTR7]]
739 ; IS__CGSCC_OPM-NEXT:    br label [[CONT2:%.*]]
740 ; IS__CGSCC_OPM:       cont.else:
741 ; IS__CGSCC_OPM-NEXT:    tail call void @fun0() #[[ATTR7]]
742 ; IS__CGSCC_OPM-NEXT:    br label [[CONT2]]
743 ; IS__CGSCC_OPM:       cont2:
744 ; IS__CGSCC_OPM-NEXT:    tail call void @fun1(i8* nonnull [[A]]) #[[ATTR7]]
745 ; IS__CGSCC_OPM-NEXT:    ret void
747   %cmp1 = icmp eq i8 %c, 0
748   br i1 %cmp1, label %if.then, label %if.else
749 if.then:
750   tail call void @fun0()
751   br label %cont
752 if.else:
753   tail call void @fun0()
754   br label %cont
755 cont:
756   %cmp2 = icmp eq i8 %c, 1
757   br i1 %cmp2, label %cont.then, label %cont.else
758 cont.then:
759   tail call void @fun1(i8* nonnull %b)
760   br label %cont2
761 cont.else:
762   tail call void @fun0()
763   br label %cont2
764 cont2:
765   tail call void @fun1(i8* nonnull %a)
766   ret void
769 ; TEST 19: Loop
771 define void @f19(i8* %a, i8* %b, i8 %c) {
772 ; NOT_CGSCC_OPM: Function Attrs: nounwind
773 ; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@f19
774 ; NOT_CGSCC_OPM-SAME: (i8* [[A:%.*]], i8* nonnull [[B:%.*]], i8 [[C:%.*]]) #[[ATTR4]] {
775 ; NOT_CGSCC_OPM-NEXT:    br label [[LOOP_HEADER:%.*]]
776 ; NOT_CGSCC_OPM:       loop.header:
777 ; NOT_CGSCC_OPM-NEXT:    [[CMP2:%.*]] = icmp eq i8 [[C]], 0
778 ; NOT_CGSCC_OPM-NEXT:    br i1 [[CMP2]], label [[LOOP_BODY:%.*]], label [[LOOP_EXIT:%.*]]
779 ; NOT_CGSCC_OPM:       loop.body:
780 ; NOT_CGSCC_OPM-NEXT:    tail call void @fun1(i8* nonnull [[B]]) #[[ATTR4]]
781 ; NOT_CGSCC_OPM-NEXT:    tail call void @fun1(i8* nonnull [[A]]) #[[ATTR4]]
782 ; NOT_CGSCC_OPM-NEXT:    br label [[LOOP_HEADER]]
783 ; NOT_CGSCC_OPM:       loop.exit:
784 ; NOT_CGSCC_OPM-NEXT:    tail call void @fun1(i8* nonnull [[B]]) #[[ATTR4]]
785 ; NOT_CGSCC_OPM-NEXT:    ret void
787 ; IS__CGSCC_OPM: Function Attrs: nounwind
788 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f19
789 ; IS__CGSCC_OPM-SAME: (i8* [[A:%.*]], i8* nonnull [[B:%.*]], i8 [[C:%.*]]) #[[ATTR5]] {
790 ; IS__CGSCC_OPM-NEXT:    br label [[LOOP_HEADER:%.*]]
791 ; IS__CGSCC_OPM:       loop.header:
792 ; IS__CGSCC_OPM-NEXT:    [[CMP2:%.*]] = icmp eq i8 [[C]], 0
793 ; IS__CGSCC_OPM-NEXT:    br i1 [[CMP2]], label [[LOOP_BODY:%.*]], label [[LOOP_EXIT:%.*]]
794 ; IS__CGSCC_OPM:       loop.body:
795 ; IS__CGSCC_OPM-NEXT:    tail call void @fun1(i8* nonnull [[B]]) #[[ATTR5]]
796 ; IS__CGSCC_OPM-NEXT:    tail call void @fun1(i8* nonnull [[A]]) #[[ATTR5]]
797 ; IS__CGSCC_OPM-NEXT:    br label [[LOOP_HEADER]]
798 ; IS__CGSCC_OPM:       loop.exit:
799 ; IS__CGSCC_OPM-NEXT:    tail call void @fun1(i8* nonnull [[B]]) #[[ATTR5]]
800 ; IS__CGSCC_OPM-NEXT:    ret void
802   br label %loop.header
803 loop.header:
804   %cmp2 = icmp eq i8 %c, 0
805   br i1 %cmp2, label %loop.body, label %loop.exit
806 loop.body:
807   tail call void @fun1(i8* nonnull %b)
808   tail call void @fun1(i8* nonnull %a)
809   br label %loop.header
810 loop.exit:
811   tail call void @fun1(i8* nonnull %b)
812   ret void
815 ; Test propagation of nonnull callsite args back to caller.
817 declare void @use1(i8* %x)
818 declare void @use2(i8* %x, i8* %y);
819 declare void @use3(i8* %x, i8* %y, i8* %z);
821 declare void @use1nonnull(i8* nonnull %x);
822 declare void @use2nonnull(i8* nonnull %x, i8* nonnull %y);
823 declare void @use3nonnull(i8* nonnull %x, i8* nonnull %y, i8* nonnull %z);
825 declare i8 @use1safecall(i8* %x) readonly nounwind willreturn ; nounwind+willreturn guarantees that execution continues to successor
827 ; Can't extend non-null to parent for any argument because the 2nd call is not guaranteed to execute.
829 define void @parent1(i8* %a, i8* %b, i8* %c) {
830 ; CHECK-LABEL: define {{[^@]+}}@parent1
831 ; CHECK-SAME: (i8* [[A:%.*]], i8* [[B:%.*]], i8* [[C:%.*]]) {
832 ; CHECK-NEXT:    call void @use3(i8* [[C]], i8* [[A]], i8* [[B]])
833 ; CHECK-NEXT:    call void @use3nonnull(i8* nonnull [[B]], i8* nonnull [[C]], i8* nonnull [[A]])
834 ; CHECK-NEXT:    ret void
836   call void @use3(i8* %c, i8* %a, i8* %b)
837   call void @use3nonnull(i8* %b, i8* %c, i8* %a)
838   ret void
841 ; Extend non-null to parent for all arguments.
843 define void @parent2(i8* %a, i8* %b, i8* %c) {
844 ; CHECK-LABEL: define {{[^@]+}}@parent2
845 ; CHECK-SAME: (i8* nonnull [[A:%.*]], i8* nonnull [[B:%.*]], i8* nonnull [[C:%.*]]) {
846 ; CHECK-NEXT:    call void @use3nonnull(i8* nonnull [[B]], i8* nonnull [[C]], i8* nonnull [[A]])
847 ; CHECK-NEXT:    call void @use3(i8* nonnull [[C]], i8* nonnull [[A]], i8* nonnull [[B]])
848 ; CHECK-NEXT:    ret void
851   call void @use3nonnull(i8* %b, i8* %c, i8* %a)
852   call void @use3(i8* %c, i8* %a, i8* %b)
853   ret void
856 ; Extend non-null to parent for 1st argument.
858 define void @parent3(i8* %a, i8* %b, i8* %c) {
859 ; CHECK-LABEL: define {{[^@]+}}@parent3
860 ; CHECK-SAME: (i8* nonnull [[A:%.*]], i8* [[B:%.*]], i8* [[C:%.*]]) {
861 ; CHECK-NEXT:    call void @use1nonnull(i8* nonnull [[A]])
862 ; CHECK-NEXT:    call void @use3(i8* [[C]], i8* [[B]], i8* nonnull [[A]])
863 ; CHECK-NEXT:    ret void
867   call void @use1nonnull(i8* %a)
868   call void @use3(i8* %c, i8* %b, i8* %a)
869   ret void
872 ; Extend non-null to parent for last 2 arguments.
874 define void @parent4(i8* %a, i8* %b, i8* %c) {
875 ; CHECK-LABEL: define {{[^@]+}}@parent4
876 ; CHECK-SAME: (i8* [[A:%.*]], i8* nonnull [[B:%.*]], i8* nonnull [[C:%.*]]) {
877 ; CHECK-NEXT:    call void @use2nonnull(i8* nonnull [[C]], i8* nonnull [[B]])
878 ; CHECK-NEXT:    call void @use2(i8* [[A]], i8* nonnull [[C]])
879 ; CHECK-NEXT:    call void @use1(i8* nonnull [[B]])
880 ; CHECK-NEXT:    ret void
885   call void @use2nonnull(i8* %c, i8* %b)
886   call void @use2(i8* %a, i8* %c)
887   call void @use1(i8* %b)
888   ret void
891 ; The callsite must execute in order for the attribute to transfer to the parent.
892 ; It appears benign to extend non-null to the parent in this case, but we can't do that
893 ; because it would incorrectly propagate the wrong information to its callers.
895 define void @parent5(i8* %a, i1 %a_is_notnull) {
896 ; CHECK-LABEL: define {{[^@]+}}@parent5
897 ; CHECK-SAME: (i8* [[A:%.*]], i1 [[A_IS_NOTNULL:%.*]]) {
898 ; CHECK-NEXT:    br i1 [[A_IS_NOTNULL]], label [[T:%.*]], label [[F:%.*]]
899 ; CHECK:       t:
900 ; CHECK-NEXT:    call void @use1nonnull(i8* nonnull [[A]])
901 ; CHECK-NEXT:    ret void
902 ; CHECK:       f:
903 ; CHECK-NEXT:    ret void
906   br i1 %a_is_notnull, label %t, label %f
908   call void @use1nonnull(i8* %a)
909   ret void
911   ret void
914 ; The callsite must execute in order for the attribute to transfer to the parent.
915 ; The volatile load can't trap, so we can guarantee that we'll get to the call.
917 define i8 @parent6(i8* %a, i8* %b) {
918 ; CHECK-LABEL: define {{[^@]+}}@parent6
919 ; CHECK-SAME: (i8* nonnull [[A:%.*]], i8* nofree noundef [[B:%.*]]) {
920 ; CHECK-NEXT:    [[C:%.*]] = load volatile i8, i8* [[B]], align 1
921 ; CHECK-NEXT:    call void @use1nonnull(i8* nonnull [[A]])
922 ; CHECK-NEXT:    ret i8 [[C]]
925   %c = load volatile i8, i8* %b
926   call void @use1nonnull(i8* %a)
927   ret i8 %c
930 ; The nonnull callsite is guaranteed to execute, so the argument must be nonnull throughout the parent.
932 define i8 @parent7(i8* %a) {
933 ; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@parent7
934 ; NOT_CGSCC_OPM-SAME: (i8* nonnull [[A:%.*]]) {
935 ; NOT_CGSCC_OPM-NEXT:    [[RET:%.*]] = call i8 @use1safecall(i8* nonnull readonly [[A]]) #[[ATTR14:[0-9]+]]
936 ; NOT_CGSCC_OPM-NEXT:    call void @use1nonnull(i8* nonnull [[A]])
937 ; NOT_CGSCC_OPM-NEXT:    ret i8 [[RET]]
939 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@parent7
940 ; IS__CGSCC_OPM-SAME: (i8* nonnull [[A:%.*]]) {
941 ; IS__CGSCC_OPM-NEXT:    [[RET:%.*]] = call i8 @use1safecall(i8* nonnull readonly [[A]]) #[[ATTR15:[0-9]+]]
942 ; IS__CGSCC_OPM-NEXT:    call void @use1nonnull(i8* nonnull [[A]])
943 ; IS__CGSCC_OPM-NEXT:    ret i8 [[RET]]
947   %ret = call i8 @use1safecall(i8* %a)
948   call void @use1nonnull(i8* %a)
949   ret i8 %ret
952 ; Make sure that an invoke works similarly to a call.
954 declare i32 @esfp(...)
956 define i1 @parent8(i8* %a, i8* %bogus1, i8* %b) personality i8* bitcast (i32 (...)* @esfp to i8*){
957 ; NOT_CGSCC_OPM: Function Attrs: nounwind
958 ; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@parent8
959 ; NOT_CGSCC_OPM-SAME: (i8* nonnull [[A:%.*]], i8* nocapture nofree readnone [[BOGUS1:%.*]], i8* nonnull [[B:%.*]]) #[[ATTR4]] personality i8* bitcast (i32 (...)* @esfp to i8*) {
960 ; NOT_CGSCC_OPM-NEXT:  entry:
961 ; NOT_CGSCC_OPM-NEXT:    invoke void @use2nonnull(i8* nonnull [[A]], i8* nonnull [[B]])
962 ; NOT_CGSCC_OPM-NEXT:    to label [[CONT:%.*]] unwind label [[EXC:%.*]]
963 ; NOT_CGSCC_OPM:       cont:
964 ; NOT_CGSCC_OPM-NEXT:    ret i1 false
965 ; NOT_CGSCC_OPM:       exc:
966 ; NOT_CGSCC_OPM-NEXT:    [[LP:%.*]] = landingpad { i8*, i32 }
967 ; NOT_CGSCC_OPM-NEXT:    filter [0 x i8*] zeroinitializer
968 ; NOT_CGSCC_OPM-NEXT:    unreachable
970 ; IS__CGSCC_OPM: Function Attrs: nounwind
971 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@parent8
972 ; IS__CGSCC_OPM-SAME: (i8* nonnull [[A:%.*]], i8* nocapture nofree readnone [[BOGUS1:%.*]], i8* nonnull [[B:%.*]]) #[[ATTR5]] personality i8* bitcast (i32 (...)* @esfp to i8*) {
973 ; IS__CGSCC_OPM-NEXT:  entry:
974 ; IS__CGSCC_OPM-NEXT:    invoke void @use2nonnull(i8* nonnull [[A]], i8* nonnull [[B]])
975 ; IS__CGSCC_OPM-NEXT:    to label [[CONT:%.*]] unwind label [[EXC:%.*]]
976 ; IS__CGSCC_OPM:       cont:
977 ; IS__CGSCC_OPM-NEXT:    ret i1 false
978 ; IS__CGSCC_OPM:       exc:
979 ; IS__CGSCC_OPM-NEXT:    [[LP:%.*]] = landingpad { i8*, i32 }
980 ; IS__CGSCC_OPM-NEXT:    filter [0 x i8*] zeroinitializer
981 ; IS__CGSCC_OPM-NEXT:    unreachable
984 entry:
985   invoke void @use2nonnull(i8* %a, i8* %b)
986   to label %cont unwind label %exc
988 cont:
989   %null_check = icmp eq i8* %b, null
990   ret i1 %null_check
992 exc:
993   %lp = landingpad { i8*, i32 }
994   filter [0 x i8*] zeroinitializer
995   unreachable
998 define i32* @gep1(i32* %p) {
999 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
1000 ; IS__TUNIT____-LABEL: define {{[^@]+}}@gep1
1001 ; IS__TUNIT____-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR1]] {
1002 ; IS__TUNIT____-NEXT:    [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 1
1003 ; IS__TUNIT____-NEXT:    ret i32* [[Q]]
1005 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
1006 ; IS__CGSCC____-LABEL: define {{[^@]+}}@gep1
1007 ; IS__CGSCC____-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR1]] {
1008 ; IS__CGSCC____-NEXT:    [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 1
1009 ; IS__CGSCC____-NEXT:    ret i32* [[Q]]
1011   %q = getelementptr inbounds i32, i32* %p, i32 1
1012   ret i32* %q
1015 define i32* @gep1_no_null_opt(i32* %p) #0 {
1016 ; Should't be able to derive nonnull based on gep.
1017 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind null_pointer_is_valid readnone willreturn
1018 ; IS__TUNIT____-LABEL: define {{[^@]+}}@gep1_no_null_opt
1019 ; IS__TUNIT____-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR8:[0-9]+]] {
1020 ; IS__TUNIT____-NEXT:    [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 1
1021 ; IS__TUNIT____-NEXT:    ret i32* [[Q]]
1023 ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn
1024 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@gep1_no_null_opt
1025 ; IS__CGSCC_OPM-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR9:[0-9]+]] {
1026 ; IS__CGSCC_OPM-NEXT:    [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 1
1027 ; IS__CGSCC_OPM-NEXT:    ret i32* [[Q]]
1029 ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn
1030 ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@gep1_no_null_opt
1031 ; IS__CGSCC_NPM-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR8:[0-9]+]] {
1032 ; IS__CGSCC_NPM-NEXT:    [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 1
1033 ; IS__CGSCC_NPM-NEXT:    ret i32* [[Q]]
1035   %q = getelementptr inbounds i32, i32* %p, i32 1
1036   ret i32* %q
1039 define i32 addrspace(3)* @gep2(i32 addrspace(3)* %p) {
1040 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
1041 ; IS__TUNIT____-LABEL: define {{[^@]+}}@gep2
1042 ; IS__TUNIT____-SAME: (i32 addrspace(3)* nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR1]] {
1043 ; IS__TUNIT____-NEXT:    [[Q:%.*]] = getelementptr inbounds i32, i32 addrspace(3)* [[P]], i32 1
1044 ; IS__TUNIT____-NEXT:    ret i32 addrspace(3)* [[Q]]
1046 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
1047 ; IS__CGSCC____-LABEL: define {{[^@]+}}@gep2
1048 ; IS__CGSCC____-SAME: (i32 addrspace(3)* nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR1]] {
1049 ; IS__CGSCC____-NEXT:    [[Q:%.*]] = getelementptr inbounds i32, i32 addrspace(3)* [[P]], i32 1
1050 ; IS__CGSCC____-NEXT:    ret i32 addrspace(3)* [[Q]]
1052   %q = getelementptr inbounds i32, i32 addrspace(3)* %p, i32 1
1053   ret i32 addrspace(3)* %q
1056 ; FIXME: We should propagate dereferenceable here but *not* nonnull
1057 define i32 addrspace(3)* @as(i32 addrspace(3)* dereferenceable(4) %p) {
1058 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
1059 ; IS__TUNIT____-LABEL: define {{[^@]+}}@as
1060 ; IS__TUNIT____-SAME: (i32 addrspace(3)* nofree nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR1]] {
1061 ; IS__TUNIT____-NEXT:    ret i32 addrspace(3)* [[P]]
1063 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
1064 ; IS__CGSCC____-LABEL: define {{[^@]+}}@as
1065 ; IS__CGSCC____-SAME: (i32 addrspace(3)* nofree nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR1]] {
1066 ; IS__CGSCC____-NEXT:    ret i32 addrspace(3)* [[P]]
1068   ret i32 addrspace(3)* %p
1071 ; CHECK-NOT: @g2()
1072 define internal i32* @g2() {
1073 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
1074 ; IS__CGSCC____-LABEL: define {{[^@]+}}@g2
1075 ; IS__CGSCC____-SAME: () #[[ATTR1]] {
1076 ; IS__CGSCC____-NEXT:    ret i32* undef
1078   ret i32* inttoptr (i64 4 to i32*)
1081 define i32* @g1() {
1082 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
1083 ; IS__TUNIT____-LABEL: define {{[^@]+}}@g1
1084 ; IS__TUNIT____-SAME: () #[[ATTR1]] {
1085 ; IS__TUNIT____-NEXT:    ret i32* inttoptr (i64 4 to i32*)
1087 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
1088 ; IS__CGSCC____-LABEL: define {{[^@]+}}@g1
1089 ; IS__CGSCC____-SAME: () #[[ATTR1]] {
1090 ; IS__CGSCC____-NEXT:    ret i32* inttoptr (i64 4 to i32*)
1092   %c = call i32* @g2()
1093   ret i32* %c
1096 declare void @use_i32_ptr(i32* readnone nocapture) nounwind
1097 define internal void @called_by_weak(i32* %a) {
1098 ; NOT_CGSCC_OPM: Function Attrs: nounwind
1099 ; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@called_by_weak
1100 ; NOT_CGSCC_OPM-SAME: (i32* noalias nocapture nonnull readnone [[A:%.*]]) #[[ATTR4]] {
1101 ; NOT_CGSCC_OPM-NEXT:    call void @use_i32_ptr(i32* noalias nocapture nonnull readnone [[A]]) #[[ATTR4]]
1102 ; NOT_CGSCC_OPM-NEXT:    ret void
1104 ; IS__CGSCC_OPM: Function Attrs: nounwind
1105 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@called_by_weak
1106 ; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nonnull readnone [[A:%.*]]) #[[ATTR5]] {
1107 ; IS__CGSCC_OPM-NEXT:    call void @use_i32_ptr(i32* noalias nocapture nonnull readnone [[A]]) #[[ATTR5]]
1108 ; IS__CGSCC_OPM-NEXT:    ret void
1110   call void @use_i32_ptr(i32* %a)
1111   ret void
1114 ; Check we do not annotate the function interface of this weak function.
1115 define weak_odr void @weak_caller(i32* nonnull %a) {
1117 ; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@weak_caller
1118 ; NOT_CGSCC_OPM-SAME: (i32* nonnull [[A:%.*]]) {
1119 ; NOT_CGSCC_OPM-NEXT:    call void @called_by_weak(i32* noalias nocapture nonnull readnone [[A]]) #[[ATTR4]]
1120 ; NOT_CGSCC_OPM-NEXT:    ret void
1122 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@weak_caller
1123 ; IS__CGSCC_OPM-SAME: (i32* nonnull [[A:%.*]]) {
1124 ; IS__CGSCC_OPM-NEXT:    call void @called_by_weak(i32* noalias nocapture nonnull readnone [[A]]) #[[ATTR5]]
1125 ; IS__CGSCC_OPM-NEXT:    ret void
1127   call void @called_by_weak(i32* %a)
1128   ret void
1131 ; Expect nonnull
1132 define internal void @control(i32* dereferenceable(4) %a) {
1133 ; NOT_CGSCC_OPM: Function Attrs: nounwind
1134 ; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@control
1135 ; NOT_CGSCC_OPM-SAME: (i32* noalias nocapture noundef nonnull readnone align 16 dereferenceable(8) [[A:%.*]]) #[[ATTR4]] {
1136 ; NOT_CGSCC_OPM-NEXT:    call void @use_i32_ptr(i32* noalias nocapture noundef nonnull readnone align 16 dereferenceable(8) [[A]]) #[[ATTR4]]
1137 ; NOT_CGSCC_OPM-NEXT:    ret void
1139 ; IS__CGSCC_OPM: Function Attrs: nounwind
1140 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@control
1141 ; IS__CGSCC_OPM-SAME: (i32* noalias nocapture noundef nonnull readnone align 16 dereferenceable(8) [[A:%.*]]) #[[ATTR5]] {
1142 ; IS__CGSCC_OPM-NEXT:    call void @use_i32_ptr(i32* noalias nocapture noundef nonnull readnone align 16 dereferenceable(8) [[A]]) #[[ATTR5]]
1143 ; IS__CGSCC_OPM-NEXT:    ret void
1145   call void @use_i32_ptr(i32* %a)
1146   ret void
1148 ; Avoid nonnull as we do not touch naked functions
1149 define internal void @naked(i32* dereferenceable(4) %a) naked {
1150 ; NOT_CGSCC_OPM: Function Attrs: naked
1151 ; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@naked
1152 ; NOT_CGSCC_OPM-SAME: (i32* dereferenceable(4) [[A:%.*]]) #[[ATTR9:[0-9]+]] {
1153 ; NOT_CGSCC_OPM-NEXT:    call void @use_i32_ptr(i32* [[A]])
1154 ; NOT_CGSCC_OPM-NEXT:    ret void
1156 ; IS__CGSCC_OPM: Function Attrs: naked
1157 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@naked
1158 ; IS__CGSCC_OPM-SAME: (i32* dereferenceable(4) [[A:%.*]]) #[[ATTR10:[0-9]+]] {
1159 ; IS__CGSCC_OPM-NEXT:    call void @use_i32_ptr(i32* [[A]])
1160 ; IS__CGSCC_OPM-NEXT:    ret void
1162   call void @use_i32_ptr(i32* %a)
1163   ret void
1165 ; Avoid nonnull as we do not touch optnone
1166 define internal void @optnone(i32* dereferenceable(4) %a) optnone noinline {
1168 ; NOT_CGSCC_OPM: Function Attrs: noinline optnone
1169 ; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@optnone
1170 ; NOT_CGSCC_OPM-SAME: (i32* dereferenceable(4) [[A:%.*]]) #[[ATTR10:[0-9]+]] {
1171 ; NOT_CGSCC_OPM-NEXT:    call void @use_i32_ptr(i32* [[A]])
1172 ; NOT_CGSCC_OPM-NEXT:    ret void
1174 ; IS__CGSCC_OPM: Function Attrs: noinline optnone
1175 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@optnone
1176 ; IS__CGSCC_OPM-SAME: (i32* dereferenceable(4) [[A:%.*]]) #[[ATTR11:[0-9]+]] {
1177 ; IS__CGSCC_OPM-NEXT:    call void @use_i32_ptr(i32* [[A]])
1178 ; IS__CGSCC_OPM-NEXT:    ret void
1180   call void @use_i32_ptr(i32* %a)
1181   ret void
1183 define void @make_live(i32* nonnull dereferenceable(8) %a) {
1184 ; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@make_live
1185 ; NOT_CGSCC_OPM-SAME: (i32* noundef nonnull align 16 dereferenceable(8) [[A:%.*]]) {
1186 ; NOT_CGSCC_OPM-NEXT:    call void @naked(i32* noundef nonnull align 16 dereferenceable(8) [[A]])
1187 ; NOT_CGSCC_OPM-NEXT:    call void @control(i32* noalias nocapture noundef nonnull readnone align 16 dereferenceable(8) [[A]]) #[[ATTR4]]
1188 ; NOT_CGSCC_OPM-NEXT:    call void @optnone(i32* noundef nonnull align 16 dereferenceable(8) [[A]])
1189 ; NOT_CGSCC_OPM-NEXT:    ret void
1191 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@make_live
1192 ; IS__CGSCC_OPM-SAME: (i32* noundef nonnull align 16 dereferenceable(8) [[A:%.*]]) {
1193 ; IS__CGSCC_OPM-NEXT:    call void @naked(i32* noundef nonnull align 16 dereferenceable(8) [[A]])
1194 ; IS__CGSCC_OPM-NEXT:    call void @control(i32* noalias nocapture noundef nonnull readnone align 16 dereferenceable(8) [[A]]) #[[ATTR5]]
1195 ; IS__CGSCC_OPM-NEXT:    call void @optnone(i32* noundef nonnull align 16 dereferenceable(8) [[A]])
1196 ; IS__CGSCC_OPM-NEXT:    ret void
1198   call void @naked(i32* nonnull dereferenceable(8) align 16 %a)
1199   call void @control(i32* nonnull dereferenceable(8) align 16 %a)
1200   call void @optnone(i32* nonnull dereferenceable(8) align 16 %a)
1201   ret void
1205 ;int f(int *u, int n){
1206 ;  for(int i = 0;i<n;i++){
1207 ;    h(u);
1208 ;  }
1209 ;  return g(nonnull u);
1211 declare void @h(i32*) willreturn nounwind
1212 declare i32 @g(i32*) willreturn nounwind
1213 define i32 @nonnull_exec_ctx_1(i32* %a, i32 %b) {
1215 ; IS__TUNIT_OPM: Function Attrs: nounwind
1216 ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1
1217 ; IS__TUNIT_OPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]]) #[[ATTR4]] {
1218 ; IS__TUNIT_OPM-NEXT:  en:
1219 ; IS__TUNIT_OPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[B]], 0
1220 ; IS__TUNIT_OPM-NEXT:    br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
1221 ; IS__TUNIT_OPM:       ex:
1222 ; IS__TUNIT_OPM-NEXT:    [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR4]]
1223 ; IS__TUNIT_OPM-NEXT:    ret i32 [[TMP5]]
1224 ; IS__TUNIT_OPM:       hd:
1225 ; IS__TUNIT_OPM-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ]
1226 ; IS__TUNIT_OPM-NEXT:    tail call void @h(i32* [[A]]) #[[ATTR4]]
1227 ; IS__TUNIT_OPM-NEXT:    [[TMP8]] = add nuw i32 [[TMP7]], 1
1228 ; IS__TUNIT_OPM-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
1229 ; IS__TUNIT_OPM-NEXT:    br i1 [[TMP9]], label [[EX]], label [[HD]]
1231 ; IS________NPM: Function Attrs: nounwind willreturn
1232 ; IS________NPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1
1233 ; IS________NPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]]) #[[ATTR6]] {
1234 ; IS________NPM-NEXT:  en:
1235 ; IS________NPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[B]], 0
1236 ; IS________NPM-NEXT:    br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
1237 ; IS________NPM:       ex:
1238 ; IS________NPM-NEXT:    [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR6]]
1239 ; IS________NPM-NEXT:    ret i32 [[TMP5]]
1240 ; IS________NPM:       hd:
1241 ; IS________NPM-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ]
1242 ; IS________NPM-NEXT:    tail call void @h(i32* [[A]]) #[[ATTR6]]
1243 ; IS________NPM-NEXT:    [[TMP8]] = add nuw i32 [[TMP7]], 1
1244 ; IS________NPM-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
1245 ; IS________NPM-NEXT:    br i1 [[TMP9]], label [[EX]], label [[HD]]
1247 ; IS__CGSCC_OPM: Function Attrs: nounwind
1248 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1
1249 ; IS__CGSCC_OPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]]) #[[ATTR5]] {
1250 ; IS__CGSCC_OPM-NEXT:  en:
1251 ; IS__CGSCC_OPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[B]], 0
1252 ; IS__CGSCC_OPM-NEXT:    br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
1253 ; IS__CGSCC_OPM:       ex:
1254 ; IS__CGSCC_OPM-NEXT:    [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR5]]
1255 ; IS__CGSCC_OPM-NEXT:    ret i32 [[TMP5]]
1256 ; IS__CGSCC_OPM:       hd:
1257 ; IS__CGSCC_OPM-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ]
1258 ; IS__CGSCC_OPM-NEXT:    tail call void @h(i32* [[A]]) #[[ATTR5]]
1259 ; IS__CGSCC_OPM-NEXT:    [[TMP8]] = add nuw i32 [[TMP7]], 1
1260 ; IS__CGSCC_OPM-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
1261 ; IS__CGSCC_OPM-NEXT:    br i1 [[TMP9]], label [[EX]], label [[HD]]
1264   %tmp3 = icmp eq i32 %b, 0
1265   br i1 %tmp3, label %ex, label %hd
1268   %tmp5 = tail call i32 @g(i32* nonnull %a)
1269   ret i32 %tmp5
1272   %tmp7 = phi i32 [ %tmp8, %hd ], [ 0, %en ]
1273   tail call void @h(i32* %a)
1274   %tmp8 = add nuw i32 %tmp7, 1
1275   %tmp9 = icmp eq i32 %tmp8, %b
1276   br i1 %tmp9, label %ex, label %hd
1279 define i32 @nonnull_exec_ctx_1b(i32* %a, i32 %b) {
1281 ; IS__TUNIT_OPM: Function Attrs: nounwind
1282 ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1b
1283 ; IS__TUNIT_OPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]]) #[[ATTR4]] {
1284 ; IS__TUNIT_OPM-NEXT:  en:
1285 ; IS__TUNIT_OPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[B]], 0
1286 ; IS__TUNIT_OPM-NEXT:    br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
1287 ; IS__TUNIT_OPM:       ex:
1288 ; IS__TUNIT_OPM-NEXT:    [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR4]]
1289 ; IS__TUNIT_OPM-NEXT:    ret i32 [[TMP5]]
1290 ; IS__TUNIT_OPM:       hd:
1291 ; IS__TUNIT_OPM-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ]
1292 ; IS__TUNIT_OPM-NEXT:    tail call void @h(i32* [[A]]) #[[ATTR4]]
1293 ; IS__TUNIT_OPM-NEXT:    br label [[HD2]]
1294 ; IS__TUNIT_OPM:       hd2:
1295 ; IS__TUNIT_OPM-NEXT:    [[TMP8]] = add nuw i32 [[TMP7]], 1
1296 ; IS__TUNIT_OPM-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
1297 ; IS__TUNIT_OPM-NEXT:    br i1 [[TMP9]], label [[EX]], label [[HD]]
1299 ; IS________NPM: Function Attrs: nounwind willreturn
1300 ; IS________NPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1b
1301 ; IS________NPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]]) #[[ATTR6]] {
1302 ; IS________NPM-NEXT:  en:
1303 ; IS________NPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[B]], 0
1304 ; IS________NPM-NEXT:    br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
1305 ; IS________NPM:       ex:
1306 ; IS________NPM-NEXT:    [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR6]]
1307 ; IS________NPM-NEXT:    ret i32 [[TMP5]]
1308 ; IS________NPM:       hd:
1309 ; IS________NPM-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ]
1310 ; IS________NPM-NEXT:    tail call void @h(i32* [[A]]) #[[ATTR6]]
1311 ; IS________NPM-NEXT:    br label [[HD2]]
1312 ; IS________NPM:       hd2:
1313 ; IS________NPM-NEXT:    [[TMP8]] = add nuw i32 [[TMP7]], 1
1314 ; IS________NPM-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
1315 ; IS________NPM-NEXT:    br i1 [[TMP9]], label [[EX]], label [[HD]]
1317 ; IS__CGSCC_OPM: Function Attrs: nounwind
1318 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1b
1319 ; IS__CGSCC_OPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]]) #[[ATTR5]] {
1320 ; IS__CGSCC_OPM-NEXT:  en:
1321 ; IS__CGSCC_OPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[B]], 0
1322 ; IS__CGSCC_OPM-NEXT:    br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
1323 ; IS__CGSCC_OPM:       ex:
1324 ; IS__CGSCC_OPM-NEXT:    [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR5]]
1325 ; IS__CGSCC_OPM-NEXT:    ret i32 [[TMP5]]
1326 ; IS__CGSCC_OPM:       hd:
1327 ; IS__CGSCC_OPM-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ]
1328 ; IS__CGSCC_OPM-NEXT:    tail call void @h(i32* [[A]]) #[[ATTR5]]
1329 ; IS__CGSCC_OPM-NEXT:    br label [[HD2]]
1330 ; IS__CGSCC_OPM:       hd2:
1331 ; IS__CGSCC_OPM-NEXT:    [[TMP8]] = add nuw i32 [[TMP7]], 1
1332 ; IS__CGSCC_OPM-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
1333 ; IS__CGSCC_OPM-NEXT:    br i1 [[TMP9]], label [[EX]], label [[HD]]
1336   %tmp3 = icmp eq i32 %b, 0
1337   br i1 %tmp3, label %ex, label %hd
1340   %tmp5 = tail call i32 @g(i32* nonnull %a)
1341   ret i32 %tmp5
1344   %tmp7 = phi i32 [ %tmp8, %hd2 ], [ 0, %en ]
1345   tail call void @h(i32* %a)
1346   br label %hd2
1348 hd2:
1349   %tmp8 = add nuw i32 %tmp7, 1
1350   %tmp9 = icmp eq i32 %tmp8, %b
1351   br i1 %tmp9, label %ex, label %hd
1354 define i32 @nonnull_exec_ctx_2(i32* %a, i32 %b) willreturn nounwind {
1356 ; NOT_CGSCC_OPM: Function Attrs: nounwind willreturn
1357 ; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_2
1358 ; NOT_CGSCC_OPM-SAME: (i32* nonnull [[A:%.*]], i32 [[B:%.*]]) #[[ATTR6]] {
1359 ; NOT_CGSCC_OPM-NEXT:  en:
1360 ; NOT_CGSCC_OPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[B]], 0
1361 ; NOT_CGSCC_OPM-NEXT:    br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
1362 ; NOT_CGSCC_OPM:       ex:
1363 ; NOT_CGSCC_OPM-NEXT:    [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR4]]
1364 ; NOT_CGSCC_OPM-NEXT:    ret i32 [[TMP5]]
1365 ; NOT_CGSCC_OPM:       hd:
1366 ; NOT_CGSCC_OPM-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ]
1367 ; NOT_CGSCC_OPM-NEXT:    tail call void @h(i32* nonnull [[A]]) #[[ATTR4]]
1368 ; NOT_CGSCC_OPM-NEXT:    [[TMP8]] = add nuw i32 [[TMP7]], 1
1369 ; NOT_CGSCC_OPM-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
1370 ; NOT_CGSCC_OPM-NEXT:    br i1 [[TMP9]], label [[EX]], label [[HD]]
1372 ; IS__CGSCC_OPM: Function Attrs: nounwind willreturn
1373 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_2
1374 ; IS__CGSCC_OPM-SAME: (i32* nonnull [[A:%.*]], i32 [[B:%.*]]) #[[ATTR7]] {
1375 ; IS__CGSCC_OPM-NEXT:  en:
1376 ; IS__CGSCC_OPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[B]], 0
1377 ; IS__CGSCC_OPM-NEXT:    br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
1378 ; IS__CGSCC_OPM:       ex:
1379 ; IS__CGSCC_OPM-NEXT:    [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR5]]
1380 ; IS__CGSCC_OPM-NEXT:    ret i32 [[TMP5]]
1381 ; IS__CGSCC_OPM:       hd:
1382 ; IS__CGSCC_OPM-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ]
1383 ; IS__CGSCC_OPM-NEXT:    tail call void @h(i32* nonnull [[A]]) #[[ATTR5]]
1384 ; IS__CGSCC_OPM-NEXT:    [[TMP8]] = add nuw i32 [[TMP7]], 1
1385 ; IS__CGSCC_OPM-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
1386 ; IS__CGSCC_OPM-NEXT:    br i1 [[TMP9]], label [[EX]], label [[HD]]
1389   %tmp3 = icmp eq i32 %b, 0
1390   br i1 %tmp3, label %ex, label %hd
1393   %tmp5 = tail call i32 @g(i32* nonnull %a)
1394   ret i32 %tmp5
1397   %tmp7 = phi i32 [ %tmp8, %hd ], [ 0, %en ]
1398   tail call void @h(i32* %a)
1399   %tmp8 = add nuw i32 %tmp7, 1
1400   %tmp9 = icmp eq i32 %tmp8, %b
1401   br i1 %tmp9, label %ex, label %hd
1404 define i32 @nonnull_exec_ctx_2b(i32* %a, i32 %b) willreturn nounwind {
1406 ; NOT_CGSCC_OPM: Function Attrs: nounwind willreturn
1407 ; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_2b
1408 ; NOT_CGSCC_OPM-SAME: (i32* nonnull [[A:%.*]], i32 [[B:%.*]]) #[[ATTR6]] {
1409 ; NOT_CGSCC_OPM-NEXT:  en:
1410 ; NOT_CGSCC_OPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[B]], 0
1411 ; NOT_CGSCC_OPM-NEXT:    br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
1412 ; NOT_CGSCC_OPM:       ex:
1413 ; NOT_CGSCC_OPM-NEXT:    [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR4]]
1414 ; NOT_CGSCC_OPM-NEXT:    ret i32 [[TMP5]]
1415 ; NOT_CGSCC_OPM:       hd:
1416 ; NOT_CGSCC_OPM-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ]
1417 ; NOT_CGSCC_OPM-NEXT:    tail call void @h(i32* nonnull [[A]]) #[[ATTR4]]
1418 ; NOT_CGSCC_OPM-NEXT:    br label [[HD2]]
1419 ; NOT_CGSCC_OPM:       hd2:
1420 ; NOT_CGSCC_OPM-NEXT:    [[TMP8]] = add nuw i32 [[TMP7]], 1
1421 ; NOT_CGSCC_OPM-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
1422 ; NOT_CGSCC_OPM-NEXT:    br i1 [[TMP9]], label [[EX]], label [[HD]]
1424 ; IS__CGSCC_OPM: Function Attrs: nounwind willreturn
1425 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_2b
1426 ; IS__CGSCC_OPM-SAME: (i32* nonnull [[A:%.*]], i32 [[B:%.*]]) #[[ATTR7]] {
1427 ; IS__CGSCC_OPM-NEXT:  en:
1428 ; IS__CGSCC_OPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[B]], 0
1429 ; IS__CGSCC_OPM-NEXT:    br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
1430 ; IS__CGSCC_OPM:       ex:
1431 ; IS__CGSCC_OPM-NEXT:    [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR5]]
1432 ; IS__CGSCC_OPM-NEXT:    ret i32 [[TMP5]]
1433 ; IS__CGSCC_OPM:       hd:
1434 ; IS__CGSCC_OPM-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ]
1435 ; IS__CGSCC_OPM-NEXT:    tail call void @h(i32* nonnull [[A]]) #[[ATTR5]]
1436 ; IS__CGSCC_OPM-NEXT:    br label [[HD2]]
1437 ; IS__CGSCC_OPM:       hd2:
1438 ; IS__CGSCC_OPM-NEXT:    [[TMP8]] = add nuw i32 [[TMP7]], 1
1439 ; IS__CGSCC_OPM-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
1440 ; IS__CGSCC_OPM-NEXT:    br i1 [[TMP9]], label [[EX]], label [[HD]]
1443   %tmp3 = icmp eq i32 %b, 0
1444   br i1 %tmp3, label %ex, label %hd
1447   %tmp5 = tail call i32 @g(i32* nonnull %a)
1448   ret i32 %tmp5
1451   %tmp7 = phi i32 [ %tmp8, %hd2 ], [ 0, %en ]
1452   tail call void @h(i32* %a)
1453   br label %hd2
1455 hd2:
1456   %tmp8 = add nuw i32 %tmp7, 1
1457   %tmp9 = icmp eq i32 %tmp8, %b
1458   br i1 %tmp9, label %ex, label %hd
1461 ; Original from PR43833
1462 declare void @sink(i32*)
1464 define void @PR43833(i32* %0, i32 %1) {
1465 ; IS________OPM-LABEL: define {{[^@]+}}@PR43833
1466 ; IS________OPM-SAME: (i32* [[TMP0:%.*]], i32 [[TMP1:%.*]]) {
1467 ; IS________OPM-NEXT:    [[TMP3:%.*]] = icmp sgt i32 [[TMP1]], 1
1468 ; IS________OPM-NEXT:    br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP7:%.*]]
1469 ; IS________OPM:       4:
1470 ; IS________OPM-NEXT:    [[TMP5:%.*]] = zext i32 [[TMP1]] to i64
1471 ; IS________OPM-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP5]]
1472 ; IS________OPM-NEXT:    br label [[TMP8:%.*]]
1473 ; IS________OPM:       7:
1474 ; IS________OPM-NEXT:    ret void
1475 ; IS________OPM:       8:
1476 ; IS________OPM-NEXT:    [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [ [[TMP10:%.*]], [[TMP8]] ]
1477 ; IS________OPM-NEXT:    tail call void @sink(i32* [[TMP6]])
1478 ; IS________OPM-NEXT:    [[TMP10]] = add nuw nsw i32 [[TMP9]], 1
1479 ; IS________OPM-NEXT:    [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]]
1480 ; IS________OPM-NEXT:    br i1 [[TMP11]], label [[TMP7]], label [[TMP8]]
1482 ; IS________NPM-LABEL: define {{[^@]+}}@PR43833
1483 ; IS________NPM-SAME: (i32* [[TMP0:%.*]], i32 [[TMP1:%.*]]) {
1484 ; IS________NPM-NEXT:    [[TMP3:%.*]] = icmp sgt i32 [[TMP1]], 1
1485 ; IS________NPM-NEXT:    br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP7:%.*]]
1486 ; IS________NPM:       4:
1487 ; IS________NPM-NEXT:    [[TMP5:%.*]] = zext i32 [[TMP1]] to i64
1488 ; IS________NPM-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP5]]
1489 ; IS________NPM-NEXT:    br label [[TMP8:%.*]]
1490 ; IS________NPM:       7:
1491 ; IS________NPM-NEXT:    ret void
1492 ; IS________NPM:       8:
1493 ; IS________NPM-NEXT:    [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [ [[TMP10:%.*]], [[TMP8]] ]
1494 ; IS________NPM-NEXT:    tail call void @sink(i32* nonnull [[TMP6]])
1495 ; IS________NPM-NEXT:    [[TMP10]] = add nuw nsw i32 [[TMP9]], 1
1496 ; IS________NPM-NEXT:    [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]]
1497 ; IS________NPM-NEXT:    br i1 [[TMP11]], label [[TMP7]], label [[TMP8]]
1499   %3 = icmp sgt i32 %1, 1
1500   br i1 %3, label %4, label %7
1502 4:                                                ; preds = %2
1503   %5 = zext i32 %1 to i64
1504   %6 = getelementptr inbounds i32, i32* %0, i64 %5
1505   br label %8
1507 7:                                                ; preds = %8, %2
1508   ret void
1510 8:                                                ; preds = %8, %4
1511   %9 = phi i32 [ 1, %4 ], [ %10, %8 ]
1512   tail call void @sink(i32* %6)
1513   %10 = add nuw nsw i32 %9, 1
1514   %11 = icmp eq i32 %10, %1
1515   br i1 %11, label %7, label %8
1518 ; Adjusted from PR43833
1519 define void @PR43833_simple(i32* %0, i32 %1) {
1520 ; IS________OPM-LABEL: define {{[^@]+}}@PR43833_simple
1521 ; IS________OPM-SAME: (i32* [[TMP0:%.*]], i32 [[TMP1:%.*]]) {
1522 ; IS________OPM-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP1]], 0
1523 ; IS________OPM-NEXT:    br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP7:%.*]]
1524 ; IS________OPM:       4:
1525 ; IS________OPM-NEXT:    [[TMP5:%.*]] = zext i32 [[TMP1]] to i64
1526 ; IS________OPM-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP5]]
1527 ; IS________OPM-NEXT:    br label [[TMP8:%.*]]
1528 ; IS________OPM:       7:
1529 ; IS________OPM-NEXT:    ret void
1530 ; IS________OPM:       8:
1531 ; IS________OPM-NEXT:    [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [ [[TMP10:%.*]], [[TMP8]] ]
1532 ; IS________OPM-NEXT:    tail call void @sink(i32* [[TMP6]])
1533 ; IS________OPM-NEXT:    [[TMP10]] = add nuw nsw i32 [[TMP9]], 1
1534 ; IS________OPM-NEXT:    [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]]
1535 ; IS________OPM-NEXT:    br i1 [[TMP11]], label [[TMP7]], label [[TMP8]]
1537 ; IS________NPM-LABEL: define {{[^@]+}}@PR43833_simple
1538 ; IS________NPM-SAME: (i32* [[TMP0:%.*]], i32 [[TMP1:%.*]]) {
1539 ; IS________NPM-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP1]], 0
1540 ; IS________NPM-NEXT:    br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP7:%.*]]
1541 ; IS________NPM:       4:
1542 ; IS________NPM-NEXT:    [[TMP5:%.*]] = zext i32 [[TMP1]] to i64
1543 ; IS________NPM-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP5]]
1544 ; IS________NPM-NEXT:    br label [[TMP8:%.*]]
1545 ; IS________NPM:       7:
1546 ; IS________NPM-NEXT:    ret void
1547 ; IS________NPM:       8:
1548 ; IS________NPM-NEXT:    [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [ [[TMP10:%.*]], [[TMP8]] ]
1549 ; IS________NPM-NEXT:    tail call void @sink(i32* nonnull [[TMP6]])
1550 ; IS________NPM-NEXT:    [[TMP10]] = add nuw nsw i32 [[TMP9]], 1
1551 ; IS________NPM-NEXT:    [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]]
1552 ; IS________NPM-NEXT:    br i1 [[TMP11]], label [[TMP7]], label [[TMP8]]
1554   %3 = icmp ne i32 %1, 0
1555   br i1 %3, label %4, label %7
1557 4:                                                ; preds = %2
1558   %5 = zext i32 %1 to i64
1559   %6 = getelementptr inbounds i32, i32* %0, i64 %5
1560   br label %8
1562 7:                                                ; preds = %8, %2
1563   ret void
1565 8:                                                ; preds = %8, %4
1566   %9 = phi i32 [ 1, %4 ], [ %10, %8 ]
1567   tail call void @sink(i32* %6)
1568   %10 = add nuw nsw i32 %9, 1
1569   %11 = icmp eq i32 %10, %1
1570   br i1 %11, label %7, label %8
1573 declare i8* @strrchr(i8* %0, i32 %1) nofree nounwind readonly willreturn
1575 ; We should not mark the return of @strrchr as `nonnull`, it may well be NULL!
1576 define i8* @mybasename(i8* nofree readonly %str) {
1577 ; NOT_CGSCC_OPM: Function Attrs: nofree nounwind readonly willreturn
1578 ; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@mybasename
1579 ; NOT_CGSCC_OPM-SAME: (i8* nofree readonly [[STR:%.*]]) #[[ATTR11:[0-9]+]] {
1580 ; NOT_CGSCC_OPM-NEXT:    [[CALL:%.*]] = call i8* @strrchr(i8* nofree readonly [[STR]], i32 noundef 47) #[[ATTR14]]
1581 ; NOT_CGSCC_OPM-NEXT:    [[TOBOOL:%.*]] = icmp ne i8* [[CALL]], null
1582 ; NOT_CGSCC_OPM-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[CALL]], i64 1
1583 ; NOT_CGSCC_OPM-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i8* [[ADD_PTR]], i8* [[STR]]
1584 ; NOT_CGSCC_OPM-NEXT:    ret i8* [[COND]]
1586 ; IS__CGSCC_OPM: Function Attrs: nofree nounwind readonly willreturn
1587 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@mybasename
1588 ; IS__CGSCC_OPM-SAME: (i8* nofree readonly [[STR:%.*]]) #[[ATTR12:[0-9]+]] {
1589 ; IS__CGSCC_OPM-NEXT:    [[CALL:%.*]] = call i8* @strrchr(i8* nofree readonly [[STR]], i32 noundef 47) #[[ATTR15]]
1590 ; IS__CGSCC_OPM-NEXT:    [[TOBOOL:%.*]] = icmp ne i8* [[CALL]], null
1591 ; IS__CGSCC_OPM-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[CALL]], i64 1
1592 ; IS__CGSCC_OPM-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i8* [[ADD_PTR]], i8* [[STR]]
1593 ; IS__CGSCC_OPM-NEXT:    ret i8* [[COND]]
1595   %call = call i8* @strrchr(i8* %str, i32 47)
1596   %tobool = icmp ne i8* %call, null
1597   %add.ptr = getelementptr inbounds i8, i8* %call, i64 1
1598   %cond = select i1 %tobool, i8* %add.ptr, i8* %str
1599   ret i8* %cond
1602 define void @nonnull_assume_pos(i8* %arg) {
1603 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@nonnull_assume_pos
1604 ; ATTRIBUTOR-SAME: (i8* nocapture nofree nonnull readnone [[ARG:%.*]])
1605 ; ATTRIBUTOR-NEXT:    call void @llvm.assume(i1 true) #11 [ "nonnull"(i8* [[ARG]]) ]
1606 ; ATTRIBUTOR-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[ARG]])
1607 ; ATTRIBUTOR-NEXT:    [[TMP1:%.*]] = call i8* @unknown()
1608 ; ATTRIBUTOR-NEXT:    ret void
1610 ; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_assume_pos
1611 ; NOT_CGSCC_OPM-SAME: (i8* nocapture nofree nonnull readnone [[ARG:%.*]]) {
1612 ; NOT_CGSCC_OPM-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR12]] [ "nonnull"(i8* [[ARG]]) ]
1613 ; NOT_CGSCC_OPM-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR4]]
1614 ; NOT_CGSCC_OPM-NEXT:    [[TMP1:%.*]] = call i8* @unknown()
1615 ; NOT_CGSCC_OPM-NEXT:    ret void
1617 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_assume_pos
1618 ; IS__CGSCC_OPM-SAME: (i8* nocapture nofree nonnull readnone [[ARG:%.*]]) {
1619 ; IS__CGSCC_OPM-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR13]] [ "nonnull"(i8* [[ARG]]) ]
1620 ; IS__CGSCC_OPM-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR5]]
1621 ; IS__CGSCC_OPM-NEXT:    [[TMP1:%.*]] = call i8* @unknown()
1622 ; IS__CGSCC_OPM-NEXT:    ret void
1624   call void @llvm.assume(i1 true) ["nonnull"(i8* %arg)]
1625   call void @use_i8_ptr(i8* %arg)
1626   call i8* @unknown()
1627   ret void
1629 define void @nonnull_assume_neg(i8* %arg) {
1630 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@nonnull_assume_neg
1631 ; ATTRIBUTOR-SAME: (i8* nocapture nofree readnone [[ARG:%.*]])
1632 ; ATTRIBUTOR-NEXT:    [[TMP1:%.*]] = call i8* @unknown()
1633 ; ATTRIBUTOR-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[ARG]])
1634 ; ATTRIBUTOR-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(i8* [[ARG]]) ]
1635 ; ATTRIBUTOR-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[ARG]])
1636 ; ATTRIBUTOR-NEXT:    [[TMP2:%.*]] = call i8* @unknown()
1637 ; ATTRIBUTOR-NEXT:    call void @use_i8_ptr_ret(i8* noalias nocapture nofree nonnull readnone [[ARG]])
1638 ; ATTRIBUTOR-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(i8* [[ARG]]) ]
1639 ; ATTRIBUTOR-NEXT:    call void @use_i8_ptr_ret(i8* noalias nocapture nofree nonnull readnone [[ARG]])
1640 ; ATTRIBUTOR-NEXT:    ret void
1643 ; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_assume_neg
1644 ; NOT_CGSCC_OPM-SAME: (i8* nocapture nofree readnone [[ARG:%.*]]) {
1645 ; NOT_CGSCC_OPM-NEXT:    [[TMP1:%.*]] = call i8* @unknown()
1646 ; NOT_CGSCC_OPM-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[ARG]]) #[[ATTR4]]
1647 ; NOT_CGSCC_OPM-NEXT:    call void @llvm.assume(i1 noundef true) [ "nonnull"(i8* [[ARG]]) ]
1648 ; NOT_CGSCC_OPM-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR4]]
1649 ; NOT_CGSCC_OPM-NEXT:    [[TMP2:%.*]] = call i8* @unknown()
1650 ; NOT_CGSCC_OPM-NEXT:    call void @use_i8_ptr_ret(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR4]]
1651 ; NOT_CGSCC_OPM-NEXT:    call void @llvm.assume(i1 noundef true) [ "nonnull"(i8* [[ARG]]) ]
1652 ; NOT_CGSCC_OPM-NEXT:    call void @use_i8_ptr_ret(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR4]]
1653 ; NOT_CGSCC_OPM-NEXT:    ret void
1655 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_assume_neg
1656 ; IS__CGSCC_OPM-SAME: (i8* nocapture nofree readnone [[ARG:%.*]]) {
1657 ; IS__CGSCC_OPM-NEXT:    [[TMP1:%.*]] = call i8* @unknown()
1658 ; IS__CGSCC_OPM-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[ARG]]) #[[ATTR5]]
1659 ; IS__CGSCC_OPM-NEXT:    call void @llvm.assume(i1 noundef true) [ "nonnull"(i8* [[ARG]]) ]
1660 ; IS__CGSCC_OPM-NEXT:    call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR5]]
1661 ; IS__CGSCC_OPM-NEXT:    [[TMP2:%.*]] = call i8* @unknown()
1662 ; IS__CGSCC_OPM-NEXT:    call void @use_i8_ptr_ret(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR5]]
1663 ; IS__CGSCC_OPM-NEXT:    call void @llvm.assume(i1 noundef true) [ "nonnull"(i8* [[ARG]]) ]
1664 ; IS__CGSCC_OPM-NEXT:    call void @use_i8_ptr_ret(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR5]]
1665 ; IS__CGSCC_OPM-NEXT:    ret void
1667   call i8* @unknown()
1668   call void @use_i8_ptr(i8* %arg)
1669   call void @llvm.assume(i1 true) ["nonnull"(i8* %arg)]
1670   call void @use_i8_ptr(i8* %arg)
1671   call i8* @unknown()
1672   call void @use_i8_ptr_ret(i8* %arg)
1673   call void @llvm.assume(i1 true) ["nonnull"(i8* %arg)]
1674   call void @use_i8_ptr_ret(i8* %arg)
1675   ret void
1677 declare void @use_i8_ptr(i8* nofree nocapture readnone) nounwind
1678 declare void @use_i8_ptr_ret(i8* nofree nocapture readnone) nounwind willreturn
1680 define i8* @nonnull_function_ptr_1() {
1681 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
1682 ; IS__TUNIT____-LABEL: define {{[^@]+}}@nonnull_function_ptr_1
1683 ; IS__TUNIT____-SAME: () #[[ATTR1]] {
1684 ; IS__TUNIT____-NEXT:    ret i8* bitcast (i8* ()* @nonnull_function_ptr_1 to i8*)
1686 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
1687 ; IS__CGSCC____-LABEL: define {{[^@]+}}@nonnull_function_ptr_1
1688 ; IS__CGSCC____-SAME: () #[[ATTR1]] {
1689 ; IS__CGSCC____-NEXT:    ret i8* bitcast (i8* ()* @nonnull_function_ptr_1 to i8*)
1691   %bc = bitcast i8*()* @nonnull_function_ptr_1 to i8*
1692   ret i8* %bc
1695 declare i8* @function_decl()
1696 define i8* @nonnull_function_ptr_2() {
1697 ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
1698 ; IS__TUNIT____-LABEL: define {{[^@]+}}@nonnull_function_ptr_2
1699 ; IS__TUNIT____-SAME: () #[[ATTR1]] {
1700 ; IS__TUNIT____-NEXT:    ret i8* bitcast (i8* ()* @function_decl to i8*)
1702 ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
1703 ; IS__CGSCC____-LABEL: define {{[^@]+}}@nonnull_function_ptr_2
1704 ; IS__CGSCC____-SAME: () #[[ATTR1]] {
1705 ; IS__CGSCC____-NEXT:    ret i8* bitcast (i8* ()* @function_decl to i8*)
1707   %bc = bitcast i8*()* @function_decl to i8*
1708   ret i8* %bc
1711 ; FIXME: nonnull should not be propagated to the caller's p unless there is noundef
1712 define void @nonnull_caller(i8* %p) {
1713 ; CHECK-LABEL: define {{[^@]+}}@nonnull_caller
1714 ; CHECK-SAME: (i8* nonnull [[P:%.*]]) {
1715 ; CHECK-NEXT:    call void @nonnull_callee(i8* nonnull [[P]])
1716 ; CHECK-NEXT:    ret void
1718   call void @nonnull_callee(i8* %p)
1719   ret void
1722 declare void @nonnull_callee(i8* nonnull %p)
1724 attributes #0 = { null_pointer_is_valid }
1725 attributes #1 = { nounwind willreturn}
1727 ; IS__TUNIT____: attributes #[[ATTR0]] = { inaccessiblememonly nofree nosync nounwind willreturn }
1728 ; IS__TUNIT____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn }
1729 ; IS__TUNIT____: attributes #[[ATTR2]] = { nofree noreturn nosync nounwind readnone willreturn }
1730 ; IS__TUNIT____: attributes #[[ATTR3]] = { noreturn }
1731 ; IS__TUNIT____: attributes #[[ATTR4]] = { nounwind }
1732 ; IS__TUNIT____: attributes #[[ATTR5]] = { argmemonly nofree nosync nounwind readonly }
1733 ; IS__TUNIT____: attributes #[[ATTR6]] = { nounwind willreturn }
1734 ; IS__TUNIT____: attributes #[[ATTR7:[0-9]+]] = { nounwind readonly willreturn }
1735 ; IS__TUNIT____: attributes #[[ATTR8]] = { nofree nosync nounwind null_pointer_is_valid readnone willreturn }
1736 ; IS__TUNIT____: attributes #[[ATTR9]] = { naked }
1737 ; IS__TUNIT____: attributes #[[ATTR10]] = { noinline optnone }
1738 ; IS__TUNIT____: attributes #[[ATTR11]] = { nofree nounwind readonly willreturn }
1739 ; IS__TUNIT____: attributes #[[ATTR12]] = { willreturn }
1740 ; IS__TUNIT____: attributes #[[ATTR13]] = { nofree nosync nounwind readonly }
1741 ; IS__TUNIT____: attributes #[[ATTR14]] = { readonly willreturn }
1743 ; IS__CGSCC_OPM: attributes #[[ATTR0]] = { inaccessiblememonly nofree nosync nounwind willreturn }
1744 ; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn }
1745 ; IS__CGSCC_OPM: attributes #[[ATTR2]] = { nofree noreturn nosync nounwind readnone willreturn }
1746 ; IS__CGSCC_OPM: attributes #[[ATTR3]] = { nofree nosync nounwind readnone willreturn }
1747 ; IS__CGSCC_OPM: attributes #[[ATTR4]] = { noreturn }
1748 ; IS__CGSCC_OPM: attributes #[[ATTR5]] = { nounwind }
1749 ; IS__CGSCC_OPM: attributes #[[ATTR6]] = { argmemonly nofree nosync nounwind readonly }
1750 ; IS__CGSCC_OPM: attributes #[[ATTR7]] = { nounwind willreturn }
1751 ; IS__CGSCC_OPM: attributes #[[ATTR8:[0-9]+]] = { nounwind readonly willreturn }
1752 ; IS__CGSCC_OPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn }
1753 ; IS__CGSCC_OPM: attributes #[[ATTR10]] = { naked }
1754 ; IS__CGSCC_OPM: attributes #[[ATTR11]] = { noinline optnone }
1755 ; IS__CGSCC_OPM: attributes #[[ATTR12]] = { nofree nounwind readonly willreturn }
1756 ; IS__CGSCC_OPM: attributes #[[ATTR13]] = { willreturn }
1757 ; IS__CGSCC_OPM: attributes #[[ATTR14]] = { nofree nosync nounwind readonly }
1758 ; IS__CGSCC_OPM: attributes #[[ATTR15]] = { readonly willreturn }
1760 ; IS__CGSCC_NPM: attributes #[[ATTR0]] = { inaccessiblememonly nofree nosync nounwind willreturn }
1761 ; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn }
1762 ; IS__CGSCC_NPM: attributes #[[ATTR2]] = { nofree norecurse noreturn nosync nounwind readnone willreturn }
1763 ; IS__CGSCC_NPM: attributes #[[ATTR3]] = { noreturn }
1764 ; IS__CGSCC_NPM: attributes #[[ATTR4]] = { nounwind }
1765 ; IS__CGSCC_NPM: attributes #[[ATTR5]] = { argmemonly nofree nosync nounwind readonly }
1766 ; IS__CGSCC_NPM: attributes #[[ATTR6]] = { nounwind willreturn }
1767 ; IS__CGSCC_NPM: attributes #[[ATTR7:[0-9]+]] = { nounwind readonly willreturn }
1768 ; IS__CGSCC_NPM: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn }
1769 ; IS__CGSCC_NPM: attributes #[[ATTR9]] = { naked }
1770 ; IS__CGSCC_NPM: attributes #[[ATTR10]] = { noinline optnone }
1771 ; IS__CGSCC_NPM: attributes #[[ATTR11]] = { nofree nounwind readonly willreturn }
1772 ; IS__CGSCC_NPM: attributes #[[ATTR12]] = { willreturn }
1773 ; IS__CGSCC_NPM: attributes #[[ATTR13]] = { nofree nosync nounwind readonly }
1774 ; IS__CGSCC_NPM: attributes #[[ATTR14]] = { readonly willreturn }