diff options
Diffstat (limited to 'llvm/lib/IR/DataLayout.cpp')
| -rw-r--r-- | llvm/lib/IR/DataLayout.cpp | 41 |
1 files changed, 34 insertions, 7 deletions
diff --git a/llvm/lib/IR/DataLayout.cpp b/llvm/lib/IR/DataLayout.cpp index 49e1f898ca59..86573c8e0942 100644 --- a/llvm/lib/IR/DataLayout.cpp +++ b/llvm/lib/IR/DataLayout.cpp @@ -193,9 +193,12 @@ constexpr DataLayout::PrimitiveSpec DefaultVectorSpecs[] = { }; // Default pointer type specifications. -constexpr DataLayout::PointerSpec DefaultPointerSpecs[] = { +const DataLayout::PointerSpec DefaultPointerSpecs[] = { // p0:64:64:64:64 - {0, 64, Align::Constant<8>(), Align::Constant<8>(), 64, false, false}, + {/*AddrSpace=*/0, /*BitWidth=*/64, /*ABIAlign=*/Align::Constant<8>(), + /*PrefAlign=*/Align::Constant<8>(), /*IndexBitWidth=*/64, + /*NullPtrValue=*/APInt(64, 0), /*HasUnstableRepr=*/false, + /*HasExternalState=*/false}, }; DataLayout::DataLayout() @@ -408,6 +411,15 @@ Error DataLayout::parsePointerSpec(StringRef Spec) { unsigned AddrSpace = 0; bool ExternalState = false; bool UnstableRepr = false; + // Default nullptr value kind is all-zeros, which is same as the previous + // behavior. + enum { + AllZeros, + AllOnes, + // The nullptr value is neither all-zeros nor all-ones. LLVM doesn't accept + // arbitrary bit patterns, so it will not be able to fold nullptr. + Custom + } NullPtrValueKind = AllZeros; StringRef AddrSpaceStr = Components[0]; while (!AddrSpaceStr.empty()) { char C = AddrSpaceStr.front(); @@ -415,6 +427,12 @@ Error DataLayout::parsePointerSpec(StringRef Spec) { ExternalState = true; } else if (C == 'u') { UnstableRepr = true; + } else if (C == 'z') { + NullPtrValueKind = AllZeros; + } else if (C == 'o') { + NullPtrValueKind = AllOnes; + } else if (C == 'c') { + NullPtrValueKind = Custom; } else if (isAlpha(C)) { return createStringError("'%c' is not a valid pointer specification flag", C); @@ -461,8 +479,14 @@ Error DataLayout::parsePointerSpec(StringRef Spec) { return createStringError( "index size cannot be larger than the pointer size"); + std::optional<APInt> NullPtrValue; + if (NullPtrValueKind == AllZeros) + NullPtrValue = APInt::getZero(BitWidth); + else if (NullPtrValueKind == AllOnes) + NullPtrValue = APInt::getAllOnes(BitWidth); + setPointerSpec(AddrSpace, BitWidth, ABIAlign, PrefAlign, IndexBitWidth, - UnstableRepr, ExternalState); + NullPtrValue, UnstableRepr, ExternalState); return Error::success(); } @@ -638,6 +662,7 @@ Error DataLayout::parseLayoutString(StringRef LayoutString) { // the spec for AS0, and we then update that to mark it non-integral. const PointerSpec &PS = getPointerSpec(AS); setPointerSpec(AS, PS.BitWidth, PS.ABIAlign, PS.PrefAlign, PS.IndexBitWidth, + PS.NullPtrValue, /*HasUnstableRepr=*/true, /*HasExternalState=*/false); } @@ -686,18 +711,20 @@ DataLayout::getPointerSpec(uint32_t AddrSpace) const { void DataLayout::setPointerSpec(uint32_t AddrSpace, uint32_t BitWidth, Align ABIAlign, Align PrefAlign, - uint32_t IndexBitWidth, bool HasUnstableRepr, - bool HasExternalState) { + uint32_t IndexBitWidth, + std::optional<APInt> NullPtrValue, + bool HasUnstableRepr, bool HasExternalState) { auto I = lower_bound(PointerSpecs, AddrSpace, LessPointerAddrSpace()); if (I == PointerSpecs.end() || I->AddrSpace != AddrSpace) { PointerSpecs.insert(I, PointerSpec{AddrSpace, BitWidth, ABIAlign, PrefAlign, - IndexBitWidth, HasUnstableRepr, - HasExternalState}); + IndexBitWidth, NullPtrValue, + HasUnstableRepr, HasExternalState}); } else { I->BitWidth = BitWidth; I->ABIAlign = ABIAlign; I->PrefAlign = PrefAlign; I->IndexBitWidth = IndexBitWidth; + I->NullPtrValue = NullPtrValue; I->HasUnstableRepresentation = HasUnstableRepr; I->HasExternalState = HasExternalState; } |
