Name Strings

SPV_KHR_untyped_pointers

Contact

To report problems with this extension, please open a new issue at:

Contributors

  • Alan Baker, Google

  • David Neto, Google

  • Hugo Devillers, Saarland University

  • Tobias Hector, AMD

  • Caio Oliveira, Intel

  • Graeme Leese, Broadcom

  • Ruihao Zhang, Qualcomm,

  • Dmitry Sidorov, Intel

  • Jeff Bolz, Nvidia

  • Victor Lomuller, Codeplay

  • Kevin Petit, Arm

  • Ben Ashbaugh, Intel

Notice

Copyright (c) 2024 The Khronos Group Inc. Copyright terms at http://www.khronos.org/registry/speccopyright.html

Status

Provisional

  • Approved by the SPIR-V Working Group: 2024-05-29

  • Approved by the Khronos Board of Promoters: 2024-07-12

Version

Last Modified Date

2024-08-08

Revision

2

Dependencies

This extension is written against the SPIR-V Specification, Version 1.6 Revision 3.

This extension modifies SPV_KHR_workgroup_memory_explicit_layout.

This extension modifies SPV_KHR_cooperative_matrix.

This extension modifies the OpenCL.std extended instruction set.

Overview

This extension introduces support for untyped pointers. It allows for the declaration and use of pointers that do not specify the type of data they point to. It also allows memory, atomic and other instructions to reinterpret data differently than the declared type of the variables they are used with. For example, loading a vector of floating-point values from a variable with a declared type of an array of integers. It provides an equivalent set of functionality to type-punning via pointer casting in high-level languages.

This extension adds the following new instructions:

Extension Name

To use this extension within a SPIR-V module, the following OpExtension must be present in the module:

OpExtension "SPV_KHR_untyped_pointers"

Modifications to the SPIR-V Specification, Version 1.6

Modify Section 2.2.1 Instructions:

Add the following new term:

Variable: An OpVariable or OpUntypedVariableKHR.

Change the following existing terms:

Object: An instantiation of a non-void type, either as the Result <id> of an operation, or created through a variable.

Memory Object: An object created through a variable. Such an object exists only for the duration of a function if it is a function variable, and otherwise exists for the duration of the invocation.

Memory Object Declaration: A variable, or an OpFunctionParameter of pointer type, or the contents of a variable that holds either a pointer to the PhysicalStorageBuffer storage class or an array of such pointers.

Intermediate Object or Intermediate Value or Intermediate Result: An object created by an operation (not memory allocated by a variable) and dying on its last consumption.

Modify Section 2.2.2 Types:

Add the following new term:

Pointer Type: An OpTypePointer or OpTypeUntypedPointerKHR.

Changes the following existing terms:

Physical Pointer Type: A pointer type whose Storage Class uses physical addressing according to the addressing model.

Variable Pointer: A pointer of logical pointer type that results from one of the following opcodes:

Additionally, any OpAccessChain, OpInBoundsAccessChain, OpUntypedAccessChainKHR, OpUntypedInBoundsAccessChainKHR or OpCopyObject that takes a variable pointer as an operand also produces a variable pointer. An OpFunctionParameter of pointer type is a variable pointer if any OpFunctionCall to the function statically passes a variable pointer as the value of the parameter.

Modify Section 2.4 Logical Layout of a Module:

Change references to OpVariable to variable.

Modify Section 2.16.1 Universal Validation Rules:

Modify the list items under the following list item:

If neither the VariablePointers nor VariablePointersStorageBuffer capabilities are declared, the following rules apply to logical pointer types:

Change:

OpVariable must not allocate an object whose type is or contains a logical pointer type.

To:

Variables must not allocate an object whose type is or contains a logical pointer type.

Change:

It is invalid for a pointer to be an operand to any instruction other than:

  • OpLoad

  • OpStore

  • OpAccessChain

  • OpInBoundsAccessChain

  • OpFunctionCall

  • OpImageTexelPointer

  • OpCopyMemory

  • OpCopyObject

  • OpArrayLength

  • all OpAtomic instructions

  • extended instruction-set instructions that are explicitly identified as taking pointer operands

To:

It is invalid for a pointer to be an operand to any instruction other than:

Change:

