Index: include/llvm/IR/Attributes.h =================================================================== --- include/llvm/IR/Attributes.h +++ include/llvm/IR/Attributes.h @@ -379,13 +379,6 @@ static AttributeList get(LLVMContext &C, unsigned Index, const AttrBuilder &B); - /// Add an argument attribute to the list. Returns a new list because - /// attribute lists are immutable. - AttributeList addParamAttribute(LLVMContext &C, unsigned ArgNo, - Attribute::AttrKind Kind) const { - return addAttribute(C, ArgNo + FirstArgIndex, Kind); - } - /// \brief Add an attribute to the attribute set at the given index. Because /// attribute sets are immutable, this returns a new set. AttributeList addAttribute(LLVMContext &C, unsigned Index, @@ -406,6 +399,33 @@ AttributeList addAttributes(LLVMContext &C, unsigned Index, const AttrBuilder &B) const; + /// Add an argument attribute to the list. Returns a new list because + /// attribute lists are immutable. + AttributeList addParamAttribute(LLVMContext &C, unsigned ArgNo, + Attribute::AttrKind Kind) const { + return addAttribute(C, ArgNo + FirstArgIndex, Kind); + } + + /// Add an argument attribute to the list. Returns a new list because + /// attribute lists are immutable. + AttributeList addParamAttribute(LLVMContext &C, unsigned ArgNo, + StringRef Kind, + StringRef Value = StringRef()) const { + return addAttribute(C, ArgNo + FirstArgIndex, Kind, Value); + } + + /// Add an attribute to the attribute set at the given arg indices. Because + /// attribute sets are immutable, this returns a new set. + AttributeList addParamAttribute(LLVMContext &C, ArrayRef ArgNos, + Attribute A) const; + + /// Add an argument attribute to the list. Returns a new list because + /// attribute lists are immutable. + AttributeList addParamAttributes(LLVMContext &C, unsigned ArgNo, + const AttrBuilder &B) const { + return addAttributes(C, ArgNo + FirstArgIndex, B); + } + /// \brief Remove the specified attribute at the specified index from this /// attribute list. Because attribute lists are immutable, this returns the /// new list. @@ -429,23 +449,78 @@ /// new list. AttributeList removeAttributes(LLVMContext &C, unsigned Index) const; - /// \brief Add the dereferenceable attribute to the attribute set at the given + /// \brief Remove the specified attribute at the specified arg index from this + /// attribute list. Because attribute lists are immutable, this returns the + /// new list. + AttributeList removeParamAttribute(LLVMContext &C, unsigned ArgNo, + Attribute::AttrKind Kind) const { + return removeAttribute(C, ArgNo + FirstArgIndex, Kind); + } + + /// \brief Remove the specified attribute at the specified arg index from this + /// attribute list. Because attribute lists are immutable, this returns the + /// new list. + AttributeList removeParamAttribute(LLVMContext &C, unsigned ArgNo, + StringRef Kind) const { + return removeAttribute(C, ArgNo + FirstArgIndex, Kind); + } + + /// \brief Remove the specified attribute at the specified arg index from this + /// attribute list. Because attribute lists are immutable, this returns the + /// new list. + AttributeList removeParamAttributes(LLVMContext &C, unsigned ArgNo, + const AttrBuilder &AttrsToRemove) const { + return removeAttributes(C, ArgNo + FirstArgIndex, AttrsToRemove); + } + + /// \brief Remove all attributes at the specified arg index from this + /// attribute list. Because attribute lists are immutable, this returns the + /// new list. + AttributeList removeParamAttributes(LLVMContext &C, unsigned ArgNo) const { + return removeAttributes(C, ArgNo + FirstArgIndex); + } + + /// \Brief Add the dereferenceable attribute to the attribute set at the given /// index. Because attribute sets are immutable, this returns a new set. AttributeList addDereferenceableAttr(LLVMContext &C, unsigned Index, uint64_t Bytes) const; + /// \Brief Add the dereferenceable attribute to the attribute set at the given + /// arg index. Because attribute sets are immutable, this returns a new set. + AttributeList addDereferenceableParamAttr(LLVMContext &C, unsigned ArgNo, + uint64_t Bytes) const { + return addDereferenceableAttr(C, ArgNo + FirstArgIndex, Bytes); + } + /// \brief Add the dereferenceable_or_null attribute to the attribute set at /// the given index. Because attribute sets are immutable, this returns a new /// set. AttributeList addDereferenceableOrNullAttr(LLVMContext &C, unsigned Index, uint64_t Bytes) const; + /// \brief Add the dereferenceable_or_null attribute to the attribute set at + /// the given arg index. Because attribute sets are immutable, this returns a + /// new set. + AttributeList addDereferenceableOrNullParamAttr(LLVMContext &C, + unsigned ArgNo, + uint64_t Bytes) const { + return addDereferenceableOrNullAttr(C, ArgNo + FirstArgIndex, Bytes); + } + /// Add the allocsize attribute to the attribute set at the given index. /// Because attribute sets are immutable, this returns a new set. AttributeList addAllocSizeAttr(LLVMContext &C, unsigned Index, unsigned ElemSizeArg, const Optional &NumElemsArg); + /// Add the allocsize attribute to the attribute set at the given arg index. + /// Because attribute sets are immutable, this returns a new set. + AttributeList addAllocSizeParamAttr(LLVMContext &C, unsigned ArgNo, + unsigned ElemSizeArg, + const Optional &NumElemsArg) { + return addAllocSizeAttr(C, ArgNo + FirstArgIndex, ElemSizeArg, NumElemsArg); + } + //===--------------------------------------------------------------------===// // AttributeList Accessors //===--------------------------------------------------------------------===// @@ -475,6 +550,21 @@ /// \brief Return true if attribute exists at the given index. bool hasAttributes(unsigned Index) const; + /// \brief Return true if the attribute exists for the given argument + bool hasParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const { + return hasAttribute(ArgNo + FirstArgIndex, Kind); + } + + /// \brief Return true if the attribute exists for the given argument + bool hasParamAttr(unsigned ArgNo, StringRef Kind) const { + return hasAttribute(ArgNo + FirstArgIndex, Kind); + } + + /// \brief Return true if attributes exists for the given argument + bool hasParamAttrs(unsigned ArgNo) const { + return hasAttributes(ArgNo + FirstArgIndex); + } + /// \brief Equivalent to hasAttribute(AttributeList::FunctionIndex, Kind) but /// may be faster. bool hasFnAttribute(Attribute::AttrKind Kind) const; @@ -498,6 +588,16 @@ /// \brief Return the attribute object that exists at the given index. Attribute getAttribute(unsigned Index, StringRef Kind) const; + /// \brief Return the attribute object that exists at the arg index. + Attribute getParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const { + return getAttribute(ArgNo + FirstArgIndex, Kind); + } + + /// \brief Return the attribute object that exists at the given index. + Attribute getParamAttr(unsigned ArgNo, StringRef Kind) const { + return getAttribute(ArgNo + FirstArgIndex, Kind); + } + /// \brief Return the alignment of the return value. unsigned getRetAlignment() const; @@ -510,10 +610,22 @@ /// \brief Get the number of dereferenceable bytes (or zero if unknown). uint64_t getDereferenceableBytes(unsigned Index) const; + /// \brief Get the number of dereferenceable bytes (or zero if unknown) of an + /// arg. + uint64_t getParamDereferenceableBytes(unsigned ArgNo) const { + return getDereferenceableBytes(ArgNo + FirstArgIndex); + } + /// \brief Get the number of dereferenceable_or_null bytes (or zero if /// unknown). uint64_t getDereferenceableOrNullBytes(unsigned Index) const; + /// \brief Get the number of dereferenceable_or_null bytes (or zero if + /// unknown) of an arg. + uint64_t getParamDereferenceableOrNullBytes(unsigned ArgNo) const { + return getDereferenceableOrNullBytes(ArgNo + FirstArgIndex); + } + /// Get the allocsize argument numbers (or pair(0, 0) if unknown). std::pair> getAllocSizeArgs(unsigned Index) const; @@ -521,6 +633,11 @@ /// \brief Return the attributes at the index as a string. std::string getAsString(unsigned Index, bool InAttrGrp = false) const; + /// \brief Return the attributes at the arg index as a string. + std::string getParamAsString(unsigned ArgNo, bool InAttrGrp = false) const { + return getAsString(ArgNo + FirstArgIndex, InAttrGrp); + } + using iterator = ArrayRef::iterator; iterator begin(unsigned Slot) const; Index: include/llvm/IR/Function.h =================================================================== --- include/llvm/IR/Function.h +++ include/llvm/IR/Function.h @@ -214,10 +214,6 @@ addAttribute(AttributeList::FunctionIndex, Attr); } - void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) { - addAttribute(ArgNo + AttributeList::FirstArgIndex, Kind); - } - /// @brief Remove function attributes from this function. void removeFnAttr(Attribute::AttrKind Kind) { removeAttribute(AttributeList::FunctionIndex, Kind); @@ -229,10 +225,6 @@ getContext(), AttributeList::FunctionIndex, Kind)); } - void removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) { - removeAttribute(ArgNo + AttributeList::FirstArgIndex, Kind); - } - /// \brief Set the entry count for this function. /// /// Entry count is the number of times this function was executed based on @@ -299,6 +291,15 @@ /// @brief adds the attributes to the list of attributes. void addAttributes(unsigned i, const AttrBuilder &Attrs); + /// @brief adds the attribute to the list of attributes for the given arg. + void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind); + + /// @brief adds the attribute to the list of attributes for the given arg. + void addParamAttr(unsigned ArgNo, Attribute Attr); + + /// @brief adds the attributes to the list of attributes for the given arg. + void addParamAttrs(unsigned ArgNo, const AttrBuilder &Attrs); + /// @brief removes the attribute from the list of attributes. void removeAttribute(unsigned i, Attribute::AttrKind Kind); @@ -308,6 +309,15 @@ /// @brief removes the attributes from the list of attributes. void removeAttributes(unsigned i, const AttrBuilder &Attrs); + /// @brief removes the attribute from the list of attributes. + void removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind); + + /// @brief removes the attribute from the list of attributes. + void removeParamAttr(unsigned ArgNo, StringRef Kind); + + /// @brief removes the attribute from the list of attributes. + void removeParamAttrs(unsigned ArgNo, const AttrBuilder &Attrs); + /// @brief check if an attributes is in the list of attributes. bool hasAttribute(unsigned i, Attribute::AttrKind Kind) const { return getAttributes().hasAttribute(i, Kind); @@ -329,10 +339,18 @@ /// @brief adds the dereferenceable attribute to the list of attributes. void addDereferenceableAttr(unsigned i, uint64_t Bytes); + /// @brief adds the dereferenceable attribute to the list of attributes for + /// the given arg. + void addDereferenceableParamAttr(unsigned ArgNo, uint64_t Bytes); + /// @brief adds the dereferenceable_or_null attribute to the list of /// attributes. void addDereferenceableOrNullAttr(unsigned i, uint64_t Bytes); + /// @brief adds the dereferenceable_or_null attribute to the list of + /// attributes for the given arg. + void addDereferenceableOrNullParamAttr(unsigned ArgNo, uint64_t Bytes); + /// @brief Extract the alignment for a call or parameter (0=unknown). unsigned getParamAlignment(unsigned ArgNo) const { return AttributeSets.getParamAlignment(ArgNo); @@ -345,6 +363,12 @@ return AttributeSets.getDereferenceableBytes(i); } + /// @brief Extract the number of dereferenceable bytes for a parameter. + /// @param ArgNo AttributeList ArgNo, referring to an argument. + uint64_t getParamDereferenceableBytes(unsigned ArgNo) const { + return AttributeSets.getParamDereferenceableBytes(ArgNo); + } + /// @brief Extract the number of dereferenceable_or_null bytes for a call or /// parameter (0=unknown). /// @param i AttributeList index, referring to a return value or argument. @@ -352,6 +376,12 @@ return AttributeSets.getDereferenceableOrNullBytes(i); } + /// @brief Extract the number of dereferenceable_or_null bytes for a parameter. + /// @param ArgNo AttributeList ArgNo, referring to an argument. + uint64_t getParamDereferenceableOrNullBytes(unsigned ArgNo) const { + return AttributeSets.getParamDereferenceableOrNullBytes(ArgNo); + } + /// @brief Determine if the function does not access memory. bool doesNotAccessMemory() const { return hasFnAttribute(Attribute::ReadNone); Index: include/llvm/IR/Instructions.h =================================================================== --- include/llvm/IR/Instructions.h +++ include/llvm/IR/Instructions.h @@ -1659,6 +1659,9 @@ /// Adds the attribute to the indicated argument void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind); + + /// Adds the attribute to the indicated argument + void addParamAttr(unsigned ArgNo, Attribute Attr); /// removes the attribute from the list of attributes. void removeAttribute(unsigned i, Attribute::AttrKind Kind); @@ -1669,6 +1672,9 @@ /// Removes the attribute from the given argument void removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind); + /// Removes the attribute from the given argument + void removeParamAttr(unsigned ArgNo, StringRef Kind); + /// adds the dereferenceable attribute to the list of attributes. void addDereferenceableAttr(unsigned i, uint64_t Bytes); @@ -1704,6 +1710,18 @@ return getAttributes().getAttribute(i, Kind); } + /// Get the attribute of a given kind from a given arg + Attribute getParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const { + assert(ArgNo < getNumArgOperands() && "Out of bounds"); + return getAttributes().getParamAttr(ArgNo, Kind); + } + + /// Get the attribute of a given kind from a given arg + Attribute getParamAttr(unsigned ArgNo, StringRef Kind) const { + assert(ArgNo < getNumArgOperands() && "Out of bounds"); + return getAttributes().getParamAttr(ArgNo, Kind); + } + /// Return true if the data operand at index \p i has the attribute \p /// A. /// Index: lib/IR/Attributes.cpp =================================================================== --- lib/IR/Attributes.cpp +++ lib/IR/Attributes.cpp @@ -1020,6 +1020,8 @@ AttributeList AttributeList::addAttribute(LLVMContext &C, ArrayRef Indices, Attribute A) const { + // Note: Code-cloned to AttributeList::addParamAttr(C, ArgNos, A). Any edits + // here must be mirrored there. assert(std::is_sorted(Indices.begin(), Indices.end())); unsigned I = 0, E = pImpl ? pImpl->getNumSlots() : 0; @@ -1093,6 +1095,39 @@ return get(C, AttrVec); } +AttributeList AttributeList::addParamAttribute(LLVMContext &C, + ArrayRef ArgNos, + Attribute A) const { + // Note: Code-clone of AttributeList::addAttribute(C, Indices, A). Any edits + // here must be mirrored there. + assert(std::is_sorted(ArgNos.begin(), ArgNos.end())); + + unsigned I = 0, E = pImpl ? pImpl->getNumSlots() : 0; + SmallVector AttrVec; + for (unsigned ArgNo : ArgNos) { + unsigned Index = ArgNo + FirstArgIndex; + // Add all attribute slots before the current index. + for (; I < E && getSlotIndex(I) < Index; ++I) + AttrVec.emplace_back(getSlotIndex(I), pImpl->getSlotAttributes(I)); + + // Add the attribute at this index. If we already have attributes at this + // index, merge them into a new set. + AttrBuilder B; + if (I < E && getSlotIndex(I) == Index) { + B.merge(AttrBuilder(pImpl->getSlotAttributes(I))); + ++I; + } + B.addAttribute(A); + AttrVec.emplace_back(Index, AttributeSet::get(C, B)); + } + + // Add remaining attributes. + for (; I < E; ++I) + AttrVec.emplace_back(getSlotIndex(I), pImpl->getSlotAttributes(I)); + + return get(C, AttrVec); +} + AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index, Attribute::AttrKind Kind) const { if (!hasAttribute(Index, Kind)) return *this; Index: lib/IR/Function.cpp =================================================================== --- lib/IR/Function.cpp +++ lib/IR/Function.cpp @@ -118,15 +118,13 @@ uint64_t Argument::getDereferenceableBytes() const { assert(getType()->isPointerTy() && "Only pointers have dereferenceable bytes"); - return getParent()->getDereferenceableBytes(getArgNo() + - AttributeList::FirstArgIndex); + return getParent()->getParamDereferenceableBytes(getArgNo()); } uint64_t Argument::getDereferenceableOrNullBytes() const { assert(getType()->isPointerTy() && "Only pointers have dereferenceable bytes"); - return getParent()->getDereferenceableOrNullBytes( - getArgNo() + AttributeList::FirstArgIndex); + return getParent()->getParamDereferenceableOrNullBytes(getArgNo()); } bool Argument::hasNestAttr() const { @@ -169,21 +167,20 @@ void Argument::addAttrs(AttrBuilder &B) { AttributeList AL = getParent()->getAttributes(); - AL = AL.addAttributes(Parent->getContext(), - getArgNo() + AttributeList::FirstArgIndex, B); + AL = AL.addParamAttributes(Parent->getContext(), getArgNo(), B); getParent()->setAttributes(AL); } void Argument::addAttr(Attribute::AttrKind Kind) { - getParent()->addAttribute(getArgNo() + AttributeList::FirstArgIndex, Kind); + getParent()->addParamAttr(getArgNo(), Kind); } void Argument::addAttr(Attribute Attr) { - getParent()->addAttribute(getArgNo() + AttributeList::FirstArgIndex, Attr); + getParent()->addParamAttr(getArgNo(), Attr); } void Argument::removeAttr(Attribute::AttrKind Kind) { - getParent()->removeAttribute(getArgNo() + AttributeList::FirstArgIndex, Kind); + getParent()->removeParamAttr(getArgNo(), Kind); } bool Argument::hasAttribute(Attribute::AttrKind Kind) const { @@ -365,6 +362,24 @@ setAttributes(PAL); } +void Function::addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) { + AttributeList PAL = getAttributes(); + PAL = PAL.addParamAttribute(getContext(), ArgNo, Kind); + setAttributes(PAL); +} + +void Function::addParamAttr(unsigned ArgNo, Attribute Attr) { + AttributeList PAL = getAttributes(); + PAL = PAL.addParamAttribute(getContext(), ArgNo, Attr); + setAttributes(PAL); +} + +void Function::addParamAttrs(unsigned ArgNo, const AttrBuilder &Attrs) { + AttributeList PAL = getAttributes(); + PAL = PAL.addParamAttributes(getContext(), ArgNo, Attrs); + setAttributes(PAL); +} + void Function::removeAttribute(unsigned i, Attribute::AttrKind Kind) { AttributeList PAL = getAttributes(); PAL = PAL.removeAttribute(getContext(), i, Kind); @@ -383,18 +398,48 @@ setAttributes(PAL); } +void Function::removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) { + AttributeList PAL = getAttributes(); + PAL = PAL.removeParamAttribute(getContext(), ArgNo, Kind); + setAttributes(PAL); +} + +void Function::removeParamAttr(unsigned ArgNo, StringRef Kind) { + AttributeList PAL = getAttributes(); + PAL = PAL.removeParamAttribute(getContext(), ArgNo, Kind); + setAttributes(PAL); +} + +void Function::removeParamAttrs(unsigned ArgNo, const AttrBuilder &Attrs) { + AttributeList PAL = getAttributes(); + PAL = PAL.removeParamAttributes(getContext(), ArgNo, Attrs); + setAttributes(PAL); +} + void Function::addDereferenceableAttr(unsigned i, uint64_t Bytes) { AttributeList PAL = getAttributes(); PAL = PAL.addDereferenceableAttr(getContext(), i, Bytes); setAttributes(PAL); } +void Function::addDereferenceableParamAttr(unsigned ArgNo, uint64_t Bytes) { + AttributeList PAL = getAttributes(); + PAL = PAL.addDereferenceableParamAttr(getContext(), ArgNo, Bytes); + setAttributes(PAL); +} + void Function::addDereferenceableOrNullAttr(unsigned i, uint64_t Bytes) { AttributeList PAL = getAttributes(); PAL = PAL.addDereferenceableOrNullAttr(getContext(), i, Bytes); setAttributes(PAL); } +void Function::addDereferenceableOrNullParamAttr(unsigned ArgNo, uint64_t Bytes) { + AttributeList PAL = getAttributes(); + PAL = PAL.addDereferenceableOrNullParamAttr(getContext(), ArgNo, Bytes); + setAttributes(PAL); +} + const std::string &Function::getGC() const { assert(hasGC() && "Function has no collector"); return getContext().getGC(*this); Index: lib/IR/Instructions.cpp =================================================================== --- lib/IR/Instructions.cpp +++ lib/IR/Instructions.cpp @@ -393,7 +393,17 @@ } void CallInst::addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) { - addAttribute(ArgNo + AttributeList::FirstArgIndex, Kind); + assert(ArgNo < getNumArgOperands() && "Out of bounds"); + AttributeList PAL = getAttributes(); + PAL = PAL.addParamAttribute(getContext(), ArgNo, Kind); + setAttributes(PAL); +} + +void CallInst::addParamAttr(unsigned ArgNo, Attribute Attr) { + assert(ArgNo < getNumArgOperands() && "Out of bounds"); + AttributeList PAL = getAttributes(); + PAL = PAL.addParamAttribute(getContext(), ArgNo, Attr); + setAttributes(PAL); } void CallInst::removeAttribute(unsigned i, Attribute::AttrKind Kind) { @@ -409,7 +419,17 @@ } void CallInst::removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) { - removeAttribute(ArgNo + AttributeList::FirstArgIndex, Kind); + assert(ArgNo < getNumArgOperands() && "Out of bounds"); + AttributeList PAL = getAttributes(); + PAL = PAL.removeParamAttribute(getContext(), ArgNo, Kind); + setAttributes(PAL); +} + +void CallInst::removeParamAttr(unsigned ArgNo, StringRef Kind) { + assert(ArgNo < getNumArgOperands() && "Out of bounds"); + AttributeList PAL = getAttributes(); + PAL = PAL.removeParamAttribute(getContext(), ArgNo, Kind); + setAttributes(PAL); } void CallInst::addDereferenceableAttr(unsigned i, uint64_t Bytes) { @@ -802,7 +822,9 @@ } void InvokeInst::addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) { - addAttribute(ArgNo + AttributeList::FirstArgIndex, Kind); + AttributeList PAL = getAttributes(); + PAL = PAL.addParamAttribute(getContext(), ArgNo, Kind); + setAttributes(PAL); } void InvokeInst::removeAttribute(unsigned i, Attribute::AttrKind Kind) { @@ -818,7 +840,9 @@ } void InvokeInst::removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) { - removeAttribute(ArgNo + AttributeList::FirstArgIndex, Kind); + AttributeList PAL = getAttributes(); + PAL = PAL.removeParamAttribute(getContext(), ArgNo, Kind); + setAttributes(PAL); } void InvokeInst::addDereferenceableAttr(unsigned i, uint64_t Bytes) { Index: lib/Transforms/InstCombine/InstCombineCalls.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCalls.cpp +++ lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -3842,23 +3842,23 @@ // Mark any parameters that are known to be non-null with the nonnull // attribute. This is helpful for inlining calls to functions with null // checks on their arguments. - SmallVector Indices; + SmallVector ArgNos; unsigned ArgNo = 0; for (Value *V : CS.args()) { if (V->getType()->isPointerTy() && !CS.paramHasAttr(ArgNo, Attribute::NonNull) && isKnownNonNullAt(V, CS.getInstruction(), &DT)) - Indices.push_back(ArgNo + AttributeList::FirstArgIndex); + ArgNos.push_back(ArgNo); ArgNo++; } assert(ArgNo == CS.arg_size() && "sanity check"); - if (!Indices.empty()) { + if (!ArgNos.empty()) { AttributeList AS = CS.getAttributes(); LLVMContext &Ctx = CS.getInstruction()->getContext(); - AS = AS.addAttribute(Ctx, Indices, + AS = AS.addParamAttribute(Ctx, ArgNos, Attribute::get(Ctx, Attribute::NonNull)); CS.setAttributes(AS); Changed = true; Index: lib/Transforms/Scalar/CorrelatedValuePropagation.cpp =================================================================== --- lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -305,7 +305,7 @@ /// Infer nonnull attributes for the arguments at the specified callsite. static bool processCallSite(CallSite CS, LazyValueInfo *LVI) { - SmallVector Indices; + SmallVector ArgNos; unsigned ArgNo = 0; for (Value *V : CS.args()) { @@ -318,18 +318,18 @@ LVI->getPredicateAt(ICmpInst::ICMP_EQ, V, ConstantPointerNull::get(Type), CS.getInstruction()) == LazyValueInfo::False) - Indices.push_back(ArgNo + AttributeList::FirstArgIndex); + ArgNos.push_back(ArgNo); ArgNo++; } assert(ArgNo == CS.arg_size() && "sanity check"); - if (Indices.empty()) + if (ArgNos.empty()) return false; AttributeList AS = CS.getAttributes(); LLVMContext &Ctx = CS.getInstruction()->getContext(); - AS = AS.addAttribute(Ctx, Indices, Attribute::get(Ctx, Attribute::NonNull)); + AS = AS.addParamAttribute(Ctx, ArgNos, Attribute::get(Ctx, Attribute::NonNull)); CS.setAttributes(AS); return true;