This change is responsible for avoiding the replacement of constant
operands with another one not constant, in the context of atomic
operations. The related rule from the SPIR-V spec is: "All used for
Scope and Memory Semantics in shader capability must be of an
OpConstant."
Fixes#4346.
This change allows the reducer to merge together blocks even when they
are unreachable, but keeps the restriction of reachability in place
for the optimizer.
Fixes#4302.
There was a lot of code in the codebase that would get the dominator
analysis for a function and then use it to check whether a block is
reachable. In the fuzzer, a utility method had been introduced to make
this more concise, but it was not being used consistently.
This change moves the utility method to IRContext, so that it can be
used throughout the codebase, and refactors all existing checks for
block reachability to use the utility method.
Fixes#4170, by checking the signedness of bitwise operands in
TransformationAddBitInstructionSynonym, to avoid an "Expected Base
Type to be equal to Result Type" validation error.
This change prevents TransformationOutlineFunction from outlining a
region of blocks if some block in the region has an unreachable
predecessor. This avoids a bug whereby the region would be outlined,
and the unreachable predecessors would be left behind, referring to
blocks that are no longer in the function.
The def-use manager was being incorrectly updated in
TransformationPermutePhiOperands, and this was causing future
transformations to go wrong during fuzzing. This change updates the
def-use manager in a correct manner, and adds a test exposing the
previous bug.
Fixes#4300.
Sometimes, you need to change these functions during debugging (e.g.,
figure out why the transformation is inapplicable). When that happens,
you need to recompile the whole fuzzer just because these functions
are in the header file. This PR fixes the situation.
There are some edge cases where adding livesafe functions does not
succeed, due to loop limiter edges breaking SPIR-V dominance rules. As
these edge cases are rare it does not seem worth implementing complex
additional logic to handle all cases. This change accepts that trying
to add a function in a livesafe manner may not succeed.
FuzzerPassConstructComposites is adapted to use AvailableInstructions
to manage available instructions, and to use zero constants when
trying to construct a composite for which not all fields can otherwise
be constructed. The change uncovered some cases where we create
structs and arrays with struct fields or components that are
block-decorated; these possibilities have been eliminated.
It is easy to avoid the need to invalidate the def-use analysis and
instruction to block mapping when splitting blocks, and profiling has
revealed that invalidation of def-use in particular is expensive when
splitting many blocks. This change avoids these invalidations.
Profiling has shown that adding large numbers of dead block
transformations can be expensive because each on requires dominator
analysis information, and each one invalidates this information. There
is currently no obvious mechanism for incrementally updating the
dominator analysis. This change restricts the number of these
transformations that a single fuzzer pass will apply, to restrict this
performance bottleneck.
Types should only be added to the module by spirv-fuzz via
transformations, so this change removes the AddType methods from
fuzzerutil, which were only called once each from the appropriate
transformation.
The transformations have been adapted so that they avoid redundantly
invalidating all analyses - they now update the def-use manager and
invalidate only the type manager.
Avoids redundantly searching the whome module when locating an
instruction from its descriptor - instead, only the block containing
the instruction needs to be searched.
The performance of spirv-fuzz is sometimes poor due to analyses being
conservatively invalidated. This can lead to quadratic time algorithms
when a fuzzer pass applies O(N) transformations, and where every
transformation e.g. depends on def-use analysis and invalidates
def-use analysis (because building def-use analysis is O(N)).
This change avoids invalidating analyses for certain transformations.
The fuzzer library depended on CLIMessageConsumer, due to its explicit
use in a function. This change removes that dependency so that,
instead, a message consumer parameter is passed.
Avoid generating OpPhi on void types, and allow the transformation to
take place on regions that produce pointer and sampled image result
ids if such ids are not used after the region.
Fixes#3787.
Adds some functions that allow a fuzzer pass to check whether it is
spiralling out of control and exit early. The fuzzer pass for adding
bit instruction synonyms now uses this. Also make many methods in
FuzzerContext const.
This PR fixes a bug related to the transformation applicability.
When the OpNot case was implemented, its opcode was not
added to the list of supported bit instructions in IsApplicable.
So, the changes made are the following.
- Add OpNot to the list of supported bit instructions.
- Update the tests.
If enabled the following targets will be created:
* `${SPIRV_TOOLS}-static` - `STATIC` library. Has full public symbol visibility.
* `${SPIRV_TOOLS}-shared` - `SHARED` library. Has default-hidden symbol visibility.
* `${SPIRV_TOOLS}` - will alias to one of above, based on BUILD_SHARED_LIBS.
If disabled the following targets will be created:
* `${SPIRV_TOOLS}` - either `STATIC` or `SHARED` based on the new `SPIRV_TOOLS_LIBRARY_TYPE` flag. Has full public symbol visibility.
* `${SPIRV_TOOLS}-shared` - `SHARED` library. Has default-hidden symbol visibility.
Defaults to `ON`, matching existing build behavior.
This flag can be used by package maintainers to ensure that all libraries are built as shared objects.
The following implementations are introduced:
- Transformation and fuzzer pass for expanding vector reduction.
- Unit tests to cover the instructions with different vector sizes.
Fixes#3768.