It is invalid for a pointer to be the Result <id> of any instruction other than:

  • OpVariable

  • OpAccessChain

  • OpInBoundsAccessChain

  • OpFunctionParameter

  • OpImageTexelPointer

  • OpCopyObject

To:

It is invalid for a pointer to be the Result <id> of any instruction other than:

Change:

All indexes in OpAccessChain and OpInBoundsAccessChain that are OpConstant with type of OpTypeInt with a signedness of 1 must not have their sign bit set.

To:

All indexes in OpAccessChain, OpInBoundsAccessChain, OpUntypedAccessChainKHR and OpUntypedInBoundsAccessChainKHR that are OpConstant with type of OpTypeInt with a signedness of 1 must not have their sign bit set.

Modify the list items under the following list item:

If the VariablePointers or VariablePointersStorageBuffer capability is declared, the following are allowed for logical pointer types:

Change:

If OpVariable allocates an object whose type is or contains a logical pointer type, the Storage Class operand of the OpVariable must be one of the following:

  • Function

  • Private

To:

If a variable allocates an object whose type is or contains a logical pointer type, the Storage Class operand of the variable must be one of the following:

  • Function

  • Private

Change:

A pointer can be a variable pointer or an operand to one of:

  • OpPtrAccessChain

  • OpPtrEqual

  • OpPtrNotEqual

  • OpPtrDiff

To:

A pointer can be a variable pointer or an operand to one of:

Change:

The instructions OpPtrEqual and OpPtrNotEqual can be used only if the Storage Class of the operands OpTypePointer declaration:

To:

The instructions OpPtrEqual and OpPtrNotEqual can be used only if the Storage Class of the operands pointer type declaration:

Modify the list items under the following list item:

A variable pointer must not:

Change:

be an operand to an OpArrayLength instruction

To:

be an operand to an OpArrayLength or OpUntypedArrayLengthKHR instruction

Modify the list items under the following list item:

Physical Storage Buffer

Change:

OpVariable must not use the PhysicalStorageBuffer storage class.

To:

Variables must not use the PhysicalStorageBuffer storage class.

Change:

If the type an OpVariable points to is a pointer (or array of pointers) in the PhysicalStorageBuffer storage class, the OpVariable must be decorated with exactly one of AliasedPointer or RestrictPointer.

To:

If the type a variable points to is a pointer (or array of pointers) in the PhysicalStorageBuffer storage class, the variable must be decorated with exactly one of AliasedPointer or RestrictPointer.

Modify the list items under the following list item:

Global (Module Scope) Variables

Change:

A module-scope OpVariable with an Initializer operand must not be decorated with the Import Linkage Type.

To:

A module-scope variable with an Initializer operand must not be decorated with the Import Linkage Type.

Changes list items under the following list item:

The capabilities StorageBuffer16BitAccess, UniformAndStorageBuffer16BitAccess, StoragePushConstant16, and StorageInputOutput16 do not generally add 16-bit operations. Rather, they add only the following specific abilities:

Change:

A structure containing a 16-bit member can be an operand to OpArrayLength.

To:

A structure containing a 16-bit member can be an operand to OpArrayLength or OpUntypedArrayLengthKHR.

Add the following list items:

Change list items under the following list item:

The capabilities StorageBuffer8BitAccess, UniformAndStorageBuffer8BitAccess, and StoragePushConstant8, do not generally add 8-bit operations. Rather, they add only the following specific abilities:

Change:

A structure containing a 8-bit member can be an operand to OpArrayLength.

To:

A structure containing a 8-bit member can be an operand to OpArrayLength or OpUntypedArrayLengthKHR.

Add the following list items:

Modify Section 2.16.2 Validation Rules for Shader Capabilities:

Modify the list items under the following list item:

Composite objects in the StorageBuffer, PhysicalStorageBuffer, Uniform, and PushConstant Storage Classes must be explicitly laid out. The following apply to all the aggregate and matrix types describing such an object, recursively through their nested types:

Add the following list items:

Modify the list items under the following list item:

Type Rules:

Change:

All declared types are restricted to those types that are, or are contained within, valid types for an OpVariable Result Type or an OpTypeFunction Return Type.

To:

