aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/SPIRV
AgeCommit message (Collapse)AuthorFilesLines
2024-06-11[SPIR-V] Validate and fix bit width of scalar registers (#95147)Vyacheslav Levytskyy1-5/+20
This PR improves legalization process of SPIR-V instructions. Namely, it introduces validation and fixing of bit width of scalar registers as a part of pre-legalizer. A test case is added that demonstrates ability to legalize instructions with non 8/16/32/64 bit width both with and without vendor-specific SPIR-V extension (SPV_INTEL_arbitrary_precision_integers). In the case of absence of the extension, a generated SPIR-V code will fallback to 8/16/32/64 bit width in OpTypeInt, but SPIR-V Backend still is able to legalize operations with original integer sizes.
2024-06-11[SPIR-V] Implement insertion of OpGenericCastToPtr using builtin functions ↵Vyacheslav Levytskyy4-73/+130
(#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-11[SPIR-V] Ensure that DuplicatesTracker is working with TypedPointers pointee ↵Vyacheslav Levytskyy1-6/+13
types (#94952) This PR is a tweak to ensure that DuplicatesTracker is working with TypedPointers pointee types rather than with original llvm's untyped pointers. This enforces DuplicatesTracker promise to avoid emission of several identical OpTypePointer instructions.
2024-06-11[SPIR-V] Don't change switch condition type in CodeGen opts (#94959)Michal Paszkowski1-0/+5
This change makes sure the preferred switch condition int type size remains the same throughout CodeGen optimizations. The change fixes running several OpenCL applications with -O2 or higher opt levels, and fixes Basic/stream/stream_max_stmt_exceed.cpp DPC++ E2E test with -O2.
2024-06-11[SPIR-V] Fix flakiness during switch generation. (#95001)Nathan Gauër1-11/+14
The case-list of the switches generated by this pass were not "deterministic" (based on allocation patterns). This is because the CaseList order relied on an unordered_set order. Using the sorted exit target list for those should solve the problem. Fixes #94961 Signed-off-by: Nathan Gauër <brioche@google.com>
2024-06-07[SPIR-V] Improve type inference, addrspacecast and dependencies between ↵Vyacheslav Levytskyy9-95/+86
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 Voicu1-0/+4
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[SPIRV] Fix -Wunused-but-set-variable. NFCFangrui Song1-1/+1
2024-06-06[SPIR-V] Add validation to the test case with ↵Vyacheslav Levytskyy5-70/+149
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] Introduce support of '__spirv_' wrapper builtins for the ↵Vyacheslav Levytskyy2-1/+24
SPV_INTEL_subgroups extension (#94235) This PR Introduces support of '__spirv_' wrapper builtins for the SPV_INTEL_subgroups extension.
2024-06-05[SPIR-V] Emit valid SPIR-V code for integer sizes other than 8,16,32,64 (#94219)Vyacheslav Levytskyy2-15/+59
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[SPIRV] Fix -Wunused-but-set-variable after #92531Fangrui Song1-5/+2
2024-06-03[SPIR-V] Fix legalize info for G_BITREVERSE (#93699)Vyacheslav Levytskyy2-1/+6
This PR fixes legalize info for G_BITREVERSE.
2024-06-03[SPIR-V] Add pass to merge convergence region exit targets (#92531)Nathan Gauër6-1/+311
The structurizer required regions to be SESE: single entry, single exit. This new pass transforms multiple-exit regions into single-exit regions. ``` +---+ | A | +---+ / \ +---+ +---+ | B | | C | A, B & C belongs to the same convergence region. +---+ +---+ | | +---+ +---+ | D | | E | C & D belongs to the parent convergence region. +---+ +---+ This means B & C are the exit blocks of the region. \ / And D & E the targets of those exits. \ / | +---+ | F | +---+ ``` This pass would assign one value per exit target: B = 0 C = 1 Then, create one variable per exit block (B, C), and assign it to the correct value: in B, the variable will have the value 0, and in C, the value 1. Then, we'd create a new block H, with a PHI node to gather those 2 variables, and a switch, to route to the correct target. Finally, the branches in B and C are updated to exit to this new block. ``` +---+ | A | +---+ / \ +---+ +---+ | B | | C | +---+ +---+ \ / +---+ | H | +---+ / \ +---+ +---+ | D | | E | +---+ +---+ \ / \ / | +---+ | F | +---+ ``` Note: the variable is set depending on the condition used to branch. If B's terminator was conditional, the variable would be set using a SELECT. All internal edges of a region are left intact, only exiting edges are updated. --------- Signed-off-by: Nathan Gauër <brioche@google.com>
2024-06-03[SPIR-V] Validate type of the last parameter of OpGroupWaitEvents (#93661)Vyacheslav Levytskyy1-26/+73
This PR fixes invalid OpGroupWaitEvents emission to ensure that SPIR-V Backend inserts a bitcast before OpGroupWaitEvents if the last argument is a pointer that doesn't point to OpTypeEvent.
2024-05-29[SPIR-V] Implement correct zeroinitializer for extension types in SPIR-V ↵Vyacheslav Levytskyy2-11/+21
Backend (#93607) This PR implements correct zeroinitializer for extension types in SPIR-V Backend. Previous version has just created 0 of 32/64 integer type (depending on target machine word size), that caused re-use and type re-write of the corresponding integer constant 0 with a potential crash on wrong usage of the constant (i.e., 0 of integer type expected but extension type found). E.g., the following code would crash without the PR: ``` %r1 = icmp ne i64 %_arg_i, 0 %e1 = tail call spir_func target("spirv.Event") @__spirv_GroupAsyncCopy(i32 2, ptr addrspace(3) %_arg_local, ptr addrspace(1) %_arg_ptr, i64 1, i64 1, target("spirv.Event") zeroinitializer) ``` because 0 in icmp would eventually be of `Event` type.
2024-05-29[SPIR-V] Introduce support of llvm.ptr.annotation to SPIR-V Backend and ↵Vyacheslav Levytskyy5-0/+168
implement extensions which make use of spirv.Decorations (#93561) This PR introduces support of llvm.ptr.annotation to SPIR-V Backend, and implement several extensions which make use of spirv.Decorations and llvm.ptr.annotation to annotate global variables and pointers: - SPV_INTEL_cache_controls - SPV_INTEL_global_variable_host_access - SPV_INTEL_global_variable_fpga_decorations
2024-05-29[SPIR-V] Ensure that internal intrinsic functions are inserted at the ↵Vyacheslav Levytskyy1-11/+32
correct positions (#93552) The goal of the PR is to ensure that newly inserted internal intrinsic functions are inserted at the correct positions, and don't break rules of instruction domination and PHI nodes grouping at top of basic block. This is a continuation of https://github.com/llvm/llvm-project/pull/92316 and https://github.com/llvm/llvm-project/pull/92536
2024-05-24[SPIR-V] Inline assembly support (#93164)Vyacheslav Levytskyy19-15/+340
This PR introduces support for inline assembly calls for SPIR-V Backend in general, and support for SPV_INTEL_inline_assembly [1] extension in particular. The former part of the PR is agnostic towards vendor-specific requirements and resolves the task of supporting successful transformation of inline assembly as long as it's possible without specific SPIR-V instruction codes. As a part of the PR there appears an opportunity to bring coherent inline assembly information up to latest passes of the transformation process (emitting final SPIR-V instructions), so that PR makes it easy to add any another required flavor of inline assembly, other then supported by the vendor specific SPV_INTEL_inline_assembly extension, if/when needed. At the moment, however, SPV_INTEL_inline_assembly is the only implemented way to bring LLVM IR inline assembly calls up to valid SPIR-V instructions and also the default one. This means that inline assembly calls will generate an error message of such extension is not used to prevent LLVM-generated error messages at the final stages of translation. When the SPV_INTEL_inline_assembly extension is mentioned among supported, translation of inline assembly is intercepted by this extension implementation on a pre-legalizer step, and this is a place where support for a new inline assembly extension may be added if needed. This PR also extends support for register classes, improves type inference during pre-legalizer pass, and fixes a minor bug with asm-printing of string literals. [1] https://github.com/intel/llvm/blob/sycl/sycl/doc/design/spirv-extensions/SPV_INTEL_inline_assembly.asciidoc
2024-05-22[SPIR-V] Add cl_khr_kernel_clock / SPV_KHR_shader_clock extension (#92771)Sven van Haastregt6-0/+60
Recognize `cl_khr_kernel_clock` builtins and translate them to `OpReadClockKHR` instructions. The `Scope` operand is deduced from the builtin function name. spirv-val does not pass yet due to OpReadClockKHR only supporting the valid scopes for Vulkan (Device and Subgroup, but not Workgroup), so leave validation disabled with a TODO.
2024-05-20[SPIR-V] Ensure that internal intrinsic functions "ptrcast" for PHI's ↵Vyacheslav Levytskyy1-4/+13
operand are inserted at the correct positions (#92536) The goal of the PR is to ensure that newly inserted `ptrcast` internal intrinsic functions are inserted at the correct positions, and don't break rules of instruction domination and PHI nodes grouping at top of basic block.
2024-05-20[SPIR-V] reqd_work_group_size and work_group_size_hint metadata are ↵Vyacheslav Levytskyy1-6/+14
correctly converted to the LocalSize and LocalSizeHint execution mode (#92552) The goal of this PR is to ensure that reqd_work_group_size and work_group_size_hint metadata are correctly converted to the LocalSize and LocalSizeHint execution mode. reqd_work_group_size and work_group_size_hint require 3 operands (see https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Execution_Mode), if metadata contains less operands, just add a default value (1).
2024-05-19[MC] Make UseAssemblerInfoForParsing mostly trueFangrui Song1-3/+0
Commit 6c0665e22174d474050e85ca367424f6e02476be (https://reviews.llvm.org/D45164) enabled certain constant expression evaluation for `MCObjectStreamer` at parse time (e.g. `.if` directives, see llvm/test/MC/AsmParser/assembler-expressions.s). `getUseAssemblerInfoForParsing` was added to make `clang -c` handling inline assembly similar to `MCAsmStreamer` (e.g. `llvm-mc -filetype=asm`), where such expression folding (related to `AttemptToFoldSymbolOffsetDifference`) is unavailable. I believe this is overly conservative. We can make some parse-time expression folding work for `clang -c` even if `clang -S` would still report an error, a MCAsmStreamer issue (we cannot print `.if` directives) that should not restrict the functionality of MCObjectStreamer. ``` % cat b.cc asm(R"( .pushsection .text,"ax" .globl _start; _start: ret .if . -_start == 1 ret .endif .popsection )"); % gcc -S b.cc && gcc -c b.cc % clang -S -fno-integrated-as b.cc # succeeded % clang -c b.cc # succeeded with this patch % clang -S b.cc # still failed <inline asm>:4:5: error: expected absolute expression 4 | .if . -_start == 1 | ^ 1 error generated. ``` However, removing `getUseAssemblerInfoForParsing` would make MCDwarfFrameEmitter::Emit (for .eh_frame FDE) slow (~4% compile time regression for sqlite3.c amalgamation) due to expensive `AttemptToFoldSymbolOffsetDifference`. For now, make `UseAssemblerInfoForParsing` false in MCDwarfFrameEmitter::Emit. Close #62520 Link: https://discourse.llvm.org/t/rfc-clang-assembly-object-equivalence-for-files-with-inline-assembly/78841 Pull Request: https://github.com/llvm/llvm-project/pull/91082
2024-05-19[llvm] Use StringRef::contains (NFC) (#92710)Kazu Hirata1-1/+1
2024-05-19[llvm] Use operator==(StringRef, StringRef) (NFC) (#92705)Kazu Hirata1-3/+3
2024-05-17[SPIR-V] Ensure that we don't have a dangling BlockAddress constants after ↵Vyacheslav Levytskyy1-1/+18
internal intrinsic 'spv_switch' is processed (#92390) After internal intrinsic 'spv_switch' is processed we need to delete G_BLOCK_ADDR instructions that were generated to keep track of the corresponding basic blocks. If we just delete G_BLOCK_ADDR instructions with BlockAddress operands, this leaves their BasicBlock counterparts in a "address taken" status. This would make AsmPrinter to generate a series of unneeded labels of a `"Address of block that was removed by CodeGen"` kind. This PR is to ensure that we don't have a dangling BlockAddress constants by zapping the BlockAddress nodes, and only after that proceed with erasing G_BLOCK_ADDR instructions. See also https://github.com/llvm/llvm-project/pull/87823 for more details.
2024-05-17[SPIR-V] Fix types of internal intrinsic functions and add a test case for ↵Vyacheslav Levytskyy1-36/+43
__builtin_alloca() (#92265) This PR generation of argument types of internal intrinsic functions `spv_const_composite` and `spv_track_constant`, so that composite constants of ConstantVector type preserve their correct type in transformation passes and can be successfully used further by LLVM intrinsic functions. The added test case serves two purposes: it is to check the above mentioned fix and to demonstrate that a call to __builtin_alloca() maps to instructions from SPV_INTEL_variable_length_array when this extension is available.
2024-05-17[SPIR-V] Ensure that internal intrinsic functions for PHI's operand are ↵Vyacheslav Levytskyy1-2/+2
inserted at the correct positions (#92316) This PR is to ensure that internal intrinsic functions for PHI's operand are inserted at the correct positions and don't break rules of instruction domination and PHI nodes grouping at top of basic block.
2024-05-16Revert "[MC] Remove UseAssemblerInfoForParsing"Nikita Popov1-0/+3
This reverts commit 03c53c69a367008da689f0d2940e2197eb4a955c. This causes very large compile-time regressions in some cases, e.g. sqlite3 at O0 regresses by 5%.
2024-05-15[MC] Remove UseAssemblerInfoForParsingFangrui Song1-3/+0
Commit 6c0665e22174d474050e85ca367424f6e02476be (https://reviews.llvm.org/D45164) enabled certain constant expression evaluation for `MCObjectStreamer` at parse time (e.g. `.if` directives, see llvm/test/MC/AsmParser/assembler-expressions.s). `getUseAssemblerInfoForParsing` was added to make `clang -c` handling inline assembly similar to `MCAsmStreamer` (e.g. `llvm-mc -filetype=asm`), where such expression folding (related to `AttemptToFoldSymbolOffsetDifference`) is unavailable. I believe this is overly conservative. We can make some parse-time expression folding work for `clang -c` even if `clang -S` would still report an error, a MCAsmStreamer issue (we cannot print `.if` directives) that should not restrict the functionality of MCObjectStreamer. ``` % cat b.cc asm(R"( .pushsection .text,"ax" .globl _start; _start: ret .if . -_start == 1 ret .endif .popsection )"); % gcc -S b.cc && gcc -c b.cc % clang -S -fno-integrated-as b.cc # succeeded % clang -c b.cc # succeeded with this patch % clang -S b.cc # still failed <inline asm>:4:5: error: expected absolute expression 4 | .if . -_start == 1 | ^ 1 error generated. ``` Close #62520 Link: https://discourse.llvm.org/t/rfc-clang-assembly-object-equivalence-for-files-with-inline-assembly/78841 Pull Request: https://github.com/llvm/llvm-project/pull/91082
2024-05-14[SPIR-V] Introduce support for 'spirv.Decorations' metadata node in SPIR-V ↵Vyacheslav Levytskyy5-0/+67
Backend (#91736) This PR is to introduce support for 'spirv.Decorations' metadata node in SPIR-V Backend. See also https://github.com/KhronosGroup/SPIRV-LLVM-Translator/blob/main/docs/SPIRVRepresentationInLLVM.rst that describes `spirv.Decorations` as an important part of SPIRV-friendly LLVM IR.
2024-05-14[SPIR-V] Support saturation arithmetic intrinsics in SPIR-V Backend (#91722)Vyacheslav Levytskyy2-0/+13
This PR is to support saturation arithmetic intrinsics in SPIR-V Backend.
2024-05-14[SPIR-V] Set non-kernel function linkage type via OpDecorate for all linkage ↵Vyacheslav Levytskyy1-2/+2
types except for static functions (#91598) This PR fixes the issue https://github.com/llvm/llvm-project/issues/91595 by setting non-kernel function linkage type via OpDecorate for all linkage types except for static functions. A new test case is added.
2024-05-08[SPIRV] Add tan intrinsic part 3 (#90278)Farzon Lotfi2-0/+3
This change is an implementation of #87367's investigation on supporting IEEE math operations as intrinsics. Which was discussed in this RFC: https://discourse.llvm.org/t/rfc-all-the-math-intrinsics/78294 If you want an overarching view of how this will all connect see: https://github.com/llvm/llvm-project/pull/90088 Changes: - `llvm/docs/GlobalISel/GenericOpcode.rst` - Document the `G_FTAN` opcode - `llvm/include/llvm/IR/Intrinsics.td` - Create the tan intrinsic - `llvm/include/llvm/Support/TargetOpcodes.def` - Create a `G_FTAN` Opcode handler - `llvm/include/llvm/Target/GenericOpcodes.td` - Define the `G_FTAN` Opcode - `llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp` Map the tan intrinsic to `G_FTAN` Opcode - `llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp` - Map the `G_FTAN` opcode to the GLSL 4.5 and openCL tan instructions. - `llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp` - Define `G_FTAN` as a legal spirv target opcode.
2024-05-05[Target] Use StringRef::operator== instead of StringRef::equals (NFC) ↵Kazu Hirata1-1/+1
(#91072) (#91138) I'm planning to remove StringRef::equals in favor of StringRef::operator==. - StringRef::operator==/!= outnumber StringRef::equals by a factor of 38 under llvm/ in terms of their usage. - The elimination of StringRef::equals brings StringRef closer to std::string_view, which has operator== but not equals. - S == "foo" is more readable than S.equals("foo"), especially for !Long.Expression.equals("str") vs Long.Expression != "str".
2024-04-26[SPIRV] Improve builtins matching and type inference in SPIR-V Backend, ↵Vyacheslav Levytskyy5-41/+123
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-25[MC] Remove RelaxAll parameters from create*StreamerFangrui Song1-2/+2
Related to clean-up opportunities discussed at #90013. After these cleanups, the `RelaxAll` parameter from `createMCObjectStreamer` can be removed as well. As `createMCObjectStreamer` is a more user-facing API and used by two files in mlir/, we postpone the cleanup to the future.
2024-04-24[SPIR-V] Fix pre-legalizer pass in SPIR-V Backend to support more gMIR ↵Vyacheslav Levytskyy3-0/+38
opcode inserted by IRTranslator (#89890) Translating global values, IRTranslator pass can sometimes generates code patterns that require additional efforts during pre-legalization. This PR addresses this problem to support G_PTRTOINT instruction used in initialization of GV.
2024-04-24Bit width of input/result types in OpSConvert/OpUConvert must not be the ↵Vyacheslav Levytskyy2-9/+26
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 Paszkowski8-75/+90
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-22[SPIRV][HLSL] map lerp to Fmix (#88976)Farzon Lotfi1-0/+26
- `clang/lib/CodeGen/CGBuiltin.cpp` - switch to using `getLerpIntrinsic()` to abstract backend intrinsic - `clang/lib/CodeGen/CGHLSLRuntime.h` - add `getLerpIntrinsic()` - `llvm/include/llvm/IR/IntrinsicsSPIRV.td` - add SPIRV intrinsic for lerp - `llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp` - add mapping of HLSL's lerp to GLSL's Fmix. resolves #88940
2024-04-19[SPIR-V] SPIR-V Backend must generate a valid OCL version if working in ↵Vyacheslav Levytskyy1-3/+14
OpenCL environment (#89199) If there is no information about OpenCL version we are forced to generate OpenCL 1.0 by default for the OpenCL environment to avoid puzzling run-times with Unknown/0.0 version output. For a reference, LLVM-SPIRV Translator avoids potential issues with run-times in a similar manner.
2024-04-18[SPIR-V] Fix return type when sampling an image with ↵Vyacheslav Levytskyy3-3/+6
OpImageSampleExplicitLod (#89252) This PR fixes parsing of builtins return types in general and fixes return type when sampling an image with OpImageSampleExplicitLod in particular.
2024-04-17[SPIR-V] Account for zext in a llvm intrinsic call (#88903)Vyacheslav Levytskyy1-0/+25
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-04-17[SPIR-V] Improve Tablegen instruction selection and account for a pointer ↵Vyacheslav Levytskyy9-74/+104
size of the target (#88725) This PR resolves the issue that SPIR-V Backend uses the notion of a pointer size of the target, most notably, in legalizer code, but Tablegen instruction selection in SPIR-V Backend doesn't account for a pointer size of the target. See https://github.com/llvm/llvm-project/issues/88723 for a detailed description. There are 3 test cases attached to the PR that reproduced the issue, when dealing with spirv32-spirv64 differences, and are working correctly now with this PR.
2024-04-16[clang][CodeGen] Add AS for Globals to SPIR & SPIRV datalayouts (#88455)Alex Voicu1-2/+2
Currently neither the SPIR nor the SPIRV targets specify the AS for globals in their datalayout strings. This is problematic because CodeGen/LLVM will default to AS0 in this case, which produces Globals that end up in the private address space for e.g. OCL, HIPSPV or SYCL. This patch addresses it by completing the datalayout string.
2024-04-15[HLSL][SPIRV] Add any intrinsic lowering (#88325)Farzon Lotfi1-4/+25
- `CGBuiltin.cpp` - Switch to using `CGM.getHLSLRuntime().get##NAME##Intrinsic()` - `CGHLSLRuntime.h` - Add any to backend intrinsic abstraction - `IntrinsicsSPIRV.td` - Add any intrinsic to SPIR-V. - `SPIRVInstructionSelector.cpp` - Add means of selecting any intrinsic. Any and All share the same behavior up to the opCode. They are only different in vector cases. Completes #88045
2024-04-15[SPIR-V] Update type inference and instruction selection (#88254)Vyacheslav Levytskyy15-38/+267
This PR contains a series of fixes which are to improve type inference and instruction selection. Namely, it includes: * fix OpSelect to support operands of a pointer type, according to the SPIR-V specification (previously only integer/float/vectors of integer or float were supported) -- a new test case is added and existing test case is updated; * fix TableGen typo's in definition of register classes and introduce a new reg class that is a vector of pointers; * fix usage of a machine function context when there is a need to switch between different machine functions to infer/validate correct types; * add usage of TypedPointerType instead of PointerType so that later stages of type inference are able to distinguish pointer types by their element types, effectively supporting hierarchy of pointer/pointee types and avoiding more complicated recursive type matching on level of machine instructions in favor of direct pointer comparison using LLVM's `Type *` values; * extracting detailed information about operand types using known type rules for some llvm instructions (for instance, by deducing PHI's operand pointee types if PHI's results type was deducted on previous stages of type inference), and adding correspondent `Intrinsic::spv_assign_ptr_type` to keep type info along consequent passes, * ensure that OpConstantComposite reuses a constant when it's already created and available in the same machine function -- otherwise there is a crash while building a dependency graph, the corresponding test case is attached, * implement deduction of function's return type for opaque pointers, a new test case is attached, * make 'emit intrinsics' a module pass to resolve function return types over the module -- first types for all functions of the module must be calculated, and only after that it's feasible to deduct function return types on this earlier stage of translation.
2024-04-10[Spirv][HLSL] Add OpAll lowering and float vec support (#87952)Farzon Lotfi3-39/+319
The main point of this change was to add support for HLSL's all intrinsic. In the process of doing that I found a few issues around creating an `OpConstantComposite` via `buildZerosVal`. First the current code didn't support floats so the process of adding `buildZerosValF` meant I needed a float version of `getOrCreateIntConstVector`. After doing so I renamed both versions to `getOrCreateConstVector`. That meant I needed to create a float type version of `getOrCreateIntCompositeOrNull`. Luckily the type information was low for this function so was able to split it out into a helpwe and rename `getOrCreateIntCompositeOrNull` to `getOrCreateCompositeOrNull` With the exception of type handling differences of the code and Null vs 0 Constant Op codes these functions should be identical. To handle scalar floats I could not use `buildConstantFP` like this PR did: https://github.com/llvm/llvm-project/commit/0a2aaab5aba46#diff-733a189c5a8c3211f3a04fd6e719952a3fa231eadd8a7f11e6ecf1e584d57411R1603 because that would create too many superfluous registers (that causes problems in the validator), I had to create a float version of `getOrCreateConstInt` which I called `getOrCreateConstFP`. similar problems with doing it like this: https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp#L1540. `buildZerosValF` also has a use of a function `getZeroFP`. This is because half, float, and double scalar values of 0 would collide in `SPIRVDuplicatesTracker<Constant> CT` if you use `APFloat(0.0f)`. `getORCreateConstFP` needed its own version of `getOrCreateConstIntReg` which I called `getOrCreateConstFloatReg` The one difference in this function is `getOrCreateConstFloatReg` returns a bit width so we don't have to call `getScalarOrVectorBitWidth` twice ie when it is used again in `getOrCreateConstFP` for `OpConstantF` `addNumImm`. `getOrCreateConstFloatReg` needed an `assignFloatTypeToVReg` helper which called a `getOrCreateSPIRVFloatType` helper. There was no equivalent IntegerType::get for floats so I handled this with a switch statement on bit widths to get the right LLVM float type. Finally, there is the use of `bool ZeroAsNull = STI.isOpenCLEnv();` This is partly a cosmetic change. When Zeros are treated as nulls, we don't create `OpConstantComposite` vectors which is something we do in the DXCs SPIRV backend. The DXC SPIRV backend also does not use `OpConstantNull`. Finally, I needed a means to test the behavior of the OpConstantNull and `OpConstantComposite` changes and this was one way I could do that via the same tests.
2024-04-10[SPIRV] Tweak parsing of base type name in builtins (#88255)Vyacheslav Levytskyy1-4/+12
This PR is a small improvement of parsing of base type name in builtins, allowing to understand `unsigned ...` types. The test case that fails without the fix is attached.