[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