22 Commits

Author SHA1 Message Date
Vyacheslav Levytskyy
ebdadcfeb9
[SPIR-V] Improve correctness of emitted MIR between passes for branching 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-09-03 19:02:03 +02:00
Vyacheslav Levytskyy
67d3ef74b3
[SPIR-V] Rework usage of virtual registers' types and classes (#104104)
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-22 09:40:27 +02:00
Vyacheslav Levytskyy
f9c98068c8
[SPIR-V] Rework usage of virtual registers' types and classes (#101732)
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-08-12 15:49:43 +02:00
Vyacheslav Levytskyy
281f59fdf9
[SPIR-V] Emit valid Lifestart/Lifestop instructions (#98475)
This PR fixes emission of valid OpLifestart/OpLifestop instructions.
According to
https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpLifetimeStart:
"Size must be 0 if Pointer is a pointer to a non-void type or the
Addresses
[capability](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Capability)
is not declared.". The `Size` argument is set the corresponding
intrinsics arguments, so Size is not zero we must ensure that Pointer
has the required type by inserting a bitcast if needed.
2024-08-12 15:49:17 +02:00
Matt Arsenault
0f0cfcff2c
CodeGen: Avoid some references to MachineFunction's getMMI (#99652)
MachineFunction's probably should not include a backreference to
the owning MachineModuleInfo. Most of these references were used
just to query the MCContext, which MachineFunction already directly
stores. Other contexts are using it to query the LLVMContext, which
can already be accessed through the IR function reference.
2024-07-19 22:09:05 +04:00
Vyacheslav Levytskyy
bf9e9e5e84
[SPIR-V] Improve type inference for a known instruction's builtin: 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-07-03 17:56:41 +02:00
Vyacheslav Levytskyy
57520985e0
[SPIR-V] Implement insertion of OpGenericCastToPtr using builtin functions (#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 21:23:48 +02:00
Vyacheslav Levytskyy
ce73e17e3a
[SPIR-V] Validate type of the last parameter of OpGroupWaitEvents (#93661)
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-06-03 10:34:05 +02:00
Vyacheslav Levytskyy
214e6b40f8
[SPIR-V] Inline assembly support (#93164)
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-24 15:15:03 +02:00
Vyacheslav Levytskyy
1ed1ec9a99
[SPIRV] Improve builtins matching and type inference in SPIR-V Backend, 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-26 12:17:47 +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
23b058cb7f
[SPIR-V] Re-implement switch and improve validation of forward calls (#87823)
This PR fixes issue https://github.com/llvm/llvm-project/issues/87763
and preserves valid CFG in cases when previous scheme failed to generate
valid code for a switch statement. The PR hardens one existing test case
and adds one more test case as a validation of a new switch generation.
Tests are passing spirv-val now.

This PR also improves validation of forward calls.
2024-04-09 16:15:44 +02:00
Vyacheslav Levytskyy
47e996d89d
[SPIR-V] Fix OpVariable instructions place in a function (#87554)
This PR:
* fixes OpVariable instructions place in a function (see
https://github.com/llvm/llvm-project/issues/66261),
* improves type inference,
* helps avoiding unneeded bitcasts when validating function call's

This allows to improve existing and add new test cases with more strict
checks. OpVariable fix refers to "All OpVariable instructions in a
function must be the first instructions in the first block" requirement
from SPIR-V spec.
2024-04-04 10:50:35 +02:00
Vyacheslav Levytskyy
6cce67a8f9
[SPIR-V] Fix validity of atomic instructions (#87051)
This PR fixes validity of atomic instructions and improves type
inference. More tests are able now to be accepted by `spirv-val`.
2024-04-02 10:59:18 +02:00
Vyacheslav Levytskyy
b7ac8fddb5
[SPIR-V] Improve type inference: deduce types of composite data structures (#86782)
This PR improves type inference in general and deduces types of
composite data structures in particular. Also added a way to insert a
bitcast to make a fun call valid in case of arguments types mismatch due
to opaque pointers type inference.

The attached test `pointers/nested-struct-opaque-pointers.ll`
demonstrates new capabilities: the SPIRV code emitted for this test is
now (1) valid in a sense of data field types and (2) accepted by
`spirv-val`.

More strict LIT checks, support of more composite data structures and
improvement of fun calls from the perspective of type correctness are
main todo's at the moment.
2024-03-28 08:08:06 +01:00
Vyacheslav Levytskyy
949d70d5e0
[SPIR-V] Fix incorrect bitwise instructions applied to the bool type (#85929)
This PR ensures that LLVM IR bitwise instructions result in logical
SPIR-V instructions when applied to i1 type.
2024-03-20 19:23:12 +01:00
Vyacheslav Levytskyy
afec257d36
[SPIRV] Add type inference of function parameters by call instances (#85077)
This PR adds type inference of function parameters by call instances.
Two use cases that demonstrate the problem are added.
2024-03-14 10:50:11 +01:00
Vyacheslav Levytskyy
fb1be9b33c
[SPIR-V] Insert a bitcast before load/store instruction to keep SPIR-V code valid (#84069)
This PR introduces a step after instruction selection where instructions
can be traversed from the perspective of their validity from the
specification point of view. The PR adds also a way to correct
load/store when there is a type mismatch contradicting the specification
-- an additional bitcast is inserted to keep types consistent.
Correspondent test cases are added and existing test cases are
corrected.

This PR helps to successfully validate with the `spirv-val` tool
(https://github.com/KhronosGroup/SPIRV-Tools) some output that
previously led to validation errors and crashes of back translation from
SPIRV to LLVM IR from the side of SPIRV Translator project
(https://github.com/KhronosGroup/SPIRV-LLVM-Translator).

The added step of bringing instructions to required by the specification
type correspondence can be (should be and will be) extended beyond
load/store instructions to ensure validity rules of other SPIRV
instructions related to type inference.
2024-03-08 08:31:56 +01:00
Craig Topper
6006d43e2d LLVM_FALLTHROUGH => [[fallthrough]]. NFC
Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D150996
2023-05-24 12:40:10 -07:00
Michal Paszkowski
dc4330a925 [SPIR-V] Promote arbitrary width ints to regular width
After this patch all arbitrary size integers (smaller than 64 bits) in
LLVM IR will be promoted to regular size type in SPIR-V (OpTypeInt
8/16/32/64).

Differential Revision: https://reviews.llvm.org/D145137
2023-03-13 22:44:47 +01:00
Ilia Diachkov
3544d200d9 [SPIRV] add IR regularization pass
The patch adds the regularization pass that prepare LLVM IR for
the IR translation. It also contains following changes:
- reduce indentation, make getNonParametrizedType, getSamplerType,
getPipeType, getImageType, getSampledImageType static in SPIRVBuiltins,
- rename mayBeOclOrSpirvBuiltin to getOclOrSpirvBuiltinDemangledName,
- move isOpenCLBuiltinType, isSPIRVBuiltinType, isSpecialType from
SPIRVGlobalRegistry.cpp to SPIRVUtils.cpp, renaming isSpecialType to
isSpecialOpaqueType,
- implment getTgtMemIntrinsic() in SPIRVISelLowering,
- add hasSideEffects = 0 in Pseudo (SPIRVInstrFormats.td),
- add legalization rule for G_MEMSET, correct G_BRCOND rule,
- add capability processing for OpBuildNDRange in SPIRVModuleAnalysis,
- don't correct types of registers holding constants and used in
G_ADDRSPACE_CAST (SPIRVPreLegalizer.cpp),
- lower memset/bswap intrinsics to functions in SPIRVPrepareFunctions,
- change TargetLoweringObjectFileELF to SPIRVTargetObjectFile
in SPIRVTargetMachine.cpp,
- correct comments.
5 LIT tests are added to show the improvement.

Differential Revision: https://reviews.llvm.org/D133253

Co-authored-by: Aleksandr Bezzubikov <zuban32s@gmail.com>
Co-authored-by: Michal Paszkowski <michal.paszkowski@outlook.com>
Co-authored-by: Andrey Tretyakov <andrey1.tretyakov@intel.com>
Co-authored-by: Konrad Trifunovic <konrad.trifunovic@intel.com>
2022-09-15 15:53:44 +03:00
Ilia Diachkov
ec2590362e [SPIR-V](4/6) Add target lowering, TargetMachine and AsmPrinter
The patch contains target lowering for SPIRV. Also it implements
TargetMachine and AsmPrinter.

Differential Revision: https://reviews.llvm.org/D116463

Authors: Aleksandr Bezzubikov, Lewis Crawford, Ilia Diachkov,
Michal Paszkowski, Andrey Tretyakov, Konrad Trifunovic

Co-authored-by: Aleksandr Bezzubikov <zuban32s@gmail.com>
Co-authored-by: Ilia Diachkov <iliya.diyachkov@intel.com>
Co-authored-by: Michal Paszkowski <michal.paszkowski@outlook.com>
Co-authored-by: Andrey Tretyakov <andrey1.tretyakov@intel.com>
Co-authored-by: Konrad Trifunovic <konrad.trifunovic@intel.com>
2022-04-20 01:10:25 +02:00