'ptr' Dialect
Pointer dialect
The pointer dialect provides types and operations for representing and interacting with pointer values in MLIR, such as loading and storing values from/to memory addresses.
The dialect’s main type is an opaque pointer (ptr
) that can be
parameterized by a memory space. This type represents a handle to an object
in memory, or target-dependent values like nullptr
. Further, the dialect
assumes that the minimum addressable unit by a pointer is a byte. However,
the dialect does not make assumptions about the size of a byte, which is
considered a target-specific property.
Operations ¶
ptr.constant
(ptr::ConstantOp) ¶
Pointer constant operation
Syntax:
operation ::= `ptr.constant` attr-dict $value
The constant
operation produces a pointer constant. The attribute must be
a typed attribute of pointer type.
Example:
// Create a null pointer
%null = ptr.constant #ptr.null : !ptr.ptr<#ptr.generic_space>
Traits: AlwaysSpeculatableImplTrait
, ConstantLike
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes: ¶
Attribute | MLIR Type | Description |
---|---|---|
value | ::mlir::TypedAttr | TypedAttr instance
|
Results: ¶
Result | Description |
---|---|
result | pointer type |
ptr.from_ptr
(ptr::FromPtrOp) ¶
Casts a !ptr.ptr
value to a ptr-like value.
Syntax:
operation ::= `ptr.from_ptr` $ptr (`metadata` $metadata^)? attr-dict `:` type($ptr) `->` type($result)
The from_ptr
operation casts a ptr
value to a ptr-like object. It’s
important to note that:
- The ptr-like object cannot be a
!ptr.ptr
. - The memory-space of both the
ptr
and ptr-like object must match. - The cast is Pure (no UB and side-effect free).
The optional metadata
operand exists to provide any ptr-like metadata
that might be required to perform the cast.
Example:
%typed_ptr = ptr.from_ptr %ptr : !ptr.ptr<#ptr.generic_space> -> !my.ptr<f32, #ptr.generic_space>
%memref = ptr.from_ptr %ptr metadata %md : !ptr.ptr<#ptr.generic_space> -> memref<f32, #ptr.generic_space>
// Cast the `%ptr` to a memref without utilizing metadata.
%memref = ptr.from_ptr %ptr : !ptr.ptr<#ptr.generic_space> -> memref<f32, #ptr.generic_space>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands: ¶
Operand | Description |
---|---|
ptr | pointer type |
metadata | Pointer metadata type |
Results: ¶
Result | Description |
---|---|
result | PtrLikeTypeInterface instance |
ptr.gather
(ptr::GatherOp) ¶
Gather operation
Syntax:
operation ::= `ptr.gather` $ptrs `,` $mask `,` $passthrough (`alignment` `=` $alignment^)?
attr-dict `:` type($ptrs) `->` type($result)
The gather
operation performs conditional loads from multiple memory
locations specified by ptrs
based on a mask mask
. Elements of the
result corresponding to masked-off lanes are taken from the passthrough
operand.
The mask operand is a shaped type of i1
elements that must have the same
shape as the result type.
Examples:
// Gather values from multiple memory locations
%result = ptr.gather %ptrs, %mask, %passthrough :
vector<4x!ptr.ptr<#ptr.generic_space>> -> vector<4xf32>
// Gather with alignment
%result = ptr.gather %ptrs, %mask, %passthrough alignment = 8 :
vector<4x!ptr.ptr<#ptr.generic_space>> -> vector<4xf32>
Interfaces: InferTypeOpInterface
, MemoryEffectOpInterface
Operands: ¶
Operand | Description |
---|---|
ptrs | A shaped type with value semantics and rank. of pointer type values |
mask | A shaped type with value semantics and rank. of 1-bit signless integer values |
passthrough | A shaped type with value semantics and rank. of any type values |
Results: ¶
Result | Description |
---|---|
result | A shaped type with value semantics and rank. of any type values |
ptr.get_metadata
(ptr::GetMetadataOp) ¶
SSA value representing pointer metadata.
Syntax:
operation ::= `ptr.get_metadata` $ptr attr-dict `:` type($ptr)
The get_metadata
operation produces an opaque value that encodes the
metadata of the ptr-like type.
Example:
%metadata = ptr.get_metadata %memref : memref<?x?xf32>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands: ¶
Operand | Description |
---|---|
ptr | PtrLikeTypeInterface instance |
Results: ¶
Result | Description |
---|---|
result | Pointer metadata type |
ptr.load
(ptr::LoadOp) ¶
Syntax:
operation ::= `ptr.load` (`volatile` $volatile_^)? $ptr
(`atomic` (`syncscope` `(` $syncscope^ `)`)? $ordering^)?
oilist(
`nontemporal` $nontemporal |
`invariant` $invariant |
`invariant_group` $invariantGroup |
`alignment` `=` $alignment
)
attr-dict `:` qualified(type($ptr)) `->` type($value)
The load
operation is used to read from memory. A load may be marked as
atomic, volatile, and/or nontemporal.
An atomic load only supports a limited set of value types, and requires an explicit alignment.
Examples:
// A volatile load of a float variable.
%0 = ptr.load volatile %ptr : !ptr.ptr -> f32
// A nontemporal load of a float variable.
%0 = ptr.load %ptr nontemporal : !ptr.ptr -> f32
// An atomic load of an integer variable.
%0 = ptr.load %ptr atomic monotonic alignment = 8 : !ptr.ptr -> i64
See the following link for more details on the meaning of alignment
,
volatile_
, nontemporal
, invariant
, invariant_group
, ordering
,
and syncscope
:
https://llvm.org/docs/LangRef.html#load-instruction
Interfaces: MemoryEffectOpInterface
Attributes: ¶
Attribute | MLIR Type | Description |
---|---|---|
syncscope | ::mlir::StringAttr | string attribute |
Operands: ¶
Operand | Description |
---|---|
ptr | pointer type |
Results: ¶
Result | Description |
---|---|
value | any type |
ptr.masked_load
(ptr::MaskedLoadOp) ¶
Masked load operation
Syntax:
operation ::= `ptr.masked_load` $ptr `,` $mask `,` $passthrough (`alignment` `=` $alignment^)?
attr-dict `:` qualified(type($ptr)) `->` type($result)
The masked_load
operation performs a conditional load from memory based
on a mask. Elements of the result corresponding to masked-off lanes are
taken from the passthrough operand.
The mask operand is a shaped type of i1
elements that must have the same
shape as the result type.
Examples:
// Masked load with passthrough on vectors
%result = ptr.masked_load %ptr, %mask, %passthrough :
!ptr.ptr<#ptr.generic_space> -> vector<4xf32>
// Masked load with passthrough on tensors
%result = ptr.masked_load %ptr, %mask, %passthrough :
!ptr.ptr<#ptr.generic_space> -> tensor<4xf32>
Interfaces: InferTypeOpInterface
, MemoryEffectOpInterface
Operands: ¶
Operand | Description |
---|---|
ptr | pointer type |
mask | A shaped type with value semantics and rank. of 1-bit signless integer values |
passthrough | A shaped type with value semantics and rank. of any type values |
Results: ¶
Result | Description |
---|---|
result | A shaped type with value semantics and rank. of any type values |
ptr.masked_store
(ptr::MaskedStoreOp) ¶
Masked store operation
Syntax:
operation ::= `ptr.masked_store` $value `,` $ptr `,` $mask (`alignment` `=` $alignment^)? attr-dict `:`
type($value) `,` qualified(type($ptr))
The masked_store
operation performs a conditional store to memory based
on a mask. Only elements corresponding to set bits in the mask are written
to memory.
The mask operand is a shaped type of i1
elements that must have the same
shape as the value being stored.
Examples:
// Masked store
ptr.masked_store %value, %ptr, %mask :
vector<4xf32>, !ptr.ptr<#ptr.generic_space>
// Masked store with alignment
ptr.masked_store %value, %ptr, %mask alignment = 8 :
vector<4xf32>, !ptr.ptr<#ptr.generic_space>
Interfaces: MemoryEffectOpInterface
Operands: ¶
Operand | Description |
---|---|
value | A shaped type with value semantics and rank. of any type values |
ptr | pointer type |
mask | A shaped type with value semantics and rank. of 1-bit signless integer values |
ptr.ptr_add
(ptr::PtrAddOp) ¶
Pointer add operation
Syntax:
operation ::= `ptr.ptr_add` ($flags^)? $base `,` $offset attr-dict `:` type($base) `,` type($offset)
The ptr_add
operation adds an int-like offset to one or more pointers to produce one or more new pointers.
The operation supports both scalar and shaped types with value semantics:
- When both base and offset are scalar: produces a single new pointer
- When base is shaped and offset is scalar: adds the same offset to each pointer in the base
- When base is scalar and offset is shaped: adds the single pointer to each offset in the shaped value
- When both are shaped: performs element-wise addition (shapes must be compatible)
Example:
// Scalar base and offset
%x_off = ptr.ptr_add %x, %off : !ptr.ptr<#ptr.generic_space>, i32
%x_off0 = ptr.ptr_add nusw %x, %off : !ptr.ptr<#ptr.generic_space>, i32
// Shaped base with scalar offset
%ptrs_off = ptr.ptr_add %ptrs, %off : vector<4x!ptr.ptr<#ptr.generic_space>>, i32
// Scalar base with shaped offset
%x_offs = ptr.ptr_add %x, %offs : !ptr.ptr<#ptr.generic_space>, vector<4xi32>
// Both base and offset are shaped
%ptrs_offs = ptr.ptr_add %ptrs, %offs : vector<4x!ptr.ptr<#ptr.generic_space>>, vector<4xi32>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
, ViewLikeOpInterface
Effects: MemoryEffects::Effect{}
Operands: ¶
Operand | Description |
---|---|
base | A shaped type with value semantics and rank. of pointer type values or pointer type |
offset | A shaped type with value semantics and rank. of signless integer or index values or signless integer or index |
Results: ¶
Result | Description |
---|---|
result | A shaped type with value semantics and rank. of pointer type values or pointer type |
ptr.ptr_diff
(ptr::PtrDiffOp) ¶
Pointer difference operation
Syntax:
operation ::= `ptr.ptr_diff` ($flags^)? $lhs `,` $rhs attr-dict `:` type($lhs) `->` type($result)
The ptr_diff
operation computes the difference between two pointers,
returning an integer or index value representing the number of bytes
between them.
The operation supports both scalar and shaped types with value semantics:
- When both operands are scalar: produces a single difference value
- When both are shaped: performs element-wise subtraction, shapes must be the same
The operation also supports the following flags:
none
: No flags are set.nuw
: No Unsigned Wrap, if the subtraction causes an unsigned overflow (that is: the result would be negative), the result is a poison value.nsw
: No Signed Wrap, if the subtraction causes a signed overflow, the result is a poison value.
NOTE: The pointer difference is calculated using an integer type specified by the data layout. The final result will be sign-extended or truncated to fit the result type as necessary.
Example:
// Scalar pointers
%diff = ptr.ptr_diff %p1, %p2 : !ptr.ptr<#ptr.generic_space> -> i64
// Shaped pointers
%diffs = ptr.ptr_diff nsw %ptrs1, %ptrs2 :
vector<4x!ptr.ptr<#ptr.generic_space>> -> vector<4xi64>
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultShape
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands: ¶
Operand | Description |
---|---|
lhs | A shaped type with value semantics and rank. of pointer type values or pointer type |
rhs | A shaped type with value semantics and rank. of pointer type values or pointer type |
Results: ¶
Result | Description |
---|---|
result | A shaped type with value semantics and rank. of signless integer or index values or signless integer or index |
ptr.scatter
(ptr::ScatterOp) ¶
Scatter operation
Syntax:
operation ::= `ptr.scatter` $value `,` $ptrs `,` $mask (`alignment` `=` $alignment^)?
attr-dict `:` type($value) `,` type($ptrs)
The scatter
operation performs a conditional store of a value value
to
multiple memory locations specified by ptrs
based on a mask mask
.
Only elements corresponding to set bits in the mask are written to memory.
The mask operand is a shaped type of i1
elements that must have the same
shape as the value being stored.
Examples:
// Scatter values to multiple memory locations
ptr.scatter %value, %ptrs, %mask :
vector<4xf32>, vector<4x!ptr.ptr<#ptr.generic_space>>
// Scatter with alignment
ptr.scatter %value, %ptrs, %mask alignment = 8 :
vector<4xf32>, vector<4x!ptr.ptr<#ptr.generic_space>>
Interfaces: MemoryEffectOpInterface
Operands: ¶
Operand | Description |
---|---|
value | A shaped type with value semantics and rank. of any type values |
ptrs | A shaped type with value semantics and rank. of pointer type values |
mask | A shaped type with value semantics and rank. of 1-bit signless integer values |
ptr.store
(ptr::StoreOp) ¶
Syntax:
operation ::= `ptr.store` (`volatile` $volatile_^)? $value `,` $ptr
(`atomic` (`syncscope` `(` $syncscope^ `)`)? $ordering^)?
oilist(
`nontemporal` $nontemporal |
`invariant_group` $invariantGroup |
`alignment` `=` $alignment
)
attr-dict `:` type($value) `,` qualified(type($ptr))
The store
operation is used to write to memory. A store may be marked as
atomic, volatile, and/or nontemporal.
An atomic store only supports a limited set of value types, and requires an explicit alignment.
Examples:
// A volatile store of a float variable.
ptr.store volatile %val, %ptr : f32, !ptr.ptr
// A nontemporal store of a float variable.
ptr.store %val, %ptr nontemporal : f32, !ptr.ptr
// An atomic store of an integer variable.
ptr.store %val, %ptr atomic monotonic alignment = 8: i64, !ptr.ptr
See the following link for more details on the meaning of alignment
,
volatile_
, nontemporal
, invariant_group
, ordering
, and syncscope
:
https://llvm.org/docs/LangRef.html#store-instruction
Interfaces: MemoryEffectOpInterface
Attributes: ¶
Attribute | MLIR Type | Description |
---|---|---|
syncscope | ::mlir::StringAttr | string attribute |
Operands: ¶
Operand | Description |
---|---|
value | any type |
ptr | pointer type |
ptr.to_ptr
(ptr::ToPtrOp) ¶
Casts a ptr-like value to a !ptr.ptr
value.
Syntax:
operation ::= `ptr.to_ptr` $ptr attr-dict `:` type($ptr) `->` type($result)
The to_ptr
operation casts a ptr-like object to a !ptr.ptr
. It’s
important to note that:
- The ptr-like object cannot be a
!ptr.ptr
. - The memory-space of both the
ptr
and ptr-like object must match. - The cast is side-effect free.
Example:
%ptr0 = ptr.to_ptr %my_ptr : !my.ptr<f32, #ptr.generic_space> -> !ptr.ptr<#ptr.generic_space>
%ptr1 = ptr.to_ptr %memref : memref<f32, #ptr.generic_space> -> !ptr.ptr<#ptr.generic_space>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands: ¶
Operand | Description |
---|---|
ptr | PtrLikeTypeInterface instance |
Results: ¶
Result | Description |
---|---|
result | pointer type |
ptr.type_offset
(ptr::TypeOffsetOp) ¶
Type offset operation
Syntax:
operation ::= `ptr.type_offset` $elementType attr-dict `:` type($result)
The type_offset
operation produces an int or index-typed SSA value
equal to a target-specific constant representing the offset of a single
element of the given type.
Example:
// Return the offset between two f32 stored in memory
%0 = ptr.type_offset f32 : index
// Return the offset between two memref descriptors stored in memory
%1 = ptr.type_offset memref<12 x f64> : i32
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes: ¶
Attribute | MLIR Type | Description |
---|---|---|
elementType | ::mlir::TypeAttr | any type attribute |
Results: ¶
Result | Description |
---|---|
result | signless integer or index |
Attributes ¶
AddressAttr ¶
Address attribute
Syntax:
#ptr.address<
PtrType, # type
::llvm::APInt # value
>
The address
attribute represents a raw memory address, expressed in bytes.
Example:
#ptr.address<0x1000> : !ptr.ptr<#ptr.generic_space>
Parameters: ¶
Parameter | C++ type | Description |
---|---|---|
type | PtrType | |
value | ::llvm::APInt |
GenericSpaceAttr ¶
Generic memory space
Syntax: #ptr.generic_space
The generic_space
attribute defines a memory space attribute with the
following properties:
- Load and store operations are always valid, regardless of the type.
- Atomic operations are always valid, regardless of the type.
- Cast operations to
generic_space
are always valid.
Example:
#ptr.generic_space : !ptr.ptr<#ptr.generic_space>
NullAttr ¶
Null pointer attribute
Syntax:
#ptr.null<
PtrType # type
>
The null
attribute represents a null pointer.
Example:
#ptr.null
Parameters: ¶
Parameter | C++ type | Description |
---|---|---|
type | PtrType |
SpecAttr ¶
Ptr data layout spec
Syntax:
#ptr.spec<
uint32_t, # size
uint32_t, # abi
uint32_t, # preferred
uint32_t # index
>
Defines the data layout spec for a pointer type. This attribute has 4 fields:
- [Required] size: size of the pointer in bits.
- [Required] abi: ABI-required alignment for the pointer in bits.
- [Required] preferred: preferred alignment for the pointer in bits.
- [Optional] index: bitwidth that should be used when performing index
computations for the type. Setting the field to
kOptionalSpecValue
, means the field is optional.
Furthermore, the attribute will verify that all present values are divisible
by 8 (number of bits in a byte), and that preferred
> abi
.
Example:
// Spec for a 64 bit ptr, with a required alignment of 64 bits, but with
// a preferred alignment of 128 bits and an index bitwidth of 64 bits.
#ptr.spec<size = 64, abi = 64, preferred = 128, index = 64>
Parameters: ¶
Parameter | C++ type | Description |
---|---|---|
size | uint32_t | |
abi | uint32_t | |
preferred | uint32_t | |
index | uint32_t |
Types ¶
PtrMetadataType ¶
Pointer metadata type
Syntax:
!ptr.ptr_metadata<
PtrLikeTypeInterface # type
>
The ptr_metadata
type represents an opaque-view of the metadata associated
with a ptr-like
object type.
Note: It’s a verification error to construct a ptr_metadata
type using a
ptr-like
type with no metadata.
Example:
// The metadata associated with a `memref` type.
!ptr.ptr_metadata<memref<f32>>
Parameters: ¶
Parameter | C++ type | Description |
---|---|---|
type | PtrLikeTypeInterface |
PtrType ¶
Pointer type
Syntax:
!ptr.ptr<
MemorySpaceAttrInterface # memorySpace
>
The ptr
type is an opaque pointer type. This type typically represents a
handle to an object in memory or target-dependent values like nullptr
.
Pointers are parameterized by a memory space.
Syntax:
pointer ::= `ptr` (`<` memory-space `>`)?
memory-space ::= attribute-value
Parameters: ¶
Parameter | C++ type | Description |
---|---|---|
memorySpace | MemorySpaceAttrInterface |
Enums ¶
AtomicBinOp ¶
Ptr.atomicrmw binary operations
Cases: ¶
Symbol | Value | String |
---|---|---|
xchg | 0 | xchg |
add | 1 | add |
sub | 2 | sub |
_and | 3 | _and |
nand | 4 | nand |
_or | 5 | _or |
_xor | 6 | _xor |
max | 7 | max |
min | 8 | min |
umax | 9 | umax |
umin | 10 | umin |
fadd | 11 | fadd |
fsub | 12 | fsub |
fmax | 13 | fmax |
fmin | 14 | fmin |
uinc_wrap | 15 | uinc_wrap |
udec_wrap | 16 | udec_wrap |
AtomicOrdering ¶
Atomic ordering for LLVM’s memory model
Cases: ¶
Symbol | Value | String |
---|---|---|
not_atomic | 0 | not_atomic |
unordered | 1 | unordered |
monotonic | 2 | monotonic |
acquire | 3 | acquire |
release | 4 | release |
acq_rel | 5 | acq_rel |
seq_cst | 6 | seq_cst |
PtrAddFlags ¶
Pointer add flags
Cases: ¶
Symbol | Value | String |
---|---|---|
none | 0 | none |
nusw | 1 | nusw |
nuw | 2 | nuw |
inbounds | 3 | inbounds |
PtrDiffFlags ¶
Pointer difference flags
Cases: ¶
Symbol | Value | String |
---|---|---|
none | 0 | none |
nuw | 1 | nuw |
nsw | 2 | nsw |