Commit Graph

773 Commits

Author SHA1 Message Date
Laura Hermanns
bd83b772c3
Fix operand index out of bounds when folding OpCompositeExtract. (#5107)
GetExtractOperandsForElementOfCompositeConstruct() states "Returns the
empty vector if |result_index| is out-of-bounds", but violates that
contract for non-vector result types.
2023-03-03 15:52:49 +00:00
alan-baker
5d2bc6f064
Fix removal of dependent non-semantic instructions (#5122)
Fixes #5121

* If the non-semantic info instructions depended on other moved
  instructions the def/use manager would get corrupted.
2023-02-24 01:10:35 +00:00
Laura Hermanns
cac9a5a3ee
Fix null pointer in FoldInsertWithConstants. (#5093)
* Fix null pointer in FoldInsertWithConstants.

Struct types are not supported in constant folding yet.

* Added 'Test case 16' to fold_test.

Tests OpCompositeInsert not to be folded on a struct type.
2023-02-03 15:03:15 +00:00
Jeremy Gebben
5890763734
instrument: Clean up generation code (#5090)
-Make more use of InstructionBuilder instruction helper methods
-Use MakeUnique<>() rather than new
-Add InstrumentPass::GenReadFunctionCall() which optimizes function
calls in a loop with constant arguments and no side effects.

This is a prepatory change for future work on the instrumentation
code which will add more generated functions.
2023-02-03 00:39:09 +00:00
Daniel Story
0994ca45b6
Add C interface for Optimizer (#5030) 2023-02-01 13:58:52 +00:00
Jeremy Gebben
ba4c9fe534
Instrument: Fix bindless checking for BufferDeviceAddress (#5049)
Avoid using OpConstantNull with types that do not allow it.

Update existing tests for slight changes in code generation.

Add new tests based on the Vulkan Validation layer test case
that exposed this problem.
2023-01-16 20:57:37 +00:00
Rafael Marinheiro
c5d2316430
Enforce layering_check in Bazel build rules. (#5032)
* Enforce layering_check in Bazel build rules.

Enforcing layering_check ensures that the Build targets do not rely on
transitive dependencies. See
https://github.com/bazelbuild/bazel/pull/11440 for a detailed
description of the feature.

We also do a style pass on the build files, ensuring that common linters
are happy with it.

* Add .bazelversion file and fix build_defs.bzl.

We fix build_defs.bzl to work on Bazel 5.0.0.
2022-12-20 10:54:46 -05:00
Greg Fischer
f64a4b64b7
[spirv-opt] Clone names for new struct in EliminateIODeadComponents (#5016) 2022-12-19 10:20:44 -07:00
alan-baker
235182cfee
Fix use of invalid analysis (#5013)
Fixes https://crbug.com/1395415

* Block merging needed to invalid structured cfg analysis
2022-12-12 10:49:59 -05:00
Spencer Fricke
7b8f00f00a
spirv-opt: Fix OpCompositeInsert with Null Constant (#5008)
* spirv-opt: Unify GetConstId function names

* spirv-opt: Fix OpCompositeInsert with Null Constant

* spirv-opt: Improve GetNullCompositeConstant description
2022-12-06 09:00:10 -05:00
Greg Fischer
00018e58af
Change EliminateDeadInputComponentsPass to EliminateDeadIOComponentsPass (#4997)
To reflect processing of both Input and Output variables.

Also renamed files as needed.
2022-11-25 16:48:13 -07:00
alelenv
f33d152400
Add validation support for SPV_NV_shader_invocation_reorder. (#4979)
Co-authored-by: Pankaj Mistry <pmistry@nvidia.com>
2022-11-24 09:50:45 -05:00
Spencer Fricke
597631b693
spirv-opt: Handle null CompositeInsert (#4998)
Fixes #4996
2022-11-24 08:38:12 -05:00
Greg Fischer
81ec2aaa0e
Add option to ADCE to remove output variables from interface. (#4994)
This can cause interface incompatibility and should only be done
if ADCE has been applied to the following shader in the pipeline.
For this reason this capability is not available through the CLI
but rather only non-default through the API. This functionality is
intended as part of a larger cross-shader dead code elimination
sequence.
2022-11-23 10:48:58 -07:00
Greg Fischer
46ca66e699
Add support for tesc, tese and geom to EliminateDead*Components (#4990) 2022-11-18 15:08:18 -07:00
Greg Fischer
8ea3ae6be2
Split EliminateDeadInputComponents into safe and unsafe versions. (#4984)
Safe version will only optimize vertex shaders. All other shaders will
succeed without change.

Change --eliminate-dead-input-components to use new safe version.

Unsafe version (allowing non-vertex shaders) currently only available
through API. Should only be used in combination with other optimizations
to keep interfaces consistent. See optimizer.hpp for more details.
2022-11-14 11:44:26 -07:00
Jeremy Gebben
68e8327f29
Instrument: Change output buffer offset definitions (#4961)
Add a flags field at the first offset within this buffer.
Define flags to allow buffer OOB checking to be enabled or
disabled at run time. This is to support VK_EXT_pipeline_robustnes.
2022-11-10 12:35:18 -05:00
Greg Fischer
525bc38062
Add pass to eliminate dead output components (#4982)
This pass eliminates components of output variables that are not stored
to. Currently this just eliminates trailing components of arrays and
structs, all of which are dead.

WARNING: This pass is not designed to be a standalone pass as it can
cause interface incompatibiliies with the following shader in the
pipeline. See the comment in optimizer.hpp for best usage. This pass is
currently available only through the API; it is not available in the CLI.

This commit also fixes a bug in CreateDecoration() which is part of the
system of generating SPIR-V from the Type manager.
2022-11-08 10:45:32 -07:00
Spencer Fricke
54d4e77fa5
spirv-opt: Add const folding for CompositeInsert (#4943)
* spirv-opt: Add const folding pass for CompositeInsert

* spirv-opt: Fix anas stack-use-after-scope
2022-11-08 10:50:42 -05:00
alan-baker
d35a78db57
Switch SPIRV-Tools to use spirv.hpp11 internally (#4981)
Fixes #4960

* Switches to using enum classes with an underlying type to avoid
  undefined behaviour
2022-11-04 17:27:10 -04:00
Greg Fischer
c8e1588cfa
Add passes to eliminate dead output stores (#4970)
This adds two passes to accomplish this: one pass to analyze a shader
to determine the input slots that are live. The second pass is run on
the preceding shader to eliminate any stores to output slots that are
not consumed by the following shader.

These passes support vert, tesc, tese, geom, and frag shaders.

These passes are currently only available through the API.

These passes together with dead code elimination, and elimination of
dead input and output components and variables (WIP), will allow users
to do dead code elimination across shader boundaries.
2022-11-02 11:23:25 -06:00
alan-baker
a52de681dd
Prevent eliminating case constructs in block merging (#4976)
Fixes #4918

* Prevent block merging from producing an invalid case construct by
  merging a switch target/default with another construct's merge or
  continue block
* This is to satisfy the structural dominance requirement between the
  switch header and the case constructs
2022-10-28 14:13:20 -04:00
Spencer Fricke
0ebf830572
spirv-val: Add OpPtrAccessChain Base checks (#4965) 2022-10-24 12:45:08 -04:00
gmitrano-unity
1cecf91701
Support Narrow Types in BitCast Folding Rule (#4941)
* Support Narrow Types in BitCast Folding Rule

This change adds support for narrow types in the BitCastScalarOrVector
folding rule. According to Section 2.2.1 of the SPIR-V spec, types that
are narrower than 32 bits are automatically either sign extended, or
zero extended depending on the type. With that guaranteed, we should
be able to use the first 32-bit word of any narrow type for the folding
logic without performing any special conversions.

In order to reduce code duplication, this change moves the
GetU32BitValue and GetU64BitValue functions from IntConstant to
ScalarConstant. Without this move, we would have needed an identical
version of GetU32BitValue on FloatConstant.

* Add Tests for 16-bit BitCast Folding

This change adds several new test cases to the
IntegerInstructionFoldingTest which trigger the 16-bit BitCast logic.
The logic for half types was also added to the integer case since we
can't easily validate half float types in C++ code. It's easier to
validate them as unsigned integers instead. Pllus this also allows us
to verify the SPIR-V constant sign extension logic too.

* Add 8-Bit Folding Test Cases

This change adds a couple more test cases to the integer instruction
folding test suite in order to ensure that the BitCast logic also
works correctly with the Int8 shader capability.
2022-10-06 10:35:18 -04:00
Greg Fischer
265b455c99
Fix CreatDebugInlinedAt to not invoke def_use_mgr (#4939) 2022-09-23 08:45:32 -04:00
Spencer Fricke
ddbee48f85
spirv-opt: Fix stacked CompositeExtract constant folds (#4932)
This was spotted in the Validation Layers where OpSpecConstantOp %x CompositeExtract %y 0 was being folded to a constant, but anything that was using it wasn't recognizing it as a constant, the simple fix was to add a const_mgr->MapInst(new_const_inst); so the next instruction knew it was a const
2022-09-23 08:45:11 -04:00
Greg Fischer
272e4b3d07
Fix missing and incorrect DebugValues (#4929)
Specificially, fixes DebugValues coming out of
eliminate-local-single-store and eliminate-local-multi-store AKA SSA
rewrite.
2022-09-13 14:41:07 +00:00
Jeremy Hayes
fb27bbf307
Fix DebugInlinedAt Line operand (#4928)
Line instructions may be OpLine or DebugLine. This commit adds support
for DebugLine.
2022-09-09 13:56:35 -04:00
jeremyg-lunarg
33113abf45
Instrument: Add OpNames to generated functions and variables (#4873)
Add name annotations to the generated instrumentation code to
make it easier to understand. Example spirv-cross output:

    vec4 _140;
    if (0u < inst_bindless_direct_read_4(0u, 0u, 1u, uint(_19)))
    {
        _140 = texture(textures[nonuniformEXT(_19)], inUV);
    }
    else
    {
        inst_bindless_stream_write_4(50u, 1u, uint(_19), 0u);
        _140 = vec4(0.0);
    }
2022-09-01 18:32:00 +00:00
Steven Perron
d51dc53d2c
Improve algorithm to reorder blocks in a function (#4911)
* Improve algorithm to reorder blocks in a function

In dead branch elimination, blocks can end up in a the wrong order, so
there is code to reorder the blocks in structured order.  The problem is
that the algorithm to do that is very poor.  It involves many searchs in
the function for the correct position to place the block, as well as
moving many block in the vector.

The solution is to write a specialized function in the function class
that will reorder the blocks in structured order.  After computing the
structured order, reordering the block can be done in linear time, with
very little overhead.
2022-08-31 11:06:15 -04:00
jeremyg-lunarg
a98f05d02f
tests: Make InstrumentPass tests use SinglePassRunAndMatch<> and stateful pattern matching (#4897)
Using SinglePassRunAndMatch<> instead of SinglePassRunAndCheck<>
makes tests more concise and makes it possible to use pattern
matching features.

Using Effcee stateful pattern matching to make it less repetitive
to check for generated functions and global variables.

This approach isn't worth
it for DebugPrintf functions because the generated code will change
depending on how many parameters are passed to every debugPrintfEXT()
call.
2022-08-23 12:28:00 -06:00
Greg Fischer
71b2aee6c8
Add structs to eliminate dead input components (#4894)
Will eliminate all trailing members of input struct that are not
referenced.
2022-08-16 11:31:04 -04:00
Nathan Gauër
1728c1d40a
spirv-opt: fix copy-propagate-arrays index opti on structs. (#4891)
* spirv-opt: fix copy-propagate-arrays index opti on structs.

As per SPIR-V spec:
OpAccessChain indices must be OpConstant when indexing into a structure.

This optimization tried to remove load cascade. But in some scenario
failed:

```c
cbuffer MyStruct {
    uint my_field;
};

uint main(uint index) {
    const uint my_array[1] = { my_field };
    return my_array[index]
}
```

This is valid as the struct is indexed with a constant index, and then
the array is indexed using a dynamic index.
The optimization would consider the local array to be useless and
generated a load directly into the struct.

* spirv-opt: prevent creation of unused instructions

Copy-propagate-arrays optimization pass would create unused constants,
even if the optimization not completed.
This was caused by the way we handled OpAccessChain squashing: we
only referenced constants, and had to create them upfront.

Fixes #4887
Signed-off-by: Nathan Gauër <brioche@google.com>
2022-08-16 16:05:47 +02:00
Greg Fischer
9abacb34a5
Fix ADCE to not eliminate top level DebugInfo instructions (#4889)
Specifically, DebugSourceContinued, DebugCompilationUnit, and
DebugEntryPoint. These instructions are top-level instructions
which do not or may not have a user except for the tool and so
should not be eliminated.
2022-08-15 15:23:23 -06:00
Cassandra Beckley
3a8a961cff
Fix array copy propagation (#4890)
Array copy propagation was interpreting OpEntryPoint as a store
2022-08-11 09:59:37 -07:00
Steven Perron
0a43a84e02
Fix shuffle feeding shuffle with undef literal (#4883)
When folding a vector shuffle with an undef literal, it is possible that the
literal is adjusted so that it will then be interpreted as an index into
the input operands.  This is fixed by special casing that case, and not
adjusting those operands.

Fixes #4859
2022-08-10 09:04:35 -04:00
Steven Perron
ed3b9c83b1
Local access chain convert: check for negative indexes (#4884)
An access chain instruction interpretes its index operands as signed.
The composite insert and extract instruction interpret their index
operands as unsigned, so it is not possible to represent a negative
number.

This commit adds a check to the local-access-chain-convert pass to check
for a negative number in the access chain and to not do the conversion.

Fixes #4856
2022-08-09 17:33:04 +00:00
alan-baker
4773879b68
Update structure layout validation (#4876)
* Uniform block layout rules for matrices should use extended layouts by
  default
2022-07-29 10:16:54 -04:00
Greg Fischer
faa8d6a653
Revert "Optimize DefUseManager allocations (#4709)" (#4846)
This reverts commit d18d0d92e5.

This is reverted because it causes a 7X slowdown when legalizing
SPIR-V with NonSemantic.Shader.DebugInfo.100 instructions.
This is due to the creation of very large UseLists for several
heavily used operands for this extension combined with the fact
that the original commit changed the performance of Uselists to O(n).
2022-07-12 13:14:47 -06:00
Steven Perron
92fe420c8a
Reduce load size does not work for array with spec const size (#4845)
Arrays do not have to have a size that is known at compile time.  It
could be a spec constant.  In these cases, treat the array
as if it is arbitrarily long.  This commit will treat it like it is an
array of size UINT32_MAX.

Fixes https://crbug.com/oss-fuzz/47397.
2022-07-05 16:16:50 -04:00
Steven Perron
d5a3bfcf2f
Avoid undefined behaviour when getting debug opcode (#4842)
If the `instruction` operand in an extended instruction instruction is
too large, it causes undefined behaviour when that value is cast to the
enum for the corresponding set.  This is done with the
NonSemanticDebug100 instruction set.  We need to avoid the undefined
behaviour.

Fixes #4727
2022-07-05 14:14:29 -04:00
Steven Perron
32622ba7c6
DCE: clean up the cfg for all functions that were processed. (#4840)
Which functions are processed is determined by which ones are on the
call tree from the entry points before dead code is removed.  So it is
possible that a function is process because it is called from an entry
point, but the CFG is not cleaned up because the call to the function
was removed.

The fix is to process and cleanup every function in the module.  Since
all of the dead functions would have already been removed in an earlier
step of DCE, it should not make a different in compile time.

Fixes #4731
2022-07-05 12:23:32 -04:00
alan-baker
286e9c1187
Use structural dominance to validate cfg (#4832)
* Structural dominance introduced in SPIR-V 1.6 rev2
* Changes the structured cfg validation to use structural dominance
  * structural dominance is based on a cfg where merge and continue
    declarations are counted as graph edges
* Basic blocks now track structural predecessors and structural
  successors
* Add validation for entry into a loop
* Fixed an issue with inlining a single block loop
  * The continue target needs to be moved to the latch block
* Simplify the calculation of structured exits
  * no longer requires block depth
* Update many invalid tests
2022-06-29 23:32:20 -04:00
Steven Perron
66d88508dd
Build struct order only for the section needed when unrolling. (#4830)
We currently build the structured order for all nodes reachable from the
loop header when unrolling a loop.  However, unrolling only needs the
nodes in the loop and possibly the merge node.

To avoid needless computation, I have implemented a search that will
stop at the merge node.

Fixes #4827
2022-06-29 09:53:26 -04:00
Steven Perron
37d2396cab
Fix SplitLoopHeader to handle single block loop (#4829)
The code in `CFG::SplitLoopHeader` assumes the loop header is not the
latch.  This leads to it not being able to find the latch block.  This
has been fixed, and a test added.

Fixes #4527
2022-06-24 12:33:45 -04:00
Steven Perron
3c9fd7577f
Avoid if-conversion if both predecessors are the same (#4826)
If the predecessor blocks are the same, then there is only 1 value for the
OpPhi.  The simplition pass will simplify it, and it causes problems for
if-conversion.  In these cases, if-conversion can just punt.

Fixes #3554.
2022-06-24 15:28:06 +00:00
David Neto
2eff41e707
Remove stray output to stdout from tests (#4816) 2022-06-20 10:57:44 -04:00
manas-kulkarni
fbcb6cf4c8
Ability to fold Constant Vector times Matrix and Matrix times vector instructions (#4818) 2022-06-16 13:54:12 -04:00
Steven Perron
76ebfb989f
Avoid replacing access chain with OOB access (#4819)
An access chain could have a constant index that is an out of bounds
access.  This is valid spir-v, even if it can cause problems at runtime.
However, it is not valid to have an OpCompositeExtract with an out of
bounds access.  This means we have to stop local-access-chain-convert
from making that change.

Fixes #4605
2022-06-14 13:06:38 -04:00
David Neto
8f7f5024f8
Simplify invocation of snprintf (#4815) 2022-06-10 17:55:45 -04:00