Index: lib/Transforms/InstCombine/InstCombineCalls.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCalls.cpp +++ lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1068,24 +1068,30 @@ return EraseInstFromFunction(*II); } - // assume( (load addr) != null ) -> add 'nonnull' metadata to load - // (if assume is valid at the load) if (ICmpInst* ICmp = dyn_cast(IIOperand)) { Value *LHS = ICmp->getOperand(0); Value *RHS = ICmp->getOperand(1); if (ICmpInst::ICMP_NE == ICmp->getPredicate() && - isa(LHS) && isa(RHS) && RHS->getType()->isPointerTy() && cast(RHS)->isNullValue()) { - LoadInst* LI = cast(LHS); - if (isValidAssumeForContext(II, LI, DL, DT)) { - MDNode *MD = MDNode::get(II->getContext(), None); - LI->setMetadata(LLVMContext::MD_nonnull, MD); - return EraseInstFromFunction(*II); + // assume( (load addr) != null ) -> add 'nonnull' metadata to load + // (if assume is valid at the load) + if (LoadInst* LI = dyn_cast(LHS)) { + if (isValidAssumeForContext(II, LI, DL, DT)) { + MDNode *MD = MDNode::get(II->getContext(), None); + LI->setMetadata(LLVMContext::MD_nonnull, MD); + return EraseInstFromFunction(*II); + } } + else if (CallInst *I = dyn_cast(LHS)) { + // assume( (call|invoke) != null ) -> add 'nonnull' return attribute + if (isValidAssumeForContext(II, I, DL, DT)) + I->addAttribute(AttributeSet::ReturnIndex, Attribute::NonNull); + } else if (InvokeInst *I = dyn_cast(LHS)) + if (isValidAssumeForContext(II, I, DL, DT)) + I->addAttribute(AttributeSet::ReturnIndex, Attribute::NonNull); } - // TODO: apply nonnull return attributes to calls and invokes // TODO: apply range metadata for range check patterns? } // If there is a dominating assume with the same condition as this one, @@ -1126,7 +1132,9 @@ if (isKnownNonNull(DerivedPtr)) II->addAttribute(AttributeSet::ReturnIndex, Attribute::NonNull); - // TODO: dereferenceable -> deref attribute + // isDereferenceablePointer -> deref attribute + if (DerivedPtr->isDereferenceablePointer()) + II->addAttribute(AttributeSet::ReturnIndex, Attribute::Dereferenceable); // TODO: bitcast(relocate(p)) -> relocate(bitcast(p)) // Canonicalize on the type from the uses to the defs