[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