[llvm] r277085 - [IR] Introduce a non-integral pointer type

Sanjoy Das via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 28 16:43:38 PDT 2016


Author: sanjoy
Date: Thu Jul 28 18:43:38 2016
New Revision: 277085

URL: http://llvm.org/viewvc/llvm-project?rev=277085&view=rev
Log:
[IR] Introduce a non-integral pointer type

Summary:
This change adds a `ni` specifier in the `datalayout` string to denote
pointers in some given address spaces as "non-integral", and adds some
typing rules around these special pointers.

Reviewers: majnemer, chandlerc, atrick, dberlin, eli.friedman, tstellarAMD, arsenm

Subscribers: arsenm, mcrosier, llvm-commits

Differential Revision: https://reviews.llvm.org/D22488

Added:
    llvm/trunk/test/Verifier/non-integral-pointers.ll
Modified:
    llvm/trunk/docs/LangRef.rst
    llvm/trunk/include/llvm/IR/DataLayout.h
    llvm/trunk/lib/IR/DataLayout.cpp
    llvm/trunk/lib/IR/Verifier.cpp

Modified: llvm/trunk/docs/LangRef.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=277085&r1=277084&r2=277085&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.rst (original)
+++ llvm/trunk/docs/LangRef.rst Thu Jul 28 18:43:38 2016
@@ -546,6 +546,26 @@ An example of an identified structure sp
 Prior to the LLVM 3.0 release, identified types were structurally uniqued. Only
 literal types are uniqued in recent versions of LLVM.
 
+.. _nointptrtype:
+
+Non-Integral Pointer Type
+-------------------------
+
+Note: non-integral pointer types are a work in progress, and they should be
+considered experimental at this time.
+
+LLVM IR optionally allows the frontend to denote pointers in certain address
+spaces as "non-integral" via the :ref:```datalayout``
+string<langref_datalayout>`.  Non-integral pointer types represent pointers that
+have an *unspecified* bitwise representation; that is, the integral
+representation may be target dependent or unstable (not backed by a fixed
+integer).
+
+``inttoptr`` instructions converting integers to non-integral pointer types are
+ill-typed, and so are ``ptrtoint`` instructions converting values of
+non-integral pointer types to integers.  Vector versions of said instructions
+are ill-typed as well.
+
 .. _globalvars:
 
 Global Variables
@@ -1831,6 +1851,10 @@ 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.
+``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``
+    address space cannot be specified as non-integral.
 
 On every specification that takes a ``<abi>:<pref>``, specifying the
 ``<pref>`` alignment is optional. If omitted, the preceding ``:``

Modified: llvm/trunk/include/llvm/IR/DataLayout.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/DataLayout.h?rev=277085&r1=277084&r2=277085&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/DataLayout.h (original)
+++ llvm/trunk/include/llvm/IR/DataLayout.h Thu Jul 28 18:43:38 2016
@@ -21,6 +21,7 @@
 #define LLVM_IR_DATALAYOUT_H
 
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Type.h"
 #include "llvm/Pass.h"
@@ -144,6 +145,10 @@ private:
   // The StructType -> StructLayout map.
   mutable void *LayoutMap;
 
+  /// Pointers in these address spaces are non-integral, and don't have a
+  /// well-defined bitwise representation.
+  SmallVector<unsigned, 8> NonIntegralAddressSpaces;
+
   void setAlignment(AlignTypeEnum align_type, unsigned abi_align,
                     unsigned pref_align, uint32_t bit_width);
   unsigned getAlignmentInfo(AlignTypeEnum align_type, uint32_t bit_width,
@@ -199,6 +204,7 @@ public:
     LegalIntWidths = DL.LegalIntWidths;
     Alignments = DL.Alignments;
     Pointers = DL.Pointers;
+    NonIntegralAddressSpaces = DL.NonIntegralAddressSpaces;
     return *this;
   }
 
@@ -320,6 +326,18 @@ public:
   /// the backends/clients are updated.
   unsigned getPointerSize(unsigned AS = 0) const;
 
+  /// Return the address spaces containing non-integral pointers.  Pointers in
+  /// this address space don't have a well-defined bitwise representation.
+  ArrayRef<unsigned> getNonIntegralAddressSpaces() const {
+    return NonIntegralAddressSpaces;
+  }
+
+  bool isNonIntegralPointerType(PointerType *PT) const {
+    ArrayRef<unsigned> NonIntegralSpaces = getNonIntegralAddressSpaces();
+    return find(NonIntegralSpaces, PT->getAddressSpace()) !=
+           NonIntegralSpaces.end();
+  }
+
   /// Layout pointer size, in bits
   /// FIXME: The defaults need to be removed once all of
   /// the backends/clients are updated.

