summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR/DataLayout.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/IR/DataLayout.cpp')
-rw-r--r--llvm/lib/IR/DataLayout.cpp41
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;
}