1 ; RUN: opt -S -functionattrs %s | FileCheck %s
2 declare nonnull i8* @ret_nonnull()
4 ; Return a pointer trivially nonnull (call return attribute)
6 ; CHECK: define nonnull i8* @test1
7 %ret = call i8* @ret_nonnull()
11 ; Return a pointer trivially nonnull (argument attribute)
12 define i8* @test2(i8* nonnull %p) {
13 ; CHECK: define nonnull i8* @test2
17 ; Given an SCC where one of the functions can not be marked nonnull,
18 ; can we still mark the other one which is trivially nonnull
19 define i8* @scc_binder() {
20 ; CHECK: define i8* @scc_binder
26 ; CHECK: define nonnull i8* @test3
27 call i8* @scc_binder()
28 %ret = call i8* @ret_nonnull()
32 ; Given a mutual recursive set of functions, we can mark them
33 ; nonnull if neither can ever return null. (In this case, they
34 ; just never return period.)
35 define i8* @test4_helper() {
36 ; CHECK: define noalias nonnull i8* @test4_helper
37 %ret = call i8* @test4()
42 ; CHECK: define noalias nonnull i8* @test4
43 %ret = call i8* @test4_helper()
47 ; Given a mutual recursive set of functions which *can* return null
48 ; make sure we haven't marked them as nonnull.
49 define i8* @test5_helper() {
50 ; CHECK: define noalias i8* @test5_helper
51 %ret = call i8* @test5()
56 ; CHECK: define noalias i8* @test5
57 %ret = call i8* @test5_helper()
61 ; Local analysis, but going through a self recursive phi
64 ; CHECK: define nonnull i8* @test6
65 %ret = call i8* @ret_nonnull()
68 %phi = phi i8* [%ret, %entry], [%phi, %loop]
69 br i1 undef, label %loop, label %exit