All declared types are restricted to those types that are, or are contained within, valid types for an OpVariable Result Type, an OpUntypedVariableKHR Data Type, or an OpTypeFunction Return Type.

Change:

Aggregate types for intermediate objects are restricted to those types that are a valid Type of an OpVariable Result Type in the global storage classes.

To:

Aggregate types for intermediate objects are restricted to those types that are a valid Type of an OpVariable Result Type, or an OpUntypedVariableKHR Data Type in the global storage classes.

Modify Section 2.17 Universal Limits:

Change the table entry:

Indexes for OpAccessChain, OpInBoundsAccessChain, OpPtrAccessChain, OpInBoundsPtrAccessChain, OpCompositeExtract, and OpCompositeInsert

To:

Indexes for OpAccessChain, OpInBoundsAccessChain, OpPtrAccessChain, OpInBoundsPtrAccessChain, OpCompositeExtract, OpCompositeInsert, OpUntypedAccessChainKHR, OpUntypedInBoundsAccessChainKHR, OpUntypedPtrAccessChainKHR, and OpUntypedInBoundsPtrAccessChainKHR

Modify Section 2.18 Memory Model:

Change references to OpVariable to variable.

Add a new section at the end of Section 2 Specification titled Untyped Pointers:

OpTypePointer includes the data type of the memory that it points to as an operand of the type-declaration. Logical pointer types of type OpTypePointer are strongly typed. That is, the data they point to cannot be reinterpreted as another type in memory. Physical pointer types of type OpTypePointer are not strongly typed as OpBitcast can be used to cast from one representation to another. Unlike, OpTypePointer, OpTypeUntypedPointerKHR does not encode the type of data that it points to. This means that interpretation of the data type is left to instructions that utilize the pointer.

Each untyped instruction (OpUntyped…​) has an operand that specifies how the data should be interpreted (e.g. Base Type in OpUntypedAccessChainKHR). Also, OpUntypedAccessChainKHR, OpUntypedInBoundsAccessChainKHR, OpUntypedPtrAccessChainKHR, and OpUntypedInBoundsPtrAccessChainKHR may take either a typed or untyped pointer as the Base operand. This facilitates translations from high-level languages as it can localize where untyped pointers appear in syntax evaluation.

When memory accessed via instructions have a pointer operand with type OpTypeUntypedPointerKHR (e.g. OpLoad or atomic instructions), the interpreted data type is specified by the Result Type if it exists. The intepreted data type for instructions without a Result Type (e.g. OpStore) comes from the type of the operand of the object being stored. OpCopyMemorySized interprets the data as an array of 8-bit integers.

When an instruction accesses memory via an untyped pointer for storage class S and with interpreted data type T, the instruction behaves as if the pointer were of type OpTypePointer having Storage Class S and Type T. That is, the instruction will access exactly the same memory locations and interpret the data there as if using the corresponding strongly typed pointer.

Modify Section 3.7 Storage Class:

Add OpTypeUntypedPointerKHR and OpUntypedVariableKHR to the list of "Used by" instructions.

Modify Section 3.20 Decoration:

Change references to OpVariable to variable.

Modify Section 3.21 BuiltIn:

Change references to OpVariable to variable.

Modify Section 3.31 Capability:

Change references to OpTypePointer to pointer type.

Add the following rows to the table:

Capability Implicitly Declares

4473

UntypedPointersKHR

Enables the use of untyped pointers.

Modify Section 3.37 Instructions:

In the following instructions, change references to OpVariable to variable:

  • OpDecorateId

  • OpEntryPoint

  • OpTypeBool

Change the description of Result Type in OpImageTexelPointer to:

Result Type must be a pointer type whose Storage Class is Image. If it is an OpTypePointer type, its Type operand must be a numerical scalar type or OpTypeVoid.

Change the description of Pointer in OpLoad to:

Pointer is the pointer to load through. It must be a pointer type. If it is an OpTypePointer type, its Type operand must be the same as Result Type.

Change the description of Pointer in OpStore to:

Pointer is the pointer to store through. It must be a pointer type. If it is an OpTypePointer type, its Type operand must be the same as the type of Object.

Change the description of OpCopyMemory to:

