Index: lib/Analysis/ValueTracking.cpp =================================================================== --- lib/Analysis/ValueTracking.cpp +++ lib/Analysis/ValueTracking.cpp @@ -3220,6 +3220,8 @@ /// Return true if we know that the specified value is never null. bool llvm::isKnownNonNull(const Value *V, const TargetLibraryInfo *TLI) { + assert(V->getType()->isPointerTy() && "V must be pointer type"); + // Alloca never returns null, malloc might. if (isa(V)) return true; @@ -3252,6 +3254,8 @@ static bool isKnownNonNullFromDominatingCondition(const Value *V, const Instruction *CtxI, const DominatorTree *DT) { + assert(V->getType()->isPointerTy() && "V must be pointer type"); + unsigned NumUsesExplored = 0; for (auto U : V->users()) { // Avoid massive lists Index: lib/Transforms/InstCombine/InstCombineCalls.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCalls.cpp +++ lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1583,8 +1583,8 @@ // checks on their arguments. unsigned ArgNo = 0; for (Value *V : CS.args()) { - if (!CS.paramHasAttr(ArgNo+1, Attribute::NonNull) && - isKnownNonNull(V)) { + if (V->getType()->isPointerTy() && !CS.paramHasAttr(ArgNo+1, Attribute::NonNull) && + isKnownNonNullAt(V, CS.getInstruction(), DT, TLI)) { AttributeSet AS = CS.getAttributes(); AS = AS.addAttribute(CS.getInstruction()->getContext(), ArgNo+1, Attribute::NonNull); Index: test/Transforms/InstCombine/call_nonnull_arg.ll =================================================================== --- test/Transforms/InstCombine/call_nonnull_arg.ll +++ test/Transforms/InstCombine/call_nonnull_arg.ll @@ -0,0 +1,20 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +; InstCombine should mark null-checked argument as nonnull at callsite +declare void @dummy(i32*, i32) + +define void @test(i32* %a, i32 %b) { +; CHECK-LABEL: @test +; CHECK: call void @dummy(i32* nonnull %a, i32 %b) +entry: + %cond1 = icmp eq i32* %a, null + br i1 %cond1, label %dead, label %not_null +not_null: + %cond2 = icmp eq i32 %b, 0 + br i1 %cond2, label %dead, label %not_zero +not_zero: + call void @dummy(i32* %a, i32 %b) + ret void +dead: + unreachable +}