diff --git a/llvm/lib/IR/AttributeImpl.h b/llvm/lib/IR/AttributeImpl.h --- a/llvm/lib/IR/AttributeImpl.h +++ b/llvm/lib/IR/AttributeImpl.h @@ -244,10 +244,10 @@ friend TrailingObjects; private: - /// Bitset with a bit for each available attribute Attribute::AttrKind. - uint64_t AvailableFunctionAttrs; LLVMContext &Context; unsigned NumAttrSets; ///< Number of entries in this set. + /// Bitset with a bit for each available attribute Attribute::AttrKind. + uint8_t AvailableFunctionAttrs[12]; // Helper fn for TrailingObjects class. size_t numTrailingObjects(OverloadToken) { return NumAttrSets; } @@ -267,7 +267,7 @@ /// Return true if the AttributeSet or the FunctionIndex has an /// enum attribute of the given kind. bool hasFnAttribute(Attribute::AttrKind Kind) const { - return AvailableFunctionAttrs & ((uint64_t)1) << Kind; + return AvailableFunctionAttrs[Kind / 8] & ((uint64_t)1) << (Kind % 8); } using iterator = const AttributeSet *; diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -896,7 +896,7 @@ AttributeListImpl::AttributeListImpl(LLVMContext &C, ArrayRef Sets) - : AvailableFunctionAttrs(0), Context(C), NumAttrSets(Sets.size()) { + : Context(C), NumAttrSets(Sets.size()), AvailableFunctionAttrs{} { assert(!Sets.empty() && "pointless AttributeListImpl"); // There's memory after the node where we can store the entries in. @@ -909,8 +909,10 @@ static_assert(attrIdxToArrayIdx(AttributeList::FunctionIndex) == 0U, "function should be stored in slot 0"); for (const auto I : Sets[0]) { - if (!I.isStringAttribute()) - AvailableFunctionAttrs |= 1ULL << I.getKindAsEnum(); + if (!I.isStringAttribute()) { + Attribute::AttrKind Kind = I.getKindAsEnum(); + AvailableFunctionAttrs[Kind / 8] |= 1ULL << (Kind % 8); + } } }