1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4; InstCombine should mark null-checked argument as nonnull at callsite 5declare void @dummy(ptr, i32) 6 7define void @test(ptr %a, i32 %b) { 8; CHECK-LABEL: @test( 9; CHECK-NEXT: entry: 10; CHECK-NEXT: [[COND1:%.*]] = icmp eq ptr [[A:%.*]], null 11; CHECK-NEXT: br i1 [[COND1]], label [[DEAD:%.*]], label [[NOT_NULL:%.*]] 12; CHECK: not_null: 13; CHECK-NEXT: [[COND2:%.*]] = icmp eq i32 [[B:%.*]], 0 14; CHECK-NEXT: br i1 [[COND2]], label [[DEAD]], label [[NOT_ZERO:%.*]] 15; CHECK: not_zero: 16; CHECK-NEXT: call void @dummy(ptr nonnull [[A]], i32 [[B]]) 17; CHECK-NEXT: ret void 18; CHECK: dead: 19; CHECK-NEXT: unreachable 20; 21entry: 22 %cond1 = icmp eq ptr %a, null 23 br i1 %cond1, label %dead, label %not_null 24not_null: 25 %cond2 = icmp eq i32 %b, 0 26 br i1 %cond2, label %dead, label %not_zero 27not_zero: 28 call void @dummy(ptr %a, i32 %b) 29 ret void 30dead: 31 unreachable 32} 33 34; The nonnull attribute in the 'bar' declaration is 35; propagated to the parameters of the 'baz' callsite. 36 37declare void @bar(ptr, ptr nonnull noundef) 38declare void @bar_without_noundef(ptr, ptr nonnull) 39declare void @baz(ptr, ptr) 40 41define void @deduce_nonnull_from_another_call(ptr %a, ptr %b) { 42; CHECK-LABEL: @deduce_nonnull_from_another_call( 43; CHECK-NEXT: call void @bar(ptr [[A:%.*]], ptr [[B:%.*]]) 44; CHECK-NEXT: call void @baz(ptr nonnull [[B]], ptr nonnull [[B]]) 45; CHECK-NEXT: ret void 46; 47 call void @bar(ptr %a, ptr %b) 48 call void @baz(ptr %b, ptr %b) 49 ret void 50} 51 52 53define void @deduce_nonnull_from_another_call2(ptr %a, ptr %b) { 54; CHECK-LABEL: @deduce_nonnull_from_another_call2( 55; CHECK-NEXT: call void @bar_without_noundef(ptr [[A:%.*]], ptr [[B:%.*]]) 56; CHECK-NEXT: call void @baz(ptr [[B]], ptr [[B]]) 57; CHECK-NEXT: ret void 58; 59 call void @bar_without_noundef(ptr %a, ptr %b) 60 call void @baz(ptr %b, ptr %b) 61 ret void 62} 63 64