Skip to content

[DataLayout] Introduce sentinel pointer value #131557

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions clang/lib/Basic/Targets/AMDGPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ static const char *const DataLayoutStringR600 =
"-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1";

static const char *const DataLayoutStringAMDGCN =
"e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32"
"-p7:160:256:256:32-p8:128:128-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:"
"32-v48:64-v96:128"
"e-p:64:64-p1:64:64-p2:32:32:32:32:f-p3:32:32:32:32:f-p4:64:64"
"-p5:32:32:32:32:f-p6:32:32-p7:160:256:256:32-p8:128:128-p9:192:256:256:32"
"-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128"
"-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1"
"-ni:7:8:9";

Expand Down
4 changes: 2 additions & 2 deletions clang/test/CodeGen/target-data.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,12 +176,12 @@

// RUN: %clang_cc1 -triple amdgcn-unknown -target-cpu hawaii -o - -emit-llvm %s \
// RUN: | FileCheck %s -check-prefix=R600SI
// R600SI: target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9"
// R600SI: target datalayout = "e-p:64:64-p1:64:64-p2:32:32:32:32:f-p3:32:32:32:32:f-p4:64:64-p5:32:32:32:32:f-p6:32:32-p7:160:256:256:32-p8:128:128-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9"

// Test default -target-cpu
// RUN: %clang_cc1 -triple amdgcn-unknown -o - -emit-llvm %s \
// RUN: | FileCheck %s -check-prefix=R600SIDefault
// R600SIDefault: target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9"
// R600SIDefault: target datalayout = "e-p:64:64-p1:64:64-p2:32:32:32:32:f-p3:32:32:32:32:f-p4:64:64-p5:32:32:32:32:f-p6:32:32-p7:160:256:256:32-p8:128:128-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9"

// RUN: %clang_cc1 -triple arm64-unknown -o - -emit-llvm %s | \
// RUN: FileCheck %s -check-prefix=AARCH64
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenOpenCL/amdgpu-env-amdgcn.cl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 %s -O0 -triple amdgcn -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 %s -O0 -triple amdgcn---opencl -emit-llvm -o - | FileCheck %s

// CHECK: target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9"
// CHECK: target datalayout = "e-p:64:64-p1:64:64-p2:32:32:32:32:f-p3:32:32:32:32:f-p4:64:64-p5:32:32:32:32:f-p6:32:32-p7:160:256:256:32-p8:128:128-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9"
void foo(void) {}
6 changes: 3 additions & 3 deletions lld/test/ELF/lto/amdgcn-oses.ll
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

;--- amdhsa.ll
target triple = "amdgcn-amd-amdhsa"
target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5"
target datalayout = "e-p:64:64-p1:64:64-p2:32:32:32:32:f-p3:32:32:32:32:f-p4:64:64-p5:32:32:32:32:f-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5"

