@@ -344,4 +344,75 @@ define i1 @test_store_same_block(ptr %arg) {
344344 ret i1 %cmp
345345}
346346
347+
348+ define i1 @test_known_nonnull_at_callsite (ptr %src ) {
349+ ; CHECK-LABEL: @test_known_nonnull_at_callsite(
350+ ; CHECK-NEXT: entry:
351+ ; CHECK-NEXT: call void @callee(ptr noundef nonnull [[SRC:%.*]])
352+ ; CHECK-NEXT: [[NONNULL:%.*]] = icmp eq ptr [[SRC]], null
353+ ; CHECK-NEXT: ret i1 [[NONNULL]]
354+ ;
355+ entry:
356+ call void @callee (ptr noundef nonnull %src )
357+ %nonnull = icmp eq ptr %src , null
358+ ret i1 %nonnull
359+ }
360+
361+ define i1 @test_known_nonnull_mixed (ptr %src ) {
362+ ; CHECK-LABEL: @test_known_nonnull_mixed(
363+ ; CHECK-NEXT: entry:
364+ ; CHECK-NEXT: call void @callee2(ptr nonnull [[SRC:%.*]])
365+ ; CHECK-NEXT: [[NONNULL:%.*]] = icmp eq ptr [[SRC]], null
366+ ; CHECK-NEXT: ret i1 [[NONNULL]]
367+ ;
368+ entry:
369+ call void @callee2 (ptr nonnull %src )
370+ %nonnull = icmp eq ptr %src , null
371+ ret i1 %nonnull
372+ }
373+
374+ define i1 @test_known_nonnull_at_callsite_dereferenceable (ptr %src ) {
375+ ; CHECK-LABEL: @test_known_nonnull_at_callsite_dereferenceable(
376+ ; CHECK-NEXT: entry:
377+ ; CHECK-NEXT: call void @callee(ptr dereferenceable(1) [[SRC:%.*]])
378+ ; CHECK-NEXT: [[NONNULL:%.*]] = icmp eq ptr [[SRC]], null
379+ ; CHECK-NEXT: ret i1 [[NONNULL]]
380+ ;
381+ entry:
382+ call void @callee (ptr dereferenceable (1 ) %src )
383+ %nonnull = icmp eq ptr %src , null
384+ ret i1 %nonnull
385+ }
386+
387+ ; Negative tests
388+
389+ define i1 @test_known_nonnull_at_callsite_without_noundef (ptr %src ) {
390+ ; CHECK-LABEL: @test_known_nonnull_at_callsite_without_noundef(
391+ ; CHECK-NEXT: entry:
392+ ; CHECK-NEXT: call void @callee(ptr nonnull [[SRC:%.*]])
393+ ; CHECK-NEXT: [[NONNULL:%.*]] = icmp eq ptr [[SRC]], null
394+ ; CHECK-NEXT: ret i1 [[NONNULL]]
395+ ;
396+ entry:
397+ call void @callee (ptr nonnull %src )
398+ %nonnull = icmp eq ptr %src , null
399+ ret i1 %nonnull
400+ }
401+
402+ define i1 @test_known_nonnull_at_callsite_dereferenceable_null_is_defined (ptr %src ) #0 {
403+ ; CHECK-LABEL: @test_known_nonnull_at_callsite_dereferenceable_null_is_defined(
404+ ; CHECK-NEXT: entry:
405+ ; CHECK-NEXT: call void @callee(ptr dereferenceable(1) [[SRC:%.*]])
406+ ; CHECK-NEXT: [[NONNULL:%.*]] = icmp eq ptr [[SRC]], null
407+ ; CHECK-NEXT: ret i1 [[NONNULL]]
408+ ;
409+ entry:
410+ call void @callee (ptr dereferenceable (1 ) %src )
411+ %nonnull = icmp eq ptr %src , null
412+ ret i1 %nonnull
413+ }
414+
415+ declare void @callee (ptr )
416+ declare void @callee2 (ptr noundef)
417+
347418attributes #0 = { null_pointer_is_valid }
0 commit comments