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 @@ -22,6 +22,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Config/llvm-config.h" +#include "llvm/Support/Alignment.h" #include "llvm/Support/PointerLikeTypeTraits.h" #include #include @@ -705,8 +706,8 @@ class AttrBuilder { std::bitset Attrs; std::map TargetDepAttrs; - uint64_t Alignment = 0; - uint64_t StackAlignment = 0; + MaybeAlign Alignment; + MaybeAlign StackAlignment; uint64_t DerefBytes = 0; uint64_t DerefOrNullBytes = 0; uint64_t AllocSizeArgs = 0; @@ -773,10 +774,10 @@ bool hasAlignmentAttr() const; /// Retrieve the alignment attribute, if it exists. - uint64_t getAlignment() const { return Alignment; } + uint64_t getAlignment() const { return Alignment ? Alignment->value() : 0; } /// Retrieve the stack alignment attribute, if it exists. - uint64_t getStackAlignment() const { return StackAlignment; } + uint64_t getStackAlignment() const { return StackAlignment ? StackAlignment->value() : 0; } /// Retrieve the number of dereferenceable bytes, if the /// dereferenceable attribute exists (zero is returned otherwise). 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 @@ -1438,7 +1438,9 @@ void AttrBuilder::clear() { Attrs.reset(); TargetDepAttrs.clear(); - Alignment = StackAlignment = DerefBytes = DerefOrNullBytes = 0; + Alignment.reset(); + StackAlignment.reset(); + DerefBytes = DerefOrNullBytes = 0; AllocSizeArgs = 0; ByValType = nullptr; } @@ -1462,9 +1464,9 @@ Attrs[Kind] = true; if (Kind == Attribute::Alignment) - Alignment = Attr.getAlignment(); + Alignment = MaybeAlign(Attr.getAlignment()); else if (Kind == Attribute::StackAlignment) - StackAlignment = Attr.getStackAlignment(); + StackAlignment = MaybeAlign(Attr.getStackAlignment()); else if (Kind == Attribute::ByVal) ByValType = Attr.getValueAsType(); else if (Kind == Attribute::Dereferenceable) @@ -1486,9 +1488,9 @@ Attrs[Val] = false; if (Val == Attribute::Alignment) - Alignment = 0; + Alignment.reset(); else if (Val == Attribute::StackAlignment) - StackAlignment = 0; + StackAlignment.reset(); else if (Val == Attribute::ByVal) ByValType = nullptr; else if (Val == Attribute::Dereferenceable) @@ -1517,23 +1519,23 @@ return unpackAllocSizeArgs(AllocSizeArgs); } -AttrBuilder &AttrBuilder::addAlignmentAttr(unsigned Align) { - if (Align == 0) return *this; +AttrBuilder &AttrBuilder::addAlignmentAttr(unsigned A) { + MaybeAlign Align(A); + if (!Align) return *this; - assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); - assert(Align <= 0x40000000 && "Alignment too large."); + assert(*Align <= 0x40000000 && "Alignment too large."); Attrs[Attribute::Alignment] = true; Alignment = Align; return *this; } -AttrBuilder &AttrBuilder::addStackAlignmentAttr(unsigned Align) { +AttrBuilder &AttrBuilder::addStackAlignmentAttr(unsigned A) { + MaybeAlign Align(A); // Default alignment, allow the target to define how to align it. - if (Align == 0) return *this; + if (!Align) return *this; - assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); - assert(Align <= 0x100 && "Alignment too large."); + assert(*Align <= 0x100 && "Alignment too large."); Attrs[Attribute::StackAlignment] = true; StackAlignment = Align; @@ -1610,10 +1612,10 @@ AttrBuilder &AttrBuilder::remove(const AttrBuilder &B) { // FIXME: What if both have alignments, but they don't match?! if (B.Alignment) - Alignment = 0; + Alignment.reset(); if (B.StackAlignment) - StackAlignment = 0; + StackAlignment.reset(); if (B.DerefBytes) DerefBytes = 0;