[llvm] [WIP] Extend data layout to add non zero null value for address space. (PR #83109)

Rana Pratap Reddy via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 14 03:30:56 PDT 2024


https://github.com/ranapratap55 updated https://github.com/llvm/llvm-project/pull/83109

>From 86013ce85cfbc9a63a9f7c1312437347e38dae89 Mon Sep 17 00:00:00 2001
From: Rana Pratap Reddy N <RanaPratapReddy.Nimmakayala at amd.com>
Date: Tue, 27 Feb 2024 13:07:00 +0530
Subject: [PATCH 1/4] [WIP] Extend data layout to add non zero null value for
 address space

---
 llvm/include/llvm/IR/DataLayout.h             | 14 ++++++
 llvm/lib/IR/DataLayout.cpp                    | 44 +++++++++++++++++++
 .../datalayout-invalid-address-space-value.ll |  5 +++
 ...datalayout-invalid-address-space-value1.ll |  5 +++
 ...datalayout-invalid-address-space-value2.ll |  5 +++
 ...datalayout-invalid-address-space-value3.ll |  5 +++
 .../datalayout-invalid-address-space.ll       |  5 +++
 .../AMDGPU/datalayout-non-zero-lds-value.ll   | 20 +++++++++
 8 files changed, 103 insertions(+)
 create mode 100644 llvm/test/Assembler/datalayout-invalid-address-space-value.ll
 create mode 100644 llvm/test/Assembler/datalayout-invalid-address-space-value1.ll
 create mode 100644 llvm/test/Assembler/datalayout-invalid-address-space-value2.ll
 create mode 100644 llvm/test/Assembler/datalayout-invalid-address-space-value3.ll
 create mode 100644 llvm/test/Assembler/datalayout-invalid-address-space.ll
 create mode 100644 llvm/test/CodeGen/AMDGPU/datalayout-non-zero-lds-value.ll

diff --git a/llvm/include/llvm/IR/DataLayout.h b/llvm/include/llvm/IR/DataLayout.h
index 71f7f51d8ee431..0d9b3890bb3246 100644
--- a/llvm/include/llvm/IR/DataLayout.h
+++ b/llvm/include/llvm/IR/DataLayout.h
@@ -21,6 +21,7 @@
 
 #include "llvm/ADT/APInt.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
@@ -164,6 +165,8 @@ class DataLayout {
   /// well-defined bitwise representation.
   SmallVector<unsigned, 8> NonIntegralAddressSpaces;
 
+  DenseMap<unsigned, int64_t> AddrSpaceToNonZeroValueMap;
+
   /// Attempts to set the alignment of the given type. Returns an error
   /// description on failure.
   Error setAlignment(AlignTypeEnum AlignType, Align ABIAlign, Align PrefAlign,
@@ -299,6 +302,17 @@ class DataLayout {
     return ManglingMode == MM_WinCOFFX86;
   }
 
+  int64_t getNullPointerValue(unsigned AddrSpace) {
+    auto It = AddrSpaceToNonZeroValueMap.find(AddrSpace);
+    if (It == AddrSpaceToNonZeroValueMap.end())
+      return 0;
+    return It->second;
+  }
+
+  void setNullPointerValue(unsigned AddrSpace, int64_t Value) {
+    AddrSpaceToNonZeroValueMap[AddrSpace] = Value;
+  }
+
   /// Returns true if symbols with leading question marks should not receive IR
   /// mangling. True for Windows mangling modes.
   bool doNotMangleLeadingQuestionMark() const {
diff --git a/llvm/lib/IR/DataLayout.cpp b/llvm/lib/IR/DataLayout.cpp
index a2f5714c706874..5c540cfc641ea6 100644
--- a/llvm/lib/IR/DataLayout.cpp
+++ b/llvm/lib/IR/DataLayout.cpp
@@ -216,6 +216,8 @@ void DataLayout::reset(StringRef Desc) {
   if (Error Err = setPointerAlignmentInBits(0, Align(8), Align(8), 64, 64))
     return report_fatal_error(std::move(Err));
 
+  setNullPointerValue(INT_MAX, 0);
+
   if (Error Err = parseSpecifier(Desc))
     return report_fatal_error(std::move(Err));
 }
@@ -251,6 +253,22 @@ template <typename IntTy> static Error getInt(StringRef R, IntTy &Result) {
   return Error::success();
 }
 
+template <typename IntTy>
+static Error getIntForAddrSpace(StringRef R, IntTy &Result) {
+  if (R.starts_with("neg")) {
+    StringRef AfterNeg = R.slice(3, R.size());
+    bool error = AfterNeg.getAsInteger(10, Result);
+    (void)error;
+    if (error || Result <= 0)
+      return reportError("not a number, or does not fit in an unsigned int");
+    Result *= -1;
+    return Error::success();
+  } else if (R.contains("neg"))
+    return reportError("not a valid value for address space");
+  else
+    return getInt<IntTy>(R, Result);
+}
+
 /// Get an unsigned integer representing the number of bits and convert it into
 /// bytes. Error out of not a byte width multiple.
 template <typename IntTy>
@@ -502,6 +520,32 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
         return Err;
       break;
     }
+    case 'z': {
+      unsigned AddrSpace = 0;
+      int64_t Value;
+      // for unlisted address spaces e.g., z:0
+      if (Tok.empty()) {
+        if (Error Err = getIntForAddrSpace(Rest, Value))
+          return Err;
+        setNullPointerValue(INT_MAX, Value);
+        break;
+      } else {
+        if (Error Err = getInt(Tok, AddrSpace))
+          return Err;
+        if (!isUInt<24>(AddrSpace))
+          return reportError("Invalid address space, must be a 24-bit integer");
+      }
+      if (Rest.empty())
+        return reportError(
+            "Missing address space value specification for pointer in "
+            "datalayout string");
+      if (Error Err = ::split(Rest, ':', Split))
+        return Err;
+      if (Error Err = getIntForAddrSpace(Tok, Value))
+        return Err;
+      setNullPointerValue(AddrSpace, Value);
+      break;
+    }
     case 'G': { // Default address space for global variables.
       if (Error Err = getAddrSpace(Tok, DefaultGlobalsAddrSpace))
         return Err;
diff --git a/llvm/test/Assembler/datalayout-invalid-address-space-value.ll b/llvm/test/Assembler/datalayout-invalid-address-space-value.ll
new file mode 100644
index 00000000000000..bf90b3078add85
--- /dev/null
+++ b/llvm/test/Assembler/datalayout-invalid-address-space-value.ll
@@ -0,0 +1,5 @@
+; RUN: not llvm-as %s 2>&1 | FileCheck %s
+
+; CHECK: error: not a number, or does not fit in an unsigned int
+
+target datalayout = "z:neg"
\ No newline at end of file
diff --git a/llvm/test/Assembler/datalayout-invalid-address-space-value1.ll b/llvm/test/Assembler/datalayout-invalid-address-space-value1.ll
new file mode 100644
index 00000000000000..3747af0b952f2e
--- /dev/null
+++ b/llvm/test/Assembler/datalayout-invalid-address-space-value1.ll
@@ -0,0 +1,5 @@
+; RUN: not llvm-as %s 2>&1 | FileCheck %s
+
+; CHECK: error: not a number, or does not fit in an unsigned int
+
+target datalayout = "z:neg-1"
\ No newline at end of file
diff --git a/llvm/test/Assembler/datalayout-invalid-address-space-value2.ll b/llvm/test/Assembler/datalayout-invalid-address-space-value2.ll
new file mode 100644
index 00000000000000..31160a599b2a34
--- /dev/null
+++ b/llvm/test/Assembler/datalayout-invalid-address-space-value2.ll
@@ -0,0 +1,5 @@
+; RUN: not llvm-as %s 2>&1 | FileCheck %s
+
+; CHECK: error: Trailing separator in datalayout string
+
+target datalayout = "z:"
\ No newline at end of file
diff --git a/llvm/test/Assembler/datalayout-invalid-address-space-value3.ll b/llvm/test/Assembler/datalayout-invalid-address-space-value3.ll
new file mode 100644
index 00000000000000..57106758fbd0ed
--- /dev/null
+++ b/llvm/test/Assembler/datalayout-invalid-address-space-value3.ll
@@ -0,0 +1,5 @@
+; RUN: not llvm-as %s 2>&1 | FileCheck %s
+
+; CHECK: error: Trailing separator in datalayout string
+
+target datalayout = "z:-1"
\ No newline at end of file
diff --git a/llvm/test/Assembler/datalayout-invalid-address-space.ll b/llvm/test/Assembler/datalayout-invalid-address-space.ll
new file mode 100644
index 00000000000000..78f8e7c6e97487
--- /dev/null
+++ b/llvm/test/Assembler/datalayout-invalid-address-space.ll
@@ -0,0 +1,5 @@
+; RUN: not llvm-as %s 2>&1 | FileCheck %s
+
+; CHECK: error: not a number, or does not fit in an unsigned int
+
+target datalayout = "za:0"
diff --git a/llvm/test/CodeGen/AMDGPU/datalayout-non-zero-lds-value.ll b/llvm/test/CodeGen/AMDGPU/datalayout-non-zero-lds-value.ll
new file mode 100644
index 00000000000000..c73128fed39619
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/datalayout-non-zero-lds-value.ll
@@ -0,0 +1,20 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
+; RUN: opt < %s -S -mtriple=amdgcn-- | 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-z:0-z2:neg1-z3:neg1-z5:neg1-S32-A5-G1-ni:7:8:9"
+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"
+ at lds = addrspace(3) global [8 x i32] [i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8]
+
+define amdgpu_kernel void @load_init_lds_global(ptr addrspace(1) %out, i1 %p) {
+; CHECK-LABEL: define amdgpu_kernel void @load_init_lds_global(
+; CHECK-SAME: ptr addrspace(1) [[OUT:%.*]], i1 [[P:%.*]]) {
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr [8 x i32], ptr addrspace(3) @lds, i32 0, i32 10
+; CHECK-NEXT:    [[LD:%.*]] = load i32, ptr addrspace(3) [[GEP]], align 4
+; CHECK-NEXT:    store i32 [[LD]], ptr addrspace(1) [[OUT]], align 4
+; CHECK-NEXT:    ret void
+;
+  %gep = getelementptr [8 x i32], ptr addrspace(3) @lds, i32 0, i32 10
+  %ld = load i32, ptr addrspace(3) %gep
+  store i32 %ld, ptr addrspace(1) %out
+  ret void
+}

>From 06e253bfbc40c8fabe9c664e3649a7dcf9d72d96 Mon Sep 17 00:00:00 2001
From: Rana Pratap Reddy N <RanaPratapReddy.Nimmakayala at amd.com>
Date: Thu, 14 Mar 2024 12:36:22 +0530
Subject: [PATCH 2/4] Added default null address space value specification in
 Data Layout string

---
 llvm/docs/LangRef.rst | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 570a058bde8daa..feb469c123837e 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -3044,6 +3044,14 @@ as follows:
     ``n32:64`` for PowerPC 64, or ``n8:16:32:64`` for X86-64. Elements of
     this set are considered to support most general arithmetic operations
     efficiently.
+``z[n]:<value>``
+    This specifies the default null value for an address space. ``n`` denotes
+    the address space number, and if not specified, it is considered to be
+    for the unlisted address space. For unlisted address space, the default
+    null value is ``0``. ``value`` denotes the default null value for an
+    address space ``n``. To represent negatives values, prefix ``neg`` is
+    added to ``value``. for e.g., ``z0:neg1`` represents for ``0`` address
+    space ``-1`` is the default null value.
 ``ni:<address space0>:<address space1>:<address space2>...``
     This specifies pointer types with the specified address spaces
     as :ref:`Non-Integral Pointer Type <nointptrtype>` s.  The ``0``
@@ -3076,6 +3084,7 @@ specifications are given in this list:
 -  ``v64:64:64`` - 64-bit vector is 64-bit aligned
 -  ``v128:128:128`` - 128-bit vector is 128-bit aligned
 -  ``a:0:64`` - aggregates are 64-bit aligned
+-  ``z:0`` - default null value of 0 for unlisted(INT_MAX) address space
 
 When LLVM is determining the alignment for a given type, it uses the
 following rules:

>From 468c19e95c44cc02d5b5a988821c3db48024b625 Mon Sep 17 00:00:00 2001
From: Rana Pratap Reddy N <RanaPratapReddy.Nimmakayala at amd.com>
Date: Thu, 14 Mar 2024 12:41:40 +0530
Subject: [PATCH 3/4] Renamed the function from Null to defaultNull

---
 llvm/include/llvm/IR/DataLayout.h | 4 ++--
 llvm/lib/IR/DataLayout.cpp        | 8 ++++----
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/llvm/include/llvm/IR/DataLayout.h b/llvm/include/llvm/IR/DataLayout.h
index 0d9b3890bb3246..e192a32a74aeaa 100644
--- a/llvm/include/llvm/IR/DataLayout.h
+++ b/llvm/include/llvm/IR/DataLayout.h
@@ -302,14 +302,14 @@ class DataLayout {
     return ManglingMode == MM_WinCOFFX86;
   }
 
-  int64_t getNullPointerValue(unsigned AddrSpace) {
+  int64_t getDefaultNullPointerValue(unsigned AddrSpace) {
     auto It = AddrSpaceToNonZeroValueMap.find(AddrSpace);
     if (It == AddrSpaceToNonZeroValueMap.end())
       return 0;
     return It->second;
   }
 
-  void setNullPointerValue(unsigned AddrSpace, int64_t Value) {
+  void setDefaultNullPointerValue(unsigned AddrSpace, int64_t Value) {
     AddrSpaceToNonZeroValueMap[AddrSpace] = Value;
   }
 
diff --git a/llvm/lib/IR/DataLayout.cpp b/llvm/lib/IR/DataLayout.cpp
index 5c540cfc641ea6..0b4af052e78db6 100644
--- a/llvm/lib/IR/DataLayout.cpp
+++ b/llvm/lib/IR/DataLayout.cpp
@@ -216,7 +216,7 @@ void DataLayout::reset(StringRef Desc) {
   if (Error Err = setPointerAlignmentInBits(0, Align(8), Align(8), 64, 64))
     return report_fatal_error(std::move(Err));
 
-  setNullPointerValue(INT_MAX, 0);
+  setDefaultNullPointerValue(INT_MAX, 0);
 
   if (Error Err = parseSpecifier(Desc))
     return report_fatal_error(std::move(Err));
@@ -262,11 +262,11 @@ static Error getIntForAddrSpace(StringRef R, IntTy &Result) {
     if (error || Result <= 0)
       return reportError("not a number, or does not fit in an unsigned int");
     Result *= -1;
-    return Error::success();
   } else if (R.contains("neg"))
     return reportError("not a valid value for address space");
   else
     return getInt<IntTy>(R, Result);
+  return Error::success();
 }
 
 /// Get an unsigned integer representing the number of bits and convert it into
@@ -527,7 +527,7 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
       if (Tok.empty()) {
         if (Error Err = getIntForAddrSpace(Rest, Value))
           return Err;
-        setNullPointerValue(INT_MAX, Value);
+        setDefaultNullPointerValue(INT_MAX, Value);
         break;
       } else {
         if (Error Err = getInt(Tok, AddrSpace))
@@ -543,7 +543,7 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
         return Err;
       if (Error Err = getIntForAddrSpace(Tok, Value))
         return Err;
-      setNullPointerValue(AddrSpace, Value);
+      setDefaultNullPointerValue(AddrSpace, Value);
       break;
     }
     case 'G': { // Default address space for global variables.

>From dd6fdb5bd1ee974f67ba74d20797fc699bf207fc Mon Sep 17 00:00:00 2001
From: Rana Pratap Reddy N <RanaPratapReddy.Nimmakayala at amd.com>
Date: Thu, 14 Mar 2024 16:00:15 +0530
Subject: [PATCH 4/4] Renamed from defaultNull to Sentinel pointer value and
 updated the LangRef

---
 llvm/docs/LangRef.rst             | 15 ++++++++-------
 llvm/include/llvm/IR/DataLayout.h | 12 ++++++------
 llvm/lib/IR/DataLayout.cpp        |  6 +++---
 3 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index feb469c123837e..c24199e5a233d5 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -3045,13 +3045,14 @@ as follows:
     this set are considered to support most general arithmetic operations
     efficiently.
 ``z[n]:<value>``
-    This specifies the default null value for an address space. ``n`` denotes
-    the address space number, and if not specified, it is considered to be
-    for the unlisted address space. For unlisted address space, the default
-    null value is ``0``. ``value`` denotes the default null value for an
-    address space ``n``. To represent negatives values, prefix ``neg`` is
-    added to ``value``. for e.g., ``z0:neg1`` represents for ``0`` address
-    space ``-1`` is the default null value.
+    This specifies the sentinel pointer value for an address space. Sentinel
+    pointer value is the default non zero null value for a given address
+    space. ``n`` denotes the address space number, and if not specified, it
+    is considered to be for the unlisted address space. For unlisted address
+    space, the sentinel pointer value is ``0``. ``value`` denotes the sentinel
+    pointer value for an address space ``n``. To represent negatives values,
+    prefix ``neg`` is added to ``value``. for e.g., ``z0:neg1`` represents for
+    ``0`` address space ``-1`` is the sentinel pointer value.
 ``ni:<address space0>:<address space1>:<address space2>...``
     This specifies pointer types with the specified address spaces
     as :ref:`Non-Integral Pointer Type <nointptrtype>` s.  The ``0``
diff --git a/llvm/include/llvm/IR/DataLayout.h b/llvm/include/llvm/IR/DataLayout.h
index e192a32a74aeaa..faae5177fce551 100644
--- a/llvm/include/llvm/IR/DataLayout.h
+++ b/llvm/include/llvm/IR/DataLayout.h
@@ -165,7 +165,7 @@ class DataLayout {
   /// well-defined bitwise representation.
   SmallVector<unsigned, 8> NonIntegralAddressSpaces;
 
-  DenseMap<unsigned, int64_t> AddrSpaceToNonZeroValueMap;
+  DenseMap<unsigned, int64_t> AddrSpaceToSentinelValueMap;
 
   /// Attempts to set the alignment of the given type. Returns an error
   /// description on failure.
@@ -302,15 +302,15 @@ class DataLayout {
     return ManglingMode == MM_WinCOFFX86;
   }
 
-  int64_t getDefaultNullPointerValue(unsigned AddrSpace) {
-    auto It = AddrSpaceToNonZeroValueMap.find(AddrSpace);
-    if (It == AddrSpaceToNonZeroValueMap.end())
+  int64_t getSentinelPointerValue(unsigned AddrSpace) {
+    auto It = AddrSpaceToSentinelValueMap.find(AddrSpace);
+    if (It == AddrSpaceToSentinelValueMap.end())
       return 0;
     return It->second;
   }
 
-  void setDefaultNullPointerValue(unsigned AddrSpace, int64_t Value) {
-    AddrSpaceToNonZeroValueMap[AddrSpace] = Value;
+  void setSentinelPointerValue(unsigned AddrSpace, int64_t Value) {
+    AddrSpaceToSentinelValueMap[AddrSpace] = Value;
   }
 
   /// Returns true if symbols with leading question marks should not receive IR
diff --git a/llvm/lib/IR/DataLayout.cpp b/llvm/lib/IR/DataLayout.cpp
index 0b4af052e78db6..02016f82a12af7 100644
--- a/llvm/lib/IR/DataLayout.cpp
+++ b/llvm/lib/IR/DataLayout.cpp
@@ -216,7 +216,7 @@ void DataLayout::reset(StringRef Desc) {
   if (Error Err = setPointerAlignmentInBits(0, Align(8), Align(8), 64, 64))
     return report_fatal_error(std::move(Err));
 
-  setDefaultNullPointerValue(INT_MAX, 0);
+  setSentinelPointerValue(INT_MAX, 0);
 
   if (Error Err = parseSpecifier(Desc))
     return report_fatal_error(std::move(Err));
@@ -527,7 +527,7 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
       if (Tok.empty()) {
         if (Error Err = getIntForAddrSpace(Rest, Value))
           return Err;
-        setDefaultNullPointerValue(INT_MAX, Value);
+        setSentinelPointerValue(INT_MAX, Value);
         break;
       } else {
         if (Error Err = getInt(Tok, AddrSpace))
@@ -543,7 +543,7 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
         return Err;
       if (Error Err = getIntForAddrSpace(Tok, Value))
         return Err;
-      setDefaultNullPointerValue(AddrSpace, Value);
+      setSentinelPointerValue(AddrSpace, Value);
       break;
     }
     case 'G': { // Default address space for global variables.



More information about the llvm-commits mailing list