diff --git a/llvm/include/llvm/IR/Attributes.h b/llvm/include/llvm/IR/Attributes.h --- a/llvm/include/llvm/IR/Attributes.h +++ b/llvm/include/llvm/IR/Attributes.h @@ -151,11 +151,11 @@ /// Returns the alignment field of an attribute as a byte alignment /// value. - unsigned getAlignment() const; + MaybeAlign getAlignment() const; /// Returns the stack alignment field of an attribute as a byte /// alignment value. - unsigned getStackAlignment() const; + MaybeAlign getStackAlignment() const; /// Returns the number of dereferenceable bytes from the /// dereferenceable attribute. @@ -285,8 +285,8 @@ /// Return the target-dependent attribute object. Attribute getAttribute(StringRef Kind) const; - unsigned getAlignment() const; - unsigned getStackAlignment() const; + MaybeAlign getAlignment() const; + MaybeAlign getStackAlignment() const; uint64_t getDereferenceableBytes() const; uint64_t getDereferenceableOrNullBytes() const; Type *getByValType() const; @@ -604,16 +604,16 @@ } /// Return the alignment of the return value. - unsigned getRetAlignment() const; + MaybeAlign getRetAlignment() const; /// Return the alignment for the specified function parameter. - unsigned getParamAlignment(unsigned ArgNo) const; + MaybeAlign getParamAlignment(unsigned ArgNo) const; /// Return the byval type for the specified function parameter. Type *getParamByValType(unsigned ArgNo) const; /// Get the stack alignment. - unsigned getStackAlignment(unsigned Index) const; + MaybeAlign getStackAlignment(unsigned Index) const; /// Get the number of dereferenceable bytes (or zero if unknown). uint64_t getDereferenceableBytes(unsigned Index) const; @@ -798,11 +798,29 @@ /// This turns an int alignment (which must be a power of 2) into the /// form used internally in Attribute. - AttrBuilder &addAlignmentAttr(unsigned Align); + /// This call has no effect if Align is not. + AttrBuilder &addAlignmentAttr(MaybeAlign Align); + + /// This turns an int alignment (which must be a power of 2) into the + /// form used internally in Attribute. + /// This call has no effect if Align is 0. + /// Deprecated, use the version using a MaybeAlign. + inline AttrBuilder &addAlignmentAttr(unsigned Align) { + return addAlignmentAttr(MaybeAlign(Align)); + } /// This turns an int stack alignment (which must be a power of 2) into /// the form used internally in Attribute. - AttrBuilder &addStackAlignmentAttr(unsigned Align); + /// This call has no effect if Align is not. + AttrBuilder &addStackAlignmentAttr(MaybeAlign Align); + + /// This turns an int stack alignment (which must be a power of 2) into + /// the form used internally in Attribute. + /// This call has no effect if Align is 0. + /// Deprecated, use the version using a MaybeAlign. + inline AttrBuilder &addStackAlignmentAttr(unsigned Align) { + return addStackAlignmentAttr(MaybeAlign(Align)); + } /// This turns the number of dereferenceable bytes into the form used /// internally in Attribute. diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h --- a/llvm/include/llvm/IR/Function.h +++ b/llvm/include/llvm/IR/Function.h @@ -343,7 +343,10 @@ unsigned getFnStackAlignment() const { if (!hasFnAttribute(Attribute::StackAlignment)) return 0; - return AttributeSets.getStackAlignment(AttributeList::FunctionIndex); + if (const auto MA = + AttributeSets.getStackAlignment(AttributeList::FunctionIndex)) + return MA->value(); + return 0; } /// hasGC/getGC/setGC/clearGC - The name of the garbage collection algorithm @@ -433,7 +436,9 @@ /// Extract the alignment for a call or parameter (0=unknown). unsigned getParamAlignment(unsigned ArgNo) const { - return AttributeSets.getParamAlignment(ArgNo); + if (const auto MA = AttributeSets.getParamAlignment(ArgNo)) + return MA->value(); + return 0; } /// Extract the byval type for a parameter. diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h --- a/llvm/include/llvm/IR/InstrTypes.h +++ b/llvm/include/llvm/IR/InstrTypes.h @@ -1567,11 +1567,17 @@ } /// Extract the alignment of the return value. - unsigned getRetAlignment() const { return Attrs.getRetAlignment(); } + unsigned getRetAlignment() const { + if (const auto MA = Attrs.getRetAlignment()) + return MA->value(); + return 0; + } /// Extract the alignment for a call or parameter (0=unknown). unsigned getParamAlignment(unsigned ArgNo) const { - return Attrs.getParamAlignment(ArgNo); + if (const auto MA = Attrs.getParamAlignment(ArgNo)) + return MA->value(); + return 0; } /// Extract the byval type for a call or parameter. 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 @@ -208,8 +208,8 @@ Attribute getAttribute(Attribute::AttrKind Kind) const; Attribute getAttribute(StringRef Kind) const; - unsigned getAlignment() const; - unsigned getStackAlignment() const; + MaybeAlign getAlignment() const; + MaybeAlign getStackAlignment() const; uint64_t getDereferenceableBytes() const; uint64_t getDereferenceableOrNullBytes() const; std::pair> getAllocSizeArgs() const; 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 @@ -241,16 +241,16 @@ return pImpl && pImpl->hasAttribute(Kind); } -unsigned Attribute::getAlignment() const { +MaybeAlign Attribute::getAlignment() const { assert(hasAttribute(Attribute::Alignment) && "Trying to get alignment from non-alignment attribute!"); - return pImpl->getValueAsInt(); + return MaybeAlign(pImpl->getValueAsInt()); } -unsigned Attribute::getStackAlignment() const { +MaybeAlign Attribute::getStackAlignment() const { assert(hasAttribute(Attribute::StackAlignment) && "Trying to get alignment from non-alignment attribute!"); - return pImpl->getValueAsInt(); + return MaybeAlign(pImpl->getValueAsInt()); } uint64_t Attribute::getDereferenceableBytes() const { @@ -667,12 +667,12 @@ return SetNode ? SetNode->getAttribute(Kind) : Attribute(); } -unsigned AttributeSet::getAlignment() const { - return SetNode ? SetNode->getAlignment() : 0; +MaybeAlign AttributeSet::getAlignment() const { + return SetNode ? SetNode->getAlignment() : None; } -unsigned AttributeSet::getStackAlignment() const { - return SetNode ? SetNode->getStackAlignment() : 0; +MaybeAlign AttributeSet::getStackAlignment() const { + return SetNode ? SetNode->getStackAlignment() : None; } uint64_t AttributeSet::getDereferenceableBytes() const { @@ -833,18 +833,18 @@ return {}; } -unsigned AttributeSetNode::getAlignment() const { +MaybeAlign AttributeSetNode::getAlignment() const { for (const auto I : *this) if (I.hasAttribute(Attribute::Alignment)) return I.getAlignment(); - return 0; + return None; } -unsigned AttributeSetNode::getStackAlignment() const { +MaybeAlign AttributeSetNode::getStackAlignment() const { for (const auto I : *this) if (I.hasAttribute(Attribute::StackAlignment)) return I.getStackAlignment(); - return 0; + return None; } Type *AttributeSetNode::getByValType() const { @@ -1161,7 +1161,7 @@ #ifndef NDEBUG // FIXME it is not obvious how this should work for alignment. For now, say // we can't change a known alignment. - unsigned OldAlign = getAttributes(Index).getAlignment(); + const MaybeAlign OldAlign = getAttributes(Index).getAlignment(); unsigned NewAlign = B.getAlignment(); assert((!OldAlign || !NewAlign || OldAlign == NewAlign) && "Attempt to change alignment!"); @@ -1346,11 +1346,11 @@ return getAttributes(Index).getAttribute(Kind); } -unsigned AttributeList::getRetAlignment() const { +MaybeAlign AttributeList::getRetAlignment() const { return getAttributes(ReturnIndex).getAlignment(); } -unsigned AttributeList::getParamAlignment(unsigned ArgNo) const { +MaybeAlign AttributeList::getParamAlignment(unsigned ArgNo) const { return getAttributes(ArgNo + FirstArgIndex).getAlignment(); } @@ -1358,8 +1358,7 @@ return getAttributes(Index+FirstArgIndex).getByValType(); } - -unsigned AttributeList::getStackAlignment(unsigned Index) const { +MaybeAlign AttributeList::getStackAlignment(unsigned Index) const { return getAttributes(Index).getStackAlignment(); } @@ -1516,8 +1515,7 @@ return unpackAllocSizeArgs(AllocSizeArgs); } -AttrBuilder &AttrBuilder::addAlignmentAttr(unsigned A) { - MaybeAlign Align(A); +AttrBuilder &AttrBuilder::addAlignmentAttr(MaybeAlign Align) { if (!Align) return *this; @@ -1528,8 +1526,7 @@ return *this; } -AttrBuilder &AttrBuilder::addStackAlignmentAttr(unsigned A) { - MaybeAlign Align(A); +AttrBuilder &AttrBuilder::addStackAlignmentAttr(MaybeAlign Align) { // Default alignment, allow the target to define how to align it. if (!Align) return *this; diff --git a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp --- a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp +++ b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp @@ -1473,12 +1473,11 @@ // Just print .param .align .b8 .param[size]; // = PAL.getparamalignment // size = typeallocsize of element type - unsigned align = PAL.getParamAlignment(paramIndex); - if (align == 0) - align = DL.getABITypeAlignment(Ty); + const Align align = DL.getValueOrABITypeAlignment( + PAL.getParamAlignment(paramIndex), Ty); unsigned sz = DL.getTypeAllocSize(Ty); - O << "\t.param .align " << align << " .b8 "; + O << "\t.param .align " << align.value() << " .b8 "; printParamName(I, paramIndex, O); O << "[" << sz << "]"; @@ -1559,9 +1558,8 @@ // Just print .param .align .b8 .param[size]; // = PAL.getparamalignment // size = typeallocsize of element type - unsigned align = PAL.getParamAlignment(paramIndex); - if (align == 0) - align = DL.getABITypeAlignment(ETy); + Align align = + DL.getValueOrABITypeAlignment(PAL.getParamAlignment(paramIndex), ETy); // Work around a bug in ptxas. When PTX code takes address of // byval parameter with alignment < 4, ptxas generates code to // spill argument into memory. Alas on sm_50+ ptxas generates @@ -1574,9 +1572,9 @@ // device-side compilation as it breaks ABI compatibility with nvcc. // Hopefully ptxas bug is fixed by then. if (!isKernelFunc && align < 4) - align = 4; + align = Align(4); unsigned sz = DL.getTypeAllocSize(ETy); - O << "\t.param .align " << align << " .b8 "; + O << "\t.param .align " << align.value() << " .b8 "; printParamName(I, paramIndex, O); O << "[" << sz << "]"; continue; diff --git a/llvm/unittests/IR/AttributesTest.cpp b/llvm/unittests/IR/AttributesTest.cpp --- a/llvm/unittests/IR/AttributesTest.cpp +++ b/llvm/unittests/IR/AttributesTest.cpp @@ -144,15 +144,15 @@ Attribute::getWithAlignment(C, Align(8))); AL = AL.addAttribute(C, AttributeList::FirstArgIndex + 1, Attribute::getWithAlignment(C, Align(32))); - EXPECT_EQ(8U, AL.getParamAlignment(0)); - EXPECT_EQ(32U, AL.getParamAlignment(1)); + EXPECT_EQ(Align(8), AL.getParamAlignment(0)); + EXPECT_EQ(Align(32), AL.getParamAlignment(1)); AttrBuilder B; B.addAttribute(Attribute::NonNull); B.addAlignmentAttr(8); AL = AL.addAttributes(C, AttributeList::FirstArgIndex, B); - EXPECT_EQ(8U, AL.getParamAlignment(0)); - EXPECT_EQ(32U, AL.getParamAlignment(1)); + EXPECT_EQ(Align(8), AL.getParamAlignment(0)); + EXPECT_EQ(Align(32), AL.getParamAlignment(1)); EXPECT_TRUE(AL.hasParamAttribute(0, Attribute::NonNull)); }