xref: /aosp_15_r20/external/llvm/test/Transforms/FunctionAttrs/nonnull.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt -S -functionattrs %s | FileCheck %s
2*9880d681SAndroid Build Coastguard Workerdeclare nonnull i8* @ret_nonnull()
3*9880d681SAndroid Build Coastguard Worker
4*9880d681SAndroid Build Coastguard Worker; Return a pointer trivially nonnull (call return attribute)
5*9880d681SAndroid Build Coastguard Workerdefine i8* @test1() {
6*9880d681SAndroid Build Coastguard Worker; CHECK: define nonnull i8* @test1
7*9880d681SAndroid Build Coastguard Worker  %ret = call i8* @ret_nonnull()
8*9880d681SAndroid Build Coastguard Worker  ret i8* %ret
9*9880d681SAndroid Build Coastguard Worker}
10*9880d681SAndroid Build Coastguard Worker
11*9880d681SAndroid Build Coastguard Worker; Return a pointer trivially nonnull (argument attribute)
12*9880d681SAndroid Build Coastguard Workerdefine i8* @test2(i8* nonnull %p) {
13*9880d681SAndroid Build Coastguard Worker; CHECK: define nonnull i8* @test2
14*9880d681SAndroid Build Coastguard Worker  ret i8* %p
15*9880d681SAndroid Build Coastguard Worker}
16*9880d681SAndroid Build Coastguard Worker
17*9880d681SAndroid Build Coastguard Worker; Given an SCC where one of the functions can not be marked nonnull,
18*9880d681SAndroid Build Coastguard Worker; can we still mark the other one which is trivially nonnull
19*9880d681SAndroid Build Coastguard Workerdefine i8* @scc_binder() {
20*9880d681SAndroid Build Coastguard Worker; CHECK: define i8* @scc_binder
21*9880d681SAndroid Build Coastguard Worker  call i8* @test3()
22*9880d681SAndroid Build Coastguard Worker  ret i8* null
23*9880d681SAndroid Build Coastguard Worker}
24*9880d681SAndroid Build Coastguard Worker
25*9880d681SAndroid Build Coastguard Workerdefine i8* @test3() {
26*9880d681SAndroid Build Coastguard Worker; CHECK: define nonnull i8* @test3
27*9880d681SAndroid Build Coastguard Worker  call i8* @scc_binder()
28*9880d681SAndroid Build Coastguard Worker  %ret = call i8* @ret_nonnull()
29*9880d681SAndroid Build Coastguard Worker  ret i8* %ret
30*9880d681SAndroid Build Coastguard Worker}
31*9880d681SAndroid Build Coastguard Worker
32*9880d681SAndroid Build Coastguard Worker; Given a mutual recursive set of functions, we can mark them
33*9880d681SAndroid Build Coastguard Worker; nonnull if neither can ever return null.  (In this case, they
34*9880d681SAndroid Build Coastguard Worker; just never return period.)
35*9880d681SAndroid Build Coastguard Workerdefine i8* @test4_helper() {
36*9880d681SAndroid Build Coastguard Worker; CHECK: define noalias nonnull i8* @test4_helper
37*9880d681SAndroid Build Coastguard Worker  %ret = call i8* @test4()
38*9880d681SAndroid Build Coastguard Worker  ret i8* %ret
39*9880d681SAndroid Build Coastguard Worker}
40*9880d681SAndroid Build Coastguard Worker
41*9880d681SAndroid Build Coastguard Workerdefine i8* @test4() {
42*9880d681SAndroid Build Coastguard Worker; CHECK: define noalias nonnull i8* @test4
43*9880d681SAndroid Build Coastguard Worker  %ret = call i8* @test4_helper()
44*9880d681SAndroid Build Coastguard Worker  ret i8* %ret
45*9880d681SAndroid Build Coastguard Worker}
46*9880d681SAndroid Build Coastguard Worker
47*9880d681SAndroid Build Coastguard Worker; Given a mutual recursive set of functions which *can* return null
48*9880d681SAndroid Build Coastguard Worker; make sure we haven't marked them as nonnull.
49*9880d681SAndroid Build Coastguard Workerdefine i8* @test5_helper() {
50*9880d681SAndroid Build Coastguard Worker; CHECK: define noalias i8* @test5_helper
51*9880d681SAndroid Build Coastguard Worker  %ret = call i8* @test5()
52*9880d681SAndroid Build Coastguard Worker  ret i8* null
53*9880d681SAndroid Build Coastguard Worker}
54*9880d681SAndroid Build Coastguard Worker
55*9880d681SAndroid Build Coastguard Workerdefine i8* @test5() {
56*9880d681SAndroid Build Coastguard Worker; CHECK: define noalias i8* @test5
57*9880d681SAndroid Build Coastguard Worker  %ret = call i8* @test5_helper()
58*9880d681SAndroid Build Coastguard Worker  ret i8* %ret
59*9880d681SAndroid Build Coastguard Worker}
60*9880d681SAndroid Build Coastguard Worker
61*9880d681SAndroid Build Coastguard Worker; Local analysis, but going through a self recursive phi
62*9880d681SAndroid Build Coastguard Workerdefine i8* @test6() {
63*9880d681SAndroid Build Coastguard Workerentry:
64*9880d681SAndroid Build Coastguard Worker; CHECK: define nonnull i8* @test6
65*9880d681SAndroid Build Coastguard Worker  %ret = call i8* @ret_nonnull()
66*9880d681SAndroid Build Coastguard Worker  br label %loop
67*9880d681SAndroid Build Coastguard Workerloop:
68*9880d681SAndroid Build Coastguard Worker  %phi = phi i8* [%ret, %entry], [%phi, %loop]
69*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %loop, label %exit
70*9880d681SAndroid Build Coastguard Workerexit:
71*9880d681SAndroid Build Coastguard Worker  ret i8* %phi
72*9880d681SAndroid Build Coastguard Worker}
73*9880d681SAndroid Build Coastguard Worker
74*9880d681SAndroid Build Coastguard Worker
75