!llvm.module.flags = !{!0}
!0 = !{i32 1, !"amdhsa_code_object_version", i32 500}
Expand All @@ -36,15 +36,15 @@ define void @_start() {

;--- amdpal.ll
target triple = "amdgcn-amd-amdpal"
target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5"
target datalayout = "e-p:64:64-p1:64:64-p2:32:32:32:32:f-p3:32:32:32:32:f-p4:64:64-p5:32:32:32:32:f-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5"

define amdgpu_cs void @_start() {
ret void
}

;--- mesa3d.ll
target triple = "amdgcn-amd-mesa3d"
target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5"
target datalayout = "e-p:64:64-p1:64:64-p2:32:32:32:32:f-p3:32:32:32:32:f-p4:64:64-p5:32:32:32:32:f-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5"

define void @_start() {
ret void
Expand Down
2 changes: 1 addition & 1 deletion lld/test/ELF/lto/amdgcn.ll
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
; Make sure the amdgcn triple is handled

target triple = "amdgcn-amd-amdhsa"
target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5"
target datalayout = "e-p:64:64-p1:64:64-p2:32:32:32:32:f-p3:32:32:32:32:f-p4:64:64-p5:32:32:32:32:f-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5"

define void @_start() {
ret void
Expand Down
7 changes: 5 additions & 2 deletions llvm/docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3134,7 +3134,7 @@ as follows:
``A<address space>``
Specifies the address space of objects created by '``alloca``'.
Defaults to the default address space of 0.
``p[n]:<size>:<abi>[:<pref>][:<idx>]``
``p[<n>]:<size>:<abi>[:<pref>[:<idx>[:<sentinel>]]]``
This specifies the *size* of a pointer and its ``<abi>`` and
``<pref>``\erred alignments for address space ``n``. ``<pref>`` is optional
and defaults to ``<abi>``. The fourth parameter ``<idx>`` is the size of the
Expand All @@ -3143,7 +3143,10 @@ as follows:
specified, the default index size is equal to the pointer size. All sizes
are in bits. The address space, ``n``, is optional, and if not specified,
denotes the default address space 0. The value of ``n`` must be
in the range [1,2^24).
in the range [1,2^24). The fifth parameter ``<sentinel>`` specifies the
sentinel value of the pointer for the corresponding address space. It
currently accepts two values: ``z`` for an all-zero value and ``f`` for a
full-bit set value. The default sentinel pointer value is all-zero.
``i<size>:<abi>[:<pref>]``
This specifies the alignment for an integer type of a given bit
``<size>``. The value of ``<size>`` must be in the range [1,2^24).
Expand Down
8 changes: 7 additions & 1 deletion llvm/include/llvm/IR/DataLayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ class DataLayout {
Align ABIAlign;
Align PrefAlign;
uint32_t IndexBitWidth;
APInt SentinelValue;
/// Pointers in this address space don't have a well-defined bitwise
/// representation (e.g. may be relocated by a copying garbage collector).
/// Additionally, they may also be non-integral (i.e. containing additional
Expand Down Expand Up @@ -148,7 +149,7 @@ class DataLayout {
/// Sets or updates the specification for pointer in the given address space.
void setPointerSpec(uint32_t AddrSpace, uint32_t BitWidth, Align ABIAlign,
Align PrefAlign, uint32_t IndexBitWidth,
bool IsNonIntegral);
APInt SentinelValue, bool IsNonIntegral);

/// Internal helper to get alignment for integer of given bitwidth.
Align getIntegerAlignment(uint32_t BitWidth, bool abi_or_pref) const;
Expand Down Expand Up @@ -552,6 +553,11 @@ class DataLayout {
///
/// This includes an explicitly requested alignment (if the global has one).
Align getPreferredAlign(const GlobalVariable *GV) const;

/// Returns the sentinel pointer value for a given address space. If the
/// address space is invalid, it defaults to the sentinel pointer value of
/// address space 0, aligning with the behavior of \p getPointerSpec.
APInt getSentinelPointerValue(unsigned AS) const;
};

inline DataLayout *unwrap(LLVMTargetDataRef P) {
Expand Down
55 changes: 45 additions & 10 deletions llvm/lib/IR/DataLayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ bool DataLayout::PointerSpec::operator==(const PointerSpec &Other) const {
return AddrSpace == Other.AddrSpace && BitWidth == Other.BitWidth &&
ABIAlign == Other.ABIAlign && PrefAlign == Other.PrefAlign &&
IndexBitWidth == Other.IndexBitWidth &&
SentinelValue == Other.SentinelValue &&
IsNonIntegral == Other.IsNonIntegral;
}

Expand Down Expand Up @@ -206,9 +207,10 @@ constexpr DataLayout::PrimitiveSpec DefaultVectorSpecs[] = {
};

// Default pointer type specifications.
constexpr DataLayout::PointerSpec DefaultPointerSpecs[] = {
// p0:64:64:64:64
{0, 64, Align::Constant<8>(), Align::Constant<8>(), 64, false},
const DataLayout::PointerSpec DefaultPointerSpecs[] = {
// p0:64:64:64:64:0
{0, 64, Align::Constant<8>(), Align::Constant<8>(), 64, APInt(64, 0),
false},
};

DataLayout::DataLayout()
Expand Down Expand Up @@ -296,6 +298,22 @@ static Error parseSize(StringRef Str, unsigned &BitWidth,
return Error::success();
}

static Error parseSentinelValue(StringRef Str, APInt &V) {
if (Str.empty())
return createStringError("sentinel value component cannot be empty");
if (Str.size() != 1)
return createStringError("sentinel value component must be a 'z' or 'f'");
if (Str[0] == 'z') {
V.clearAllBits();
return Error::success();
}
if (Str[0] == 'f') {
V.setAllBits();
return Error::success();
}
return createStringError("sentinel value component must be a 'z' or 'f'");
}

/// Attempts to parse an alignment component of a specification.
///
/// On success, returns the value converted to byte amount in \p Alignment.
Expand Down Expand Up @@ -409,13 +427,14 @@ Error DataLayout::parseAggregateSpec(StringRef Spec) {
}

Error DataLayout::parsePointerSpec(StringRef Spec) {
// p[<n>]:<size>:<abi>[:<pref>[:<idx>]]
// p[<n>]:<size>:<abi>[:<pref>[:<idx>[:<sentinel>]]]
SmallVector<StringRef, 5> Components;
assert(Spec.front() == 'p');
Spec.drop_front().split(Components, ':');

if (Components.size() < 3 || Components.size() > 5)
return createSpecFormatError("p[<n>]:<size>:<abi>[:<pref>[:<idx>]]");
if (Components.size() < 3 || Components.size() > 6)
return createSpecFormatError(
"p[<n>]:<size>:<abi>[:<pref>[:<idx>[:<sentinel>]]]");

// Address space. Optional, defaults to 0.
unsigned AddrSpace = 0;
Expand Down Expand Up @@ -454,8 +473,14 @@ Error DataLayout::parsePointerSpec(StringRef Spec) {
return createStringError(
"index size cannot be larger than the pointer size");

APInt SentinelValue(BitWidth, 0);
if (Components.size() > 5) {
if (Error Err = parseSentinelValue(Components[5], SentinelValue))
return Err;
}

setPointerSpec(AddrSpace, BitWidth, ABIAlign, PrefAlign, IndexBitWidth,
false);
SentinelValue, /*IsNonIntegral=*/false);
return Error::success();
}

Expand Down Expand Up @@ -631,7 +656,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,
true);
PS.SentinelValue, /*IsNonIntegral=*/true);
}

return Error::success();
Expand Down Expand Up @@ -679,16 +704,19 @@ DataLayout::getPointerSpec(uint32_t AddrSpace) const {

void DataLayout::setPointerSpec(uint32_t AddrSpace, uint32_t BitWidth,
Align ABIAlign, Align PrefAlign,
uint32_t IndexBitWidth, bool IsNonIntegral) {
uint32_t IndexBitWidth, APInt SentinelValue,
bool IsNonIntegral) {
auto I = lower_bound(PointerSpecs, AddrSpace, LessPointerAddrSpace());
if (I == PointerSpecs.end() || I->AddrSpace != AddrSpace) {
PointerSpecs.insert(I, PointerSpec{AddrSpace, BitWidth, ABIAlign, PrefAlign,
IndexBitWidth, IsNonIntegral});
IndexBitWidth, SentinelValue,
IsNonIntegral});
} else {
I->BitWidth = BitWidth;
I->ABIAlign = ABIAlign;
I->PrefAlign = PrefAlign;
I->IndexBitWidth = IndexBitWidth;
I->SentinelValue = SentinelValue;
I->IsNonIntegral = IsNonIntegral;
}
}
Expand Down Expand Up @@ -1020,3 +1048,10 @@ Align DataLayout::getPreferredAlign(const GlobalVariable *GV) const {
}
return Alignment;
}

APInt DataLayout::getSentinelPointerValue(unsigned AS) const {
auto I = lower_bound(PointerSpecs, AS, LessPointerAddrSpace());
if (I != PointerSpecs.end() || I->AddrSpace == AS)
return I->SentinelValue;
return PointerSpecs[0].SentinelValue;
}
10 changes: 5 additions & 5 deletions llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -677,11 +677,11 @@ static StringRef computeDataLayout(const Triple &TT) {
// (address space 7), and 128-bit non-integral buffer resourcees (address
// space 8) which cannot be non-trivilally accessed by LLVM memory operations
// like getelementptr.
return "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32"
"-p7:160:256:256:32-p8:128:128-p9:192:256:256:32-i64:64-v16:16-v24:32-"
"v32:32-v48:64-v96:"
"128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-"
"G1-ni:7:8:9";
return "e-p:64:64-p1:64:64-p2:32:32:32:32:f-p3:32:32:32:32:f-p4:64:64"
"-p5:32:32:32:32:f-p6:32:32-p7:160:256:256:32-p8:128:128"
"-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128"
"-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1"
"-ni:7:8:9";
}

LLVM_READNONE
Expand Down
20 changes: 17 additions & 3 deletions llvm/unittests/IR/DataLayoutTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,11 +313,12 @@ TEST(DataLayout, ParsePointerSpec) {
EXPECT_THAT_EXPECTED(DataLayout::parse(Str), Succeeded());

for (StringRef Str :
{"p", "p0", "p:32", "p0:32", "p:32:32:32:32:32", "p0:32:32:32:32:32"})
{"p", "p0", "p:32", "p0:32", "p:32:32:32:32:32:0", "p0:32:32:32:32:32:0"})
EXPECT_THAT_EXPECTED(
DataLayout::parse(Str),
FailedWithMessage("malformed specification, must be of the form "
"\"p[<n>]:<size>:<abi>[:<pref>[:<idx>]]\""));
FailedWithMessage(
"malformed specification, must be of the form "
"\"p[<n>]:<size>:<abi>[:<pref>[:<idx>[:<sentinel>]]]\""));

// address space
for (StringRef Str : {"p0x0:32:32", "px:32:32:32", "p16777216:32:32:32:32"})
Expand Down Expand Up @@ -401,6 +402,19 @@ TEST(DataLayout, ParsePointerSpec) {
EXPECT_THAT_EXPECTED(
DataLayout::parse(Str),
FailedWithMessage("index size cannot be larger than the pointer size"));

// sentinel value
for (StringRef Str :
{"p:32:32:32:32:a", "p0:32:32:32:32:ab", "p42:32:32:32:32:123"})
EXPECT_THAT_EXPECTED(
DataLayout::parse(Str),
FailedWithMessage("sentinel value component must be a 'z' or 'f'"));

for (StringRef Str :
{"p:32:32:32:32:", "p0:32:32:32:32:", "p42:32:32:32:32:"})
EXPECT_THAT_EXPECTED(
DataLayout::parse(Str),
FailedWithMessage("sentinel value component cannot be empty"));
}

TEST(DataLayoutTest, ParseNativeIntegersSpec) {
Expand Down
Loading