Copy from the memory pointed to by Source to the memory pointed to by Target. Both operands must be pointers and at least one must be an OpTypePointer type. If either Source or Target has type of OpTypePointer, the <id> Type operand must be non-void. If both Source and Target have a type of OpTypePointer, they must have the <id> Type operand. Matching Storage Class is not required. The amount of memory copied is the size of the type pointed to by an operand with a type of OpTypePointer. The copied type must have a fixed size; i.e., it must not be, nor include, any OpTypeRuntimeArray types.

If present, any Memory Operands must begin with a memory operand literal. If not present, it is the same as specifying the memory operand None. Before version 1.4, at most one memory operands mask can be provided. Starting with version 1.4 two masks can be provided, as described in Memory Operands. If no masks or only one mask is present, it applies to both Source and Target. If two masks are present, the first applies to Target and must not include MakePointerVisible, and the second applies to Source and must not include MakePointerAvailable.

Add the enabling capability UntypedPointersKHR to OpCopyMemorySized.

Change the restrictions on Operand 1 and Operand 2 in OpPtrEqual and OpPtrNotEqual to:

The Storage Class operand of the type of both Operand 1 and Operand 2 must match. If the types of Operand 1 and Operand 2 are OpTypePointer, they must be the same type.

Change the restriction on Operand 1 and Operand 2 in OpPtrDiff to:

The types of Operand 1 and Operand 2 must be the same OpTypePointer or OpTypeUntypedPointerKHR. If the types of Operand 1 and Operand 2 are OpTypePointer, they must point to a type that can be aggregated into an array. For an array of length L, Operand 1 and Operand 2 can point to any element in the range [0, L], where element L is outside the array but has a representative address computed with the same stride as elements in the array. Additionally, Operand 1 must be a valid Base operand of OpPtrAccessChain, OpUntypedPtrAccessChainKHR, OpInBoundsPtrAccessChain, or OpUntypedInBoundsPtrAccessChainKHR. Behavior is undefined if Operand 1 and Operand 2 are not pointers to element numbers in [0, L] in the same array. If Operand 1 and Operand 2 are OpTypeUntypedPointerKHR, the array is interpreted as an array of 8-bit integers.

Change the description of Result Type in OpPtrCastToGeneric to:

Result Type must be a pointer type. Its Storage Class must be Generic.

Change the description of OpGenericCastToPtr to:

Convert a pointer’s Storage Class to a non-Generic class.

Result Type must be a pointer type. Its Storage Class must be Workgroup, CrossWorkgroup, or Function.

Pointer must point to the Generic Storage Class.

If Result Type and the type of Pointer are OpTypePointer, they must point to the same type.

Change the description of OpGenericCastToPtrExplicit to:

Attempts to explicitly convert Pointer to Storage storage-class pointer value.

Result Type must be a pointer type. Its Storage Class must be Storage.

The type of Pointer must be a pointer type. Pointer must point to the Generic Storage Class. If the cast fails, the instruction result is an OpConstantNull pointer in the Storage Storage Class.

If Result Type and the type of Pointer are OpTypePointer, they must point to the same type.

Storage must be one of the following literal values from Storage Class: Workgroup, CrossWorkgroup, or Function.

Change the description of OpBitcast to:

Bit pattern-preserving type conversion.

Result Type must be a pointer type, or a scalar or vector of numerical-type.

Operand must be a pointer type, or a scalar or vector of numerical-type. It must be a different type than Result Type.

Before version 1.5: If either Result Type or Operand is a pointer, the other must be a pointer or an integer scalar. Starting with version 1.5: If either Result Type or Operand is a pointer, the other must be a pointer, an integer scalar, or an integer vector.

If Result Type has the same number of components as Operand, they must also have the same component width, and results are computed per component.

If Result Type has a different number of components than Operand, the total number of bits in Result Type must equal the total number of bits in Operand. Let L be the type, either Result Type or Operand’s type, that has the larger number of components. Let S be the other type, with the smaller number of components. The number of components in L must be an integer multiple of the number of components in S. The first component (that is, the only or lowest-numbered component) of S maps to the first components of L, and so on, up to the last component of S mapping to the last components of L. Within this mapping, any single component of S (mapping to multiple components of L) maps its lower-ordered bits to the lower-numbered components of L.

