[llvm-branch-commits] [llvm] [DataLayout][LangRef] Split non-integral and unstable pointer properties (PR #105735)
Alexander Richardson via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Sep 22 08:33:35 PDT 2025
================
@@ -355,30 +364,111 @@ class DataLayout {
/// \sa DataLayout::getAddressSizeInBits
unsigned getAddressSize(unsigned AS) const { return getIndexSize(AS); }
- /// Return the address spaces containing non-integral pointers. Pointers in
- /// this address space don't have a well-defined bitwise representation.
- SmallVector<unsigned, 8> getNonIntegralAddressSpaces() const {
+ /// Return the address spaces with special pointer semantics (such as being
+ /// unstable or non-integral).
+ SmallVector<unsigned, 8> getNonStandardAddressSpaces() const {
SmallVector<unsigned, 8> AddrSpaces;
for (const PointerSpec &PS : PointerSpecs) {
- if (PS.IsNonIntegral)
+ if (PS.HasUnstableRepresentation || PS.HasExternalState ||
+ PS.BitWidth != PS.IndexBitWidth)
AddrSpaces.push_back(PS.AddrSpace);
}
return AddrSpaces;
}
+ /// Returns whether this address space has a non-integral pointer
+ /// representation, i.e. the pointer is not just an integer address but some
+ /// other bitwise representation. When true, passes cannot assume that all
+ /// bits of the representation map directly to the allocation address.
+ /// NOTE: This also returns true for "unstable" pointers where the
+ /// representation may be just an address, but this value can change at any
+ /// given time (e.g. due to copying garbage collection).
+ /// Examples include AMDGPU buffer descriptors with a 128-bit fat pointer
+ /// and a 32-bit offset or CHERI capabilities that contain bounds, permissions
+ /// and an out-of-band validity bit.
+ ///
+ /// In general, more specialized functions such as shouldAvoidIntToPtr(),
+ /// shouldAvoidPtrToInt(), or hasExternalState() should be preferred over
+ /// this one when reasoning about the behavior of IR analysis/transforms.
+ /// TODO: should remove/deprecate this once all uses have migrated.
bool isNonIntegralAddressSpace(unsigned AddrSpace) const {
- return getPointerSpec(AddrSpace).IsNonIntegral;
+ const auto &PS = getPointerSpec(AddrSpace);
+ return PS.BitWidth != PS.IndexBitWidth || PS.HasUnstableRepresentation ||
+ PS.HasExternalState;
+ }
+
+ /// Returns whether this address space has an "unstable" pointer
+ /// representation. The bitwise pattern of such pointers is allowed to change
+ /// in a target-specific way. For example, this could be used for copying
+ /// garbage collection where the garbage collector could update the pointer
+ /// value as part of the collection sweep.
+ bool hasUnstableRepresentation(unsigned AddrSpace) const {
+ return getPointerSpec(AddrSpace).HasUnstableRepresentation;
+ }
+ bool hasUnstableRepresentation(Type *Ty) const {
+ auto *PTy = dyn_cast<PointerType>(Ty->getScalarType());
+ return PTy && hasUnstableRepresentation(PTy->getPointerAddressSpace());
+ }
+
+ /// Returns whether this address space has external state (implies having
+ /// a non-integral pointer representation).
+ /// These pointer types must be loaded and stored using appropriate
+ /// instructions and cannot use integer loads/stores as this would not
+ /// propagate the out-of-band state. An example of such a pointer type is a
+ /// CHERI capability that contain bounds, permissions and an out-of-band
+ /// validity bit that is invalidated whenever an integer/FP store is performed
+ /// to the associated memory location.
+ bool hasExternalState(unsigned AddrSpace) const {
+ return getPointerSpec(AddrSpace).HasExternalState;
+ }
+ bool hasExternalState(Type *Ty) const {
+ auto *PTy = dyn_cast<PointerType>(Ty->getScalarType());
+ return PTy && hasExternalState(PTy->getPointerAddressSpace());
+ }
+
+ /// Returns whether passes should avoid introducing `inttoptr` instructions
+ /// for this address space.
+ ///
+ /// This is currently the case for non-integral pointer representations with
+ /// external state (hasExternalState()) since `inttoptr` cannot recreate the
+ /// external state bits.
+ /// New `inttoptr` instructions should also be avoided for "unstable" bitwise
+ /// representations (hasUnstableRepresentation()) unless the pass knows it is
+ /// within a critical section that retains the current representation.
+ bool shouldAvoidIntToPtr(unsigned AddrSpace) const {
----------------
arichardson wrote:
We could drop them and just use `(hasExternalState || hasUnstableRepresentation)` in #159959 ?
https://github.com/llvm/llvm-project/pull/105735
More information about the llvm-branch-commits
mailing list