diff --git a/llvm/include/llvm/IR/GlobalObject.h b/llvm/include/llvm/IR/GlobalObject.h --- a/llvm/include/llvm/IR/GlobalObject.h +++ b/llvm/include/llvm/IR/GlobalObject.h @@ -17,6 +17,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/IR/GlobalValue.h" #include "llvm/IR/Value.h" +#include "llvm/Support/Alignment.h" #include #include @@ -58,9 +59,13 @@ unsigned getAlignment() const { unsigned Data = getGlobalValueSubClassData(); unsigned AlignmentData = Data & AlignmentMask; - return (1u << AlignmentData) >> 1; + MaybeAlign Align = decodeMaybeAlign(AlignmentData); + return Align ? Align->value() : 0; } + + /// FIXME: Remove this setter once the migration to MaybeAlign is over. void setAlignment(unsigned Align); + void setAlignment(MaybeAlign Align); unsigned getGlobalObjectSubClassData() const { unsigned ValueData = getGlobalValueSubClassData(); diff --git a/llvm/include/llvm/Support/Alignment.h b/llvm/include/llvm/Support/Alignment.h --- a/llvm/include/llvm/Support/Alignment.h +++ b/llvm/include/llvm/Support/Alignment.h @@ -101,7 +101,7 @@ explicit MaybeAlign(uint64_t Value) { assert((Value == 0 || llvm::isPowerOf2_64(Value)) && - "Alignment is not 0 or a power of 2"); + "Alignment is neither 0 nor a power of 2"); if (Value) emplace(Value); } diff --git a/llvm/lib/IR/Globals.cpp b/llvm/lib/IR/Globals.cpp --- a/llvm/lib/IR/Globals.cpp +++ b/llvm/lib/IR/Globals.cpp @@ -114,13 +114,17 @@ } void GlobalObject::setAlignment(unsigned Align) { - assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!"); - assert(Align <= MaximumAlignment && - "Alignment is greater than MaximumAlignment!"); - unsigned AlignmentData = Log2_32(Align) + 1; + setAlignment(MaybeAlign(Align)); +} + +void GlobalObject::setAlignment(MaybeAlign Align) { + assert(!Align || Align <= MaximumAlignment && + "Alignment is greater than MaximumAlignment!"); + unsigned AlignmentData = encode(Align); unsigned OldData = getGlobalValueSubClassData(); setGlobalValueSubClassData((OldData & ~AlignmentMask) | AlignmentData); - assert(getAlignment() == Align && "Alignment representation error!"); + assert(MaybeAlign(getAlignment()) == Align && + "Alignment representation error!"); } void GlobalObject::copyAttributesFrom(const GlobalObject *Src) { diff --git a/llvm/unittests/IR/ValueTest.cpp b/llvm/unittests/IR/ValueTest.cpp --- a/llvm/unittests/IR/ValueTest.cpp +++ b/llvm/unittests/IR/ValueTest.cpp @@ -99,7 +99,8 @@ Constant::getAllOnesValue(Int32Ty), "var", nullptr, GlobalVariable::NotThreadLocal, 1); - EXPECT_DEATH(Var->setAlignment(536870913U), "Alignment is not a power of 2"); + EXPECT_DEATH(Var->setAlignment(536870913U), + "Alignment is neither 0 nor a power of 2"); EXPECT_DEATH(Var->setAlignment(1073741824U), "Alignment is greater than MaximumAlignment"); } diff --git a/llvm/unittests/Support/AlignmentTest.cpp b/llvm/unittests/Support/AlignmentTest.cpp --- a/llvm/unittests/Support/AlignmentTest.cpp +++ b/llvm/unittests/Support/AlignmentTest.cpp @@ -256,7 +256,8 @@ EXPECT_DEATH((Align(0)), "Value must not be 0"); for (uint64_t Value : getNonPowerOfTwo()) { EXPECT_DEATH((Align(Value)), "Alignment is not a power of 2"); - EXPECT_DEATH((MaybeAlign(Value)), "Alignment is not 0 or a power of 2"); + EXPECT_DEATH((MaybeAlign(Value)), + "Alignment is neither 0 nor a power of 2"); } }