Change the description of Pointer in OpLifetimeStart and OpLifetimeStop to:

Pointer is a pointer to the object whose lifetime is starting/ending. Its type must be a pointer type with Storage Class Function.

Change the description of Pointer in OpAtomicLoad to:

Pointer is the pointer to the memory to read. It must be a pointer type. If its type is OpTypePointer, the type of the value pointed to by Pointer must be the same as Result Type.

Change the description of Pointer in OpAtomicStore to:

Pointer is the pointer to the memory to write. It must be a pointer type. If its type is OpTypePointer, the type it points to must be a scalar of integer type or floating-point type.

Change the description of Value in OpAtomicExchange to:

The type of Value must be the same as Result Type. Pointer must be a pointer type. If the type of Pointer is OpTypePointer, the type of the value pointed to by Pointer must be the same as Result Type.

Change the description of Value in OpAtomicCompareExchange to:

The type of Value must be the same as Result Type. Pointer must be a pointer type. If the type of Pointer is OpTypePointer, the type of the value pointed to by Pointer must be the same as Result Type. This type must also match the type of Comparator.

Change the description of Value in OpAtomicIIncrement, OpAtomicIDecrement, OpAtomicIAdd, OpAtomicISub, OpAtomicSMin, OpAtomicUMin, OpAtomicSMax, OpAtomicUMax, OpAtomicAnd, OpAtomicOr, and OpAtomicXor to:

The type of Value must be the same as Result Type. Pointer must be a pointer type. If the type of Pointer is OpTypePointer, the type of the value pointed to by Pointer must be the same as Result Type.

Add the following instruction to Section 3.37.6 Type-Declaration Instructions:

OpTypeUntypedPointerKHR

Declare a new pointer type.

Storage Class is the Storage Class of the memory holding object pointed to. Refer to the client API for allowed storage classes.

Capability:
UntypedPointersKHR

3

4417

Result <id>

Storage Class

Add the following instructions to Section 3.37.8 Memory Instructions:

OpUntypedVariableKHR

Allocate an object in memory, resulting in a pointer to it.

Result Type must be an OpTypeUntypedPointerKHR.

Storage Class is the Storage Class of the memory holding the object. It must not be Generic. It must be the same storage class as the Storage Class operand of the Result Type.

Data Type is optional. It is the type of the object in memory. Data Type must be specified if Storage Class is Function, Private, or Workgroup. Refer to the client API for other storage classes.

Initializer is optional. If Initializer is present, it will be the initial value of the variable’s memory content. Initializer must be an <id> from a constant instruction or a global (module scope) variable. Initializer must have the same type as Data Type.

Capability:
UntypedPointersKHR

4 + variable

4418

<id> Result Type

Result <id>

Storage Class

Optional <id> Data Type

Optional <id> Initializer

OpUntypedAccessChainKHR

Has the same semantics as OpAccessChain, with the following additions:
- Result Type must be an OpTypeUntypedPointerKHR. Its Storage Class operand must be the same Storage Class as Base.
- a Base Type operand. It must be a non-pointer type-declaration instruction.
- Base must be a pointer type.
- Indexes walk the type hierarchy of Base Type instead of Base.

Capability:
UntypedPointersKHR

5 + variable

4419

<id> Result Type

Result <id>

<id> Base Type

<id> Base

<id>, <id>, …​
Indexes

OpUntypedInBoundsAccessChainKHR

Has the same semantics as OpUntypedAccessChainKHR, with the addition that the resulting pointer is known to point within the base object.

Capability:
UntypedPointersKHR

5 + variable

4420

<id> Result Type

Result <id>

<id> Base Type

<id> Base

<id>, <id>, …​
Indexes

OpUntypedPtrAccessChainKHR

Has the same semantics as OpPtrAccessChain, with the following additions:
- Result Type must be an OpTypeUntypedPointerKHR. Its Storage Class operand must be the same Storage Class as Base.
- a Base Type operand. It must be a non-pointer type-declaration instruction.
- Base must be a pointer type.
- Element is used to generate an OpUntypedAccessChainKHR Base.
- Indexes walk the type hierarchy of Base Type instead of Base.

Capability:
UntypedPointersKHR

6 + variable

4423

