67 Commits

Author SHA1 Message Date
Marcos Maronas
dfd506b948
[SPIRV] Fix code quality issues. (#152005)
Fix code quality issues reported by static analysis tool, such as:
- Rule of Three/Five.
- Dereference after null check.
- Unchecked return value.
- Variable copied when it could be moved.
2025-08-06 15:50:00 +01:00
Marcos Maronas
1d02de28dd
[SPIRV] Implement translation for llvm.modf.* intrinsics (#147556)
Based on
https://github.com/KhronosGroup/SPIRV-LLVM-Translator/pull/3100, I'm
adding translation for `llvm.modf.*` intrinsics.
2025-07-21 14:51:34 +02:00
Steven Perron
bd33eef7f1
[HLSL][SPIRV] Use resource names (#143412)
The SPIR-V backend does not have access to the original name of a
resource in the source, so it tries to create a name. This leads to some
problems with reflection.
    
That is why start to pass the name of the resource from Clang to the
SPIR-V backend.
    
Fixes #138533
2025-06-13 12:21:38 -04:00
Steven Perron
7c9e0d5b5d
[SPIRV] Lower spirv.Layout type (#140059)
Add this type in accordance with the [design
doc](https://github.com/llvm/wg-hlsl/pull/171).

Fixes https://github.com/llvm/llvm-project/issues/138276

---------

Co-authored-by: Nathan Gauër <github@keenuts.net>
2025-05-27 14:55:45 -04:00
Iris Shi
bdf03fcff3
Revert "[llvm][NFC] Use llvm::sort()" (#140668) 2025-05-20 11:27:03 +08:00
Iris Shi
061a7699f3
[llvm][NFC] Use llvm::sort() (#140335) 2025-05-17 14:49:46 +08:00
Steven Perron
a77d807781
[SPIRV] Add spirv.VulkanBuffer types to the backend (#133475)
Adds code to expand the `llvm.spv.resource.handlefrombinding` and
`llvm.spv.resource.getpointer` when the resource type is
`spirv.VulkanBuffer`.

It gets expanded as a storage buffer or uniform buffer denpending on the
storage class used.

This is implementing part of

https://github.com/llvm/wg-hlsl/blob/main/proposals/0018-spirv-resource-representation.md.
2025-04-03 09:44:07 -04:00
Kazu Hirata
ad1ba15ea8
[Target] Use llvm::append_range (NFC) (#133606) 2025-03-29 18:47:47 -07:00
Dmitry Sidorov
7f103ad537
[SPIR-V] Add llvm.loop.unroll metadata lowering (#132062)
.enable lowers to Unroll LoopControl
.disable lowers to DontUnroll LoopControl
.count lowers to PartialCount LoopControl
.full lowers to Unroll LoopControl

TODO in future patches: enable structurizer for non-vulkan targets.

---------

Signed-off-by: Sidorov, Dmitry <dmitry.sidorov@intel.com>
2025-03-28 13:27:08 +01:00
Vyacheslav Levytskyy
54cc4141e4
[SPIR-V] Rework duplicate tracker and tracking of IR entities and types to 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-03-26 17:58:10 +01:00
Viktoria Maximova
128f381650
[SPIR-V] Add OpConstantCompositeContinuedINTEL instruction (#129086)
Specification:

https://github.khronos.org/SPIRV-Registry/extensions/INTEL/SPV_INTEL_long_composites.html
2025-03-17 22:23:58 +01:00
Nathan Gauër
7c8b1275bc
[SPIR-V] Add pass to remove spv_ptrcast intrinsics (#128896)
OpenCL is allowed to cast pointers, meaning they can resolve some type
mismatches this way. In logical SPIR-V, those are restricted. This new
pass legalizes such pointer cast when targeting logical SPIR-V.

For now, this pass supports 3 cases we witnessed:
 - loading a vec3 from a vec4*.
 - loading a scalar from a vec*.
 - loading the 1st element of an array.

---------

Co-authored-by: Steven Perron <stevenperron@google.com>
2025-03-04 10:30:46 +01:00
Viktoria Maximova
c19a303867
[SPIR-V] Support 2 more instructions from SPV_INTEL_long_composites (#128190)
This change adds support for `OpSpecConstantCompositeContinuedINTEL` and
`OpCompositeConstructContinuedINTEL` instructions and continues work
done in #126545.

Specification:

https://github.khronos.org/SPIRV-Registry/extensions/INTEL/SPV_INTEL_long_composites.html
2025-02-27 15:46:23 +01:00
Vyacheslav Levytskyy
d21b2e619a
[SPIR-V] Fix generation of gMIR vs. SPIR-V code from utility methods (#128159)
The SPIR-V Backend uses the same set of utility functions, mostly though
not entirely from SPIRVGlobalRegistry, to generate gMIR and SPIR-V
opcodes, depending on the current stage of translation. This is
controlled by an explicit EmitIR flag rather than the current
translation pass, and there are legacy pieces of code where the EmitIR
flag is declared so that it has a default true value, allowing using
utility functions without explicitly declaring their intent to work
either in gMIR or in SPIR-V part of the lowering process.

While it may be ok to leave this default EmitIR flag as is in generation
of scalar integer/float types, as we don't expect to see any dependent
opcodes derived from such OpTypeXXX instructions, using of EmitIR by
default in aggregation types is a source of hidden logical flaws and
actual issues.

This PR provides a partial fix to the problem by removing default status
of EmitIR, requiring a user call site to explicitly announce its intent
to generate gMIR or SPIR-V code, fixes several cases of misuse of
EmitIR, and, the most important, fixes a nasty logical error that breaks
passing of actually asked EmitIR value by the default value in the
middle of the chain of calls, in the `findSPIRVType` call. The latter
error was a source of issues in the post-instruction selection pass that
has been getting gMIR code where SPIR-V was explicitly requested due to
overloaded with default parameters internal API in SPIRVGlobalRegistry
(most notably, `findSPIRVType`).
2025-02-25 14:44:12 +01:00
Vyacheslav Levytskyy
3ed2a81358
[SPIR-V] Fix issue #120078 and simplifies parsing of floating point decoration tips in demangled function name (#120128)
This PR fixes https://github.com/llvm/llvm-project/issues/120078 and
improves/simplifies parsing of demangled function name that aims to
detect a tip for floating point decorations. The latter improvement
fixes also a complaint from `LLVM_USE_SANITIZER=Address`.
2024-12-18 10:04:13 +01:00
Vyacheslav Levytskyy
489db6538e
[SPIR-V] Emit Alignment decoration for alloca instructions and improve type 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-06 09:59:33 +01:00
Nathan Gauër
920ea4af64
[SPIR-V] Replace assert with report_fatal (#118617)
Irreducible must always be rejected, not only in debug builds.

Signed-off-by: Nathan Gauër <brioche@google.com>
2024-12-04 13:47:21 +01:00
Vyacheslav Levytskyy
874b4fb6ad
[SPIR-V] Fix emission of debug and annotation instructions and add SPV_EXT_optnone SPIR-V extension (#118402)
This PR fixes:
* emission of OpNames (added newly inserted internal intrinsics and
basic blocks)
* emission of function attributes (SRet is added)
* implementation of SPV_INTEL_optnone so that it emits OptNoneINTEL
Function Control flag, and add implementation of the SPV_EXT_optnone
SPIR-V extension.
2024-12-03 16:18:06 +01:00
Nathan Gauër
5f99eb9b13
[SPIR-V] Fixup storage class for global private (#118318)
Re-land of #116636
Adds a new address spaces: hlsl_private. Variables with such address
space will be emitted with a Private storage class.
This is useful for variables global to a SPIR-V module, since up to now,
they were still emitted with a Function storage class, which is wrong.

---------

Signed-off-by: Nathan Gauër <brioche@google.com>
2024-12-03 13:42:02 +01:00
Nathan Gauër
f8b4182f07
Revert "[SPIR-V] Fixup storage class for global private (#116636)" (#118312)
This reverts commit aa7fe1c10e5d6d0d3aacdb345fed995de413e142.
2024-12-02 17:32:54 +01:00
Nathan Gauër
aa7fe1c10e
[SPIR-V] Fixup storage class for global private (#116636)
Adds a new address spaces: `hlsl_private`. Variables with such address
space will be emitted with a `Private` storage class.
This is useful for variables global to a SPIR-V module, since up to now,
they were still emitted with a `Function` storage class, which is wrong.

---------

Signed-off-by: Nathan Gauër <brioche@google.com>
2024-12-02 16:17:44 +01:00
Vyacheslav Levytskyy
b5132b7d04
[SPIR-V] Improve type inference: fix types of return values in call lowering (#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-29 20:44:25 +01:00
Nathan Gauër
45b567be8d
[SPIR-V] Add partial order tests, assert reducible (#117887)
Add testing for the visitor and added a note explaining irreducible CFG
are not supported.
Related to #116692

---------

Signed-off-by: Nathan Gauër <brioche@google.com>
2024-11-28 16:33:01 +01:00
Nathan Gauër
53326ee0cf
[SPIR-V] Fix block sorting with irreducible CFG (#116996)
Block sorting was assuming reducible CFG. Meaning we always had a best
node to continue with. Irreducible CFG makes breaks this assumption, so
the algorithm looped indefinitely because no node was a valid candidate.

Fixes #116692

---------

Signed-off-by: Nathan Gauër <brioche@google.com>
2024-11-28 13:42:57 +01:00
Vyacheslav Levytskyy
86b69c3164
[SPIR-V] Fix SPIR-V extension SPV_INTEL_function_pointers: introduce CodeSectionINTEL (#117250)
This PR fixes generation of OpConstantFunctionPointerINTEL instruction
for the SPIR-V extension SPV_INTEL_function_pointers. Result type of
OpConstantFunctionPointerINTEL must be OpTypePointer with Storage Class
operand equal to CodeSectionINTEL.

See also https://github.com/llvm/llvm-project/pull/116636

CC: @MrSidims
2024-11-22 14:19:50 +01:00
Vyacheslav Levytskyy
8ac46d6b4f
[SPIR-V] Implement builtins for OpIAddCarry/OpISubBorrow and improve/fix type inference (#115192)
This PR is to solve several intertwined issues with type inference while
adding support for builtins for OpIAddCarry and OpISubBorrow:
* OpIAddCarry and OpISubBorrow generation in a way of supporting SPIR-V
friendly builtins `__spirv_...` -- introduces a new element to account
for, namely, `ptr sret (%struct) %0` argument that is a place to put a
result of the instruction;
* fix early definition of SPIR-V types during call lowering -- namely,
the goal of the PR is to ensure that correct types are applied to
virtual registers which were used as arguments in call lowering and so
caused early definition of SPIR-V types; reproducers are attached as a
new test cases;
* improve parsing of builtin names (e.g., understand a name of a kind
`"anon<int, int> __spirv_IAddCarry<int, int>(int, int)"` that was
incorrectly parsed as `anon` before the PR);
* improve type inference and fix access to erased from parent after
visit instructions -- before the PR visiting of instructions in
emitintrinsics pass replaced old alloca's, bitcast's, etc. instructions
with a newly generated internal SPIR-V intrinsics and after erasing old
instructions there were still references to them in a postprocessing
working list, while records for newly deduced pointee types were lost;
this PR fixes the issue by adding as consistent wrt. internal data
structures action `SPIRVEmitIntrinsics::replaceAllUsesWith()` that fixes
above mentioned problems;
* LLVM IR add/sub instructions result in logical SPIR-V instructions
when applied to bool type;
* fix validation of pointer types for frexp and lgamma_r,
* fix hardcoded reference to AS0 as a Function storage class in
lib/Target/SPIRV/SPIRVBuiltins.cpp -- now it's
`storageClassToAddressSpace(SPIRV::StorageClass::Function)`,
* re-use the same OpTypeStruct for two identical references to struct's
in arithmetic with overflow instructions.
2024-11-14 15:30:05 +01:00
Nathan Gauër
cba70550cc
[SPIR-V] Fix BB ordering & register lifetime (#111026)
The "topological" sorting was behaving incorrectly in some cases: 
the exit of a loop could have a lower rank than a node in the loop.
This causes issues when structurizing some patterns, and also codegen
issues as we could generate BBs in the incorrect order in regard to the
SPIR-V spec.

Fixing this ordering alone broke other parts of the structurizer, which
by luck worked. Had to fix those.

Added more test cases, especially to test basic patterns.

I also needed to tweak/disable some tests for 2 reasons:
 - SPIR-V now required reg2mem/mem2reg to run. Meaning dead stores
   are optimized away. Some tests require tweaks to avoid having the
   whole function removed.
 - Mem2Reg will generate variable & load/stores. This generates
   G_BITCAST in several cases. And there is currently something wrong
   we do with G_BITCAST which causes MIR verifier to complain.
   Until this is resolved, I disabled -verify-machineinstrs flag on
   those tests.

---------

Signed-off-by: Nathan Gauër <brioche@google.com>
2024-10-30 14:57:32 +01:00
Vyacheslav Levytskyy
8d8996dd1e
[SPIRV] Implement type deduction and reference to function declarations for indirect calls using SPV_INTEL_function_pointers (#111159)
This PR improves implementation of SPV_INTEL_function_pointers and type
inference for phi-nodes and indirect calls.
2024-10-15 18:42:51 +02:00
Vyacheslav Levytskyy
3e79c7fec0
[SPIR-V] Implement OpSpecConstantOp with ptr-cast operation (#109979)
This PR reworks implementation of OpSpecConstantOp with ptr-cast
operation (PtrCastToGeneric, GenericCastToPtr). Previous implementation
didn't take into account a lot of use cases, including multiple
inclusion of pointers, reference to a pointer from OpName, etc. A
reproducer is attached as a new test case.

This PR also fixes wrong type inference for IR patterns which generate
new virtual registers without SPIRV type. Previous implementation
assumed always that result has the same address space as a source that
is not the fact, and, for example, led to impossibility to emit a
ptr-cast operation in the reproducer, because wrong type inference
rendered source and destination with the same address space, eliminating
translation of G_ADDRSPACE_CAST.
2024-10-01 10:47:15 +02:00
Vyacheslav Levytskyy
a059b29930
[SPIR-V] Allow intrinsics with aggregate return type to reach GlobalISel (#108893)
Two main goals of this PR are:
* to support "Arithmetic with Overflow" intrinsics, including the
special case when those intrinsics are being generated by the
CodeGenPrepare pass during translations with optimization;
* to redirect intrinsics with aggregate return type to be lowered via
GlobalISel operations instead of SPIRV-specific unfolding/lowering (see
https://github.com/llvm/llvm-project/pull/95012).

There is a new test case
`llvm/test/CodeGen/SPIRV/passes/translate-aggregate-uaddo.ll` that
describes and checks the general logics of the translation.

This PR continues a series of PRs aimed to identify and fix flaws in
code emission, to improve pass rates for the mode with expensive checks
set on (see https://github.com/llvm/llvm-project/pull/101732,
https://github.com/llvm/llvm-project/pull/104104,
https://github.com/llvm/llvm-project/pull/106966), having in mind the
ultimate goal of proceeding towards the non-experimental status of
SPIR-V Backend.

The reproducers are:

1) consider `llc -O3 -mtriple=spirv64-unknown-unknown ...` with:

```
define spir_func i32 @foo(i32 %a, ptr addrspace(4) %p) {
entry:
  br label %l1

l1:
  %e = phi i32 [ %a, %entry ], [ %i, %body ]
  %i = add nsw i32 %e, 1
  %fl = icmp eq i32 %i, 0
  br i1 %fl, label %exit, label %body

body:
  store i8 42, ptr addrspace(4) %p
  br label %l1

exit:
  ret i32 %i
}
```

2) consider `llc -O0 -mtriple=spirv64-unknown-unknown ...` with:

```
define spir_func i32 @foo(i32 %a, ptr addrspace(4) %p) {
entry:
  br label %l1

l1:                                               ; preds = %body, %entry
  %e = phi i32 [ %a, %entry ], [ %math, %body ]
  %0 = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %e, i32 1)
  %math = extractvalue { i32, i1 } %0, 0
  %ov = extractvalue { i32, i1 } %0, 1
  br i1 %ov, label %exit, label %body

body:                                             ; preds = %l1
  store i8 42, ptr addrspace(4) %p, align 1
  br label %l1

exit:                                             ; preds = %l1
  ret i32 %math
}
```
2024-09-26 10:57:02 +02:00
bwlodarcz
4ffb747aa4
[SPIR-V][NFC] More efficient getPaddedLen (#105823)
Quick fix with small performance improvement for getPaddedLen function.
2024-09-25 18:07:55 -07:00
Vyacheslav Levytskyy
bbb3679ad8
[SPIRV] Fix compilation error 'use of parameter from containing function' when building PR #106429 with gcc (#109924)
It appears that PR https://github.com/llvm/llvm-project/pull/106429
introduced an issue for builds with SPIRV Backend target when building
with gcc, e.g.:
```
/llvm-project/llvm/lib/Target/SPIRV/SPIRVUtils.cpp:263:36: error: use of parameter from containing function
  263 |     llvm::SyncScope::ID SubGroup = Ctx.getOrInsertSyncScopeID("subgroup");
      |                                    ^~~
/llvm-project/llvm/lib/Target/SPIRV/SPIRVUtils.cpp:256:46: note: ‘llvm::LLVMContext& Ctx’ declared here
  256 | SPIRV::Scope::Scope getMemScope(LLVMContext &Ctx, SyncScope::ID Id) {
```
This PR fixes this by removing struct and using static const variables
instead.
2024-09-25 11:06:17 +02:00
Alex Voicu
3cfd0c0d36
[SPIRV][RFC] Rework / extend support for memory scopes (#106429)
This change adds support for correctly lowering the `__scoped` Clang
builtins, and corresponding scoped LLVM instructions. These were
previously unconditionally lowered to Device scope, which is possibly incorrect. 
Furthermore, the default / implicit scope is changed from Device (an 
OpenCL assumption) to AllSvmDevices (aka System), since the SPIR-V BE is not 
OpenCL specific / can ingest IR coming from other language front-ends. OpenCL 
defaulting to Device scope is now reflected in the front-end handling of atomic 
ops, which seems preferable.
2024-09-25 00:44:57 +01:00
Nathan Gauër
1ed65febd9
[SPIR-V] Add SPIR-V structurizer (#107408)
This commit adds an initial SPIR-V structurizer.
It leverages the previously merged passes, and the convergence region
analysis to determine the correct merge and continue blocks for SPIR-V.

The first part does a branch cleanup (simplifying switches, and
legalizing them), then merge instructions are added to cycles,
convergent and later divergent blocks.
Then comes the important part: splitting critical edges, and making sure
the divergent construct boundaries don't cross.

- we split blocks with multiple headers into 2 blocks.
- we split blocks that are a merge blocks for 2 or more constructs:
SPIR-V spec disallow a merge block to be shared by 2
loop/switch/condition construct.
- we split merge & continue blocks: SPIR-V spec disallow a basic block
to be both a continue block, and a merge block.
- we remove superfluous headers: when a header doesn't bring more info
than the parent on the divergence state, it must be removed.

This PR leverages the merged SPIR-V simulator for testing, as long as
spirv-val. For now, most DXC structurization tests are passing. The
unsupported ones are either caused by unsupported features like switches
on boolean types, or switches in region exits, because the MergeExit
pass doesn't support those yet (there is a FIXME).

This PR is quite large, and the addition not trivial, so I tried to keep
it simple. E.G: as soon as the CFG changes, I recompute the dominator
trees and other structures instead of updating them.

---------

Signed-off-by: Nathan Gauër <brioche@google.com>
2024-09-20 11:36:43 +02:00
Vyacheslav Levytskyy
f6aa508734
[SPIR-V]: Fix creation of constants of array types in SPIRV Backend (#96514)
This PR fixes https://github.com/llvm/llvm-project/issues/96513.

The way of creation of array type constant was incorrect: instead of
creating [1, 1, 1] or [1, 1, 1, 1, 1, ....] constants, the same [1]
constant was always created, substituting original composite constants.
This in its turn led to a situation when only one of constants might
exist in the code without emitting invalid code, the second constant
would be eventually rewritten to the first constant, because a key to
address both was an array of a single element (like [1]).

This PR fixes the issue and purges from the code unneeded copy/pasted
clone of the function that creates an array constant.
2024-06-25 10:56:56 +02:00
Vyacheslav Levytskyy
9a737109a0
[SPIR-V] Improve type inference, addrspacecast and dependencies between 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 21:12:33 +02:00
Vyacheslav Levytskyy
be9b4dab40
[SPIR-V] Introduce support for 'spirv.Decorations' metadata node in SPIR-V 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 11:35:11 +02:00
Vyacheslav Levytskyy
eb989f625e
[SPIR-V] Fix return type when sampling an image with 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-18 19:38:04 +02:00
Vyacheslav Levytskyy
f768083516
[SPIR-V] Update type inference and instruction selection (#88254)
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-15 09:59:47 +02:00
Vyacheslav Levytskyy
335d5d5f47
[SPIRV] Tweak parsing of base type name in builtins (#88255)
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.
2024-04-10 19:04:31 +02:00
Nathan Gauër
f0eb908340
[SPIR-V] Add WaveGetLaneIndex() intrinsic support (#85979)
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 11:30:47 +01:00
Michal Paszkowski
43222bd309
[SPIR-V] Do not use OpenCL metadata for ptr element type resolution (#82678)
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-03-03 22:38:59 -08:00
Vyacheslav Levytskyy
4a602d9250
Add support for the SPV_INTEL_usm_storage_classes extension (#82247)
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 11:05:19 +01:00
Vyacheslav Levytskyy
8e8f9c0bc0
fix generation of unnecessary OpExecutionMode records (#81839)
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-19 20:51:32 +01:00
Vyacheslav Levytskyy
925768eeab
Add support for atomic instruction on floating-point numbers (#81683)
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-19 12:12:09 +01:00
Nathan Gauër
a9ffc92fc4
[SPIR-V] Add pre-headers to loops. (#75844)
This is the first of the 7 steps outlined in #75801. This PR explicitely
calls the SimplifyLoops pass. Directly following this pass should follow
the 6 others required to structurize the IR.

Running this pass could generate empty basic-blocks, which are implicit
fallthrough to the successor BB.
There was a specific condition in the SPIR-V ISel which handled implicit
fallthrough, but it couldn't work on empty basic-blocks. This commits
removes the old logic, and adds this new logic, which checks all
basic-blocks for implicit fallthroughs, including empty ones.

---------

Signed-off-by: Nathan Gauër <brioche@google.com>
2024-01-08 11:41:45 +01:00
Kazu Hirata
395f9ce30e Use StringRef::{starts,ends}_with (NFC)
This patch replaces uses of StringRef::{starts,ends}with with
StringRef::{starts,ends}_with for consistency with
std::{string,string_view}::{starts,ends}_with in C++20.

I'm planning to deprecate and eventually remove
StringRef::{starts,ends}with.
2023-12-16 10:14:44 -08:00
Natalie Chouinard
d40eb0a575
[SPIR-V] Remove deleted functions (#74660)
Remove references to functions that were deleted in #74521 which are
causing SPIR-V backend build failures.
2023-12-07 09:37:31 -05:00
Michal Paszkowski
817519058a
[SPIR-V] Emit proper pointer type for OpenCL kernel arguments (#67726) 2023-10-18 20:51:53 -07:00
Sameer Sahasrabuddhe
d9847cde48 [GlobalISel] convergent intrinsics
Introduced the convergent equivalent of the existing G_INTRINSIC opcodes:

- G_INTRINSIC_CONVERGENT
- G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS

Out of the targets that currently have some support for GlobalISel, the patch
assumes that the convergent intrinsics only relevant to SPIRV and AMDGPU.

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D154766
2023-07-31 12:15:39 +05:30