aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/SPIRV
AgeCommit message (Collapse)AuthorFilesLines
2024-04-09[SPIR-V] Re-implement switch and improve validation of forward calls (#87823)Vyacheslav Levytskyy6-183/+113
This PR fixes issue https://github.com/llvm/llvm-project/issues/87763 and preserves valid CFG in cases when previous scheme failed to generate valid code for a switch statement. The PR hardens one existing test case and adds one more test case as a validation of a new switch generation. Tests are passing spirv-val now. This PR also improves validation of forward calls.
2024-04-09[SPIR-V] Map llvm.{min,max}num to GL::N{Min,Max} (#88009)Natalie Chouinard1-2/+2
SPIR-V intsruction selection was mapping the LLVM float min/max intrinsics to FMin and FMax respectively for GL/Vulkan environments, which does not match the intrinsics' documented treatment of NaN operands. This patch switches the mapping to the correctly matched NMin and NMax operations. Fixes #87072
2024-04-04[SPIR-V] Fix OpVariable instructions place in a function (#87554)Vyacheslav Levytskyy4-7/+28
This PR: * fixes OpVariable instructions place in a function (see https://github.com/llvm/llvm-project/issues/66261), * improves type inference, * helps avoiding unneeded bitcasts when validating function call's This allows to improve existing and add new test cases with more strict checks. OpVariable fix refers to "All OpVariable instructions in a function must be the first instructions in the first block" requirement from SPIR-V spec.
2024-04-02[SPIR-V] Fix validity of atomic instructions (#87051)Vyacheslav Levytskyy3-10/+128
This PR fixes validity of atomic instructions and improves type inference. More tests are able now to be accepted by `spirv-val`.
2024-03-28[SPIR-V] Improve type inference: deduce types of composite data structures ↵Vyacheslav Levytskyy7-76/+382
(#86782) This PR improves type inference in general and deduces types of composite data structures in particular. Also added a way to insert a bitcast to make a fun call valid in case of arguments types mismatch due to opaque pointers type inference. The attached test `pointers/nested-struct-opaque-pointers.ll` demonstrates new capabilities: the SPIRV code emitted for this test is now (1) valid in a sense of data field types and (2) accepted by `spirv-val`. More strict LIT checks, support of more composite data structures and improvement of fun calls from the perspective of type correctness are main todo's at the moment.
2024-03-26[SPIR-V] Support extension toggling and enabling all (#85503)Michal Paszkowski4-76/+146
2024-03-25[SPIR-V] Add WaveGetLaneIndex() intrinsic support (#85979)Nathan Gauër7-27/+59
Add support to generate valid SPIR-V for the WaveGetLaneIndex() HLSL builtin. To implement this, I had to fix a few small issues in the backend, like the i8* pointer type being emitted, even if we have the type information elsewhere. Signed-off-by: Nathan Gauër <brioche@google.com>
2024-03-25[SPIR-V] Fix illegal OpConstantComposite instruction with non-const ↵Vyacheslav Levytskyy7-16/+95
constituents in SPIR-V Backend (#86352) This PR fixes illegal use of OpConstantComposite with non-constant constituents. The test attached to the PR is able now to satisfy `spirv-val` check. Before the fix SPIR-V Backend produced for the attached test case a pattern like ``` %a = OpVariable %_ptr_CrossWorkgroup_uint CrossWorkgroup %uint_123 %11 = OpConstantComposite %_struct_6 %a %a ``` so that `spirv-val` complained with ``` error: line 25: OpConstantComposite Constituent <id> '10[%a]' is not a constant or undef. %11 = OpConstantComposite %_struct_6 %a %a ```
2024-03-25[SPIR-V] Improve type inference in SPIR-V Backend for opaque pointers (#86283)Vyacheslav Levytskyy3-50/+86
This PR improves type inference in SPIR-V Backend for opaque pointers, accounting or a case when there is a chain of function calls that allows to deduce formal parameter types from actual arguments. The attached test demonstrates the case.
2024-03-25[SPIR-V] Introduce a command line option to support compatibility with ↵Vyacheslav Levytskyy1-1/+7
Khronos SPIRV Translator (#86101) SPIRV-LLVM-Translator project (https://github.com/KhronosGroup/SPIRV-LLVM-Translator) from Khronos Group is a tool and a library for bi-directional translation between SPIR-V and LLVM IR. In its backward translation from SPIR-V to LLVM IR SPIRV-LLVM-Translator isn't necessarily able to cover the same SPIR-V patterns/instructions set that SPIRV Backend produces, even if we target the same SPIR-V version in both SPIRV-LLVM-Translator and SPIRV Backend projects. To improve interoperability and ability to apply SPIRV Backend output in different products this PR introduces a notion of a mode of SPIR-V output that is compatible with a subset of SPIR-V supported by SPIRV-LLVM-Translator. This includes a new command line option that doesn't influence default behavior of SPIRV Backend and one test case that demonstrates how this command line option may be used to get a practical benefit of producing that one of two possible and similar output options that can be understood by SPIRV-LLVM-Translator.
2024-03-20[SPIRV] Add __spirv_ builtins for existing instructions (#85654)Vyacheslav Levytskyy4-40/+167
This PR: * adds __spirv_ builtins for existing instructions; * fixes parsing of "syncscope" values in atomic instructions; * fix a special case of binary header emision.
2024-03-20[SPIR-V] Fix incorrect bitwise instructions applied to the bool type (#85929)Vyacheslav Levytskyy1-0/+20
This PR ensures that LLVM IR bitwise instructions result in logical SPIR-V instructions when applied to i1 type.
2024-03-18[SPIRV] Add Lifetime intrinsics/instructions (#85391)Vyacheslav Levytskyy9-14/+112
This PR: * adds Lifetime intrinsics/instructions * fixes how the binary header is emitted (correct version and better approximation of Bound) * add validation into more test cases
2024-03-14[SPIRV] Add type inference of function parameters by call instances (#85077)Vyacheslav Levytskyy4-6/+77
This PR adds type inference of function parameters by call instances. Two use cases that demonstrate the problem are added.
2024-03-13[SPIR-V] Add implementation of G_SPLAT_VECTOR opcode and fix invalid types ↵Vyacheslav Levytskyy7-55/+236
processing (#84766) This PR: * adds support for G_SPLAT_VECTOR generic opcode that may be legally generated instead of G_BUILD_VECTOR by previous passes of the translator (see https://github.com/llvm/llvm-project/pull/80378 for the source of breaking changes); * improves deduction of types for opaque pointers. This PR also fixes the following issues: * if a function has ptr argument(s), two functions that have different SPIR-V type definitions may get identical LLVM function types and break agreements of global register and duplicate checker; * checks for pointer types do not account for TypedPointerType. Update of tests: * A test case is added to cover the issue with function ptr parameters. * The first case, that is support for G_SPLAT_VECTOR generic opcode, is covered by existing test cases. * Multiple additional checks by `spirv-val` is added to cover more possibilities of generation of invalid code.
2024-03-08[SPIR-V] Insert a bitcast before load/store instruction to keep SPIR-V code ↵Vyacheslav Levytskyy5-48/+142
valid (#84069) This PR introduces a step after instruction selection where instructions can be traversed from the perspective of their validity from the specification point of view. The PR adds also a way to correct load/store when there is a type mismatch contradicting the specification -- an additional bitcast is inserted to keep types consistent. Correspondent test cases are added and existing test cases are corrected. This PR helps to successfully validate with the `spirv-val` tool (https://github.com/KhronosGroup/SPIRV-Tools) some output that previously led to validation errors and crashes of back translation from SPIRV to LLVM IR from the side of SPIRV Translator project (https://github.com/KhronosGroup/SPIRV-LLVM-Translator). The added step of bringing instructions to required by the specification type correspondence can be (should be and will be) extended beyond load/store instructions to ensure validity rules of other SPIRV instructions related to type inference.
2024-03-05[SPIR-V] Memory leak fix in SPIRVEmitIntrinsics (#83015)bwlodarcz1-121/+152
The architecture of SPIRVEmitIntrinsics is build in such way that every private method is called by one main function runOnFunction which then calls private methods. Private member IRB is allocated in runOnFunction method but it's not freed. Due to that every time when IR function contains intrinsics to emit, runOnFunction is entered and memory is leaked on exit. It's especially true when there are two or more IR functions to emit. IRB is set to nullptr during construction of object and it's left without pointing resource until runOnFunction is entered. This also create possibility of simple mistake when private method is called but there is no resource pointed. Change requires passing IRBuilder by reference to private methods. The visit* functions create it's own IRBuilder thus IRB is eliminated from class scope. In addition there is a small performance improvement because IRBuilder is not allocated by heap.
2024-03-04[HLSL][SPIR-V] Add SV_DispatchThreadID semantic support (#82536)Natalie Chouinard2-1/+71
Add SPIR-V backend support for the HLSL SV_DispatchThreadID semantic attribute, which is lowered to a @llvm.dx.thread.id intrinsic in LLVM IR. In the SPIR-V backend, this is now correctly translated to a `GlobalInvocationId` builtin variable. Fixes #82534
2024-03-04[SPIR-V] Fix warning -Wsometimes-uninitialized (#83901)Michal Paszkowski1-1/+1
2024-03-04[SPIR-V] Add support for the SPIR-V extension SPV_INTEL_bfloat16_conversion ↵Vyacheslav Levytskyy8-9/+102
(#83443) This PR is to add support for the SPIR-V extension SPV_INTEL_bfloat16_conversion (https://github.com/KhronosGroup/SPIRV-Registry/blob/main/extensions/INTEL/SPV_INTEL_bfloat16_conversion.asciidoc) and OpenCL extension cl_intel_bfloat16_conversions (https://registry.khronos.org/OpenCL/extensions/intel/cl_intel_bfloat16_conversions.html).
2024-03-04[SPIR-V] Add support for SPV_KHR_float_controls (#83418)Vyacheslav Levytskyy2-0/+20
This PR is to add explicit support for SPV_KHR_float_controls (https://github.com/KhronosGroup/SPIRV-Registry/blob/main/extensions/KHR/SPV_KHR_float_controls.asciidoc). This extension is included into SPIR-V after version 1.4, but in case of lower versions it is to be included explicitly and OpExtension must be present in the module with `OpExtension "SPV_KHR_float_controls"`. This PR fixes this issue and fixes the test case test/CodeGen/SPIRV/exec_mode_float_control_khr.ll to account for a version lower than 1.4.
2024-03-04[SPIR-V] Fix bitcast legalization/instruction selection in SPIR-V Backend ↵Vyacheslav Levytskyy4-14/+73
(#83139) This PR is to fix a way how SPIR-V Backend describes legality of OpBitcast instruction and how it is validated on a step of instruction selection. Instead of checking a size of virtual registers (that makes no sense due to lack of guarantee of direct relations between size of virtual register and bit width associated with the type size), this PR allows to legalize OpBitcast without size check and postpones validation to the instruction selection step. As an example, let's consider the next example that was copied as is from a bigger test suite: ``` %355:id(s16) = G_BITCAST %301:id(s32) %303:id(s16) = ASSIGN_TYPE %355:id(s16), %349:type(s32) %644:fid(s32) = G_FMUL %645:fid, %646:fid %301:id(s32) = ASSIGN_TYPE %644:fid(s32), %40:type(s32) ``` Without the PR this leads to a crash with complains to an illegal bitcast, because %355 is s16 and %301 is s32. However, we must check not virtual registers in this case, but types of %355 and %301, i.e., %349:type(s32) and %40:type(s32), which are perfectly well compatible in a sense of OpBitcast in this case. In a test case that is a part of this PR OpBitcast is legal, being applied for `OpTypeInt 16` and `OpTypeFloat 16`, but would not be legalized without this PR due to virtual registers defined as having size 16 and 32.
2024-03-04[SPIRV] Add vector reduction instructions (#82786)Vyacheslav Levytskyy7-53/+291
This PR is to add vector reduction instructions according to https://llvm.org/docs/GlobalISel/GenericOpcode.html#vector-reduction-operations and widen in such a way a range of successful supported conversions, covering new cases of vector reduction instructions which IRTranslator is unable to resolve. By legalizing vector reduction instructions we introduce a new instruction patterns that should be addressed, including patterns that are delegated to pre-legalize step. To address this problem, a new pass is added that is to bring newly generated instructions after legalization to an aspect required by instruction selection. Expected overheads for existing cases is minimal, because a new pass is working only with newly introduced instructions, otherwise it's just a additional code traverse without any actions.
2024-03-03[SPIR-V] Do not use OpenCL metadata for ptr element type resolution (#82678)Michal Paszkowski10-170/+276
This pull request aims to remove any dependency on OpenCL/SPIR-V type information in LLVM IR metadata. While, using metadata might simplify and prettify the resulting SPIR-V output (and restore some of the information missed in the transformation to opaque pointers), the overall methodology for resolving kernel parameter types is highly inefficient. The high-level strategy is to assign kernel parameter types in this order: 1. Resolving the types using builtin function calls as mangled names must contain type information or by looking up builtin definition in SPIRVBuiltins.td. Then: - Assigning the type temporarily using an intrinsic and later setting the right SPIR-V type in SPIRVGlobalRegistry after IRTranslation - Inserting a bitcast 2. Defaulting to LLVM IR types (in case of pointers the generic i8* type or types from byval/byref attributes) In case of type incompatibility (e.g. parameter defined initially as sampler_t and later used as image_t) the error will be found early on before IRTranslation (in the SPIRVEmitIntrinsics pass).
2024-02-27[SPIR-V]: add SPIR-V extension: SPV_INTEL_variable_length_array (#83002)Vyacheslav Levytskyy7-1/+98
This PR adds SPIR-V extension SPV_INTEL_variable_length_array that allows to allocate local arrays whose number of elements is unknown at compile time: * add a new SPIR-V internal intrinsic:int_spv_alloca_array * legalize G_STACKSAVE and G_STACKRESTORE * implement allocation of arrays (previously getArraySize() of AllocaInst was not used) * add tests
2024-02-27Add support for the 'freeze' instruction (#82979)Vyacheslav Levytskyy2-1/+45
This PR is to add support for the 'freeze' instruction: https://llvm.org/docs/LangRef.html#freeze-instruction There is no way to implement `freeze` correctly without support on SPIR-V standard side, but we may at least address a simple (static) case when undef/poison value presence is obvious. The main benefit of even incomplete `freeze` support is preventing of translation from crashing due to lack of support on legalization and instruction selection steps.
2024-02-22Add support for the SPV_INTEL_usm_storage_classes extension (#82247)Vyacheslav Levytskyy11-28/+99
Add support for the SPV_INTEL_usm_storage_classes extension: * https://github.com/intel/llvm/blob/sycl/sycl/doc/design/spirv-extensions/SPV_INTEL_usm_storage_classes.asciidoc
2024-02-22[SPIRV] Prevent creation of jump tables from switch (#82287)Vyacheslav Levytskyy1-0/+3
This PR is to prevent creation of jump tables from switch. The reason is that SPIR-V doesn't know how to lower jump tables, and a sequence of commands that IRTranslator generates for switch via jump tables breaks SPIR-V Backend code generation with complains to G_BRJT. The next example is the shortest code to break SPIR-V Backend code generation in this way: ``` target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64" target triple = "spir64-unknown-unknown" define spir_func void @foo(i32 noundef %val) { entry: switch i32 %val, label %sw.epilog [ i32 0, label %sw.bb i32 1, label %sw.bb2 i32 2, label %sw.bb3 i32 3, label %sw.bb4 ] sw.bb: br label %sw.epilog sw.bb2: br label %sw.epilog sw.bb3: br label %sw.epilog sw.bb4: br label %sw.epilog sw.epilog: ret void } ``` To resolve the issue we set a high lower limit for number of blocks in a jump table via getMinimumJumpTableEntries() and prevent undesirable (or rather unsupported at the moment) path of code generation.
2024-02-22[SPIRV] Add support for the SPV_KHR_subgroup_rotate extension (#82374)Vyacheslav Levytskyy5-1/+25
This PR adds support for the SPV_KHR_subgroup_rotate extension that enables rotating values across invocations within a subgroup: * https://github.com/KhronosGroup/SPIRV-Registry/blob/main/extensions/KHR/SPV_KHR_subgroup_rotate.asciidoc
2024-02-20[SPIR-V] Fix vloadn OpenCL builtin lowering (#81148)Michal Paszkowski3-19/+26
This pull request fixes an issue with missing vector element count immediate in OpExtInst calls and adds a case for generating bitcasts before GEPs for kernel arguments of non-matching pointer type. The new LITs are based on basic/vload_local and basic/vload_global OpenCL CTS tests. The tests after this change pass SPIR-V validation.
2024-02-19[SPIRV] Fix warning after #81683Fangrui Song1-1/+1
2024-02-19Add support for the SPIR-V extension SPV_KHR_uniform_group_instructions (#82064)Vyacheslav Levytskyy6-1/+196
This PR is to add support for the SPIR-V extension SPV_KHR_uniform_group_instructions that adds new instructions to SPIR-V to support additional group operations within uniform control flow.
2024-02-19fix generation of unnecessary OpExecutionMode records (#81839)Vyacheslav Levytskyy4-15/+20
SPIRV-V Backend generates unnecessary OpExecutionMode records, putting into the id's which are not the Entry Point operands of an OpEntryPoint (ref: https://github.com/llvm/llvm-project/issues/81753). This PR is to fix the issue.
2024-02-19Add support for atomic instruction on floating-point numbers (#81683)Vyacheslav Levytskyy12-21/+250
This PR adds support for atomic instruction on floating-point numbers: * SPV_EXT_shader_atomic_float_add * SPV_EXT_shader_atomic_float_min_max * SPV_EXT_shader_atomic_float16_add and fixes asm printer output for half floating-type.
2024-02-15add support for the SPV_KHR_linkonce_odr extension (#81512)Vyacheslav Levytskyy5-6/+29
This PR adds support for the SPV_KHR_linkonce_odr extension and modifies existing negative test with a positive check for the extension and proper linkage type in case when the extension is enabled. SPV_KHR_linkonce_odr adds a "LinkOnceODR" linkage type, allowing proper translation of, for example, C++ templates classes merging during linking from different modules and supporting any other cases when a global variable/function must be merged with equivalent global variable(s)/function(s) from other modules during the linking process.
2024-02-15let a user select preferred/unpreferred capabilities in a list of enabling ↵Vyacheslav Levytskyy2-10/+42
capabilities (#81476) By SPIR-V specification: "If an instruction, enumerant, or other feature specifies multiple enabling capabilities, only one such capability needs to be declared to use the feature." However, one capability may be preferred over another. One important case is Shader capability that may not be supported by a backend, but always is inserted if "OpDecorate SpecId" is found, because Enabling Capabilities for the latter is the list of Shader and Kernel, where Shader is coming first and thus always selected as the first available option. In this PR we address the problem by keeping current behaviour of selecting the first option among enabling capabilities as is, but giving a user a way to filter capabilities during the selection process via a newly introduced "--avoid-spirv-capabilities" command line option. This option is to avoid selection of certain capabilities if there are other available enabling capabilities. This PR is changing also existing pruneCapabilities() function. It doesn't remove capability from module requirement anymore, but only adds implicitly required capabilities recursively, so its name is changed accordingly. This change fixes the present bug in collecting required by a module capabilities. Before the change, introduced by this PR, pruneCapabilities() function has been removing, for example, Kernel capability from required by a module, because Kernel is initially required and the second time it was needed pruneCapabilities() removed it by mistake.
2024-02-13[SPIRV] Add to LINK_COMPONENTS to fix BUILD_SHARED_LIBS buildJessica Clarke1-0/+2
Fixes: 7b08b4360b488b35428c97132b3f9d2a777bd770
2024-02-12Add support for SPIR-V extension: SPV_INTEL_function_pointers (#80759)Vyacheslav Levytskyy11-24/+239
This PR adds initial support for "SPV_INTEL_function_pointers" SPIR-V extension: https://github.com/intel/llvm/blob/sycl/sycl/doc/design/spirv-extensions/SPV_INTEL_function_pointers.asciidoc The goal of the extension is to support indirect function calls and translation of function pointers into SPIR-V.
2024-02-12Add support for SPIR-V extension: SPV_INTEL_subgroups (#81023)Vyacheslav Levytskyy6-4/+184
The goal of this PR is to implement SPV_INTEL_subgroups extension in SPIR-V Backend.
2024-02-02[SPIR-V] add convergence region analysis (#78456)Nathan Gauër6-0/+540
This new analysis returns a hierarchical view of the convergence regions in the given function. This will allow our passes to query which basic block belongs to which convergence region, and structurize the code in consequence. Definition ---------- A convergence region is a CFG with: - a single entry node. - one or multiple exit nodes (different from LLVM's regions). - one back-edge - zero or more subregions. Excluding sub-regions nodes, the nodes of a region can only reference a single convergence token. A subregion uses a different convergence token. Algorithm --------- This algorithm assumes all loops are in the Simplify form. Create an initial convergence region for the whole function. - the convergence token is the function entry token. - the entry is the function entrypoint. - Exits are all the basic blocks terminating with a return instruction. Take the function CFG, and process it in DAG order (ignoring back-edges). If a basic block is a loop header: - Create a new region. - The parent region is the parent's loop region if any, otherwise, the top level region. - The region blocks are all the blocks belonging to this loop. - For each loop exit: - visit the rest of the CFG in DAG order (ignore back-edges). - if the region's convergence token is found, add all the blocks dominated by the exit from which the token is reachable to the region. - continue the algorithm with the loop headers successors.
2024-01-31[SPIR-V] Improve how lowering of formal arguments in SPIR-V Backend ↵Vyacheslav Levytskyy4-20/+30
interprets a value of 'kernel_arg_type' (#78730) The goal of this PR is to tolerate differences between description of formal arguments by function metadata (represented by "kernel_arg_type") and LLVM actual parameter types. A compiler may use "kernel_arg_type" of function metadata fields to encode detailed type information, whereas LLVM IR may utilize for an actual parameter a more general type, in particular, opaque pointer type. This PR proposes to resolve this by a fallback to LLVM actual parameter types during the lowering of formal function arguments in cases when the type can't be created by string content of "kernel_arg_type", i.e., when "kernel_arg_type" contains a type unknown for the SPIR-V Backend. An example of the issue manifestation is https://github.com/KhronosGroup/SPIRV-LLVM-Translator/blob/main/test/transcoding/KernelArgTypeInOpString.ll, where a compiler generates for the following kernel function detailed `kernel_arg_type` info in a form of `!{!"image_kernel_data*", !"myInt", !"struct struct_name*"}`, and in LLVM IR same arguments are referred to as `@foo(ptr addrspace(1) %in, i32 %out, ptr addrspace(1) %outData)`. Both definitions are correct, and the resulting LLVM IR is correct, but lowering stage of SPIR-V Backend fails to generate SPIR-V type. ``` typedef int myInt; typedef struct { int width; int height; } image_kernel_data; struct struct_name { int i; int y; }; void kernel foo(__global image_kernel_data* in, __global struct struct_name *outData, myInt out) {} ``` ``` define spir_kernel void @foo(ptr addrspace(1) %in, i32 %out, ptr addrspace(1) %outData) ... !kernel_arg_type !7 ... { entry: ret void } ... !7 = !{!"image_kernel_data*", !"myInt", !"struct struct_name*"} ``` The PR changes a contract of `SPIRVType *getArgSPIRVType(...)` in a way that it may return `nullptr` to signal that the metadata string content is not recognized, so corresponding comments are added and a couple of checks for `nullptr` are inserted where appropriate.
2024-01-30fix producing multiple identical opaque pointer types (#79060)Vyacheslav Levytskyy1-4/+5
This PR fixes https://github.com/llvm/llvm-project/issues/79057 and improves code generation for opaque pointers by replacing the culprit SPIRVGlobalRegistry::getOpTypePointer() call with a more appropriate SPIRVGlobalRegistry::getOrCreateSPIRVPointerType() call. The latter function works together with the `DuplicatesTracker` (`SPIRVGeneralDuplicatesTracker DT;` from `class SPIRVGlobalRegistry`) to trace existence of previous definitions of opaque pointers. This allows to produce just one `OpTypePointer` command for all identical opaque pointers definitions and to return the very same type record for subsequent `SPIRVGlobalRegistry::createSPIRVType()` invocations. This PR alone improves code generation by producing a single needed definition per all opaque pointers to i8 of the same address space instead of multiple identical definitions produced before the patch. From the root cause analysis of https://github.com/llvm/llvm-project/issues/79057 we see also that this PR resolves the problem of inconsistency between keeping multiple instruction for identical opaque pointer types and just a single record for all such instructions in the `DuplicatesTracker`, and so it also resolves the issue with crashes on creation of a struct with opaque pointer fields due to the fact that now such struct fields refer to the same operand `<id>` having a required record in the data structure used for dependencies analysis (see https://github.com/llvm/llvm-project/issues/79057).
2024-01-30prevent undefined behaviour of SPIR-V Backend non-asserts builds when ↵Vyacheslav Levytskyy1-0/+10
dealing with token type (#78437) The goal of this PR is to fix the issue when use of token type in LLVM intrinsic causes undefined behavior of SPIR-V Backend code generator when assertions are disabled: https://github.com/llvm/llvm-project/issues/78434 Among possible fix options, discussed in the https://github.com/llvm/llvm-project/issues/78434 issue description, the option to generate a meaningful error before execution arrives at the `llvm_unreachable` call looks like a better solution for now, because SPIR-V doesn't support token type anyway without additional extensions. The PR is to generate a user-friendly error message and exit without generating a stack dump when such a usage of token type was detected that would lead to undefined behavior of SPIR-V Backend code generator.
2024-01-30generate a name of an unnamed global variable for Instruction Selection (#78293)Vyacheslav Levytskyy1-1/+15
The goal of this PR is to fix the issue of global unnamed variables causing SPIR-V Backend code generation to crash: https://github.com/llvm/llvm-project/issues/78278 The reason for the crash is that GlobalValue's getGlobalIdentifier() would fail for unnamed global variable when trying to access the first character of the name (see lib/IR/Globals.cpp:150). This leads to assert in Debug and undefined behaviour in Release builds. The proposed fix generates a name of an unnamed global variable as __unnamed_<unsigned number>, in a style of similar existing LLVM implementation (see lib/IR/Mangler.cpp:131). A new class member variable is added into `SPIRVInstructionSelector` class to keep track of the number we give to anonymous global values to generate the same name every time when this is needed. The patch adds a new LIT test with the smallest implementation of reproducer ll code.
2024-01-28[SPIR-V] Cast ptr kernel args to i8* when used as Store's value operand (#78603)Michal Paszkowski5-64/+157
Handle a special case when StoreInst's value operand is a kernel argument of a pointer type. Since these arguments could have either a basic element type (e.g. float*) or OpenCL builtin type (sampler_t), bitcast the StoreInst's value operand to default pointer element type (i8). This pull request addresses the issue https://github.com/llvm/llvm-project/issues/72864
2024-01-22[SPIRV] Use llvm::find (NFC)Kazu Hirata1-1/+1
2024-01-18[SPIR-V] improve performance of Module Analysis stage in the part of ↵Vyacheslav Levytskyy1-36/+37
processing "other instructions" (#76047) The goal of this PR is to fix an issue when Module Analysis stage is not able to complete processing of a really big LLVM source: https://github.com/llvm/llvm-project/issues/76048. There is an example of a bulky LLVM source: https://github.com/KhronosGroup/SPIRV-LLVM-Translator/blob/main/test/SpecConstants/long-spec-const-composite.ll Processing of this file with `llc -mtriple=spirv64-unknown-unknown -O0 long-spec-const-composite.ll -o long-spec-const-composite.spvt` to produce SPIR-V output using LLVM SPIR-V backend takes too long, and I've never been able to see it actually completes. After the patch from this PR applied elapsed time for me is ~30 sec. The fix changes underlying data structure to be `std::set` to trace instructions with identical operands instead of the existing approach of the `findSameInstrInMS()` function.
2024-01-15[SPIR-V] Do not emit spv_ptrcast if GEP result is of expected type (#78122)Michal Paszkowski1-1/+3
Prior to this change spv_ptrcast (and OpBitcast) was never emitted for GEP resulting pointers. While such SPIR-V was (mostly) accepted by the NEO GPU driver, the generated SPIR-V was incorrect. The newly added test (pointers/getelementptr-bitcast-load.ll) verifies that a correct bitcast is added for more complex cases and passes spirv-val. The test is based on an OpenCL CTS test (basic/prefetch).
2024-01-15[SPIR-V] Strip convergence intrinsics before ISel (#75948)Nathan Gauër4-0/+89
The structurizer will require the frontend to emit convergence intrinsics. Once uses to restructurize the control-flow, those intrinsics shall be removed, as they cannot be converted to SPIR-V. This commit adds a new pass to the SPIR-V backend which strips those intrinsics. Those 2 new steps are not limited to Vulkan as OpenCL could also benefit from not crashing if a convertent operation is in the IR (even though the frontend doesn't generate such intrinsics). Signed-off-by: Nathan Gauër <brioche@google.com>
2024-01-12[SPIR-V] Add Float16 support when targeting Vulkan (#77115)Natalie Chouinard1-3/+7
Add Float16 to Vulkan's available capabilities, and guard Float16Buffer (Kernel-only capability) against being added outside OpenCL environments. Add tests to verify half and half vector types, and validate with spirv-val. Fixes #66398