<id> Result Type

Result <id>

<id> Base Type

<id> Base

<id> Element

<id>, <id>, …​
Indexes

OpUntypedInBoundsPtrAccessChainKHR

Has the same semantics as OpUntypedPtrAccessChainKHR, with the addition that the resulting pointer is known to point within the base object.

Capability:
UntypedPointersKHR

6 + variable

4424

<id> Result Type

Result <id>

<id> Base Type

<id> Base

<id> Element

<id>, <id>, …​
Indexes

OpUntypedArrayLengthKHR

Length of a run-time array.

Result Type must be an OpTypeInt with 32-bit Width and 0 Signedness.

Structure must be a Block-decorated OpTypeStruct whose last member is a run-time array.

Pointer must be a pointer type. Pointer must have the same value as a descriptor. That is, the value must be the same as a variable decorated with DescriptorSet and Binding or an element in such a variable when the data type is an array of Block-decorated structures.

Array member is an unsigned 32-bit integer index of the last member of Structure. That member’s type must be from OpTypeRuntimeArray.

Capability:
UntypedPointersKHR

6

4425

<id> Result Type

Result <id>

<id> Structure

<id> Pointer

Literal Array member

OpUntypedPrefetchKHR

Prefetch Num Bytes bytes of data from Pointer into the global cache. This instruction does not affect the functionality of the module.

Pointer must be a pointer whose Storage Class is CrossWorkgroup.

Num Bytes is the number of bytes to prefetch. Its type must be an integer scalar.

RW is optional. If RW is present, it specifies whether the fetch should be for a read or write. It must be a constant instruction with an integer scalar type. The value must be either 0 (for read) or 1 (for write).

Locality is optional. If Locality is present, it specifies the temporal locality for the caching. It must be a constant instruction with an integer scalar type. The value must be between 0 (for no locality) and 3 (for extreme locality) inclusive.

Cache Type is optional. If Cache Type is present, it specifies the type of cache. It must be a constant instruction with an integer scalar type. The value must be either 0 (for instruction cache) or 1 (for data cache).

The default values of all optional operands are implementation defined.

Capability:
UntypedPointersKHR

3 + variable

4426

<id> Pointer Type

<id> Num Bytes

Optional <id> RW

Optional <id> Locality

Optional <id> Cache Type

Modifications to the extension SPV_KHR_workgroup_memory_explicit_layout

Change:

If WorkgroupMemoryExplicitLayoutKHR capability is declared, for each entry point in the module

  • Either all or none of the Workgroup Storage Class variables in the entry point interface must point to struct types decorated with Block.

  • If more than one Workgroup Storage Class variable in the entry point interface point to a type decorated with Block, all of them must be decorated with Aliased.

To:

If WorkgroupMemoryExplicitLayoutKHR capability is declared, for each entry point in the module

  • Either all or none of the Workgroup Storage Class variables in the entry point interface must point to struct types decorated with Block.

  • If more than one Workgroup Storage Class variable in the entry point interface point to a type decorated with Block, all of them must be decorated with Aliased, unless the UntypedPointersKHR capability is declared. Only those variables decorated with Aliased may alias each other.

Change:

In addition to the above table, memory object declarations in the CrossWorkgroup, Function, Input, Output or Private storage classes must also have matching pointee types for aliasing to be present. The restriction also applies for Workgroup storage class, except when WorkgroupMemoryExplicitLayoutKHR capability is declared and the pointee types are structs decorated with Block. In all other cases the decoration is ignored.

To:

In addition to the above table, memory object declarations in the CrossWorkgroup, Function, Input, Output or Private storage classes must also have matching pointee types for aliasing to be present. The restriction also applies for Workgroup storage class, except when WorkgroupMemoryExplicitLayoutKHR capability is declared and the pointee types are structs decorated with Block or the pointer has the type OpTypeUntypedPointerKHR. In all other cases the decoration is ignored.

Modifications to the extension SPV_KHR_cooperative_matrix

In the descriptions of OpCooperativeMatrixLoadKHR and OpCooperativeMatrixStoreKHR change:

Pointer is a pointer. Its type must be an OpTypePointer whose Type operand is a scalar or vector type. If the Shader capability was declared, Pointer must point into an array and any ArrayStride decoration on Pointer is ignored.

