Commit Graph

116 Commits

Author SHA1 Message Date
Alastair Donaldson
a9f2a145e6
spirv-fuzz: Fix to fact manager (#3339)
Reworks the way uniforms with known constants are queried to avoid
unintended side effects to the constant manager.

Fixes #3338.
2020-05-13 22:04:52 +01:00
Alastair Donaldson
045a26e6e3
spirv-fuzz: Get rid of unnecessary template method (#3340)
A template method turned out not to be necessary.
2020-05-13 22:04:24 +01:00
Alastair Donaldson
2e1d208ed9
spirv-fuzz: Do not allow adding stores to read-only pointers (#3316)
Re-uses IsReadOnlyPointer functionality for the optimizer to make the check
that avoids storing through read-only pointers more thorough.
2020-05-01 02:50:44 +01:00
Alastair Donaldson
f278b467df
spirv-fuzz: Do not outline regions that end with a loop header (#3312)
The outliner would outline regions ending with a loop header, making
the block containing the call to the outlined function serve as the
loop header.  This, however, is incorrect in general, since the whole
outlined function -- rather than just the exit block for the region --
would end up getting called every time the loop would iterate.

This change restricts the outliner so that the last block in a region
cannot be a loop header.
2020-04-28 13:32:06 +01:00
Alastair Donaldson
94d6002dc5
spirv-fuzz: Pass on validator options during shrinking (#3317)
Fixes an issue where the shrinker's validator options were not
actually being passed to the validator.
2020-04-27 14:25:46 +01:00
Alastair Donaldson
88faf63ad3
spirv-fuzz: Clamp statically out-of-bounds accesses in code donation (#3315)
It has been resolved that statically out-of-bounds accesses are not
invalid in SPIR-V (they lead to undefind behaviour at runtime but
should not cause a module to be rejected during validation).  This
change tolerates such accesses in donated code, clamping them in-bound
as part of making a function live-safe.
2020-04-27 14:24:54 +01:00
Alastair Donaldson
b74199a22d
spirv-fuzz: Fix memory management in the fact manager (#3313)
Fixes a bug where, while recursively adding id equation facts, a
reference to a set of id equations could be used after it had been
freed (due to equivalence classes of equations being merged).
2020-04-27 14:24:11 +01:00
Alastair Donaldson
d158ffe540
spirv-fuzz: Do not replace the Sample argument in OpImageTexelPointer (#3311)
The Sample argument of OpImageTexelPointer is sometimes required to be
a zero constant.  It thus cannot be replaced with a synonym in
general.  This change avoids replacing this argument with a synonym.
2020-04-27 14:23:11 +01:00
Alastair Donaldson
67f4838659
spirv-fuzz: Make handling of synonym facts more efficient (#3301)
The fact manager maintains an equivalence relation on data descriptors
that tracks when one data descriptor could be used in place of
another.  An algorithm to compute the closure of such facts allows
deducing new synonym facts from existing facts.  E.g., for two 2D
vectors u and v it is known that u.x is synonymous with v.x and u.y is
synonymous with v.y, it can be deduced that u and v are synonymous.

The closure computation algorithm is very expensive if we get large
equivalence relations.

This change addresses this in three ways:

- The size of equivalence relations is reduced by limiting the extent
  to which the components of a composite are recursively noted as
  being equivalent, so that when we have large synonymous arrays we do
  not record all array elements as being pairwise equivalent.

- When computing the closure of facts, equivalence classes above a
  certain size are simply skipped (which can lead to missed facts)

- The closure computation is performed less frequently - it is invoked
  explicitly before fuzzer passes that will benefit from data synonym
  facts.  A new transformation is used to control its invocation, so
  that fuzzing and replaying do not get out of sync.

The change also tidies up the order in which some getters are declared
in FuzzerContext.
2020-04-20 19:02:49 +01:00
Alastair Donaldson
ed96301c6c
spirv-fuzz: Fix to outliner (#3302)
Adds an extra condition on when a region can be outlined to avoid the
case where a region ends with a loop head but such that the loop's
continue target is in the region.  (Outlining such a region would mean
that the loop merge is in the original function and the continue target
in the outlined function.)
2020-04-15 11:39:33 +01:00
Alastair Donaldson
c018fc6ae6
spirv-fuzz: Do not outline regions that produce pointer outputs (#3291)
The function outliner uses a struct to return ids that a region
generates and that are used outside that region.  If these ids have
pointer type this would result in a struct with pointer members, which
leads to illegal loading from non-logical pointers if logical
addressing is used.  This change bans that outlining possibility.
2020-04-14 20:22:30 +01:00
Alastair Donaldson
f460cca9dc
spirv-fuzz: Handle OpRuntimeArray when replacing ids with synonyms (#3292)
Provides support for runtime arrays in the code that traverses
composite types when checking applicability of transformations that
replace ids with synonyms.
2020-04-14 20:21:58 +01:00
Alastair Donaldson
2f180468a7
spirv-fuzz: Handle image storage class in donation (#3290)
Demotes the image storage class to Private during donation.  Also
fixes an issue where instructions that depended on non-donated global
values would not be handled properly.
2020-04-14 20:21:33 +01:00
Alastair Donaldson
f82d47003e
spirv-fuzz: Respect rules for OpSampledImage (#3287)
The SPIR-V data rules say that all uses of an OpSampledImage
instruction must be in the same block as the instruction, and highly
restrict those instructions that can consume the result id of an
OpSampledImage.

This adapts the transformations that split blocks and create synonyms
to avoid separating an OpSampledImage use from its definition, and to
avoid synonym-creation instructions such as OpCopyObject consuming an
OpSampledImage result id.
2020-04-14 20:17:42 +01:00
Alastair Donaldson
7ce2db1763
spirv-fuzz: Fix comment. (#3300) 2020-04-14 20:17:05 +01:00
Alastair Donaldson
538512e8e8
spirv-fuzz: Improve the handling of equation facts (#3281)
The management of equation facts suffered from two problems:

(1) The processing of an equation fact required the data descriptors
    used in the equation to be in canonical form.  However, during
    fact processing it can be deduced that certain data descriptors
    are equivalent, causing their equivalence classes to be merged,
    and that could cause previously canonical data descriptors to no
    longer be canonical.

(2) Related to this, if id equations were known about a canonical data
    descriptor dd1, and other id equations known about a different
    canonical data descriptor dd2, the equation facts about these data
    descriptors were not being merged in the event that dd1 and dd2
    were deduced to be equivalent.

This changes solves (1) by not requiring equation facts to be in
canonical form while processing them, but instead always checking
whether (not necessary canonical) data descriptors are equivalent when
looking for corollaries of equation facts, rather than comparing them
using ==.

Problem (2) is solved by adding logic to merge sets of equations when
data descriptors are made equivalent.

In addition, the change also requires elements to be registered in an
equivalence relation before they can be made equivalent, rather than
being added (if not already present) at the point of being made
equivalent.
2020-04-07 17:38:27 +01:00
Alastair Donaldson
183e3242a3
spirv-fuzz: Handle more general SPIR-V in donation (#3280)
This change increases the extent to which arbitrary SPIR-V can be used
by the fuzzer pass that donates modules. It handles the case where
various ingredients (such as types, variables and particular
instructions) cannot be donated by omitting them, and then either
omitting their dependencies or replacing their dependencies with
alternative instructions.

The change pays particular attention to allowing code that manipulates
image types to be handled (by skipping anything image-specific).
2020-04-07 17:37:51 +01:00
Alastair Donaldson
4af38c49bf
spirv-fuzz: Improve support for compute shaders in donation (#3277)
(1) Runtime arrays are turned into fixed-size arrays, by turning
    OpTypeRuntimeArray into OpTypeArray and uses of OpArrayLength into
    uses of the constant used for the length of the fixed-size array.

(2) Atomic instructions are not donated, and uses of their results are
    replaced with uses of constants of the result type.
2020-04-06 16:08:14 +01:00
Alastair Donaldson
e95fbfb1f5
spirv-fuzz: Transformation to add OpConstantNull (#3273)
Adds a transformation for adding OpConstantNull to a module, for
appropriate data types.
2020-04-02 19:25:30 +01:00
Alastair Donaldson
5d491a7ed6
spirv-fuzz: Handle isomorphic types property in composite construction (#3262)
The fuzzer pass that constructs composites had an issue where it would
regard isomorphic but distinct structs (similarly arrays) as being
interchangeable when constructing composites.  This change fixes the
problem by relying less on the type manager.
2020-04-02 18:33:19 +01:00
Alastair Donaldson
bfd25ace08
spirv-fuzz: Limit adding of new variables to 'basic' types (#3257)
To avoid problems where global and local variables of opaque or
runtime-sized types are added to a module, this change introduces the
notion of a 'basic type' -- a type made up from floats, ints, bools,
or vectors, matrices, structs and fixed-size arrays of basic types.
Added variables have to be of basic type.
2020-04-02 17:35:18 +01:00
Alastair Donaldson
f28cdeff16
spirv-fuzz: Only replace regular ids with synonyms (#3255)
Fixes an issue where an id use in a non-regular context, e.g. as a
scope parameter to an atomic instruction, would be replaced with a
synonym.
2020-04-02 17:35:00 +01:00
Alastair Donaldson
8d4261bc44
spirv-fuzz: Introduce TransformationContext (#3272)
Some transformations (e.g. TransformationAddFunction) rely on running
the validator to decide whether the transformation is applicable.  A
recent change allowed spirv-fuzz to take validator options, to cater
for the case where a module should be considered valid under
particular conditions.  However, validation during the checking of
transformations had no access to these validator options.

This change introduced TransformationContext, which currently consists
of a fact manager and a set of validator options, but could in the
future have other fields corresponding to other objects that it is
useful to have access to when applying transformations.  Now, instead
of checking and applying transformations in the context of a
FactManager, a TransformationContext is used.  This gives access to
the fact manager as before, and also access to the validator options
when they are needed.
2020-04-02 15:54:46 +01:00
Alastair Donaldson
2fdea57d19
spirv-fuzz: Add validator options (#3254)
Allows several validator options to be passed to the fuzzer, to be
used when validation is invoked during fuzzing.
2020-04-02 14:37:59 +01:00
Vasyl Teliman
6428ad05e7
spirv-fuzz: Support OpPhi when adding dead break and continue (#3225)
Fixes #2856.
2020-03-12 12:40:38 +00:00
Alastair Donaldson
1af1df3b23
spirv-fuzz: Fix vector width issue in 'add equation instructions' pass (#3223)
Fixes #3213.
2020-03-12 10:56:11 +00:00
Vasyl Teliman
7c3de218f4
spirv-fuzz: Remove duplicated functionality (#3220)
Fixes #3218.
2020-03-09 16:17:43 +00:00
André Perez Maselco
659470446c
spirv-fuzz: Allow OpPhi operand to be replaced with a composite synonym (#3221)
In this PR, the class FuzzerPassApplyIdSynonyms was updated to allow OpPhi operand to be replaced with a composite synonym.

Fixes #3209.
2020-03-09 16:16:18 +00:00
André Perez Maselco
4c027048d8
spirv-fuzz: Add toggle access chain instruction transformation (#3211)
In this PR, the classes that represent the toggle access chain
instruction transformation and fuzzer pass were implemented. This
transformation toggles the instructions OpAccessChain and
OpInBoundsAccessChain between them.

Fixes #3193.
2020-03-08 22:33:24 +00:00
Vasyl Teliman
533af49812
spirv-fuzz: Add fuzzer pass to permute function parameters (#3212)
Fixes #3194.
2020-03-08 14:27:05 +00:00
Alastair Donaldson
da4cd21485
spirv-fuzz: Use better function name (#3207)
Changes FuzzerPass::MaybeAddTransformationBeforeEachInstruction to
FuzzerPass::ForEachInstructionWithInstructionDescriptor.

Fixes #3184.
2020-03-06 12:25:57 +00:00
Alastair Donaldson
66a682b6a8
spirv-fuzz: Add swap commutable operands transformation (#3205)
In this PR, the classes that represent the swap commutable operands
transformation and the fuzzer pass were implemented.

Fixes #3205.
2020-03-05 08:18:39 +00:00
Alastair Donaldson
044ecc0b2c
spirv-fuzz: Fuzzer pass to add equation instructions (#3202)
This introduces a new fuzzer pass to add instructions to the module
that define equations, and support in the fact manager for recording
equation facts and deducing synonym facts from equation facts.

Initially the only equations that are supported involve OpIAdd,
OpISub, OpSNegate and OpLogicalNot, but there is scope for adding
support for equations over various other operators.
2020-03-04 14:54:08 +00:00
André Perez Maselco
a6d3a2dd41
Refactor FuzzerPass::ApplyTransformation code duplication. (#3206) 2020-03-04 06:56:38 +00:00
Alastair Donaldson
77fefe765c
spirvfuzz: Fix type-related bug, change undef to zero, and add assert (#3188)
This fixes a bug where the type id of a type instruction, rather than
its result id, was being used.  It also favours using zero as the
return value when replacing an OpKill or OpUnreachable with a return
instruction, and adds a check that the donor module is valid when
doing module donation.

Fixes #3187.
2020-02-14 10:04:03 +00:00
Alastair Donaldson
6c218ec60b
spirv-fuzz: Fuzzer pass that adds access chains (#3182)
This change adds a fuzzer pass that sprinkles access chain
instructions into a module at random. This allows other passes to
have a richer set of pointers available to them, in particular the
passes that add loads and stores.
2020-02-11 23:10:57 +00:00
Alastair Donaldson
77fb303e58
spirv-fuzz: Fuzzer pass to add function calls (#3178)
Adds a fuzzer pass that inserts function calls into the module at
random. Calls from dead blocks can be arbitrary (so long as they do
not introduce recursion), while calls from other blocks can only be to
livesafe functions.

The change fixes some oversights in transformations to replace
constants with uniforms and to obfuscate constants which testing of
this fuzzer pass identified.
2020-02-10 23:22:34 +00:00
Alastair Donaldson
3d4a0dd48f
spirv-fuzz: Ensure that donated variables are always initialized (#3181)
This change ensures that global and local variables donated from other
modules are always initialized at their declaration in the module
being transformed.  This is to help limit issues related to undefined
behaviour that might arise due to accessing uninitialized memory.

The change also introduces some helper functions in fuzzer_util to
make it easier to find the pointee types of pointer types.
2020-02-10 20:10:41 +00:00
Alastair Donaldson
fe10239f92
spirv-fuzz: Add fuzzer passes to add loads/stores (#3176)
This change adds fuzzer passes that sprinkle loads and stores into a
module at random, with stores restricted to occur in either dead
blocks, or to use pointers for which it is known that the pointee
value does not influence the module's overall behaviour.

The change also generalises the VariableValueIsArbitrary fact to
PointeeValueIsIrrelevant, to allow stores through access chains or
object copies of variables whose values are known to be irrelevant.

The change includes some other minor refactorings.
2020-02-06 16:54:34 +00:00
Alastair Donaldson
1f03ac1027
spirv-fuzz: Fuzzer passes to add local and global variables (#3175)
Adds two new fuzzer passes to add variables to a module: one that adds
Private storage class global variables, another that adds Function
storage class local variables.
2020-02-05 21:07:44 +00:00
Alastair Donaldson
bb56e892f5
spirv-fuzz: Fuzzer pass to add composite types (#3171)
Adds a fuzzer pass that randomly adds vector and matrix types not
already present in the module, and randomly adds structs with random
field types and arrays with random base types and sizes. Other passes
will be able to create variables and ids using these types.
2020-02-04 14:00:19 +00:00
Alastair Donaldson
b7e0998e3d
spirv-fuzz: Disallow copying of null and undefined pointers (#3172)
If the fuzzer object-copies a pointer we would like to be able to
perform loads from the copy (and stores to it, if its value is known
not to matter).  Undefined and null pointers present a problem here,
so this change disallows copying them.
2020-02-04 11:15:07 +00:00
Alastair Donaldson
1fc7a9ec77
spirv-fuzz: Arbitrary variable facts (#3165)
This change adds a new kind of fact to the fact manager, which records
when a variable (or pointer parameter) refers to an arbitrary value,
so that anything can be stored to it, without affecting the observable
behaviour of the module, and nothing can be guaranteed about values
loaded from it. Donated modules are the current source of such
variables, and other transformations, such as outlining, have been
adapted to propagate these facts appropriately.
2020-01-30 11:25:29 +00:00
Alastair Donaldson
521223b70a
spirv-fuzz: Make functions "livesafe" during donation (#3146)
This change allows the generator to (optionally and at random) make
the functions of a module "livesafe" during donation. This involves
introducing a loop limiter variable to each function and gating the
number of total loop iterations for the function using that variable.
It also involves eliminating OpKill and OpUnreachable instructions
(changing them to OpReturn/OpReturnValue), and clamping access chain
indices so that they are always in-bounds.
2020-01-29 15:52:31 +00:00
Alastair Donaldson
ab7ac60f14
spirv-fuzz: Refactoring and type-related fixes (#3144)
This change refactors some code for walking access chain indexes to
make it mirror the structure of other code (to improve readability in
the first instance and potentially enable a future refactoring to
extract common code), and fixes a problem related to module donation
and function types.
2020-01-21 05:59:57 -08:00
Alastair Donaldson
8013d477ae
spirv-fuzz: add dead blocks (#3135)
This adds a new kind of fact to the fact manager that knows whether a
block is dead - i.e. guaranteed to be statically unreachable - and a
new transformation for adding a selection construct to a CFG that
conditionally branches to a fresh, dead block, such that the branch
will never be dynamically taken. Transformations that may create new
blocks ('split block' and 'outline function') are updated to propagate
dead block facts to newly-created blocks where appropriate. A fuzzer
pass randomly adds dead blocks to the module.

Future transformations will be able to exploit the fact that such
blocks are known to be dead.
2020-01-13 22:04:01 +00:00
Alastair Donaldson
31acc78821
spirv-fuzz: Add fuzzer pass to perform module donation (#3117)
This change adds a fuzzer pass that allows code from other SPIR-V
modules to be donated into the module under transformation.  It also
changes the command-line options of the tools so that, in fuzzing
mode, a file must be specified that contains the names of available
donor modules.
2020-01-07 08:39:55 +00:00
Alastair Donaldson
e01bc6d4e8
spirv-fuzz: Always add new globals to entry point interfaces (#3113)
In the context of SPIR-V 1.4 or higher, global variables cannot be
used by an instruction unless they are listed in the interface of all
entry points that might invoke the instruction.  This change
conservatively adds new global variables to the interfaces of all
entry points (if the SPIR-V version is 1.4 or higher).

Issue #3111 notes that a more rigorous approach to entry point
interfaces could be taken in spirv-fuzz, which would allow being less
conservative here.
2019-12-19 21:16:09 +00:00
Alastair Donaldson
dcb7169bbd
spirv-fuzz: Transformation to add a new function to a module (#3114)
This adds a large transformation that can add a new function to a
SPIR-V module.  This paves the way for donation of code from one
module to another.
2019-12-19 21:15:09 +00:00
Alastair Donaldson
2e41d5ece7
spirv-fuzz: Avoid passing access chains as parameters (#3112)
This change prevents the spirv-fuzz function outliner from outlining a
region that uses the result of an OpAccessChain not defined inside the
region.  Such accesses were turning into parameters to the outlined
function, and the result of an OpAccessChain cannot be passed as a
function parameter according to the SPIR-V specification.
2019-12-19 17:34:36 +00:00