1 ; RUN: opt -S -functionattrs %s | FileCheck %s 2 declare nonnull i8* @ret_nonnull() 3 4 ; Return a pointer trivially nonnull (call return attribute) 5 define i8* @test1() { 6 ; CHECK: define nonnull i8* @test1 7 %ret = call i8* @ret_nonnull() 8 ret i8* %ret 9 } 10 11 ; Return a pointer trivially nonnull (argument attribute) 12 define i8* @test2(i8* nonnull %p) { 13 ; CHECK: define nonnull i8* @test2 14 ret i8* %p 15 } 16 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 21 call i8* @test3() 22 ret i8* null 23 } 24 25 define i8* @test3() { 26 ; CHECK: define nonnull i8* @test3 27 call i8* @scc_binder() 28 %ret = call i8* @ret_nonnull() 29 ret i8* %ret 30 } 31 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() 38 ret i8* %ret 39 } 40 41 define i8* @test4() { 42 ; CHECK: define noalias nonnull i8* @test4 43 %ret = call i8* @test4_helper() 44 ret i8* %ret 45 } 46 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() 52 ret i8* null 53 } 54 55 define i8* @test5() { 56 ; CHECK: define noalias i8* @test5 57 %ret = call i8* @test5_helper() 58 ret i8* %ret 59 } 60 61 ; Local analysis, but going through a self recursive phi 62 define i8* @test6() { 63 entry: 64 ; CHECK: define nonnull i8* @test6 65 %ret = call i8* @ret_nonnull() 66 br label %loop 67 loop: 68 %phi = phi i8* [%ret, %entry], [%phi, %loop] 69 br i1 undef, label %loop, label %exit 70 exit: 71 ret i8* %phi 72 } 73 74 75