blob: 1fb64b7434abac58eabf21f257648af4fac496de [file] [log] [blame]
Philip Reamesa88caea2015-08-31 19:44:38 +00001; RUN: opt -S -functionattrs %s | FileCheck %s
2declare nonnull i8* @ret_nonnull()
3
4; Return a pointer trivially nonnull (call return attribute)
5define 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)
12define 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
19define i8* @scc_binder() {
20; CHECK: define i8* @scc_binder
21 call i8* @test3()
22 ret i8* null
23}
24
25define 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.)
35define i8* @test4_helper() {
36; CHECK: define noalias nonnull i8* @test4_helper
37 %ret = call i8* @test4()
38 ret i8* %ret
39}
40
41define 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.
49define i8* @test5_helper() {
50; CHECK: define noalias i8* @test5_helper
51 %ret = call i8* @test5()
52 ret i8* null
53}
54
55define 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
62define i8* @test6() {
63entry:
64; CHECK: define nonnull i8* @test6
65 %ret = call i8* @ret_nonnull()
66 br label %loop
67loop:
68 %phi = phi i8* [%ret, %entry], [%phi, %loop]
69 br i1 undef, label %loop, label %exit
70exit:
71 ret i8* %phi
72}
73
74