spirv-opt: Add --graphics-robust-access
Clamps access chain indices so they are always
in bounds.
Assumes:
- Logical addressing mode
- No runtime-array-descriptor-indexing
- No variable pointers
Adds stub code for clamping coordinate and samples
for OpImageTexelPointer.
Adds SinglePassRunAndFail optimizer test fixture.
Android.mk: add source/opt/graphics_robust_access_pass.cpp
Adds Constant::GetSignExtendedValue, Constant::GetZeroExtendedValue
This makes it symmetric with the result type of ...->element_type which
returns a const Type.
So now we can write code like this:
analysis::Vector v = ...
analysis::Vector(v->element_type(), 2);
This fixes#2608.
The original test case had an out-of-bounds reference that ended up
folding into OpCompositeExtract that was indexing right outside the
constant composite.
The returned constant would then cause a segfault during constant
propagation.
Fixes#2764
* Don't replace all uses when simplifying instructions, instead only
update non-debug, non-decoration uses
* added a test
* Add a new version of RAUW that takes a predicate to decide whether to
replace the use or not
* used in simplification pass
* Fix#2609 - Handle out-of-bounds scalar replacements.
When SROA tries to do a replacement for an OpAccessChain that is exactly
one element out of bounds, the code was trying to access its internal
array of replacements and segfaulting.
This protects the code from doing this, and it additionally fixes the
way SROA works by not returning failure when it refuses to do a
replacement. Instead of failing the optimization pass, SROA will now
simply refuse to do the replacement and keep going.
Additionally, this patch fixes the SROA logic to now return a proper status so we can
correctly state that the pass made no changes to the IR if it only found
invalid references.
The recently added fuzzer_replayer and fuzzer_shrinker tests were
rather heavyweight and were leading to CI timeouts. This change
reduces the runtime of those tests by having them do fewer iterations.
Merge return expects unreachable merge block to look a certain way, and
unreachable continue blocks to look a certain way. What if an
unreachable block is both a merge and a continue? The continue is
suppose to take precedent, but merge-return implements it with the merge
taking precedent. This change flips that around.
Fixes#2746
Similar to the existing 'add dead breaks' pass, this adds a pass to
add dead continues to blocks in loops where such a transformation is
viable. Various functionality common to this new pass and 'add dead
breaks' has been factored into 'fuzzer_util', and some small
improvements to 'add dead breaks' that were identified while reviewing
that code again have been applied.
Fixes#2719.
* Process OpDecorateId in ADCE
When there is an OpDecorateId instruction that is live,
the ids that is references must be kept live. This change
adds them to the worklist.
I've also updated a validator check to allow OpDecorateId
to be able to apply to decoration groups.
Fixes#1759.
* Remove dead code.
In merge return, we need to know the original dominator for a block in order to
traverse code from the original dominator to the new dominator and add
appropriate Phi nodes. The current code gets this wrong because the dominator
tree is build as needed. The first time we get the immediate dominator for a
function we just built the dominator tree and it takes into account that a
block has been split. The second time it does not.
This inconsistency needs to be fixed. We do that by recording the original
dominator for all blocks at the start of the pass.
If we were to record just the basic block, that could change if the block is
split. We want to traverse the code in the body of the original dominator,
whatever block it ends up in. To make this easy to track, we not save the
terminator instruction to represent the original dominator.
Fixes#2745
When a phi candidate is marked as trivial, we are suppose to update all
of its uses to the reference the value that it is being folded to.
However, the code updates the uses misses `defs_at_block_`. So at a
later time, the id for the trivial phi can reemerge.
Fixes#2744
* Bindless Instrument: Make init check depend solely on input_init_enabled
Previously was dependent on presense of descriptor_indexing extension
in SPIR-V, but this missed some cases. Tests updated to refect this new
policy.
* Fix format.
This change refactors all storage class validation for atomics
to reflect the similar refactoring in the specification.
It is currently not possible to write a test for the check
rejecting Generic in an OpenCL 1.2 environment as the required
GenericPointer capability isn't allowed there. I've decided
to keep the check nonetheless to guard against the capability
becoming available without the rules for atomics being updated.
The ID changes in existing tests aren't ideal but introducing
names drags in a substantial refactoring of this file.
Contributes to #2595.
Signed-off-by: Kevin Petit <kevin.petit@arm.com>
* Fix bug in merge return
The merge return pass seems to assume that the only new edges in the cfg
are from return block to merge blocks. However, it is possible that a
merge block branches to a merge block when it did not before.
This change add a new variable to track all of the new edges. It also
renames some other variables and cleans us the code to make it a bit
easier to read.
Fixes#2702.
This adds all the command-line tools from the CMakeLists.txt
file to the BUILD.gn used by Chromium and Fuchsia.
+ Add a convenient "all_spirv_tools" GN target to rebuild
all command-line tools at once.
+ "gn format" pass to fix a few minor issues in the file.
Tested on Chromium with the following procedure:
1) Have a clean Chromium checkout
2) # Update to upstream spirv-headers (otherwise spirv-tools build fails)
cd $CHROMIUM_SRC/third_party/spirv-headers/src &&
git remote add upstream https://github.com/KhronosGroup/SPIRV-Headers.git &&
git fetch upstream &&
git checkout upstream/master
3) # Update to upstream spirv-tools (Chromium is tracking older revision)
cd $CHROMIUM_SRC/third_party/SPIRV-Tools/src &&
git remote add upstream https://github.com/KhronosGroup/SPIRV-Tools.git &&
git fetch upstream &&
git checkout -tb check-patch upstream/master &&
git cherry-pick <patch>
3) # Rebuild Chromium and all SPIR-V tools for the host
cd $CHROMIUM_SRC/src &&
gn gen out/Linux --args 'use_goma = true' &&
ninja -C out/Linux -j1000 -l30 gn_all all_spirv_tools
4) Run the command-line tools, e.g.:
out/Linux/spirv-link --help
Dead branch elimination needs to know about the constructs that a block is contained it when determining what to do with its merge instruction. We currently fold branches in block as we see them, which is parent constructs before their children. This causes the struct cfg analysis to crash because it tries to get the parent construct for a block after the parent has been folded.
This can be fixed by folding the branch of the children before the parents.
Fixes#2667.
There are a couple spots where we are not looking at decorations when we should.
1. Value numbering is suppose to assign a different value number to ids if they have different decorations. However that is not being done for OpCopyObject and OpPhi.
1. Instruction simplification is propagating OpCopyObject instruction without checking for decorations. It should only do that if no decorations are being lost.
Add a new function to the decoration manager to check if the decorations of one id are a subset of the decorations of another.
Fixes#2715.
Fixes#2669
* Check capabilities when validating variables
* validate load and store types
* Constant check
* Don't checks pointers for stores, constants and loads
* Validate composite instructions
* Validate conversions for 8- and 16-bit limited types
* Unified tests and expanded them
* Disallow OpCopyMemory
* new tests and update old tests
Adds to spirv-fuzz the option to shrink a sequence of transformations
that lead to an interesting binary to be generated, to find a smaller
sub-sequence of transformations that still lead to an interesting (but
hopefully simpler) binary being generated. The notion of what counts
as "interesting" comes from a user-provided script, the
"interestingness function", similar to the way the spirv-reduce tool
works. The shrinking process will give up after a maximum number of
steps, which can be configured on the command line.
Tests for the combination of fuzzing and shrinking are included, using
a variety of interestingness functions.
Inlining does not inline functions that have a single return that is in a loop. This is because the return cannot be replaced by a branch outside of the loop easily. Merge return knows how to rewrite the function so the return is replaced by a branch.
Fixes#2038.
It is illegal to inline an OpKill instruction into a continue construct because the continue header will no longer dominate the backedge.
This commit adds a check for this, and does not inline.
If we still want to be able to inline a function that contains an OpKill, we can add a new pass that will wrap OpKill instructions into its own function with just the single instruction.
I do not believe that this is a common case right now, so I will not do that yet.
Fixes#2433.
In order for the Fuchsia source tree to update its
version of SPIRV-Tools to a newer upstream, the
BUILD.gn needs to be slightly altered to take care
of the fact that it can be used with a different
GN //build set of rules and configs than the
Chromium one.
This is done by using |build_with_chromium|, already
defined by //build_overrides/build.gni, to guard
Chromium-specific statements.
+ Add a target to generate spirv-opt which is used by
Fuchsia to optimize shaders at build time for some
of its graphics libraries.
When working on descriptor indexing validation for compute shaders, the
gl_GlobalInvocationID builtin was being loaded as uint which would cause
compute shaders instrumented by the bindless check pass to have:
%83 = OpLoad %uint %gl_GlobalInvocationID
%84 = OpCompositeExtract %uint %83 0
%85 = OpCompositeExtract %uint %83 1
%86 = OpCompositeExtract %uint %83 2
which results in validation failures:
error: line 127: Reached non-composite type while indexes still remain
to be traversed.
%84 = OpCompositeExtract %uint %83 0
for trying to extract a uint from a uint.
Fixes#2621.
Instead of aborting when an invalid input fact is provided, the tool
now warns about the invalid fact and then ignores it. This is
convenient for example if facts are specified about uniforms with
descriptor sets and bindings that happen to not be present in the
input binary.
Fixes#2695. Allowing unreachable blocks to be moved can lead to an
unreachable block A getting placed after an unreachable successor B,
which is a problem if B uses ids that A generates.