1; RUN: opt -S -functionattrs -enable-nonnull-arg-prop %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; Test propagation of nonnull callsite args back to caller.
75
76declare void @use1(i8* %x)
77declare void @use2(i8* %x, i8* %y);
78declare void @use3(i8* %x, i8* %y, i8* %z);
79
80declare void @use1nonnull(i8* nonnull %x);
81declare void @use2nonnull(i8* nonnull %x, i8* nonnull %y);
82declare void @use3nonnull(i8* nonnull %x, i8* nonnull %y, i8* nonnull %z);
83
84declare i8 @use1safecall(i8* %x) readonly nounwind ; readonly+nounwind guarantees that execution continues to successor
85
86; Can't extend non-null to parent for any argument because the 2nd call is not guaranteed to execute.
87
88define void @parent1(i8* %a, i8* %b, i8* %c) {
89; CHECK-LABEL: @parent1(i8* %a, i8* %b, i8* %c)
90; CHECK-NEXT:    call void @use3(i8* %c, i8* %a, i8* %b)
91; CHECK-NEXT:    call void @use3nonnull(i8* %b, i8* %c, i8* %a)
92; CHECK-NEXT:    ret void
93;
94  call void @use3(i8* %c, i8* %a, i8* %b)
95  call void @use3nonnull(i8* %b, i8* %c, i8* %a)
96  ret void
97}
98
99; Extend non-null to parent for all arguments.
100
101define void @parent2(i8* %a, i8* %b, i8* %c) {
102; CHECK-LABEL: @parent2(i8* nonnull %a, i8* nonnull %b, i8* nonnull %c)
103; CHECK-NEXT:    call void @use3nonnull(i8* %b, i8* %c, i8* %a)
104; CHECK-NEXT:    call void @use3(i8* %c, i8* %a, i8* %b)
105; CHECK-NEXT:    ret void
106;
107  call void @use3nonnull(i8* %b, i8* %c, i8* %a)
108  call void @use3(i8* %c, i8* %a, i8* %b)
109  ret void
110}
111
112; Extend non-null to parent for 1st argument.
113
114define void @parent3(i8* %a, i8* %b, i8* %c) {
115; CHECK-LABEL: @parent3(i8* nonnull %a, i8* %b, i8* %c)
116; CHECK-NEXT:    call void @use1nonnull(i8* %a)
117; CHECK-NEXT:    call void @use3(i8* %c, i8* %b, i8* %a)
118; CHECK-NEXT:    ret void
119;
120  call void @use1nonnull(i8* %a)
121  call void @use3(i8* %c, i8* %b, i8* %a)
122  ret void
123}
124
125; Extend non-null to parent for last 2 arguments.
126
127define void @parent4(i8* %a, i8* %b, i8* %c) {
128; CHECK-LABEL: @parent4(i8* %a, i8* nonnull %b, i8* nonnull %c)
129; CHECK-NEXT:    call void @use2nonnull(i8* %c, i8* %b)
130; CHECK-NEXT:    call void @use2(i8* %a, i8* %c)
131; CHECK-NEXT:    call void @use1(i8* %b)
132; CHECK-NEXT:    ret void
133;
134  call void @use2nonnull(i8* %c, i8* %b)
135  call void @use2(i8* %a, i8* %c)
136  call void @use1(i8* %b)
137  ret void
138}
139
140; The callsite must execute in order for the attribute to transfer to the parent.
141; It appears benign to extend non-null to the parent in this case, but we can't do that
142; because it would incorrectly propagate the wrong information to its callers.
143
144define void @parent5(i8* %a, i1 %a_is_notnull) {
145; CHECK-LABEL: @parent5(i8* %a, i1 %a_is_notnull)
146; CHECK-NEXT:    br i1 %a_is_notnull, label %t, label %f
147; CHECK:       t:
148; CHECK-NEXT:    call void @use1nonnull(i8* %a)
149; CHECK-NEXT:    ret void
150; CHECK:       f:
151; CHECK-NEXT:    ret void
152;
153  br i1 %a_is_notnull, label %t, label %f
154t:
155  call void @use1nonnull(i8* %a)
156  ret void
157f:
158  ret void
159}
160
161; The callsite must execute in order for the attribute to transfer to the parent.
162; The volatile load might trap, so there's no guarantee that we'll ever get to the call.
163
164define i8 @parent6(i8* %a, i8* %b) {
165; CHECK-LABEL: @parent6(i8* %a, i8* %b)
166; CHECK-NEXT:    [[C:%.*]] = load volatile i8, i8* %b
167; CHECK-NEXT:    call void @use1nonnull(i8* %a)
168; CHECK-NEXT:    ret i8 [[C]]
169;
170  %c = load volatile i8, i8* %b
171  call void @use1nonnull(i8* %a)
172  ret i8 %c
173}
174
175; The nonnull callsite is guaranteed to execute, so the argument must be nonnull throughout the parent.
176
177define i8 @parent7(i8* %a) {
178; CHECK-LABEL: @parent7(i8* nonnull %a)
179; CHECK-NEXT:    [[RET:%.*]] = call i8 @use1safecall(i8* %a)
180; CHECK-NEXT:    call void @use1nonnull(i8* %a)
181; CHECK-NEXT:    ret i8 [[RET]]
182;
183  %ret = call i8 @use1safecall(i8* %a)
184  call void @use1nonnull(i8* %a)
185  ret i8 %ret
186}
187
188; Make sure that an invoke works similarly to a call.
189
190declare i32 @esfp(...)
191
192define i1 @parent8(i8* %a, i8* %bogus1, i8* %b) personality i8* bitcast (i32 (...)* @esfp to i8*){
193; CHECK-LABEL: @parent8(i8* nonnull %a, i8* nocapture readnone %bogus1, i8* nonnull %b)
194; CHECK-NEXT:  entry:
195; CHECK-NEXT:    invoke void @use2nonnull(i8* %a, i8* %b)
196; CHECK-NEXT:    to label %cont unwind label %exc
197; CHECK:       cont:
198; CHECK-NEXT:    [[NULL_CHECK:%.*]] = icmp eq i8* %b, null
199; CHECK-NEXT:    ret i1 [[NULL_CHECK]]
200; CHECK:       exc:
201; CHECK-NEXT:    [[LP:%.*]] = landingpad { i8*, i32 }
202; CHECK-NEXT:    filter [0 x i8*] zeroinitializer
203; CHECK-NEXT:    unreachable
204;
205entry:
206  invoke void @use2nonnull(i8* %a, i8* %b)
207  to label %cont unwind label %exc
208
209cont:
210  %null_check = icmp eq i8* %b, null
211  ret i1 %null_check
212
213exc:
214  %lp = landingpad { i8*, i32 }
215  filter [0 x i8*] zeroinitializer
216  unreachable
217}
218
219; CHECK: define nonnull i32* @gep1(
220define i32* @gep1(i32* %p) {
221  %q = getelementptr inbounds i32, i32* %p, i32 1
222  ret i32* %q
223}
224
225; CHECK: define i32 addrspace(3)* @gep2(
226define i32 addrspace(3)* @gep2(i32 addrspace(3)* %p) {
227  %q = getelementptr inbounds i32, i32 addrspace(3)* %p, i32 1
228  ret i32 addrspace(3)* %q
229}
230