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 @@ -774,12 +774,10 @@ bool hasAlignmentAttr() const; /// Retrieve the alignment attribute, if it exists. - uint64_t getAlignment() const { return Alignment ? Alignment->value() : 0; } + MaybeAlign getAlignment() const { return Alignment; } /// Retrieve the stack alignment attribute, if it exists. - uint64_t getStackAlignment() const { - return StackAlignment ? StackAlignment->value() : 0; - } + MaybeAlign getStackAlignment() const { return StackAlignment; } /// Retrieve the number of dereferenceable bytes, if the /// dereferenceable attribute exists (zero is returned otherwise). diff --git a/llvm/lib/AsmParser/LLParser.h b/llvm/lib/AsmParser/LLParser.h --- a/llvm/lib/AsmParser/LLParser.h +++ b/llvm/lib/AsmParser/LLParser.h @@ -281,14 +281,14 @@ void ParseOptionalVisibility(unsigned &Res); void ParseOptionalDLLStorageClass(unsigned &Res); bool ParseOptionalCallingConv(unsigned &CC); - bool ParseOptionalAlignment(unsigned &Alignment); + bool ParseOptionalAlignment(MaybeAlign &Alignment); bool ParseOptionalDerefAttrBytes(lltok::Kind AttrKind, uint64_t &Bytes); bool ParseScopeAndOrdering(bool isAtomic, SyncScope::ID &SSID, AtomicOrdering &Ordering); bool ParseScope(SyncScope::ID &SSID); bool ParseOrdering(AtomicOrdering &Ordering); bool ParseOptionalStackAlignment(unsigned &Alignment); - bool ParseOptionalCommaAlign(unsigned &Alignment, bool &AteExtraComma); + bool ParseOptionalCommaAlign(MaybeAlign &Alignment, bool &AteExtraComma); bool ParseOptionalCommaAddrSpace(unsigned &AddrSpace, LocTy &Loc, bool &AteExtraComma); bool ParseOptionalCommaInAlloca(bool &IsInAlloca); diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -140,7 +140,7 @@ // If the alignment was parsed as an attribute, move to the alignment // field. if (FnAttrs.hasAlignmentAttr()) { - Fn->setAlignment(MaybeAlign(FnAttrs.getAlignment())); + Fn->setAlignment(FnAttrs.getAlignment()); FnAttrs.removeAttribute(Attribute::Alignment); } @@ -1122,9 +1122,9 @@ if (ParseToken(lltok::StringConstant, "expected partition string")) return true; } else if (Lex.getKind() == lltok::kw_align) { - unsigned Alignment; + MaybeAlign Alignment; if (ParseOptionalAlignment(Alignment)) return true; - GV->setAlignment(MaybeAlign(Alignment)); + GV->setAlignment(Alignment); } else if (Lex.getKind() == lltok::MetadataVar) { if (ParseGlobalObjectMetadataAttachment(*GV)) return true; @@ -1229,12 +1229,13 @@ // As a hack, we allow function alignment to be initially parsed as an // attribute on a function declaration/definition or added to an attribute // group and later moved to the alignment field. - unsigned Alignment; + MaybeAlign Alignment; if (inAttrGrp) { Lex.Lex(); - if (ParseToken(lltok::equal, "expected '=' here") || - ParseUInt32(Alignment)) + uint32_t Value = 0; + if (ParseToken(lltok::equal, "expected '=' here") || ParseUInt32(Value)) return true; + Alignment = Align(Value); } else { if (ParseOptionalAlignment(Alignment)) return true; @@ -1603,7 +1604,7 @@ continue; } case lltok::kw_align: { - unsigned Alignment; + MaybeAlign Alignment; if (ParseOptionalAlignment(Alignment)) return true; B.addAlignmentAttr(Alignment); @@ -1720,7 +1721,7 @@ continue; } case lltok::kw_align: { - unsigned Alignment; + MaybeAlign Alignment; if (ParseOptionalAlignment(Alignment)) return true; B.addAlignmentAttr(Alignment); @@ -2069,16 +2070,19 @@ /// ParseOptionalAlignment /// ::= /* empty */ /// ::= 'align' 4 -bool LLParser::ParseOptionalAlignment(unsigned &Alignment) { - Alignment = 0; +bool LLParser::ParseOptionalAlignment(MaybeAlign &Alignment) { + Alignment = None; if (!EatIfPresent(lltok::kw_align)) return false; LocTy AlignLoc = Lex.getLoc(); - if (ParseUInt32(Alignment)) return true; - if (!isPowerOf2_32(Alignment)) + uint32_t Value = 0; + if (ParseUInt32(Value)) + return true; + if (!isPowerOf2_32(Value)) return Error(AlignLoc, "alignment is not a power of two"); - if (Alignment > Value::MaximumAlignment) + if (Value > Value::MaximumAlignment) return Error(AlignLoc, "huge alignments are not supported yet"); + Alignment = Align(Value); return false; } @@ -2115,7 +2119,7 @@ /// /// This returns with AteExtraComma set to true if it ate an excess comma at the /// end. -bool LLParser::ParseOptionalCommaAlign(unsigned &Alignment, +bool LLParser::ParseOptionalCommaAlign(MaybeAlign &Alignment, bool &AteExtraComma) { AteExtraComma = false; while (EatIfPresent(lltok::comma)) { @@ -5370,7 +5374,7 @@ LocTy BuiltinLoc; std::string Section; std::string Partition; - unsigned Alignment; + MaybeAlign Alignment; std::string GC; GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::UnnamedAddr::None; unsigned AddrSpace = 0; @@ -6865,7 +6869,7 @@ int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) { Value *Size = nullptr; LocTy SizeLoc, TyLoc, ASLoc; - unsigned Alignment = 0; + MaybeAlign Alignment; unsigned AddrSpace = 0; Type *Ty = nullptr; @@ -6913,7 +6917,8 @@ if (Size && !Size->getType()->isIntegerTy()) return Error(SizeLoc, "element count must have integer type"); - AllocaInst *AI = new AllocaInst(Ty, AddrSpace, Size, Alignment); + AllocaInst *AI = + new AllocaInst(Ty, AddrSpace, Size, Alignment ? Alignment->value() : 0); AI->setUsedWithInAlloca(IsInAlloca); AI->setSwiftError(IsSwiftError); Inst = AI; @@ -6926,7 +6931,7 @@ /// 'singlethread'? AtomicOrdering (',' 'align' i32)? int LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS) { Value *Val; LocTy Loc; - unsigned Alignment = 0; + MaybeAlign Alignment; bool AteExtraComma = false; bool isAtomic = false; AtomicOrdering Ordering = AtomicOrdering::NotAtomic; @@ -6964,7 +6969,8 @@ return Error(ExplicitTypeLoc, "explicit pointee type doesn't match operand's pointee type"); - Inst = new LoadInst(Ty, Val, "", isVolatile, Alignment, Ordering, SSID); + Inst = new LoadInst(Ty, Val, "", isVolatile, + Alignment ? Alignment->value() : 0, Ordering, SSID); return AteExtraComma ? InstExtraComma : InstNormal; } @@ -6975,7 +6981,7 @@ /// 'singlethread'? AtomicOrdering (',' 'align' i32)? int LLParser::ParseStore(Instruction *&Inst, PerFunctionState &PFS) { Value *Val, *Ptr; LocTy Loc, PtrLoc; - unsigned Alignment = 0; + MaybeAlign Alignment; bool AteExtraComma = false; bool isAtomic = false; AtomicOrdering Ordering = AtomicOrdering::NotAtomic; @@ -7011,7 +7017,8 @@ Ordering == AtomicOrdering::AcquireRelease) return Error(Loc, "atomic store cannot use Acquire ordering"); - Inst = new StoreInst(Val, Ptr, isVolatile, Alignment, Ordering, SSID); + Inst = new StoreInst(Val, Ptr, isVolatile, Alignment ? Alignment->value() : 0, + Ordering, SSID); return AteExtraComma ? InstExtraComma : InstNormal; } 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 @@ -779,10 +779,12 @@ Attr = Attribute::getWithByValType(C, B.getByValType()); break; case Attribute::Alignment: - Attr = Attribute::getWithAlignment(C, Align(B.getAlignment())); + assert(B.getAlignment() && "Alignment must be set"); + Attr = Attribute::getWithAlignment(C, *B.getAlignment()); break; case Attribute::StackAlignment: - Attr = Attribute::getWithStackAlignment(C, Align(B.getStackAlignment())); + assert(B.getStackAlignment() && "StackAlignment must be set"); + Attr = Attribute::getWithStackAlignment(C, *B.getStackAlignment()); break; case Attribute::Dereferenceable: Attr = Attribute::getWithDereferenceableBytes( @@ -1162,7 +1164,7 @@ // FIXME it is not obvious how this should work for alignment. For now, say // we can't change a known alignment. const MaybeAlign OldAlign = getAttributes(Index).getAlignment(); - unsigned NewAlign = B.getAlignment(); + const MaybeAlign NewAlign = B.getAlignment(); assert((!OldAlign || !NewAlign || OldAlign == NewAlign) && "Attempt to change alignment!"); #endif @@ -1460,9 +1462,9 @@ Attrs[Kind] = true; if (Kind == Attribute::Alignment) - Alignment = MaybeAlign(Attr.getAlignment()); + Alignment = Attr.getAlignment(); else if (Kind == Attribute::StackAlignment) - StackAlignment = MaybeAlign(Attr.getStackAlignment()); + StackAlignment = Attr.getStackAlignment(); else if (Kind == Attribute::ByVal) ByValType = Attr.getValueAsType(); else if (Kind == Attribute::Dereferenceable)