To:

Pointer is a pointer. Its type must be a pointer type. If it is an OpTypePointer, its Type operand must be a scalar or vector type. If the Shader capability was declared and Pointer’s type is OpTypePointer, Pointer must point into an array and any ArrayStride decoration on Pointer is ignored.

And, change:

Stride further qualifies how matrix elements are laid out in memory. It must be a scalar integer type and its exact semantics depend on MemoryLayout.

To:

Stride further qualifies how matrix elements are laid out in memory. It must be a scalar integer type and its exact semantics depend on MemoryLayout. When the type of Pointer is OpTypePointer, Stride is specified in number of elements based on the Type operand of the pointer type. When the type of Pointer is OpTypeUntypedPointerKHR, Stride is specified in bytes.

Modifications to the OpenCL.std extended instruction set

Change the pointer naming conventions from:

  • pointer(storage) denotes an OpTypePointer which points to the storage Storage Class.

    • pointer(constant) denotes an OpTypePointer which points to the UniformConstant Storage Class.

    • pointer(generic) denotes an OpTypePointer which points to the Generic Storage Class.

    • pointer(global) denotes an OpTypePointer which points to the CrossWorkgroup Storage Class.

    • pointer(local) denotes an OpTypePointer which points to the Workgroup Storage Class.

    • pointer(private) denotes an OpTypePointer which points to the Function Storage Class.

To:

  • pointer(storage) denotes an OpTypePointer or OpTypeUntypedPointerKHR which points to the storage Storage Class.

    • pointer(constant) denotes an OpTypePointer or OpTypeUntypedPointerKHR which points to the UniformConstant Storage Class.

    • pointer(generic) denotes an OpTypePointer or OpTypeUntypedPointerKHR which points to the Generic Storage Class.

    • pointer(global) denotes an OpTypePointer or OpTypeUntypedPointerKHR which points to the CrossWorkgroup Storage Class.

    • pointer(local) denotes an OpTypePointer or OpTypeUntypedPointerKHR which points to the Workgroup Storage Class.

    • pointer(private) denotes an OpTypePointer or OpTypeUntypedPointerKHR which points to the Function Storage Class.

In the descriptions of the extended instructions, whenever a pointer operand is described as pointer(p1, p2, …​) to data types, split the sentence into two as follows:

operand must be a pointer(p1, …​). If it is a typed pointer, it must point to data types.

This applies to the following instructions:

  • ptr in fract

  • exp in frexp

  • signp in lgamma_r

  • iptr in modf

  • quo in remquo

  • cosval in sincos

  • p in vloadn

  • p in vstoren

  • p in vload_half

  • p in vload_halfn

  • p in vstore_half

  • p in vstore_half_r

  • p in vstore_halfn

  • p in vstore_halfn_r

  • p in vloada_halfn

  • p in vstorea_halfn

  • p in vstorea_halfn_r

  • format in printf

In the above instructions any type matching rule that applies to a pointee type is only applied to typed pointers. For untyped pointers, the instructions as if the it were an appropriate typed pointer.

Note: prefetch should be replaced with OpUntypedPrefetchKHR.

Issues

  1. Should this extension modify any other extensions?

    Resolved

    This extension modifies SPV_KHR_workgroup_memory_explicit_layout and SPV_KHR_cooperative_matrix.

  2. Should this extension include pointer access chain equivalents?

    Resolved

    OpUntypedPtrAccessChainKHR and OpUntypedInBoundsPtrAccessChainKHR are not strictly necessary. OpUntypedAccessChainKHR (or OpUntypedInBoundsAccessChainKHR) could be used in place in all cases by changing the Base Type to be an array instead of just the element type; however, to simplify implementation transitions these instructions are included.

  3. Should this extension modify any extended instructions?

    Resolved

    This extension modifies the OpenCL.std extended instruction set. GLSL.std.450 is not modified as the interpolation instructions operate on the Input storage class and FrexpStruct and ModfStruct should be preferred to the version that utilize pointers.

Revision History

Rev

Date

Author

Changes

2

2024-08-08

Kevin Petit

Clarify OpPtrDiff support

1

2024-05-29

Alan Baker

Initial Revision