@@ -220,3 +220,73 @@ return:
220220 %retval.0 = phi ptr [ %1 , %if.end ], [ null , %entry ]
221221 ret ptr %retval.0
222222}
223+
224+ define i1 @test_known_nonnull_at_callsite (ptr %src ) {
225+ ; CHECK-LABEL: @test_known_nonnull_at_callsite(
226+ ; CHECK-NEXT: entry:
227+ ; CHECK-NEXT: call void @callee(ptr noundef nonnull [[SRC:%.*]])
228+ ; CHECK-NEXT: [[NONNULL:%.*]] = icmp eq ptr [[SRC]], null
229+ ; CHECK-NEXT: ret i1 [[NONNULL]]
230+ ;
231+ entry:
232+ call void @callee (ptr noundef nonnull %src )
233+ %nonnull = icmp eq ptr %src , null
234+ ret i1 %nonnull
235+ }
236+
237+ define i1 @test_known_nonnull_mixed (ptr %src ) {
238+ ; CHECK-LABEL: @test_known_nonnull_mixed(
239+ ; CHECK-NEXT: entry:
240+ ; CHECK-NEXT: call void @callee2(ptr nonnull [[SRC:%.*]])
241+ ; CHECK-NEXT: [[NONNULL:%.*]] = icmp eq ptr [[SRC]], null
242+ ; CHECK-NEXT: ret i1 [[NONNULL]]
243+ ;
244+ entry:
245+ call void @callee2 (ptr nonnull %src )
246+ %nonnull = icmp eq ptr %src , null
247+ ret i1 %nonnull
248+ }
249+
250+ define i1 @test_known_nonnull_at_callsite_dereferenceable (ptr %src ) {
251+ ; CHECK-LABEL: @test_known_nonnull_at_callsite_dereferenceable(
252+ ; CHECK-NEXT: entry:
253+ ; CHECK-NEXT: call void @callee(ptr dereferenceable(1) [[SRC:%.*]])
254+ ; CHECK-NEXT: [[NONNULL:%.*]] = icmp eq ptr [[SRC]], null
255+ ; CHECK-NEXT: ret i1 [[NONNULL]]
256+ ;
257+ entry:
258+ call void @callee (ptr dereferenceable (1 ) %src )
259+ %nonnull = icmp eq ptr %src , null
260+ ret i1 %nonnull
261+ }
262+
263+ ; Negative tests
264+
265+ define i1 @test_known_nonnull_at_callsite_without_noundef (ptr %src ) {
266+ ; CHECK-LABEL: @test_known_nonnull_at_callsite_without_noundef(
267+ ; CHECK-NEXT: entry:
268+ ; CHECK-NEXT: call void @callee(ptr nonnull [[SRC:%.*]])
269+ ; CHECK-NEXT: [[NONNULL:%.*]] = icmp eq ptr [[SRC]], null
270+ ; CHECK-NEXT: ret i1 [[NONNULL]]
271+ ;
272+ entry:
273+ call void @callee (ptr nonnull %src )
274+ %nonnull = icmp eq ptr %src , null
275+ ret i1 %nonnull
276+ }
277+
278+ define i1 @test_known_nonnull_at_callsite_dereferenceable_null_is_defined (ptr %src ) null_pointer_is_valid {
279+ ; CHECK-LABEL: @test_known_nonnull_at_callsite_dereferenceable_null_is_defined(
280+ ; CHECK-NEXT: entry:
281+ ; CHECK-NEXT: call void @callee(ptr dereferenceable(1) [[SRC:%.*]])
282+ ; CHECK-NEXT: [[NONNULL:%.*]] = icmp eq ptr [[SRC]], null
283+ ; CHECK-NEXT: ret i1 [[NONNULL]]
284+ ;
285+ entry:
286+ call void @callee (ptr dereferenceable (1 ) %src )
287+ %nonnull = icmp eq ptr %src , null
288+ ret i1 %nonnull
289+ }
290+
291+ declare void @callee (ptr )
292+ declare void @callee2 (ptr noundef)
0 commit comments