diff --git a/llvm/include/llvm/IR/DataLayout.h b/llvm/include/llvm/IR/DataLayout.h index 56fc749838ef9..a2106dd7c4dd0 100644 --- a/llvm/include/llvm/IR/DataLayout.h +++ b/llvm/include/llvm/IR/DataLayout.h @@ -398,6 +398,16 @@ class DataLayout { PS.HasExternalState; } + /// Return the bit value of the null pointer for the given address space. + std::optional getNullPointerValue(unsigned AS) const { + // Address space zero is currently defined to always have an all-zero null + // pointer representation, the others are target-specific and will require a + // data layout property (work-in-progress). + if (AS == 0) + return APInt::getZero(getPointerSizeInBits(AS)); + return std::nullopt; + } + /// Returns whether this address space has an "unstable" pointer /// representation. The bitwise pattern of such pointers is allowed to change /// in a target-specific way. For example, this could be used for copying diff --git a/llvm/unittests/IR/DataLayoutTest.cpp b/llvm/unittests/IR/DataLayoutTest.cpp index 9ca88141ca0eb..d82e31c6dca6c 100644 --- a/llvm/unittests/IR/DataLayoutTest.cpp +++ b/llvm/unittests/IR/DataLayoutTest.cpp @@ -700,6 +700,15 @@ TEST(DataLayout, NonIntegralHelpers) { } } +TEST(DataLayoutTest, GetNullPointerValue) { + EXPECT_EQ(DataLayout("").getNullPointerValue(0), APInt::getZero(64)); + EXPECT_EQ(DataLayout("").getNullPointerValue(1), std::nullopt); + EXPECT_EQ(DataLayout("p:32:32").getNullPointerValue(0), APInt::getZero(32)); + EXPECT_EQ(DataLayout("p:32:32").getNullPointerValue(1), std::nullopt); + EXPECT_EQ(DataLayout("p:64:64").getNullPointerValue(0), APInt::getZero(64)); + EXPECT_EQ(DataLayout("p:64:64").getNullPointerValue(1), std::nullopt); +} + TEST(DataLayoutTest, CopyAssignmentInvalidatesStructLayout) { DataLayout DL1 = cantFail(DataLayout::parse("p:32:32")); DataLayout DL2 = cantFail(DataLayout::parse("p:64:64"));