Modified: llvm/trunk/lib/IR/DataLayout.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/DataLayout.cpp?rev=277085&r1=277084&r2=277085&view=diff
==============================================================================
--- llvm/trunk/lib/IR/DataLayout.cpp (original)
+++ llvm/trunk/lib/IR/DataLayout.cpp Thu Jul 28 18:43:38 2016
@@ -182,6 +182,7 @@ void DataLayout::reset(StringRef Desc) {
   BigEndian = false;
   StackNaturalAlign = 0;
   ManglingMode = MM_None;
+  NonIntegralAddressSpaces.clear();
 
   // Default alignments
   for (const LayoutAlignElem &E : DefaultAlignments) {
@@ -234,6 +235,19 @@ void DataLayout::parseSpecifier(StringRe
     StringRef &Tok  = Split.first;  // Current token.
     StringRef &Rest = Split.second; // The rest of the string.
 
+    if (Tok == "ni") {
+      do {
+        Split = split(Rest, ':');
+        Rest = Split.second;
+        unsigned AS = getInt(Split.first);
+        if (AS == 0)
+          report_fatal_error("Address space 0 can never be non-integral");
+        NonIntegralAddressSpaces.push_back(AS);
+      } while (!Rest.empty());
+
+      continue;
+    }
+
     char Specifier = Tok.front();
     Tok = Tok.substr(1);
 

Modified: llvm/trunk/lib/IR/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=277085&r1=277084&r2=277085&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Verifier.cpp (original)
+++ llvm/trunk/lib/IR/Verifier.cpp Thu Jul 28 18:43:38 2016
@@ -2409,6 +2409,11 @@ void Verifier::visitPtrToIntInst(PtrToIn
 
   Assert(SrcTy->getScalarType()->isPointerTy(),
          "PtrToInt source must be pointer", &I);
+
+  if (auto *PTy = dyn_cast<PointerType>(SrcTy->getScalarType()))
+    Assert(!M->getDataLayout().isNonIntegralPointerType(PTy),
+           "ptrtoint not supported for non-integral pointers");
+
   Assert(DestTy->getScalarType()->isIntegerTy(),
          "PtrToInt result must be integral", &I);
   Assert(SrcTy->isVectorTy() == DestTy->isVectorTy(), "PtrToInt type mismatch",
@@ -2433,6 +2438,11 @@ void Verifier::visitIntToPtrInst(IntToPt
          "IntToPtr source must be an integral", &I);
   Assert(DestTy->getScalarType()->isPointerTy(),
          "IntToPtr result must be a pointer", &I);
+
+  if (auto *PTy = dyn_cast<PointerType>(DestTy->getScalarType()))
+    Assert(!M->getDataLayout().isNonIntegralPointerType(PTy),
+           "inttoptr not supported for non-integral pointers");
+
   Assert(SrcTy->isVectorTy() == DestTy->isVectorTy(), "IntToPtr type mismatch",
          &I);
   if (SrcTy->isVectorTy()) {

Added: llvm/trunk/test/Verifier/non-integral-pointers.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/non-integral-pointers.ll?rev=277085&view=auto
==============================================================================
--- llvm/trunk/test/Verifier/non-integral-pointers.ll (added)
+++ llvm/trunk/test/Verifier/non-integral-pointers.ll Thu Jul 28 18:43:38 2016
@@ -0,0 +1,45 @@
+; RUN: not opt -verify < %s 2>&1 | FileCheck %s
+
+target datalayout = "e-ni:4:6"
+
+define i64 @f_0(i8 addrspace(4)* %ptr) {
+; CHECK: ptrtoint not supported for non-integral pointers
+  %val = ptrtoint i8 addrspace(4)* %ptr to i64
+  ret i64 %val
+}
+
+define <4 x i64> @f_1(<4 x i8 addrspace(4)*> %ptr) {
+; CHECK: ptrtoint not supported for non-integral pointers
+  %val = ptrtoint <4 x i8 addrspace(4)*> %ptr to <4 x i64>
+  ret <4 x i64> %val
+}
+
+define i64 @f_2(i8 addrspace(3)* %ptr) {
+; Negative test
+  %val = ptrtoint i8 addrspace(3)* %ptr to i64
+  ret i64 %val
+}
+
+define i8 addrspace(4)* @f_3(i64 %integer) {
+; CHECK: inttoptr not supported for non-integral pointers
+  %val = inttoptr i64 %integer to i8 addrspace(4)*
+  ret i8 addrspace(4)* %val
+}
+
+define <4 x i8 addrspace(4)*> @f_4(<4 x i64> %integer) {
+; CHECK: inttoptr not supported for non-integral pointers
+  %val = inttoptr <4 x i64> %integer to <4 x i8 addrspace(4)*>
+  ret <4 x i8 addrspace(4)*> %val
+}
+
+define i8 addrspace(3)* @f_5(i64 %integer) {
+; Negative test
+  %val = inttoptr i64 %integer to i8 addrspace(3)*
+  ret i8 addrspace(3)* %val
+}
+
+define i64 @f_6(i8 addrspace(6)* %ptr) {
+; CHECK: ptrtoint not supported for non-integral pointers
+  %val = ptrtoint i8 addrspace(6)* %ptr to i64
+  ret i64 %val
+}




More information about the llvm-commits mailing list