[llvm] f5e1cd5 - [SPIR-V] Extend SPIRVUsage.rst document (#84744)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 26 03:06:53 PDT 2024
Author: Michal Paszkowski
Date: 2024-03-26T03:06:49-07:00
New Revision: f5e1cd5625bccef71b7c914b39fcc5d547ebb610
URL: https://github.com/llvm/llvm-project/commit/f5e1cd5625bccef71b7c914b39fcc5d547ebb610
DIFF: https://github.com/llvm/llvm-project/commit/f5e1cd5625bccef71b7c914b39fcc5d547ebb610.diff
LOG: [SPIR-V] Extend SPIRVUsage.rst document (#84744)
Added:
Modified:
llvm/docs/SPIRVUsage.rst
Removed:
################################################################################
diff --git a/llvm/docs/SPIRVUsage.rst b/llvm/docs/SPIRVUsage.rst
index 5ca035b68392f0..a183877c48cb22 100644
--- a/llvm/docs/SPIRVUsage.rst
+++ b/llvm/docs/SPIRVUsage.rst
@@ -14,10 +14,43 @@ Introduction
The SPIR-V target provides code generation for the SPIR-V binary format described
in `the official SPIR-V specification <https://www.khronos.org/registry/SPIR-V/>`_.
+Usage
+=====
+
+The SPIR-V backend can be invoked either from LLVM's Static Compiler (llc) or Clang,
+allowing developers to compile LLVM intermediate language (IL) files or OpenCL kernel
+sources directly to SPIR-V. This section outlines the usage of various commands to
+leverage the SPIR-V backend for
diff erent purposes.
+
+Static Compiler Commands
+------------------------
+
+1. **Basic SPIR-V Compilation**
+ Command: `llc -mtriple=spirv32-unknown-unknown input.ll -o output.spvt`
+ Description: This command compiles an LLVM IL file (`input.ll`) to a SPIR-V binary (`output.spvt`) for a 32-bit architecture.
+
+2. **Compilation with Extensions and Optimization**
+ Command: `llc -O1 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_arbitrary_precision_integers input.ll -o output.spvt`
+ Description: Compiles an LLVM IL file to SPIR-V with (`-O1`) optimizations, targeting a 64-bit architecture. It enables the SPV_INTEL_arbitrary_precision_integers extension.
+
+3. **SPIR-V Binary Generation**
+ Command: `llc -O0 -mtriple=spirv64-unknown-unknown -filetype=obj input.ll -o output.spvt`
+ Description: Generates a SPIR-V object file (`output.spvt`) from an LLVM module, targeting a 64-bit SPIR-V architecture with no optimizations.
+
+Clang Commands
+--------------
+
+1. **SPIR-V Generation**
+ Command: `clang –target=spirv64 input.cl`
+ Description: Generates a SPIR-V file directly from an OpenCL kernel source file (`input.cl`).
+
+Compiler Options
+================
+
.. _spirv-target-triples:
Target Triples
-==============
+--------------
For cross-compilation into SPIR-V use option
@@ -32,6 +65,7 @@ to specify the target triple:
============ ==============================================================
``spirv32`` SPIR-V with 32-bit pointer width.
``spirv64`` SPIR-V with 64-bit pointer width.
+ ``spirv`` SPIR-V with logical memory layout.
============ ==============================================================
.. table:: SPIR-V Subarchitectures
@@ -39,13 +73,14 @@ to specify the target triple:
=============== ==============================================================
Subarchitecture Description
=============== ==============================================================
- *<empty>* SPIR-V version deduced by tools based on the compiled input.
+ *<empty>* SPIR-V version deduced by backend based on the input.
``v1.0`` SPIR-V version 1.0.
``v1.1`` SPIR-V version 1.1.
``v1.2`` SPIR-V version 1.2.
``v1.3`` SPIR-V version 1.3.
``v1.4`` SPIR-V version 1.4.
``v1.5`` SPIR-V version 1.5.
+ ``v1.6`` SPIR-V version 1.6.
=============== ==============================================================
.. table:: SPIR-V Vendors
@@ -62,6 +97,9 @@ to specify the target triple:
OS Description
===================== ============================================================
*<empty>*/``unknown`` Defaults to the OpenCL runtime.
+ ``vulkan`` Vulkan shader runtime.
+ ``vulkan1.2`` Vulkan 1.2 runtime, corresponding to SPIR-V 1.5.
+ ``vulkan1.3`` Vulkan 1.3 runtime, corresponding to SPIR-V 1.6.
===================== ============================================================
.. table:: SPIR-V Environments
@@ -69,20 +107,95 @@ to specify the target triple:
===================== ==============================================================
Environment Description
===================== ==============================================================
- *<empty>*/``unknown`` Defaults to the OpenCL environment.
+ *<empty>*/``unknown`` OpenCL environment or deduced by backend based on the input.
===================== ==============================================================
Example:
``-target spirv64v1.0`` can be used to compile for SPIR-V version 1.0 with 64-bit pointer width.
-.. _spirv-types:
+.. _spirv-extensions:
+
+Extensions
+----------
+
+The SPIR-V backend supports a variety of `extensions <https://github.com/KhronosGroup/SPIRV-Registry/tree/main/extensions>`_
+that enable or enhance features beyond the core SPIR-V specification.
+These extensions can be enabled using the ``-spirv-extensions`` option
+followed by the name of the extension(s) you wish to enable. Below is a
+list of supported SPIR-V extensions, sorted alphabetically by their extension names:
+
+.. list-table:: Supported SPIR-V Extensions
+ :widths: 50 150
+ :header-rows: 1
+
+ * - Extension Name
+ - Description
+ * - ``SPV_EXT_shader_atomic_float16_add``
+ - Extends the SPV_EXT_shader_atomic_float_add extension to support atomically adding to 16-bit floating-point numbers in memory.
+ * - ``SPV_EXT_shader_atomic_float_add``
+ - Adds atomic add instruction on floating-point numbers.
+ * - ``SPV_EXT_shader_atomic_float_min_max``
+ - Adds atomic min and max instruction on floating-point numbers.
+ * - ``SPV_INTEL_arbitrary_precision_integers``
+ - Allows generating arbitrary width integer types.
+ * - ``SPV_INTEL_bfloat16_conversion``
+ - Adds instructions to convert between single-precision 32-bit floating-point values and 16-bit bfloat16 values.
+ * - ``SPV_INTEL_function_pointers``
+ - Allows translation of function pointers.
+ * - ``SPV_INTEL_optnone``
+ - Adds OptNoneINTEL value for Function Control mask that indicates a request to not optimize the function.
+ * - ``SPV_INTEL_subgroups``
+ - Allows work items in a subgroup to share data without the use of local memory and work group barriers, and to utilize specialized hardware to load and store blocks of data from images or buffers.
+ * - ``SPV_INTEL_usm_storage_classes``
+ - Introduces two new storage classes that are subclasses of the CrossWorkgroup storage class that provides additional information that can enable optimization.
+ * - ``SPV_INTEL_variable_length_array``
+ - Allows to allocate local arrays whose number of elements is unknown at compile time.
+ * - ``SPV_KHR_bit_instructions``
+ - Enables bit instructions to be used by SPIR-V modules without requiring the Shader capability.
+ * - ``SPV_KHR_expect_assume``
+ - Provides additional information to a compiler, similar to the llvm.assume and llvm.expect intrinsics.
+ * - ``SPV_KHR_float_controls``
+ - Provides new execution modes to control floating-point computations by overriding an implementation’s default behavior for rounding modes, denormals, signed zero, and infinities.
+ * - ``SPV_KHR_linkonce_odr``
+ - Allows to use the LinkOnceODR linkage type that lets a function or global variable to be merged with other functions or global variables of the same name when linkage occurs.
+ * - ``SPV_KHR_no_integer_wrap_decoration``
+ - Adds decorations to indicate that a given instruction does not cause integer wrapping.
+ * - ``SPV_KHR_subgroup_rotate``
+ - Adds a new instruction that enables rotating values across invocations within a subgroup.
+ * - ``SPV_KHR_uniform_group_instructions``
+ - Allows support for additional group operations within uniform control flow.
-Representing special types in SPIR-V
-====================================
+To enable multiple extensions, list them separated by spaces. For example, to enable support for atomic operations on floating-point numbers and arbitrary precision integers, use:
+
+``-spirv-ext=+SPV_EXT_shader_atomic_float_add,+SPV_INTEL_arbitrary_precision_integers``
+
+To enable all extensions, use the following option:
+``-spirv-ext=all``
+
+To enable all extensions except specified, specify ``all`` followed by a list of disallowed extensions. For example:
+``-spirv-ext=all,-SPV_INTEL_arbitrary_precision_integers``
+
+SPIR-V representation in LLVM IR
+================================
+
+SPIR-V is intentionally designed for seamless integration with various Intermediate
+Representations (IRs), including LLVM IR, facilitating straightforward mappings for
+most of its entities. The development of the SPIR-V backend has been guided by a
+principle of compatibility with the `Khronos Group SPIR-V LLVM Translator <https://github.com/KhronosGroup/SPIRV-LLVM-Translator>`_.
+Consequently, the input representation accepted by the SPIR-V backend aligns closely
+with that detailed in `the SPIR-V Representation in LLVM document <https://github.com/KhronosGroup/SPIRV-LLVM-Translator/blob/main/docs/SPIRVRepresentationInLLVM.rst>`_.
+This document, along with the sections that follow, delineate the main points and focus
+on any
diff erences between the LLVM IR that this backend processes and the conventions
+used by other tools.
+
+.. _spirv-special-types:
+
+Special types
+-------------
SPIR-V specifies several kinds of opaque types. These types are represented
-using target extension types. These types are represented as follows:
+using target extension types and are represented as follows:
.. table:: SPIR-V Opaque Types
@@ -108,3 +221,210 @@ dimensionality parameter as ``1`` meaning 2D. Sampled image types include the
parameters of its underlying image type, so that a sampled image for the
previous type has the representation
``target("spirv.SampledImage, void, 1, 1, 0, 0, 0, 0, 0)``.
+
+.. _spirv-intrinsics:
+
+Target Intrinsics
+-----------------
+
+The SPIR-V backend employs several LLVM IR intrinsics that facilitate various low-level
+operations essential for generating correct and efficient SPIR-V code. These intrinsics
+cover a range of functionalities from type assignment and memory management to control
+flow and atomic operations. Below is a detailed table of selected intrinsics used in the
+SPIR-V backend, along with their descriptions and argument details.
+
+.. list-table:: LLVM IR Intrinsics for SPIR-V
+ :widths: 25 15 20 40
+ :header-rows: 1
+
+ * - Intrinsic ID
+ - Return Type
+ - Argument Types
+ - Description
+ * - `int_spv_assign_type`
+ - None
+ - `[Type, Metadata]`
+ - Associates a type with metadata, crucial for maintaining type information in SPIR-V structures. Not emitted directly but supports the type system internally.
+ * - `int_spv_assign_ptr_type`
+ - None
+ - `[Type, Metadata, Integer]`
+ - Similar to `int_spv_assign_type`, but for pointer types with an additional integer specifying the storage class. Supports SPIR-V's detailed pointer type system. Not emitted directly.
+ * - `int_spv_assign_name`
+ - None
+ - `[Type, Vararg]`
+ - Assigns names to types or values, enhancing readability and debuggability of SPIR-V code. Not emitted directly but used for metadata enrichment.
+ * - `int_spv_track_constant`
+ - Type
+ - `[Type, Metadata]`
+ - Tracks constants in the SPIR-V module. Essential for optimizing and reducing redundancy. Emitted for internal use only.
+ * - `int_spv_init_global`
+ - None
+ - `[Type, Type]`
+ - Initializes global variables, a necessary step for ensuring correct global state management in SPIR-V. Emitted for internal use only.
+ * - `int_spv_unref_global`
+ - None
+ - `[Type]`
+ - Manages the lifetime of global variables by marking them as unreferenced, thus enabling optimizations related to global variable usage. Emitted for internal use only.
+ * - `int_spv_gep`
+ - Pointer
+ - `[Boolean, Type, Vararg]`
+ - Computes the address of a sub-element of an aggregate type. Critical for accessing array elements and structure fields. Supports conditionally addressing elements in a generic way.
+ * - `int_spv_load`
+ - 32-bit Integer
+ - `[Pointer, 16-bit Integer, 8-bit Integer]`
+ - Loads a value from a memory location. The additional integers specify memory access and alignment details, vital for ensuring correct and efficient memory operations.
+ * - `int_spv_store`
+ - None
+ - `[Type, Pointer, 16-bit Integer, 8-bit Integer]`
+ - Stores a value to a memory location. Like `int_spv_load`, it includes specifications for memory access and alignment, essential for memory operations.
+ * - `int_spv_extractv`
+ - Type
+ - `[32-bit Integer, Vararg]`
+ - Extracts a value from a vector, allowing for vector operations within SPIR-V. Enables manipulation of vector components.
+ * - `int_spv_insertv`
+ - 32-bit Integer
+ - `[32-bit Integer, Type, Vararg]`
+ - Inserts a value into a vector. Complementary to `int_spv_extractv`, it facilitates the construction and manipulation of vectors.
+ * - `int_spv_extractelt`
+ - Type
+ - `[Type, Any Integer]`
+ - Extracts an element from an aggregate type based on an index. Essential for operations on arrays and vectors.
+ * - `int_spv_insertelt`
+ - Type
+ - `[Type, Type, Any Integer]`
+ - Inserts an element into an aggregate type at a specified index. Allows for building and modifying arrays and vectors.
+ * - `int_spv_const_composite`
+ - 32-bit Integer
+ - `[Vararg]`
+ - Constructs a composite type from given elements. Key for creating arrays, structs, and vectors from individual components.
+ * - `int_spv_bitcast`
+ - Type
+ - `[Type]`
+ - Performs a bit-wise cast between types. Critical for type conversions that do not change the bit representation.
+ * - `int_spv_ptrcast`
+ - Type
+ - `[Type, Metadata, Integer]`
+ - Casts pointers between
diff erent types. Similar to `int_spv_bitcast` but specifically for pointers, taking into account SPIR-V's strict type system.
+ * - `int_spv_switch`
+ - None
+ - `[Type, Vararg]`
+ - Implements a multi-way branch based on a value. Enables complex control flow structures, similar to the switch statement in high-level languages.
+ * - `int_spv_cmpxchg`
+ - 32-bit Integer
+ - `[Type, Vararg]`
+ - Performs an atomic compare-and-exchange operation. Crucial for synchronization and concurrency control in compute shaders.
+ * - `int_spv_unreachable`
+ - None
+ - `[]`
+ - Marks a point in the code that should never be reached, enabling optimizations by indicating unreachable code paths.
+ * - `int_spv_alloca`
+ - Type
+ - `[]`
+ - Allocates memory on the stack. Fundamental for local variable storage in functions.
+ * - `int_spv_alloca_array`
+ - Type
+ - `[Any Integer]`
+ - Allocates an array on the stack. Extends `int_spv_alloca` to support array allocations, essential for temporary arrays.
+ * - `int_spv_undef`
+ - 32-bit Integer
+ - `[]`
+ - Generates an undefined value. Useful for optimizations and indicating uninitialized variables.
+ * - `int_spv_assume`
+ - None
+ - `[1-bit Integer]`
+ - Provides hints to the optimizer about assumptions that can be made about program state. Improves optimization potential.
+ * - `int_spv_expect`
+ - Any Integer Type
+ - `[Type, Type]`
+ - Guides branch prediction by indicating expected branch paths. Enhances performance by optimizing common code paths.
+ * - `int_spv_thread_id`
+ - 32-bit Integer
+ - `[32-bit Integer]`
+ - Retrieves the thread ID within a workgroup. Essential for identifying execution context in parallel compute operations.
+ * - `int_spv_create_handle`
+ - Pointer
+ - `[8-bit Integer]`
+ - Creates a resource handle for graphics or compute resources. Facilitates the management and use of resources in shaders.
+
+.. _spirv-builtin-functions:
+
+Builtin Functions
+-----------------
+
+The following section highlights the representation of SPIR-V builtins in LLVM IR,
+emphasizing builtins that do not have direct counterparts in LLVM.
+
+Instructions as Function Calls
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+SPIR-V builtins without direct LLVM counterparts are represented as LLVM function calls.
+These functions, termed SPIR-V builtin functions, follow an IA64 mangling scheme with
+SPIR-V-specific extensions. Parsing non-mangled calls to builtins is supported in some cases,
+but not tested extensively. The general format is:
+
+.. code-block:: c
+
+ __spirv_{OpCodeName}{_OptionalPostfixes}
+
+Where `{OpCodeName}` is the SPIR-V opcode name sans the "Op" prefix, and
+`{OptionalPostfixes}` are decoration-specific postfixes, if any. The mangling and
+postfixes allow for the representation of SPIR-V's rich instruction set within LLVM's
+framework.
+
+Extended Instruction Sets
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+SPIR-V defines several extended instruction sets for additional functionalities, such as
+OpenCL-specific operations. In LLVM IR, these are represented by function calls to
+mangled builtins and selected based on the environment. For example:
+
+.. code-block:: c
+
+ acos_f32
+
+represents the `acos` function from the OpenCL extended instruction set for a float32
+input.
+
+Builtin Variables
+~~~~~~~~~~~~~~~~~
+
+SPIR-V builtin variables, which provide access to special hardware or execution model
+properties, are mapped to either LLVM function calls or LLVM global variables. The
+representation follows the naming convention:
+
+.. code-block:: c
+
+ __spirv_BuiltIn{VariableName}
+
+For instance, the SPIR-V builtin `GlobalInvocationId` is accessible in LLVM IR as
+`__spirv_BuiltInGlobalInvocationId`.
+
+Vector Load and Store Builtins
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+SPIR-V's capabilities for loading and storing vectors are represented in LLVM IR using
+functions that mimic the SPIR-V instructions. These builtins handle cases that LLVM's
+native instructions do not directly support, enabling fine-grained control over memory
+operations.
+
+Atomic Operations
+~~~~~~~~~~~~~~~~~
+
+SPIR-V's atomic operations, especially those operating on floating-point data, are
+represented in LLVM IR with corresponding function calls. These builtins ensure
+atomicity in operations where LLVM might not have direct support, essential for parallel
+execution and synchronization.
+
+Image Operations
+~~~~~~~~~~~~~~~~
+
+SPIR-V provides extensive support for image and sampler operations, which LLVM
+represents through function calls to builtins. These include image reads, writes, and
+queries, allowing detailed manipulation of image data and parameters.
+
+Group and Subgroup Operations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+For workgroup and subgroup operations, LLVM uses function calls to represent SPIR-V's
+group-based instructions. These builtins facilitate group synchronization, data sharing,
+and collective operations essential for efficient parallel computation.
More information about the llvm-commits
mailing list