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.
This PR fixes illegal use of OpConstantComposite with non-constant
constituents. The test attached to the PR is able now to satisfy
`spirv-val` check. Before the fix SPIR-V Backend produced for the
attached test case a pattern like
```
%a = OpVariable %_ptr_CrossWorkgroup_uint CrossWorkgroup %uint_123
%11 = OpConstantComposite %_struct_6 %a %a
```
so that `spirv-val` complained with
```
error: line 25: OpConstantComposite Constituent <id> '10[%a]' is not a constant or undef.
%11 = OpConstantComposite %_struct_6 %a %a
```
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.
This PR fixes https://github.com/llvm/llvm-project/issues/79057 and
improves code generation for opaque pointers by replacing the culprit
SPIRVGlobalRegistry::getOpTypePointer() call with a more appropriate
SPIRVGlobalRegistry::getOrCreateSPIRVPointerType() call. The latter
function works together with the `DuplicatesTracker`
(`SPIRVGeneralDuplicatesTracker DT;` from `class SPIRVGlobalRegistry`)
to trace existence of previous definitions of opaque pointers. This
allows to produce just one `OpTypePointer` command for all identical
opaque pointers definitions and to return the very same type record for
subsequent `SPIRVGlobalRegistry::createSPIRVType()` invocations.
This PR alone improves code generation by producing a single needed
definition per all opaque pointers to i8 of the same address space
instead of multiple identical definitions produced before the patch.
From the root cause analysis of
https://github.com/llvm/llvm-project/issues/79057 we see also that this
PR resolves the problem of inconsistency between keeping multiple
instruction for identical opaque pointer types and just a single record
for all such instructions in the `DuplicatesTracker`, and so it also
resolves the issue with crashes on creation of a struct with opaque
pointer fields due to the fact that now such struct fields refer to the
same operand `<id>` having a required record in the data structure used
for dependencies analysis (see
https://github.com/llvm/llvm-project/issues/79057).