brintos

brintos / llvm-project-archived public Read only

0
0
Text · 33.0 KiB · 88164e6 Raw
635 lines · plain
1=============================2User Guide for SPIR-V Target3=============================4 5.. contents::6   :local:7 8.. toctree::9   :hidden:10 11Introduction12============13 14The SPIR-V target provides code generation for the SPIR-V binary format described15in  `the official SPIR-V specification <https://www.khronos.org/registry/SPIR-V/>`_.16 17Usage18=====19 20The SPIR-V backend can be invoked either from LLVM's Static Compiler (llc) or Clang,21allowing developers to compile LLVM intermediate language (IL) files or OpenCL kernel22sources directly to SPIR-V. This section outlines the usage of various commands to23leverage the SPIR-V backend for different purposes.24 25Static Compiler Commands26------------------------27 281. **Basic SPIR-V Compilation**29   Command: `llc -mtriple=spirv32-unknown-unknown input.ll -o output.spvt`30   Description: This command compiles an LLVM IL file (`input.ll`) to a SPIR-V binary (`output.spvt`) for a 32-bit architecture.31 322. **Compilation with Extensions and Optimization**33   Command: `llc -O1 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_ALTERA_arbitrary_precision_integers input.ll -o output.spvt`34   Description: Compiles an LLVM IL file to SPIR-V with (`-O1`) optimizations, targeting a 64-bit architecture. It enables the SPV_ALTERA_arbitrary_precision_integers extension.35 363. **Compilation with experimental NonSemantic.Shader.DebugInfo.100 support**37   Command: `llc --spv-emit-nonsemantic-debug-info --spirv-ext=+SPV_KHR_non_semantic_info input.ll -o output.spvt`38   Description: Compiles an LLVM IL file to SPIR-V with additional NonSemantic.Shader.DebugInfo.100 instructions. It enables the required SPV_KHR_non_semantic_info extension.39 404. **SPIR-V Binary Generation**41   Command: `llc -O0 -mtriple=spirv64-unknown-unknown -filetype=obj input.ll -o output.spvt`42   Description: Generates a SPIR-V object file (`output.spvt`) from an LLVM module, targeting a 64-bit SPIR-V architecture with no optimizations.43 44Clang Commands45--------------46 471. **SPIR-V Generation**48   Command: `clang –target=spirv64 input.cl`49   Description: Generates a SPIR-V file directly from an OpenCL kernel source file (`input.cl`).50 51Compiler Options52================53 54.. _spirv-target-triples:55 56Target Triples57--------------58 59For cross-compilation into SPIR-V use option60 61``-target <Architecture><Subarchitecture>-<Vendor>-<OS>-<Environment>``62 63to specify the target triple:64 65  .. table:: SPIR-V Architectures66 67     ============ ==============================================================68     Architecture Description69     ============ ==============================================================70     ``spirv32``   SPIR-V with 32-bit pointer width.71     ``spirv64``   SPIR-V with 64-bit pointer width.72     ``spirv``     SPIR-V with logical memory layout.73     ============ ==============================================================74 75  .. table:: SPIR-V Subarchitectures76 77     =============== ==============================================================78     Subarchitecture Description79     =============== ==============================================================80     *<empty>*        SPIR-V version deduced by backend based on the input.81     ``v1.0``         SPIR-V version 1.0.82     ``v1.1``         SPIR-V version 1.1.83     ``v1.2``         SPIR-V version 1.2.84     ``v1.3``         SPIR-V version 1.3.85     ``v1.4``         SPIR-V version 1.4.86     ``v1.5``         SPIR-V version 1.5.87     ``v1.6``         SPIR-V version 1.6.88     =============== ==============================================================89 90  .. table:: SPIR-V Vendors91 92     ===================== ==============================================================93     Vendor                Description94     ===================== ==============================================================95     *<empty>*/``unknown``  Generic SPIR-V target without any vendor-specific settings.96     ``amd``                AMDGCN SPIR-V target, with support for target specific97                            builtins and ASM, meant to be consumed by AMDGCN toolchains.98     ===================== ==============================================================99 100  .. table:: Operating Systems101 102     ===================== ==============================================================103     OS                    Description104     ===================== ==============================================================105     *<empty>*/``unknown``  Defaults to the OpenCL runtime.106     ``vulkan``             Vulkan shader runtime.107     ``vulkan1.2``          Vulkan 1.2 runtime, corresponding to SPIR-V 1.5.108     ``vulkan1.3``          Vulkan 1.3 runtime, corresponding to SPIR-V 1.6.109     ``amdhsa``             AMDHSA runtime, meant to be used on HSA compatible runtimes,110                            corresponding to SPIR-V 1.6.111     ===================== ==============================================================112 113  .. table:: SPIR-V Environments114 115     ===================== ==============================================================116     Environment           Description117     ===================== ==============================================================118     *<empty>*/``unknown``  OpenCL environment or deduced by backend based on the input.119     ===================== ==============================================================120 121Example:122 123``-target spirv64v1.0`` can be used to compile for SPIR-V version 1.0 with 64-bit pointer width.124 125``-target spirv64-amd-amdhsa`` can be used to compile for AMDGCN flavoured SPIR-V with 64-bit pointer width.126 127.. _spirv-extensions:128 129Extensions130----------131 132The SPIR-V backend supports a variety of `extensions <https://github.com/KhronosGroup/SPIRV-Registry/tree/main/extensions>`_133that enable or enhance features beyond the core SPIR-V specification.134The enabled extensions can be controlled using the ``-spirv-ext`` option followed by a list of135extensions to enable or disable, each prefixed with ``+`` or ``-``, respectively.136 137To enable multiple extensions, list them separated by comma. For example, to enable support for atomic operations on floating-point numbers and arbitrary precision integers, use:138 139``-spirv-ext=+SPV_EXT_shader_atomic_float_add,+SPV_ALTERA_arbitrary_precision_integers``140 141To enable all extensions, use the following option:142``-spirv-ext=all``143 144To enable all KHR extensions, use the following option:145``-spirv-ext=khr``146 147To enable all extensions except specified, specify ``all`` followed by a list of disallowed extensions. For example:148``-spirv-ext=all,-SPV_ALTERA_arbitrary_precision_integers``149 150Below is a list of supported SPIR-V extensions, sorted alphabetically by their extension names:151 152.. list-table:: Supported SPIR-V Extensions153   :widths: 50 150154   :header-rows: 1155 156   * - Extension Name157     - Description158   * - ``SPV_EXT_arithmetic_fence``159     - Adds an instruction that prevents fast-math optimizations between its argument and the expression that contains it.160   * - ``SPV_EXT_demote_to_helper_invocation``161     - Adds an instruction that demotes a fragment shader invocation to a helper invocation.162   * - ``SPV_EXT_optnone``163     - Adds OptNoneEXT value for Function Control mask that indicates a request to not optimize the function.164   * - ``SPV_EXT_shader_atomic_float16_add``165     - Extends the SPV_EXT_shader_atomic_float_add extension to support atomically adding to 16-bit floating-point numbers in memory.166   * - ``SPV_EXT_shader_atomic_float_add``167     - Adds atomic add instruction on floating-point numbers.168   * - ``SPV_EXT_shader_atomic_float_min_max``169     - Adds atomic min and max instruction on floating-point numbers.170   * - ``SPV_INTEL_16bit_atomics``171     - Extends the SPV_EXT_shader_atomic_float_add and SPV_EXT_shader_atomic_float_min_max to support addition, minimum and maximum on 16-bit `bfloat16` floating-point numbers in memory.172   * - ``SPV_INTEL_2d_block_io``173     - Adds additional subgroup block prefetch, load, load transposed, load transformed and store instructions to read two-dimensional blocks of data from a two-dimensional region of memory, or to write two-dimensional blocks of data to a two dimensional region of memory.174   * - ``SPV_ALTERA_arbitrary_precision_integers``175     - Allows generating arbitrary width integer types.176   * - ``SPV_INTEL_bindless_images``177     - Adds instructions to convert convert unsigned integer handles to images, samplers and sampled images.178   * - ``SPV_INTEL_bfloat16_arithmetic``179     - Allows the use of 16-bit bfloat16 values in arithmetic and relational operators.180   * - ``SPV_INTEL_bfloat16_conversion``181     - Adds instructions to convert between single-precision 32-bit floating-point values and 16-bit bfloat16 values.182   * - ``SPV_INTEL_cache_controls``183     - Allows cache control information to be applied to memory access instructions.184   * - ``SPV_INTEL_float_controls2``185     - Adds execution modes and decorations to control floating-point computations.186   * - ``SPV_INTEL_function_pointers``187     - Allows translation of function pointers.188   * - ``SPV_INTEL_inline_assembly``189     - Allows to use inline assembly.190   * - ``SPV_INTEL_global_variable_host_access``191     - Adds decorations that can be applied to global (module scope) variables.192   * - ``SPV_INTEL_global_variable_fpga_decorations``193     - Adds decorations that can be applied to global (module scope) variables to help code generation for FPGA devices.194   * - ``SPV_INTEL_kernel_attributes``195     - Adds execution modes that can be applied to entry points to inform scheduling.196   * - ``SPV_INTEL_media_block_io``197     - Adds additional subgroup block read and write functionality that allow applications to flexibly specify the width and height of the block to read from or write to a 2D image.198   * - ``SPV_INTEL_memory_access_aliasing``199     - Adds instructions and decorations to specify memory access aliasing, similar to alias.scope and noalias LLVM metadata.200   * - ``SPV_INTEL_optnone``201     - Adds OptNoneINTEL value for Function Control mask that indicates a request to not optimize the function.202   * - ``SPV_INTEL_split_barrier``203     - Adds SPIR-V instructions to split a control barrier into two separate operations: the first indicates that an invocation has "arrived" at the barrier but should continue executing, and the second indicates that an invocation should "wait" for other invocations to arrive at the barrier before executing further.204   * - ``SPV_INTEL_subgroups``205     - 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.206   * - ``SPV_INTEL_usm_storage_classes``207     - Introduces two new storage classes that are subclasses of the CrossWorkgroup storage class that provides additional information that can enable optimization.208   * - ``SPV_INTEL_variable_length_array``209     - Allows to allocate local arrays whose number of elements is unknown at compile time.210   * - ``SPV_INTEL_joint_matrix``211     - Adds few matrix capabilities on top of SPV_KHR_cooperative_matrix extension, such as matrix prefetch, get element coordinate and checked load/store/construct instructions, tensor float 32 and bfloat type interpretations for multiply-add instruction.212   * - ``SPV_KHR_bit_instructions``213     - Enables bit instructions to be used by SPIR-V modules without requiring the Shader capability.214   * - ``SPV_KHR_expect_assume``215     - Provides additional information to a compiler, similar to the llvm.assume and llvm.expect intrinsics.216   * - ``SPV_KHR_float_controls``217     - Provides new execution modes to control floating-point computations by overriding an implementation’s default behavior for rounding modes, denormals, signed zero, and infinities.218   * - ``SPV_KHR_integer_dot_product``219     - Adds instructions for dot product operations on integer vectors with optional accumulation. Integer vectors includes 4-component vector of 8-bit integers and 4-component vectors of 8-bit integers packed into 32-bit integers.220   * - ``SPV_KHR_linkonce_odr``221     - 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.222   * - ``SPV_KHR_no_integer_wrap_decoration``223     - Adds decorations to indicate that a given instruction does not cause integer wrapping.224   * - ``SPV_KHR_shader_clock``225     - Adds the extension cl_khr_kernel_clock that adds the ability for a kernel to sample the value from clocks provided by compute units.226   * - ``SPV_KHR_subgroup_rotate``227     - Adds a new instruction that enables rotating values across invocations within a subgroup.228   * - ``SPV_KHR_uniform_group_instructions``229     - Allows support for additional group operations within uniform control flow.230   * - ``SPV_KHR_non_semantic_info``231     - Adds the ability to declare extended instruction sets that have no semantic impact and can be safely removed from a module.232   * - ``SPV_INTEL_fp_max_error``233     - Adds the ability to specify the maximum error for floating-point operations.234   * - ``SPV_INTEL_ternary_bitwise_function``235     - Adds a bitwise instruction on three operands and a look-up table index for specifying the bitwise operation to perform.236   * - ``SPV_INTEL_subgroup_matrix_multiply_accumulate``237     - Adds an instruction to compute the matrix product of an M x K matrix with a K x N matrix and then add an M x N matrix.238   * - ``SPV_INTEL_int4``239     - Adds support for 4-bit integer type, and allow this type to be used in cooperative matrices.240   * - ``SPV_KHR_float_controls2``241     - Adds execution modes and decorations to control floating-point computations in both kernels and shaders. It can be used on whole modules and individual instructions.242   * - ``SPV_INTEL_predicated_io``243     - Adds predicated load and store instructions that conditionally read from or write to memory based on a boolean predicate.244   * - ``SPV_KHR_maximal_reconvergence``245     - Adds execution mode and capability to enable maximal reconvergence.246   * - ``SPV_ALTERA_blocking_pipes``247     - Adds new pipe read and write functions that have blocking semantics instead of the non-blocking semantics of the existing pipe read/write functions.248   * - ``SPV_ALTERA_arbitrary_precision_fixed_point``249     - Add instructions for fixed point arithmetic. The extension works without SPV_ALTERA_arbitrary_precision_integers, but together they allow greater flexibility in representing arbitrary precision data types.250 251 252SPIR-V representation in LLVM IR253================================254 255SPIR-V is intentionally designed for seamless integration with various Intermediate256Representations (IRs), including LLVM IR, facilitating straightforward mappings for257most of its entities. The development of the SPIR-V backend has been guided by a258principle of compatibility with the `Khronos Group SPIR-V LLVM Translator <https://github.com/KhronosGroup/SPIRV-LLVM-Translator>`_.259Consequently, the input representation accepted by the SPIR-V backend aligns closely260with that detailed in `the SPIR-V Representation in LLVM document <https://github.com/KhronosGroup/SPIRV-LLVM-Translator/blob/main/docs/SPIRVRepresentationInLLVM.rst>`_.261This document, along with the sections that follow, delineate the main points and focus262on any differences between the LLVM IR that this backend processes and the conventions263used by other tools.264 265.. _spirv-special-types:266 267Special types268-------------269 270SPIR-V specifies several kinds of opaque types. These types are represented271using target extension types and are represented as follows:272 273  .. table:: SPIR-V Opaque Types274 275     ================== ======================= ===========================================================================================276     SPIR-V Type        LLVM type name          LLVM type arguments277     ================== ======================= ===========================================================================================278     OpTypeImage        ``spirv.Image``         sampled type, dimensionality, depth, arrayed, MS, sampled, image format, [access qualifier]279     OpTypeImage        ``spirv.SignedImage``   sampled type, dimensionality, depth, arrayed, MS, sampled, image format, [access qualifier]280     OpTypeSampler      ``spirv.Sampler``       (none)281     OpTypeSampledImage ``spirv.SampledImage``  sampled type, dimensionality, depth, arrayed, MS, sampled, image format, [access qualifier]282     OpTypeEvent        ``spirv.Event``         (none)283     OpTypeDeviceEvent  ``spirv.DeviceEvent``   (none)284     OpTypeReserveId    ``spirv.ReserveId``     (none)285     OpTypeQueue        ``spirv.Queue``         (none)286     OpTypePipe         ``spirv.Pipe``          access qualifier287     OpTypePipeStorage  ``spirv.PipeStorage``   (none)288     NA                 ``spirv.VulkanBuffer``  ElementType, StorageClass, IsWriteable289     ================== ======================= ===========================================================================================290 291All integer arguments take the same value as they do in their `corresponding292SPIR-V instruction <https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#_type_declaration_instructions>`_.293For example, the OpenCL type ``image2d_depth_ro_t`` would be represented in294SPIR-V IR as ``target("spirv.Image", void, 1, 1, 0, 0, 0, 0, 0)``, with its295dimensionality parameter as ``1`` meaning 2D. Sampled image types include the296parameters of its underlying image type, so that a sampled image for the297previous type has the representation298``target("spirv.SampledImage, void, 1, 1, 0, 0, 0, 0, 0)``.299 300The differences between ``spirv.Image`` and ``spirv.SignedImage`` is that the301backend will generate code assuming that the format of the image is a signed302integer instead of unsigned. This is required because llvm-ir will create the303same sampled type for signed and unsigned integers. If the image format is304unknown, the backend cannot distinguish the two case.305 306See `wg-hlsl proposal 0018 <https://github.com/llvm/wg-hlsl/blob/main/proposals/0018-spirv-resource-representation.md>`_307for details on ``spirv.VulkanBuffer``.308 309.. _inline-spirv-types:310 311Inline SPIR-V Types312-------------------313 314HLSL allows users to create types representing specific SPIR-V types, using ``vk::SpirvType`` and315``vk::SpirvOpaqueType``. These are specified in the `Inline SPIR-V`_ proposal. They may be316represented using target extension types:317 318.. _Inline SPIR-V: https://microsoft.github.io/hlsl-specs/proposals/0011-inline-spirv.html#types319 320  .. table:: Inline SPIR-V Types321 322    ========================== =================== =========================323    LLVM type name             LLVM type arguments LLVM integer arguments324    ========================== =================== =========================325    ``spirv.Type``             SPIR-V operands     opcode, size, alignment326    ``spirv.IntegralConstant`` integral type       value327    ``spirv.Literal``          (none)              value328    ========================== =================== =========================329 330The operand arguments to ``spirv.Type`` may be either a ``spirv.IntegralConstant`` type,331representing an ``OpConstant`` id operand, a ``spirv.Literal`` type, representing an immediate332literal operand, or any other type, representing the id of that type as an operand.333``spirv.IntegralConstant`` and ``spirv.Literal`` may not be used outside of this context.334 335For example, ``OpTypeArray`` (opcode 28) takes an id for the element type and an id for the element336length, so an array of 16 integers could be declared as:337 338``target("spirv.Type", i32, target("spirv.IntegralConstant", i32, 16), 28, 64, 32)``339 340This will be lowered to:341 342``OpTypeArray %int %int_16``343 344``OpTypeVector`` takes an id for the component type and a literal for the component count, so a3454-integer vector could be declared as:346 347``target("spirv.Type", i32, target("spirv.Literal", 4), 23, 16, 32)``348 349This will be lowered to:350 351``OpTypeVector %int 4``352 353See `Target Extension Types for Inline SPIR-V and Decorated Types`_ for further details.354 355.. _Target Extension Types for Inline SPIR-V and Decorated Types: https://github.com/llvm/wg-hlsl/blob/main/proposals/0017-inline-spirv-and-decorated-types.md356 357.. _spirv-intrinsics:358 359Target Intrinsics360-----------------361 362The SPIR-V backend employs several LLVM IR intrinsics that facilitate various low-level363operations essential for generating correct and efficient SPIR-V code. These intrinsics364cover a range of functionalities from type assignment and memory management to control365flow and atomic operations. Below is a detailed table of selected intrinsics used in the366SPIR-V backend, along with their descriptions and argument details.367 368.. list-table:: LLVM IR Intrinsics for SPIR-V369   :widths: 25 15 20 40370   :header-rows: 1371 372   * - Intrinsic ID373     - Return Type374     - Argument Types375     - Description376   * - `int_spv_assign_type`377     - None378     - `[Type, Metadata]`379     - Associates a type with metadata, crucial for maintaining type information in SPIR-V structures. Not emitted directly but supports the type system internally.380   * - `int_spv_assign_ptr_type`381     - None382     - `[Type, Metadata, Integer]`383     - 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.384   * - `int_spv_assign_name`385     - None386     - `[Type, Vararg]`387     - Assigns names to types or values, enhancing readability and debuggability of SPIR-V code. Not emitted directly but used for metadata enrichment.388   * - `int_spv_value_md`389     - None390     - `[Metadata]`391     - Assigns a set of attributes (such as name and data type) to a value that is the argument of the associated `llvm.fake.use` intrinsic call. The latter is used as a mean to map virtual registers created by IRTranslator to the original value.392   * - `int_spv_assign_decoration`393     - None394     - `[Type, Metadata]`395     - Assigns decoration to values by associating them with metadatas. Not emitted directly but used to support SPIR-V representation in LLVM IR.396   * - `int_spv_assign_aliasing_decoration`397     - None398     - `[Type, 32-bit Integer, Metadata]`399     - Assigns one of two memory aliasing decorations (specified by the second argument) to instructions using original aliasing metadata node. Not emitted directly but used to support SPIR-V representation in LLVM IR.400   * - `int_spv_assign_fpmaxerror_decoration`401     - None402     - `[Type, Metadata]`403     - Assigns the maximum error decoration to floating-point instructions using the original metadata node. Not emitted directly but used to support SPIR-V representation in LLVM IR.404   * - `int_spv_track_constant`405     - Type406     - `[Type, Metadata]`407     - Tracks constants in the SPIR-V module. Essential for optimizing and reducing redundancy. Emitted for internal use only.408   * - `int_spv_init_global`409     - None410     - `[Type, Type]`411     - Initializes global variables, a necessary step for ensuring correct global state management in SPIR-V. Emitted for internal use only.412   * - `int_spv_unref_global`413     - None414     - `[Type]`415     - Manages the lifetime of global variables by marking them as unreferenced, thus enabling optimizations related to global variable usage. Emitted for internal use only.416   * - `int_spv_gep`417     - Pointer418     - `[Boolean, Type, Vararg]`419     - 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.420   * - `int_spv_load`421     - 32-bit Integer422     - `[Pointer, 16-bit Integer, 8-bit Integer]`423     - Loads a value from a memory location. The additional integers specify memory access and alignment details, vital for ensuring correct and efficient memory operations.424   * - `int_spv_store`425     - None426     - `[Type, Pointer, 16-bit Integer, 8-bit Integer]`427     - Stores a value to a memory location. Like `int_spv_load`, it includes specifications for memory access and alignment, essential for memory operations.428   * - `int_spv_extractv`429     - Type430     - `[32-bit Integer, Vararg]`431     - Extracts a value from a vector, allowing for vector operations within SPIR-V. Enables manipulation of vector components.432   * - `int_spv_insertv`433     - 32-bit Integer434     - `[32-bit Integer, Type, Vararg]`435     - Inserts a value into a vector. Complementary to `int_spv_extractv`, it facilitates the construction and manipulation of vectors.436   * - `int_spv_extractelt`437     - Type438     - `[Type, Any Integer]`439     - Extracts an element from an aggregate type based on an index. Essential for operations on arrays and vectors.440   * - `int_spv_insertelt`441     - Type442     - `[Type, Type, Any Integer]`443     - Inserts an element into an aggregate type at a specified index. Allows for building and modifying arrays and vectors.444   * - `int_spv_const_composite`445     - Type446     - `[Vararg]`447     - Constructs a composite type from given elements. Key for creating arrays, structs, and vectors from individual components.448   * - `int_spv_bitcast`449     - Type450     - `[Type]`451     - Performs a bit-wise cast between types. Critical for type conversions that do not change the bit representation.452   * - `int_spv_ptrcast`453     - Type454     - `[Type, Metadata, Integer]`455     - Casts pointers between different types. Similar to `int_spv_bitcast` but specifically for pointers, taking into account SPIR-V's strict type system.456   * - `int_spv_switch`457     - None458     - `[Type, Vararg]`459     - Implements a multi-way branch based on a value. Enables complex control flow structures, similar to the switch statement in high-level languages.460   * - `int_spv_cmpxchg`461     - 32-bit Integer462     - `[Type, Vararg]`463     - Performs an atomic compare-and-exchange operation. Crucial for synchronization and concurrency control in compute shaders.464   * - `int_spv_unreachable`465     - None466     - `[]`467     - Marks a point in the code that should never be reached, enabling optimizations by indicating unreachable code paths.468   * - `int_spv_alloca`469     - Type470     - `[]`471     - Allocates memory on the stack. Fundamental for local variable storage in functions.472   * - `int_spv_alloca_array`473     - Type474     - `[Any Integer]`475     - Allocates an array on the stack. Extends `int_spv_alloca` to support array allocations, essential for temporary arrays.476   * - `int_spv_undef`477     - 32-bit Integer478     - `[]`479     - Generates an undefined value. Useful for optimizations and indicating uninitialized variables.480   * - `int_spv_inline_asm`481     - None482     - `[Metadata, Metadata, Vararg]`483     - Associates inline assembly features to inline assembly call instances by creating metadatas and preserving original arguments. Not emitted directly but used to support SPIR-V representation in LLVM IR.484   * - `int_spv_assume`485     - None486     - `[1-bit Integer]`487     - Provides hints to the optimizer about assumptions that can be made about program state. Improves optimization potential.488   * - `int_spv_expect`489     - Any Integer Type490     - `[Type, Type]`491     - Guides branch prediction by indicating expected branch paths. Enhances performance by optimizing common code paths.492   * - `int_spv_thread_id`493     - 32-bit Integer494     - `[32-bit Integer]`495     - Retrieves the thread ID within a workgroup. Essential for identifying execution context in parallel compute operations.496   * - `int_spv_flattened_thread_id_in_group`497     - 32-bit Integer498     - `[32-bit Integer]`499     - Provides a flattened index for a given thread within a given group (SV_GroupIndex)500   * - `int_spv_create_handle`501     - Pointer502     - `[8-bit Integer]`503     - Creates a resource handle for graphics or compute resources. Facilitates the management and use of resources in shaders.504   * - `int_spv_resource_handlefrombinding`505     - spirv.Image506     - `[32-bit Integer set, 32-bit Integer binding, 32-bit Integer arraySize, 32-bit Integer index, bool isUniformIndex]`507     - Returns the handle for the resource at the given set and binding.\508       If `arraySize > 1`, then the binding represents an array of resources\509       of the given size, and the handle for the resource at the given index is returned.\510       If the index is possibly non-uniform, then `isUniformIndex` must get set to true.511   * - `int_spv_typeBufferLoad`512     - Scalar or vector513     - `[spirv.Image ImageBuffer, 32-bit Integer coordinate]`514     - Loads a value from a Vulkan image buffer at the given coordinate. The \515       image buffer data is assumed to be stored as a 4-element vector. If the \516       return type is a scalar, then the first element of the vector is \517       returned. If the return type is an n-element vector, then the first \518       n-elements of the 4-element vector are returned.519   * - `int_spv_resource_store_typedbuffer`520     - void521     - `[spirv.Image Image, 32-bit Integer coordinate, vec4 data]`522     - Stores the data to the image buffer at the given coordinate. The \523       data must be a 4-element vector.524 525.. _spirv-builtin-functions:526 527Builtin Functions528-----------------529 530The following section highlights the representation of SPIR-V builtins in LLVM IR,531emphasizing builtins that do not have direct counterparts in LLVM.532 533Instructions as Function Calls534~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~535 536SPIR-V builtins without direct LLVM counterparts are represented as LLVM function calls.537These functions, termed SPIR-V builtin functions, follow an IA64 mangling scheme with538SPIR-V-specific extensions. Parsing non-mangled calls to builtins is supported in some cases,539but not tested extensively. The general format is:540 541.. code-block:: c542 543  __spirv_{OpCodeName}{_OptionalPostfixes}544 545Where `{OpCodeName}` is the SPIR-V opcode name sans the "Op" prefix, and546`{OptionalPostfixes}` are decoration-specific postfixes, if any. The mangling and547postfixes allow for the representation of SPIR-V's rich instruction set within LLVM's548framework.549 550Extended Instruction Sets551~~~~~~~~~~~~~~~~~~~~~~~~~552 553SPIR-V defines several extended instruction sets for additional functionalities, such as554OpenCL-specific operations. In LLVM IR, these are represented by function calls to555mangled builtins and selected based on the environment. For example:556 557.. code-block:: c558 559  acos_f32560 561represents the `acos` function from the OpenCL extended instruction set for a float32562input.563 564Builtin Variables565~~~~~~~~~~~~~~~~~566 567SPIR-V builtin variables, which provide access to special hardware or execution model568properties, are mapped to either LLVM function calls or LLVM global variables. The569representation follows the naming convention:570 571.. code-block:: c572 573  __spirv_BuiltIn{VariableName}574 575For instance, the SPIR-V builtin `GlobalInvocationId` is accessible in LLVM IR as576`__spirv_BuiltInGlobalInvocationId`.577 578Vector Load and Store Builtins579~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~580 581SPIR-V's capabilities for loading and storing vectors are represented in LLVM IR using582functions that mimic the SPIR-V instructions. These builtins handle cases that LLVM's583native instructions do not directly support, enabling fine-grained control over memory584operations.585 586Atomic Operations587~~~~~~~~~~~~~~~~~588 589SPIR-V's atomic operations, especially those operating on floating-point data, are590represented in LLVM IR with corresponding function calls. These builtins ensure591atomicity in operations where LLVM might not have direct support, essential for parallel592execution and synchronization.593 594Image Operations595~~~~~~~~~~~~~~~~596 597SPIR-V provides extensive support for image and sampler operations, which LLVM598represents through function calls to builtins. These include image reads, writes, and599queries, allowing detailed manipulation of image data and parameters.600 601Group and Subgroup Operations602~~~~~~~~~~~~~~~~~~~~~~~~~~~~~603 604For workgroup and subgroup operations, LLVM uses function calls to represent SPIR-V's605group-based instructions. These builtins facilitate group synchronization, data sharing,606and collective operations essential for efficient parallel computation.607 608SPIR-V Instructions Mapped to LLVM Metadata609~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~610Some SPIR-V instructions don't have a direct equivalent in the LLVM IR language. To611address this, the SPIR-V Target uses different specific LLVM named metadata to convey612the necessary information. The SPIR-V specification allows multiple module-scope613instructions, where as LLVM named metadata must be unique. Therefore, the encoding of614such instructions has the following format:615 616.. code-block:: llvm617 618  !spirv.<OpCodeName> = !{!<InstructionMetadata1>, !<InstructionMetadata2>, ..}619  !<InstructionMetadata1> = !{<Operand1>, <Operand2>, ..}620  !<InstructionMetadata2> = !{<Operand1>, <Operand2>, ..}621 622Below, you will find the mappings between SPIR-V instruction and their corresponding623LLVM IR representations.624 625+--------------------+---------------------------------------------------------+626| SPIR-V instruction | LLVM IR                                                 |627+====================+=========================================================+628| OpExecutionMode    | .. code-block:: llvm                                    |629|                    |                                                         |630|                    |    !spirv.ExecutionMode = !{!0}                         |631|                    |    !0 = !{void @worker, i32 30, i32 262149}             |632|                    |    ; Set execution mode with id 30 (VecTypeHint) and    |633|                    |    ; literal `262149` operand.                          |634+--------------------+---------------------------------------------------------+635