summaryrefslogtreecommitdiff
path: root/llvm/test/CodeGen/SPIRV/transcoding
AgeCommit message (Collapse)Author
2025-11-07[SPIRV] Handle `inttoptr` constant expressions in global initialisers (#166494)Alex Voicu
`inttoptr` usage in global initialisers is valid, and rather common when it comes to the machinery around vtables (construction vtables are particularly fond). This was not handled by the BE, even though SPIR-V allows forming `SpecConstantOp`s with the `OpConvertUToPtr` opcode, which is what these would map to. We augment instruction selection to address this.
2025-10-14[SPIRV] Porting Test from Translator (#152247)Subash B
These tests verify SPIR-V code generation for LLVM intrinsics and atomic operations, ensuring correct translation of fcmp false, llvm.fake.use, and atomic_compare_exchange. --------- Co-authored-by: Michal Paszkowski <michal@michalpaszkowski.com>
2025-09-28[SPIRV] Added opencl Pipe builtins (#135335)Ebin-McW
- Added opencl Pipe builtins - Pipe instructions were added in tablegen and lowered in SPIRVBuiltins.cpp --------- Co-authored-by: Michal Paszkowski <michal@michalpaszkowski.com> Co-authored-by: Dmitry Sidorov <dmitry.sidorov@intel.com>
2025-09-28[SPIRV] Test file for memmove intrinsic (#152640)Ebin-McW
- Added test for checking the lowering of memmove to OpCopyMemorySized - Modified NoSignedUnsignedWrap.ll by adding a RUN line
2025-09-28[SPIRV] Porting tests to transcoding directory from translator (#151661)Ebin-McW
Checks for built-in variables, saturating conversion, half precision fract, and workgroup variable initialization --------- Co-authored-by: Michal Paszkowski <michal@michalpaszkowski.com>
2025-08-05[SPIRV] Do not use OpTypeRuntimeArray in Kernel env. (#149522)Marcos Maronas
Prior to this patch, when `NumElems` was 0, `OpTypeRuntimeArray` was directly generated, but it requires `Shader` capability, so it can only be generated if `Shader` env is being used. We have observed a pattern of using unbound arrays that translate into `[0 x ...]` types in OpenCL, which implies `Kernel` capability, so `OpTypeRuntimeArray` should not be used. To prevent this scenario, this patch simplifies GEP instructions where type is a 0-length array and the first index is also 0. In such scenario, we effectively drop the 0-length array and the first index. Additionally, the newly added test prior to this patch was generating a module with both `Shader` and `Kernel` capabilities at the same time, but they're incompatible. This patch also fixes that. Finally, prior to this patch, the newly added test was adding `Shader` capability to the module even with the command line flag `--avoid-spirv-capabilities=Shader`. This patch also has a fix for that.
2025-08-03[SPIRV] Ported tests to transcoding directory from the translator (#151662)Ebin-McW
- Checks for printf calls - Handling of convert_* builtins and fallback - Generation of nan and shuffle OpExtInst
2025-07-31[SPIRV] Test for spirv-target-types.ll and unused-sret-opaque-ptr.ll (#142281)Aadesh Premkumar
Co-authored-by: Michal Paszkowski <michal@michalpaszkowski.com>
2025-07-18[SPIR-V] Map SPIR-V friendly work-item function to built-in variables (#148567)Wenju He
The mapping ensures the function is lowered to SPIR-V built-in variables in SPIR-V. This can fix pre-commit CI fail in https://github.com/intel/llvm/pull/19359 Also add BuiltIn to SPIR-V Builtin function name in __clang_spirv_builtins.h to align with https://github.com/llvm/llvm-project/blob/main/llvm/docs/SPIRVUsage.rst#builtin-variables
2025-04-28[SPIRV] Correctly map OpGenericCastToPtrExplicit builtins (#137189)Victor Lomuller
The __spirv_GenericCastToPtrExplicit_To* builtins and its equivalent OpenCL builtins (to_global, to_local and to_private) were mapped to OpGenericCastToPtr instead of OpGenericCastToPtrExplicit. The patch now uses OpGenericCastToPtrExplicit for these builtins.
2025-03-26[SPIR-V] Rework duplicate tracker and tracking of IR entities and types to ↵Vyacheslav Levytskyy
improve compile-time performance (#130605) This PR is to thoroughly rework duplicate tracker implementation and tracking of IR entities and types. These are legacy parts of the project resulting in an extremely bloated intermediate representation and computational delays due to inefficient data flow and structure choices. Main results of the rework: 1) Improved compile-time performance. The reference binary LLVM IR used to measure speed gains in https://github.com/llvm/llvm-project/pull/120415 shows ~x5 speed up also after this PR. The timing before this PR is ~42s and after this PR it's ~7.5s. In total this PR and the previous overhaul of the module analysis in https://github.com/llvm/llvm-project/pull/120415 results in ~x25 speed improvement. ``` $ time llc -O0 -mtriple=spirv64v1.6-unknown-unknown _group_barrier_phi.bc -o 1 --filetype=obj real 0m7.545s user 0m6.685s sys 0m0.859s ``` 2) Less bloated intermediate representation of internal translation steps. Elimination of `spv_track_constant` intrinsic usage for scalar constants, rework of `spv_assign_name`, removal of the gMIR `GET_XXX` pseudo code and a smaller number of generated `ASSIGN_TYPE` pseudo codes substantially decrease volume of data generated during translation. 3) Simpler code and easier maintenance. The duplicate tracker implementation is simplified, as well as other features. 4) Numerous fixes of issues and logical flaws in different passes. The main achievement is rework of the duplicate tracker itself that had never guaranteed a correct caching of LLVM IR entities, rarely and randomly returning stale/incorrect records (like, remove an instruction from gMIR but still refer to it). Other fixes comprise consistent generation of OpConstantNull, assigning types to newly created registers, creation of integer/bool types, and other minor fixes. 5) Numerous fixes of LIT tests: mainly CHECK-DAG to properly reflect SPIR-V spec guarantees, `{{$}}` at the end of constants to avoid matching of substrings, and XFAILS for `SPV_INTEL_long_composites` test cases, because the feature is not completed in full yet and doesn't generate a requested by the extension sequence of instructions. 6) New test cases are added.
2025-02-24[SPIR-V] Stop generating StorageImageReadWithoutFormat and ↵Vyacheslav Levytskyy
StorageImageWriteWithoutFormat for the Unknown image format in the OpenCL environment (#128497) This PR resolves the issue of the SPIR-V specification, requiring Shader-coupled capabilities to read/write images in the OpenCL SPIR-V environment, from the perspective of the LLVM SPIR-V backend. See https://github.com/KhronosGroup/SPIRV-Headers/issues/487 for details and discussion. Current implementation correctly reproduces requirements of the SPIR-V specification, however, since the requirements are problematic, out current implementation blocks generation of valid SPIR-V code for compute environments. This PR is to implement a solution discussed at the SPIR-V WG to allow proceeding with generation of valid SPIR-V code for the OpenCL environment and do not impact Vulkan environment at the same time.
2025-02-18[SPIR-V] Built-in variables: mapping from an OpenCL to SPIR-V BuiltIn and ↵Vyacheslav Levytskyy
SPIR-V friendly builtins for Image Read/Write instructions (#127242) This PR improves built-in variables and functions support: * extends mapping from an OpenCL C built-in function to the SPIR-V BuiltIn variables as in https://registry.khronos.org/OpenCL/specs/3.0-unified/html/OpenCL_Env.html#_built_in_variables, and * adds SPIR-V friendly builtins for Image Read/Write instructions. Test cases are extended accordingly.
2025-02-17[SPIR-V] Ensure that a correct pointer type is deduced from the Value ↵Vyacheslav Levytskyy
argument of OpAtomic* instructions (#127492) This PR improves the set of rules for type inference by ensuring that a correct pointer type is deduced from the Value argument of OpAtomic* instructions, also when a pointer argument is coming from an `inttoptr .. to` instruction that caused problems earlier. Existing test cases are updated accordingly. This fixes https://github.com/llvm/llvm-project/issues/127491
2025-01-14[SPIR-V] Specify target environment in tests referring to the BuiltIn ↵Vyacheslav Levytskyy
WorkgroupSize variable (#122755) https://github.com/KhronosGroup/SPIRV-Tools/pull/5407 introduces a check for WorkgroupSize variable to be a 3-component 32-bit int vector, and indeed, we see this requirement in https://registry.khronos.org/vulkan/specs/latest/man/html/WorkgroupSize.html#VUID-WorkgroupSize-WorkgroupSize-04427 However, OpenCL imposes different requirements, documented here: https://registry.khronos.org/OpenCL/specs/3.0-unified/html/OpenCL_Env.html#_built_in_variables OpenCL environment requires WorkgroupSize variable to have components of size_t size that will be 32 or 64 depending on a target. This is the way how the SPIR-V Backend implements this, by querying pointer size of the current platform/target. To allow spirv-val to account target environments difference, this PR adds `--target-env <env>` to test cases referring to the BuiltIn WorkgroupSize variable.
2025-01-07[SPIR-V] Overhaul module analysis to improve translation speed and simplify ↵Vyacheslav Levytskyy
the underlying logics (#120415) This PR is to address legacy issues with module analysis that currently uses a complicated and not so efficient approach to trace dependencies between SPIR-V id's via a duplicate tracker data structures and an explicitly built dependency graph. Even a quick performance check without any specialized benchmarks points to this part of the implementation as a biggest bottleneck. This PR specifically: * eliminates a need to build a dependency graph as a data structure, * updates the test suite (mainly, by fixing incorrect CHECK's referring to a hardcoded order of definitions, contradicting the spec requirement to allow certain definitions to go "in any order", see https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#_logical_layout_of_a_module), * improves function pointers implementation so that it now passes EXPENSIVE_CHECKS (thus removing 3 XFAIL's in the test suite). As a quick sanity check of whether goals of the PR are achieved, we can measure time of translation for any big LLVM IR. While testing the PR in the local development environment, improvements of the x5 order have been observed. For example, the SYCL test case "group barrier" that is a ~1Mb binary IR input shows the following values of the naive performance metric that we can nevertheless apply here to roughly estimate effects of the PR. before the PR: ``` $ time llc -O0 -mtriple=spirv64v1.6-unknown-unknown _group_barrier_phi.bc -o 1 --filetype=obj real 3m33.241s user 3m14.688s sys 0m18.530s ``` after the PR ``` $ time llc -O0 -mtriple=spirv64v1.6-unknown-unknown _group_barrier_phi.bc -o 1 --filetype=obj real 0m42.031s user 0m38.834s sys 0m3.193s ``` Next work should probably address Duplicate Tracker further, as it needs analysis now from the perspective of what parts of it are not necessary now, after changing the approach to implementation of the module analysis step.
2024-12-11[SPIR-V] Mark XFAIL tests which fail with LLVM_ENABLE_EXPENSIVE_CHECKS (#119497)Michal Paszkowski
The test cases marked with XFAIL by this commit are not yet supported by the SPIR-V backend with LLVM_ENABLE_EXPENSIVE_CHECKS enabled.
2024-12-09[SPIR-V] Improve general validity of emitted code between passes (#119202)Vyacheslav Levytskyy
This PR improves general validity of emitted code between passes due to generation of `TargetOpcode::PHI` instead of `SPIRV::OpPhi` after Instruction Selection, fixing generation of OpTypePointer instructions and using of proper virtual register classes. Using `TargetOpcode::PHI` instead of `SPIRV::OpPhi` after Instruction Selection has a benefit to support existing optimization passes immediately, as an alternative path to disable those passes that use `MI.isPHI()`. This PR makes it possible thus to revert https://github.com/llvm/llvm-project/pull/116060 actions and get back to use the `MachineSink` pass. This PR is a solution of the problem discussed in details in https://github.com/llvm/llvm-project/pull/110507. It accepts an advice from code reviewers of the PR #110507 to postpone generation of OpPhi rather than to patch CodeGen. This solution allows to unblock improvements wrt. expensive checks and makes it unrelated to the general points of the discussion about OpPhi vs. G_PHI/PHI. This PR contains numerous small patches of emitted code validity that allows to substantially pass rate with expensive checks. Namely, the test suite with expensive checks set ON now has only 12 fails out of 569 total test cases. FYI @bogner
2024-12-06[SPIR-V] Emit Alignment decoration for alloca instructions and improve type ↵Vyacheslav Levytskyy
inference (#118520) This PR is to fix the following issues: * the SPIR-V Backend didn't generate Alignment decoration for alloca instructions, * we need to use types from demangled function declarations to specify types for opaque pointers.
2024-12-03[SPIR-V] Fix generation of invalid SPIR-V in cases of of bitcasts between ↵Vyacheslav Levytskyy
pointers and multiple null pointers used in the input LLVM IR (#118298) This PR resolved the following issues: (1) There are rare but possible cases when there are bitcasts between pointers intertwined in a sophisticated way with loads, stores, function calls and other instructions that are part of type deduction. In this case we must account for inserted bitcasts between pointers rather than just ignore them. (2) Null pointers have the same constant representation but different types. Type info from Intrinsic::spv_track_constant() refers to the opaque (untyped) pointer, so that each MF/v-reg pair would fall into the same Const record in Duplicate Tracker and would be represented by a single OpConstantNull instruction, unless we use precise pointee type info. We must be able to distinguish one constant (null) pointer from another to avoid generating invalid code with inconsistent types of operands.
2024-11-29[SPIR-V] Improve type inference: fix types of return values in call lowering ↵Vyacheslav Levytskyy
(#116609) Goals of the PR are: * to ensure that correct types are applied to virtual registers which were used as return values in call lowering. A reproducer is attached as a new test case, before the PR it fails because spirv-val considers output invalid due to wrong result/operand types in OpPhi's; * improve type inference by speeding up postprocessing of types: by limiting iterations by checking what remains to process, and processing each instruction just once for any number of operands with uncomplete types; * improve type inference by more accurate work with uncomplete types (pass uncomplete property to dependent operands, ensure consistency of uncomplete-types data structure); * change processing order and add traversing of PHI nodes when type inference apply instructions results to specify/update/cast operands type (fixes an issue with OpPhi's result type mismatch with operand types).
2024-11-12[SPIRV] Add reads from image buffer for shaders. (#115178)Steven Perron
This commit adds an intrinsic that will read from an image buffer. We chose to match the name of the DXIL intrinsic for simplicity in clang. We cannot reuse the existing openCL readimage function because that is not a reserved name in HLSL. I considered trying to refactor generateReadImageInst, so that we could share code between the two implementations. However, most of the code in generateReadImageInst is concerned with trying to figure out which type of image read is being done. Once we factor out the code that will be common, then we end up with just a single call to the MIRBuilder being common.
2024-09-03[SPIR-V] Improve correctness of emitted MIR between passes for branching ↵Vyacheslav Levytskyy
instructions (#106966) This PR improves correctness of emitted MIR between passes for branching instructions and thus increase number of passing tests when expensive checks are on. Specifically, we address here such issues with machine verifier as: * fix switch generation: generate correct successors and undo the "address taken" status to reflect that a successor doesn't actually correspond to an IR-level basic block; * fix incorrect definition of OpBranch and OpBranchConditional in TableGen (SPIRVInstrInfo.td) to set isBarrier status properly and set a correct type of virtual registers; * fix a case when Phi refers to a type definition that goes after the Phi instruction, so that the virtual register definition of the type doesn't dominate all uses. This PR decrease number of failing tests under expensive checks from 56 to 50.
2024-08-22[SPIR-V] Rework usage of virtual registers' types and classes (#104104)Vyacheslav Levytskyy
This PR continues https://github.com/llvm/llvm-project/pull/101732 changes in virtual register processing aimed to improve correctness of emitted MIR between passes from the perspective of MachineVerifier. Namely, the following changes are introduced: * register classes (lib/Target/SPIRV/SPIRVRegisterInfo.td) and instruction patterns (lib/Target/SPIRV/SPIRVInstrInfo.td) are corrected and simplified (by removing unnecessary sophisticated options) -- e.g., this PR gets rid of duplicating 32/64 bits patterns, removes ANYID register class and simplifies definition of the rest of register classes, * hardcoded LLT scalar types in passes before instruction selection are corrected -- the goal is to have correct bit width before instruction selection, and use 64 bits registers for pattern matching in the instruction selection pass; 32-bit registers remain where they are described in such terms by SPIR-V specification (like, for example, creation of virtual registers for scope/mem semantics operands), * rework virtual register type/class assignment for calls/builtins lowering, * a series of minor changes to fix validity of emitted code between passes: - ensure that that bitcast changes the type, - fix the pattern for instruction selection for OpExtInst, - simplify inline asm operands usage, - account for arbitrary integer sizes / update legalizer rules; * add '-verify-machineinstrs' to existed test cases. See also https://github.com/llvm/llvm-project/issues/88129 that this PR may resolve. This PR fixes a great number of issues reported by MachineVerifier and, as a result, reduces a number of failed test cases for the mode with expensive checks set on from ~200 to ~57.
2024-08-14[SPIR-V] Add implementation of the non-const G_BUILD_VECTOR and fix emission ↵Vyacheslav Levytskyy
of the OpGroupBroadcast instruction (#103050) This PR addresses a TODO in lib/Target/SPIRV/SPIRVInstructionSelector.cpp by adding implementation of the non-const G_BUILD_VECTOR, and fix emission of the OpGroupBroadcast instruction for the case when the `..._group_broadcast` builtin has more than one `local_id` argument and `OpGroupBroadcast` requires a newly constructed vector with 2 or 3 components instead of originally passed series of `local_id` arguments. This PR may resolve https://github.com/llvm/llvm-project/issues/97310 if the reason for the reported fail is an incorrectly generated OpGroupBroadcast instruction that was definitely a case. Existing test is hardened and a new test is added to cover this special case of the OpGroupBroadcast instruction emission.
2024-08-12[SPIR-V] Allow non-const arguments in a Group builtin that requires a ↵Vyacheslav Levytskyy
boolean argument (#102902) This PR resolves a TODO in `generateGroupInst()` (`lib/Target/SPIRV/SPIRVBuiltins.cpp`) and Issues https://github.com/llvm/llvm-project/issues/97311 and https://github.com/llvm/llvm-project/issues/97312 by implementing support for non-const arguments in a Group builtin that requires a boolean argument.
2024-08-12[SPIR-V] Rework usage of virtual registers' types and classes (#101732)Vyacheslav Levytskyy
This PR contains changes in virtual register processing aimed to improve correctness of emitted MIR between passes from the perspective of MachineVerifier. This potentially helps to detect previously missed flaws in code emission and harden the test suite. As a measure of correctness and usefulness of this PR we may use a mode with expensive checks set on, and MachineVerifier reports problems in the test suite. In order to satisfy Machine Verifier requirements to MIR correctness not only a rework of usage of virtual registers' types and classes is required, but also corrections into pre-legalizer and instruction selection logics. Namely, the following changes are introduced: * scalar virtual registers have proper bit width, * detect register class by SPIR-V type, * add a superclass for id virtual register classes, * fix Tablegen rules used for instruction selection, * fixes of minor existed issues (missed flag for proper representation of a null constant for OpenCL vs. HLSL, wrong usage of integer virtual registers as a synonym of any non-type virtual register).
2024-07-11[SPIRV] Improve type inference of operand presented by opaque pointers and ↵Vyacheslav Levytskyy
aggregate types (#98035) This PR improves type inference of operand presented by opaque pointers and aggregate types: * tries to restore original function return type for aggregate types so that it's possible to deduce a correct type during emit-intrinsics step (see llvm/test/CodeGen/SPIRV/SpecConstants/restore-spec-type.ll for the reproducer of the previously existed issue when spirv-val found a mismatch between object and ptr types in OpStore due to the incorrect aggregate types tracing), * explores untyped pointer operands of store to deduce correct pointee types, * creates an extension type to track pointee types from emit-intrinsics step and further instead of direct and naive usage of TypePointerType that led previously to crashes due to ban of creation of Value of TypePointerType type, * tracks instructions with uncomplete type information and tries to improve their type info after pass calculated types for all machine functions (it doesn't traverse a code but rather checks only those instructions which were tracked as uncompleted), * address more cases of removing unnecessary bitcasts (see, for example, changes in test/CodeGen/SPIRV/transcoding/OpGenericCastToPtr.ll where `CHECK-SPIRV-NEXT` in LIT checks show absence of unneeded bitcasts and unmangled/mangled versions have proper typing now with equivalent type info), * address more cases of well known types or relations between types within instructions (see, for example, atomic*.ll test cases and Event-related test cases for improved SPIR-V code generated by the Backend), * fix the issue of removing unneeded ptrcast instructions in pre-legalizer pass that led to creation of new assign-type instructions with the same argument as source in ptrcast and caused errors in type inference (the reproducer `complex.ll` test case is added to the PR).
2024-07-04[SPIR-V] Add __spirv_ wrappers to Non-Uniform, Atomic, Convert Instructions ↵Vyacheslav Levytskyy
(#96790) This PR: * adds missing __spirv_ wrappers to Non-Uniform, Atomic, and Convert Instructions, * fixes emission of Group builtins, * adds relevant checks to test cases to cover newly added __spirv_ wrappers.
2024-07-03[SPIR-V] Improve type inference for a known instruction's builtin: ↵Vyacheslav Levytskyy
OpGroupAsyncCopy (#96895) This PR improves type inference for a known instruction's builtin: OpGroupAsyncCopy: * deduce a type of one source/destination pointer when it's possible to deduce a type of another argument, and * validate src and dest types and tries to unfold a parameter if it's a structure wrapper around a scalar/vector type.
2024-06-26[SPIR-V] Fix support of OpGenericCastToPtr __spirv_ wrappers (#96655)Vyacheslav Levytskyy
This PR completes implementation of insertion of OpGenericCastToPtr using builtin functions started by https://github.com/llvm/llvm-project/pull/95055 by: * fixing errors in Tablegen definition, * adding type inference info for `__spirv_GenericCastToPtrExplicit` kind of wrappers, and * hardening the test case to check correct translation of `__spirv_GenericCastToPtrExplicit` kind of wrappers.
2024-06-24[SPIR-V]: Add SPIR-V extension: SPV_KHR_cooperative_matrix (#96091)Vyacheslav Levytskyy
This PR adds SPIR-V extension SPV_KHR_cooperative_matrix that "adds a new set of types known as "cooperative matrix" types, where the storage for and computations performed on the matrix are spread across a set of invocations such as a subgroup" (see https://github.com/KhronosGroup/SPIRV-Registry/blob/main/extensions/KHR/SPV_KHR_cooperative_matrix.asciidoc). This PR also fixes https://github.com/llvm/llvm-project/issues/96170, a new test cases is attached (llvm/test/CodeGen/SPIRV/transcoding/OpPtrCastToGeneric.ll).
2024-06-13[SPIR-V] Implement insertion of 'Group and Subgroup Instructions' using ↵Vyacheslav Levytskyy
builtin functions (#95176) This PR adds builtin functions to insert instructions from 'Group and Subgroup' section of the SPIR-V Specification. Corresponding tests are updated, `spirv-val` run is added where it was missed.
2024-06-11[SPIR-V] Implement insertion of OpGenericCastToPtr using builtin functions ↵Vyacheslav Levytskyy
(#95055) This PR implements insertion of OpGenericCastToPtr using builtin functions (both opencl `to_global|local|private` and `__spirv_` wrappers), and improves type inference.
2024-06-07[SPIR-V] Improve type inference, addrspacecast and dependencies between ↵Vyacheslav Levytskyy
SPIR-V entities and required capability/extensions (#94626) This PR continues https://github.com/llvm/llvm-project/pull/94467 and contains fixes in emission of type intrinsics, constant recording and corresponding test cases: * type-deduce-global-dup.ll -- fix of integer constant emission on 32-bit platforms and correct type deduction for globals * type-deduce-simple-for.ll -- fix of GEP translation (there was an issue previously that led to incorrect translation/broken logic of for-range implementation) This PR also: * fixes a cast between identical storage classes and updates the test case to include validation run by spirv-val, * ensures that Bitcast for pointers satisfies the requirement that the address spaces must match and adds the corresponding test case, * improve encode in Tablegen and decode in code of dependencies between SPIR-V entities and required capability/extensions, * prevent emission of identical OpTypePointer instructions.
2024-06-07[clang][SPIR-V] Add support for AMDGCN flavoured SPIRV (#89796)Alex Voicu
This change seeks to add support for vendor flavoured SPIRV - more specifically, AMDGCN flavoured SPIRV. The aim is to generate SPIRV that carries some extra bits of information that are only usable by AMDGCN targets, forfeiting absolute genericity to obtain greater expressiveness for target features: - AMDGCN inline ASM is allowed/supported, under the assumption that the [SPV_INTEL_inline_assembly](https://github.com/intel/llvm/blob/sycl/sycl/doc/design/spirv-extensions/SPV_INTEL_inline_assembly.asciidoc) extension is enabled/used - AMDGCN target specific builtins are allowed/supported, under the assumption that e.g. the `--spirv-allow-unknown-intrinsics` option is enabled when using the downstream translator - the featureset matches the union of AMDGCN targets' features - the datalayout string is overspecified to affix both the program address space and the alloca address space, the latter under the assumption that the [SPV_INTEL_function_pointers](https://github.com/intel/llvm/blob/sycl/sycl/doc/design/spirv-extensions/SPV_INTEL_function_pointers.asciidoc) extension is enabled/used, case in which the extant SPIRV datalayout string would lead to pointers to function pointing to the private address space, which would be wrong. Existing AMDGCN tests are extended to cover this new target. It is currently dormant / will require some additional changes, but I thought I'd rather put it up for review to get feedback as early as possible. I will note that an alternative option is to place this under AMDGPU, but that seems slightly less natural, since this is still SPIRV, albeit relaxed in terms of preconditions & constrained in terms of postconditions, and only guaranteed to be usable on AMDGCN targets (it is still possible to obtain pristine portable SPIRV through usage of the flavoured target, though).
2024-06-06[SPIR-V] Add validation to the test case with ↵Vyacheslav Levytskyy
get_image_array_size/get_image_dim calls (#94467) This PR is to add validation to the test case with get_image_array_size/get_image_dim calls (transcoding/check_ro_qualifier.ll). This test case didn't pass validation because of invalid emission of OpCompositeExtract instruction (Result Type must be the same type as Composite.). In order to fix the problem this PR improves type inference in general and partially addresses issues: * https://github.com/llvm/llvm-project/issues/91998 * https://github.com/llvm/llvm-project/issues/91997 A reproducer from the description of the latter issue is added as a new test case as a part of this PR.
2024-06-05[SPIR-V] Emit valid SPIR-V code for integer sizes other than 8,16,32,64 (#94219)Vyacheslav Levytskyy
Only with SPV_INTEL_arbitrary_precision_integers SPIR-V Backend creates arbitrary sized integer types (<= 64 bits). Without such extension and according to the SPIR-V specification `SPIRVGlobalRegistry::getOpTypeInt()` rounds integer sizes other than 8,16,32,64 up, to one of defined by the specification sizes. For the `DuplicateTracker` class this means that several original LLVM types (e.g., i2, i4) map to the same "OpTypeInt 8" instruction. This breaks `DuplicateTracker`'s logic and leads to generation of invalid SPIR-V code eventually. For example, ``` define spir_func void @foo(i2 %a, i4 %b) { entry: %res2 = tail call i2 @llvm.bitreverse.i2(i2 %a) %res4 = tail call i4 @llvm.bitreverse.i4(i4 %b) ret void } declare i2 @llvm.bitreverse.i2(i2) declare i4 @llvm.bitreverse.i4(i4) ``` after translation to SPIR-V would fail during validation (`spirv-val`) due to two `OpTypeInt 8 0` instructions. This PR fixes the issue by changing source LLVM type according to the SPIR-V type that will be used in the emitted code.
2024-06-03[SPIR-V] Fix legalize info for G_BITREVERSE (#93699)Vyacheslav Levytskyy
This PR fixes legalize info for G_BITREVERSE.
2024-04-26[SPIRV] Improve builtins matching and type inference in SPIR-V Backend, ↵Vyacheslav Levytskyy
fix target ext type constants (#89948) This PR is to improve builtins matching and type inference in SPIR-V Backend. The model test case is printf call from OpenCL.std that has several features allowing for a wider look at builtins support/type inference: (1) call in a "spirv-friendly" style (prefixed by __spirv_ocl_) (2) restricted type of the 1st argument Attached test cases checks several possible inputs. Support of the extension SPV_EXT_relaxed_printf_string_address_space is to do (see: https://github.com/KhronosGroup/SPIRV-Registry/blob/main/extensions/EXT/SPV_EXT_relaxed_printf_string_address_space.asciidoc). This PR also fixes target ext type constants and OpGroupAsyncCopy/OpGroupWaitEvents generation. A new test case is attached.
2024-04-24Bit width of input/result types in OpSConvert/OpUConvert must not be the ↵Vyacheslav Levytskyy
same (#89737) This PR fixes the issue https://github.com/llvm/llvm-project/issues/88908 Attached test case is updated to check that OpSConvert/OpUConvert is not generated when input and result types are identical.
2024-04-22[SPIR-V] Emit SPIR-V generator magic number and version (#87951)Michal Paszkowski
This patch: - Adds SPIR-V backend's registered generator magic number to the emitted binary. The magic number consists of the generator ID (43) and LLVM major version. - Adds SPIR-V version to the binary. - Allows reading the expected (maximum supported) SPIR-V version from the target triple. - Uses VersionTuple for representing versions throughout the backend's codebase. - Registers v1.6 for spirv32 and spirv64 triple. See more: https://github.com/KhronosGroup/SPIRV-Headers/commit/7d500c
2024-04-17[SPIR-V] Account for zext in a llvm intrinsic call (#88903)Vyacheslav Levytskyy
This PR addresses an issue that may arise when an integer argument size differs from a machine word size for the target in a call to llvm intrinsic. The following example demonstrates the issue: ``` @__const.test.arr = private unnamed_addr addrspace(2) constant [3 x i32] [i32 1, i32 2, i32 3] define spir_func void @test() { entry: %arr = alloca [3 x i32], align 4 %dest = bitcast ptr %arr to ptr call void @llvm.memcpy.p0.p2.i32(ptr align 4 %dest, ptr addrspace(2) align 4 @__const.test.arr, i32 1024, i1 false) ret void } declare void @llvm.memcpy.p0.p2.i32(ptr nocapture writeonly, ptr addrspace(2) nocapture readonly, i32, i1) ``` Depending on the target this code may work or may fail without this PR due to the fact that IR Translation step introduces additional `zext` when type of the 3rd argument of `@llvm.memcpy.p0.p2.i32` differs from machine word. This PR addresses the issue by adding type deduction for a newly inserted G_ZEXT generic opcode.
2024-03-26[SPIR-V] Support extension toggling and enabling all (#85503)Michal Paszkowski
2024-03-25[SPIR-V] Add WaveGetLaneIndex() intrinsic support (#85979)Nathan Gauër
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-18[SPIRV] Add Lifetime intrinsics/instructions (#85391)Vyacheslav Levytskyy
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-13[SPIR-V] Add implementation of G_SPLAT_VECTOR opcode and fix invalid types ↵Vyacheslav Levytskyy
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-03[SPIR-V] Do not use OpenCL metadata for ptr element type resolution (#82678)Michal Paszkowski
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-15let a user select preferred/unpreferred capabilities in a list of enabling ↵Vyacheslav Levytskyy
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-01-04[SPIR-V] Emit SPIR-V bitcasts between source/expected pointer type (#69621)Michal Paszkowski
This patch introduces a new spv_ptrcast intrinsic for tracking expected pointer types. The change fixes multiple OpenCL CTS regressions due the switch to opaque pointers (e.g. basic/hiloeo).