diff --git a/llvm/include/llvm/IR/DataLayout.h b/llvm/include/llvm/IR/DataLayout.h --- a/llvm/include/llvm/IR/DataLayout.h +++ b/llvm/include/llvm/IR/DataLayout.h @@ -92,14 +92,14 @@ struct PointerAlignElem { Align ABIAlign; Align PrefAlign; - uint32_t TypeByteWidth; + uint32_t TypeBitWidth; uint32_t AddressSpace; - uint32_t IndexWidth; + uint32_t IndexBitWidth; /// Initializer - static PointerAlignElem get(uint32_t AddressSpace, Align ABIAlign, - Align PrefAlign, uint32_t TypeByteWidth, - uint32_t IndexWidth); + static PointerAlignElem getInBits(uint32_t AddressSpace, Align ABIAlign, + Align PrefAlign, uint32_t TypeBitWidth, + uint32_t IndexBitWidth); bool operator==(const PointerAlignElem &rhs) const; }; @@ -180,8 +180,9 @@ /// Attempts to set the alignment of a pointer in the given address space. /// Returns an error description on failure. - Error setPointerAlignment(uint32_t AddrSpace, Align ABIAlign, Align PrefAlign, - uint32_t TypeByteWidth, uint32_t IndexWidth); + Error setPointerAlignmentInBits(uint32_t AddrSpace, Align ABIAlign, + Align PrefAlign, uint32_t TypeBitWidth, + uint32_t IndexBitWidth); /// Internal helper to get alignment for integer of given bitwidth. Align getIntegerAlignment(uint32_t BitWidth, bool abi_or_pref) const; @@ -372,7 +373,8 @@ /// the backends/clients are updated. Align getPointerPrefAlignment(unsigned AS = 0) const; - /// Layout pointer size + /// Layout pointer size in bytes, rounded up to a whole + /// number of bytes. /// FIXME: The defaults need to be removed once all of /// the backends/clients are updated. unsigned getPointerSize(unsigned AS = 0) const; @@ -380,7 +382,8 @@ /// Returns the maximum index size over all address spaces. unsigned getMaxIndexSize() const; - // Index size used for address calculation. + // Index size in bytes used for address calculation, + /// rounded up to a whole number of bytes. unsigned getIndexSize(unsigned AS) const; /// Return the address spaces containing non-integral pointers. Pointers in @@ -407,7 +410,7 @@ /// FIXME: The defaults need to be removed once all of /// the backends/clients are updated. unsigned getPointerSizeInBits(unsigned AS = 0) const { - return getPointerSize(AS) * 8; + return getPointerAlignElem(AS).TypeBitWidth; } /// Returns the maximum index size over all address spaces. @@ -417,7 +420,7 @@ /// Size in bits of index used for address calculation in getelementptr. unsigned getIndexSizeInBits(unsigned AS) const { - return getIndexSize(AS) * 8; + return getPointerAlignElem(AS).IndexBitWidth; } /// Layout pointer size, in bits, based on the type. If this function is @@ -470,7 +473,7 @@ /// For example, returns 5 for i36 and 10 for x86_fp80. TypeSize getTypeStoreSize(Type *Ty) const { TypeSize BaseSize = getTypeSizeInBits(Ty); - return { (BaseSize.getKnownMinSize() + 7) / 8, BaseSize.isScalable() }; + return {divideCeil(BaseSize.getKnownMinSize(), 8), BaseSize.isScalable()}; } /// Returns the maximum number of bits that may be overwritten by diff --git a/llvm/lib/IR/DataLayout.cpp b/llvm/lib/IR/DataLayout.cpp --- a/llvm/lib/IR/DataLayout.cpp +++ b/llvm/lib/IR/DataLayout.cpp @@ -124,26 +124,25 @@ // PointerAlignElem, PointerAlign support //===----------------------------------------------------------------------===// -PointerAlignElem PointerAlignElem::get(uint32_t AddressSpace, Align ABIAlign, - Align PrefAlign, uint32_t TypeByteWidth, - uint32_t IndexWidth) { +PointerAlignElem PointerAlignElem::getInBits(uint32_t AddressSpace, + Align ABIAlign, Align PrefAlign, + uint32_t TypeBitWidth, + uint32_t IndexBitWidth) { assert(ABIAlign <= PrefAlign && "Preferred alignment worse than ABI!"); PointerAlignElem retval; retval.AddressSpace = AddressSpace; retval.ABIAlign = ABIAlign; retval.PrefAlign = PrefAlign; - retval.TypeByteWidth = TypeByteWidth; - retval.IndexWidth = IndexWidth; + retval.TypeBitWidth = TypeBitWidth; + retval.IndexBitWidth = IndexBitWidth; return retval; } bool PointerAlignElem::operator==(const PointerAlignElem &rhs) const { - return (ABIAlign == rhs.ABIAlign - && AddressSpace == rhs.AddressSpace - && PrefAlign == rhs.PrefAlign - && TypeByteWidth == rhs.TypeByteWidth - && IndexWidth == rhs.IndexWidth); + return (ABIAlign == rhs.ABIAlign && AddressSpace == rhs.AddressSpace && + PrefAlign == rhs.PrefAlign && TypeBitWidth == rhs.TypeBitWidth && + IndexBitWidth == rhs.IndexBitWidth); } //===----------------------------------------------------------------------===// @@ -197,7 +196,7 @@ E.PrefAlign, E.TypeBitWidth)) return report_fatal_error(std::move(Err)); } - if (Error Err = setPointerAlignment(0, Align(8), Align(8), 8, 8)) + if (Error Err = setPointerAlignmentInBits(0, Align(8), Align(8), 64, 64)) return report_fatal_error(std::move(Err)); if (Error Err = parseSpecifier(Desc)) @@ -318,7 +317,7 @@ if (Error Err = ::split(Rest, ':', Split)) return Err; unsigned PointerMemSize; - if (Error Err = getIntInBytes(Tok, PointerMemSize)) + if (Error Err = getInt(Tok, PointerMemSize)) return Err; if (!PointerMemSize) return reportError("Invalid pointer size of 0 bytes"); @@ -354,13 +353,13 @@ if (!Rest.empty()) { if (Error Err = ::split(Rest, ':', Split)) return Err; - if (Error Err = getIntInBytes(Tok, IndexSize)) + if (Error Err = getInt(Tok, IndexSize)) return Err; if (!IndexSize) return reportError("Invalid index size of 0 bytes"); } } - if (Error Err = setPointerAlignment( + if (Error Err = setPointerAlignmentInBits( AddrSpace, assumeAligned(PointerABIAlign), assumeAligned(PointerPrefAlign), PointerMemSize, IndexSize)) return Err; @@ -603,9 +602,10 @@ return Pointers[0]; } -Error DataLayout::setPointerAlignment(uint32_t AddrSpace, Align ABIAlign, - Align PrefAlign, uint32_t TypeByteWidth, - uint32_t IndexWidth) { +Error DataLayout::setPointerAlignmentInBits(uint32_t AddrSpace, Align ABIAlign, + Align PrefAlign, + uint32_t TypeBitWidth, + uint32_t IndexBitWidth) { if (PrefAlign < ABIAlign) return reportError( "Preferred alignment cannot be less than the ABI alignment"); @@ -615,13 +615,14 @@ return A.AddressSpace < AddressSpace; }); if (I == Pointers.end() || I->AddressSpace != AddrSpace) { - Pointers.insert(I, PointerAlignElem::get(AddrSpace, ABIAlign, PrefAlign, - TypeByteWidth, IndexWidth)); + Pointers.insert(I, + PointerAlignElem::getInBits(AddrSpace, ABIAlign, PrefAlign, + TypeBitWidth, IndexBitWidth)); } else { I->ABIAlign = ABIAlign; I->PrefAlign = PrefAlign; - I->TypeByteWidth = TypeByteWidth; - I->IndexWidth = IndexWidth; + I->TypeBitWidth = TypeBitWidth; + I->IndexBitWidth = IndexBitWidth; } return Error::success(); } @@ -704,13 +705,14 @@ } unsigned DataLayout::getPointerSize(unsigned AS) const { - return getPointerAlignElem(AS).TypeByteWidth; + return divideCeil(getPointerAlignElem(AS).TypeBitWidth, 8); } unsigned DataLayout::getMaxIndexSize() const { unsigned MaxIndexSize = 0; for (auto &P : Pointers) - MaxIndexSize = std::max(MaxIndexSize, P.IndexWidth); + MaxIndexSize = + std::max(MaxIndexSize, (unsigned)divideCeil(P.TypeBitWidth, 8)); return MaxIndexSize; } @@ -723,7 +725,7 @@ } unsigned DataLayout::getIndexSize(unsigned AS) const { - return getPointerAlignElem(AS).IndexWidth; + return divideCeil(getPointerAlignElem(AS).IndexBitWidth, 8); } unsigned DataLayout::getIndexTypeSizeInBits(Type *Ty) const { diff --git a/llvm/test/Assembler/datalayout-anypointersize.ll b/llvm/test/Assembler/datalayout-anypointersize.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Assembler/datalayout-anypointersize.ll @@ -0,0 +1,3 @@ +; RUN: llvm-as < %s | llvm-dis | FileCheck %s +target datalayout = "p:52:64" +; CHECK: target datalayout = "p:52:64" \ No newline at end of file diff --git a/llvm/test/Assembler/invalid-datalayout7.ll b/llvm/test/Assembler/invalid-datalayout7.ll --- a/llvm/test/Assembler/invalid-datalayout7.ll +++ b/llvm/test/Assembler/invalid-datalayout7.ll @@ -1,3 +1,3 @@ ; RUN: not --crash llvm-as < %s 2>&1 | FileCheck %s -target datalayout = "p:52" +target datalayout = "p:48:52" ; CHECK: number of bits must be a byte width multiple