Skip to content

Commit 86013ce

Browse files
committed
[WIP] Extend data layout to add non zero null value for address space
1 parent 3356818 commit 86013ce

8 files changed

+103
-0
lines changed

llvm/include/llvm/IR/DataLayout.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include "llvm/ADT/APInt.h"
2323
#include "llvm/ADT/ArrayRef.h"
24+
#include "llvm/ADT/DenseMap.h"
2425
#include "llvm/ADT/STLExtras.h"
2526
#include "llvm/ADT/SmallVector.h"
2627
#include "llvm/ADT/StringRef.h"
@@ -164,6 +165,8 @@ class DataLayout {
164165
/// well-defined bitwise representation.
165166
SmallVector<unsigned, 8> NonIntegralAddressSpaces;
166167

168+
DenseMap<unsigned, int64_t> AddrSpaceToNonZeroValueMap;
169+
167170
/// Attempts to set the alignment of the given type. Returns an error
168171
/// description on failure.
169172
Error setAlignment(AlignTypeEnum AlignType, Align ABIAlign, Align PrefAlign,
@@ -299,6 +302,17 @@ class DataLayout {
299302
return ManglingMode == MM_WinCOFFX86;
300303
}
301304

305+
int64_t getNullPointerValue(unsigned AddrSpace) {
306+
auto It = AddrSpaceToNonZeroValueMap.find(AddrSpace);
307+
if (It == AddrSpaceToNonZeroValueMap.end())
308+
return 0;
309+
return It->second;
310+
}
311+
312+
void setNullPointerValue(unsigned AddrSpace, int64_t Value) {
313+
AddrSpaceToNonZeroValueMap[AddrSpace] = Value;
314+
}
315+
302316
/// Returns true if symbols with leading question marks should not receive IR
303317
/// mangling. True for Windows mangling modes.
304318
bool doNotMangleLeadingQuestionMark() const {

llvm/lib/IR/DataLayout.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,8 @@ void DataLayout::reset(StringRef Desc) {
216216
if (Error Err = setPointerAlignmentInBits(0, Align(8), Align(8), 64, 64))
217217
return report_fatal_error(std::move(Err));
218218

219+
setNullPointerValue(INT_MAX, 0);
220+
219221
if (Error Err = parseSpecifier(Desc))
220222
return report_fatal_error(std::move(Err));
221223
}
@@ -251,6 +253,22 @@ template <typename IntTy> static Error getInt(StringRef R, IntTy &Result) {
251253
return Error::success();
252254
}
253255

256+
template <typename IntTy>
257+
static Error getIntForAddrSpace(StringRef R, IntTy &Result) {
258+
if (R.starts_with("neg")) {
259+
StringRef AfterNeg = R.slice(3, R.size());
260+
bool error = AfterNeg.getAsInteger(10, Result);
261+
(void)error;
262+
if (error || Result <= 0)
263+
return reportError("not a number, or does not fit in an unsigned int");
264+
Result *= -1;
265+
return Error::success();
266+
} else if (R.contains("neg"))
267+
return reportError("not a valid value for address space");
268+
else
269+
return getInt<IntTy>(R, Result);
270+
}
271+
254272
/// Get an unsigned integer representing the number of bits and convert it into
255273
/// bytes. Error out of not a byte width multiple.
256274
template <typename IntTy>
@@ -502,6 +520,32 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
502520
return Err;
503521
break;
504522
}
523+
case 'z': {
524+
unsigned AddrSpace = 0;
525+
int64_t Value;
526+
// for unlisted address spaces e.g., z:0
527+
if (Tok.empty()) {
528+
if (Error Err = getIntForAddrSpace(Rest, Value))
529+
return Err;
530+
setNullPointerValue(INT_MAX, Value);
531+
break;
532+
} else {
533+
if (Error Err = getInt(Tok, AddrSpace))
534+
return Err;
535+
if (!isUInt<24>(AddrSpace))
536+
return reportError("Invalid address space, must be a 24-bit integer");
537+
}
538+
if (Rest.empty())
539+
return reportError(
540+
"Missing address space value specification for pointer in "
541+
"datalayout string");
542+
if (Error Err = ::split(Rest, ':', Split))
543+
return Err;
544+
if (Error Err = getIntForAddrSpace(Tok, Value))
545+
return Err;
546+
setNullPointerValue(AddrSpace, Value);
547+
break;
548+
}
505549
case 'G': { // Default address space for global variables.
506550
if (Error Err = getAddrSpace(Tok, DefaultGlobalsAddrSpace))
507551
return Err;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
; RUN: not llvm-as %s 2>&1 | FileCheck %s
2+
3+
; CHECK: error: not a number, or does not fit in an unsigned int
4+
5+
target datalayout = "z:neg"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
; RUN: not llvm-as %s 2>&1 | FileCheck %s
2+
3+
; CHECK: error: not a number, or does not fit in an unsigned int
4+
5+
target datalayout = "z:neg-1"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
; RUN: not llvm-as %s 2>&1 | FileCheck %s
2+
3+
; CHECK: error: Trailing separator in datalayout string
4+
5+
target datalayout = "z:"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
; RUN: not llvm-as %s 2>&1 | FileCheck %s
2+
3+
; CHECK: error: Trailing separator in datalayout string
4+
5+
target datalayout = "z:-1"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
; RUN: not llvm-as %s 2>&1 | FileCheck %s
2+
3+
; CHECK: error: not a number, or does not fit in an unsigned int
4+
5+
target datalayout = "za:0"
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2+
; RUN: opt < %s -S -mtriple=amdgcn-- | FileCheck %s
3+
4+
; 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-z:0-z2:neg1-z3:neg1-z5:neg1-S32-A5-G1-ni:7:8:9"
5+
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-z:0-z2:neg1-z3:neg1-z5:neg1-S32-A5-G1-ni:7:8:9"
6+
@lds = addrspace(3) global [8 x i32] [i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8]
7+
8+
define amdgpu_kernel void @load_init_lds_global(ptr addrspace(1) %out, i1 %p) {
9+
; CHECK-LABEL: define amdgpu_kernel void @load_init_lds_global(
10+
; CHECK-SAME: ptr addrspace(1) [[OUT:%.*]], i1 [[P:%.*]]) {
11+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr [8 x i32], ptr addrspace(3) @lds, i32 0, i32 10
12+
; CHECK-NEXT: [[LD:%.*]] = load i32, ptr addrspace(3) [[GEP]], align 4
13+
; CHECK-NEXT: store i32 [[LD]], ptr addrspace(1) [[OUT]], align 4
14+
; CHECK-NEXT: ret void
15+
;
16+
%gep = getelementptr [8 x i32], ptr addrspace(3) @lds, i32 0, i32 10
17+
%ld = load i32, ptr addrspace(3) %gep
18+
store i32 %ld, ptr addrspace(1) %out
19+
ret void
20+
}

0 commit comments

Comments
 (0)