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.
This commit is contained in:
Alastair Donaldson 2020-04-20 19:02:49 +01:00 committed by GitHub
parent 61b7de3c39
commit 67f4838659
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 790 additions and 675 deletions

View File

@ -100,6 +100,7 @@ if(SPIRV_BUILD_FUZZER)
transformation_add_type_vector.h transformation_add_type_vector.h
transformation_composite_construct.h transformation_composite_construct.h
transformation_composite_extract.h transformation_composite_extract.h
transformation_compute_data_synonym_fact_closure.h
transformation_context.h transformation_context.h
transformation_copy_object.h transformation_copy_object.h
transformation_equation_instruction.h transformation_equation_instruction.h
@ -193,6 +194,7 @@ if(SPIRV_BUILD_FUZZER)
transformation_add_type_vector.cpp transformation_add_type_vector.cpp
transformation_composite_construct.cpp transformation_composite_construct.cpp
transformation_composite_extract.cpp transformation_composite_extract.cpp
transformation_compute_data_synonym_fact_closure.cpp
transformation_context.cpp transformation_context.cpp
transformation_copy_object.cpp transformation_copy_object.cpp
transformation_equation_instruction.cpp transformation_equation_instruction.cpp

View File

@ -416,17 +416,18 @@ class FactManager::DataSynonymAndIdEquationFacts {
// See method in FactManager which delegates to this method. // See method in FactManager which delegates to this method.
std::vector<const protobufs::DataDescriptor*> GetSynonymsForDataDescriptor( std::vector<const protobufs::DataDescriptor*> GetSynonymsForDataDescriptor(
const protobufs::DataDescriptor& data_descriptor, const protobufs::DataDescriptor& data_descriptor) const;
opt::IRContext* context) const;
// See method in FactManager which delegates to this method. // See method in FactManager which delegates to this method.
std::vector<uint32_t> GetIdsForWhichSynonymsAreKnown( std::vector<uint32_t> GetIdsForWhichSynonymsAreKnown() const;
opt::IRContext* context) const;
// See method in FactManager which delegates to this method. // See method in FactManager which delegates to this method.
bool IsSynonymous(const protobufs::DataDescriptor& data_descriptor1, bool IsSynonymous(const protobufs::DataDescriptor& data_descriptor1,
const protobufs::DataDescriptor& data_descriptor2, const protobufs::DataDescriptor& data_descriptor2) const;
opt::IRContext* context) const;
// See method in FactManager which delegates to this method.
void ComputeClosureOfFacts(opt::IRContext* context,
uint32_t maximum_equivalence_class_size);
private: private:
// Adds the synonym |dd1| = |dd2| to the set of managed facts, and recurses // Adds the synonym |dd1| = |dd2| to the set of managed facts, and recurses
@ -436,23 +437,10 @@ class FactManager::DataSynonymAndIdEquationFacts {
const protobufs::DataDescriptor& dd2, const protobufs::DataDescriptor& dd2,
opt::IRContext* context); opt::IRContext* context);
// Inspects all known facts and adds corollary facts; e.g. if we know that
// a.x == b.x and a.y == b.y, where a and b have vec2 type, we can record
// that a == b holds.
//
// This method is expensive, and is thus called on demand: rather than
// computing the closure of facts each time a data synonym fact is added, we
// compute the closure only when a data synonym fact is *queried*.
void ComputeClosureOfFacts(opt::IRContext* context) const;
// Records the fact that |dd1| and |dd2| are equivalent, and merges the sets // Records the fact that |dd1| and |dd2| are equivalent, and merges the sets
// of equations that are known about them. // of equations that are known about them.
//
// This is a const method, despite the fact that it mutates the (mutable)
// set of facts about data descriptors because it is invoked in a lazy fashion
// when querying facts.
void MakeEquivalent(const protobufs::DataDescriptor& dd1, void MakeEquivalent(const protobufs::DataDescriptor& dd1,
const protobufs::DataDescriptor& dd2) const; const protobufs::DataDescriptor& dd2);
// Returns true if and only if |dd1| and |dd2| are valid data descriptors // Returns true if and only if |dd1| and |dd2| are valid data descriptors
// whose associated data have the same type (modulo integer signedness). // whose associated data have the same type (modulo integer signedness).
@ -473,28 +461,17 @@ class FactManager::DataSynonymAndIdEquationFacts {
// The data descriptors that are known to be synonymous with one another are // The data descriptors that are known to be synonymous with one another are
// captured by this equivalence relation. // captured by this equivalence relation.
// EquivalenceRelation<protobufs::DataDescriptor, DataDescriptorHash,
// This member is mutable in order to allow the closure of facts captured by
// the relation to be computed lazily when a question about data synonym
// facts is asked.
mutable EquivalenceRelation<protobufs::DataDescriptor, DataDescriptorHash,
DataDescriptorEquals> DataDescriptorEquals>
synonymous_; synonymous_;
// When a new synonym fact is added, it may be possible to deduce further // When a new synonym fact is added, it may be possible to deduce further
// synonym facts by computing a closure of all known facts. However, there is // synonym facts by computing a closure of all known facts. However, this is
// no point computing this closure until a question regarding synonym facts is // an expensive operation, so it should be performed sparingly and only there
// actually asked: if several facts are added in succession with no questions // is some chance of new facts being deduced. This boolean tracks whether a
// asked in between, we can avoid computing fact closures multiple times. // closure computation is required - i.e., whether a new fact has been added
// // since the last time such a computation was performed.
// This boolean tracks whether a closure computation is required - i.e., bool closure_computation_required_ = false;
// whether a new fact has been added since the last time such a computation
// was performed.
//
// It is mutable to facilitate having const methods, that provide answers to
// questions about data synonym facts, triggering closure computation on
// demand.
mutable bool closure_computation_required_ = false;
// Represents a set of equations on data descriptors as a map indexed by // Represents a set of equations on data descriptors as a map indexed by
// left-hand-side, mapping a left-hand-side to a set of operations, each of // left-hand-side, mapping a left-hand-side to a set of operations, each of
@ -503,12 +480,7 @@ class FactManager::DataSynonymAndIdEquationFacts {
// All data descriptors occurring in equations are required to be present in // All data descriptors occurring in equations are required to be present in
// the |synonymous_| equivalence relation, and to be their own representatives // the |synonymous_| equivalence relation, and to be their own representatives
// in that relation. // in that relation.
// std::unordered_map<
// It is mutable because a closure computation can be triggered from a const
// method, and when a closure computation detects that two data descriptors
// are equivalent it is necessary to merge the equation facts for those data
// descriptors.
mutable std::unordered_map<
const protobufs::DataDescriptor*, const protobufs::DataDescriptor*,
std::unordered_set<Operation, OperationHash, OperationEquals>> std::unordered_set<Operation, OperationHash, OperationEquals>>
id_equations_; id_equations_;
@ -770,7 +742,17 @@ void FactManager::DataSynonymAndIdEquationFacts::AddDataSynonymFactRecursive(
// obj_1[a_1, ..., a_m] == obj_2[b_1, ..., b_n] // obj_1[a_1, ..., a_m] == obj_2[b_1, ..., b_n]
// then for each composite index i, we add a fact of the form: // then for each composite index i, we add a fact of the form:
// obj_1[a_1, ..., a_m, i] == obj_2[b_1, ..., b_n, i] // obj_1[a_1, ..., a_m, i] == obj_2[b_1, ..., b_n, i]
for (uint32_t i = 0; i < num_composite_elements; i++) { //
// However, to avoid adding a large number of synonym facts e.g. in the case
// of arrays, we bound the number of composite elements to which this is
// applied. Nevertheless, we always add a synonym fact for the final
// components, as this may be an interesting edge case.
// The bound on the number of indices of the composite pair to note as being
// synonymous.
const uint32_t kCompositeElementBound = 10;
for (uint32_t i = 0; i < num_composite_elements;) {
std::vector<uint32_t> extended_indices1 = std::vector<uint32_t> extended_indices1 =
fuzzerutil::RepeatedFieldToVector(dd1.index()); fuzzerutil::RepeatedFieldToVector(dd1.index());
extended_indices1.push_back(i); extended_indices1.push_back(i);
@ -781,11 +763,21 @@ void FactManager::DataSynonymAndIdEquationFacts::AddDataSynonymFactRecursive(
MakeDataDescriptor(dd1.object(), std::move(extended_indices1)), MakeDataDescriptor(dd1.object(), std::move(extended_indices1)),
MakeDataDescriptor(dd2.object(), std::move(extended_indices2)), MakeDataDescriptor(dd2.object(), std::move(extended_indices2)),
context); context);
if (i < kCompositeElementBound - 1 || i == num_composite_elements - 1) {
// We have not reached the bound yet, or have already skipped ahead to the
// last element, so increment the loop counter as standard.
i++;
} else {
// We have reached the bound, so skip ahead to the last element.
assert(i == kCompositeElementBound - 1);
i = num_composite_elements - 1;
}
} }
} }
void FactManager::DataSynonymAndIdEquationFacts::ComputeClosureOfFacts( void FactManager::DataSynonymAndIdEquationFacts::ComputeClosureOfFacts(
opt::IRContext* context) const { opt::IRContext* context, uint32_t maximum_equivalence_class_size) {
// Suppose that obj_1[a_1, ..., a_m] and obj_2[b_1, ..., b_n] are distinct // Suppose that obj_1[a_1, ..., a_m] and obj_2[b_1, ..., b_n] are distinct
// data descriptors that describe objects of the same composite type, and that // data descriptors that describe objects of the same composite type, and that
// the composite type is comprised of k components. // the composite type is comprised of k components.
@ -871,6 +863,13 @@ void FactManager::DataSynonymAndIdEquationFacts::ComputeClosureOfFacts(
synonymous_.GetEquivalenceClassRepresentatives()) { synonymous_.GetEquivalenceClassRepresentatives()) {
auto equivalence_class = synonymous_.GetEquivalenceClass(*representative); auto equivalence_class = synonymous_.GetEquivalenceClass(*representative);
if (equivalence_class.size() > maximum_equivalence_class_size) {
// This equivalence class is larger than the maximum size we are willing
// to consider, so we skip it. This potentially leads to missed fact
// deductions, but avoids excessive runtime for closure computation.
continue;
}
// Consider every data descriptor in the equivalence class. // Consider every data descriptor in the equivalence class.
for (auto dd1_it = equivalence_class.begin(); for (auto dd1_it = equivalence_class.begin();
dd1_it != equivalence_class.end(); ++dd1_it) { dd1_it != equivalence_class.end(); ++dd1_it) {
@ -1059,7 +1058,7 @@ void FactManager::DataSynonymAndIdEquationFacts::ComputeClosureOfFacts(
void FactManager::DataSynonymAndIdEquationFacts::MakeEquivalent( void FactManager::DataSynonymAndIdEquationFacts::MakeEquivalent(
const protobufs::DataDescriptor& dd1, const protobufs::DataDescriptor& dd1,
const protobufs::DataDescriptor& dd2) const { const protobufs::DataDescriptor& dd2) {
// Register the data descriptors if they are not already known to the // Register the data descriptors if they are not already known to the
// equivalence relation. // equivalence relation.
for (const auto& dd : {dd1, dd2}) { for (const auto& dd : {dd1, dd2}) {
@ -1185,9 +1184,7 @@ bool FactManager::DataSynonymAndIdEquationFacts::
std::vector<const protobufs::DataDescriptor*> std::vector<const protobufs::DataDescriptor*>
FactManager::DataSynonymAndIdEquationFacts::GetSynonymsForDataDescriptor( FactManager::DataSynonymAndIdEquationFacts::GetSynonymsForDataDescriptor(
const protobufs::DataDescriptor& data_descriptor, const protobufs::DataDescriptor& data_descriptor) const {
opt::IRContext* context) const {
ComputeClosureOfFacts(context);
if (synonymous_.Exists(data_descriptor)) { if (synonymous_.Exists(data_descriptor)) {
return synonymous_.GetEquivalenceClass(data_descriptor); return synonymous_.GetEquivalenceClass(data_descriptor);
} }
@ -1195,9 +1192,8 @@ FactManager::DataSynonymAndIdEquationFacts::GetSynonymsForDataDescriptor(
} }
std::vector<uint32_t> std::vector<uint32_t>
FactManager::DataSynonymAndIdEquationFacts ::GetIdsForWhichSynonymsAreKnown( FactManager::DataSynonymAndIdEquationFacts::GetIdsForWhichSynonymsAreKnown()
opt::IRContext* context) const { const {
ComputeClosureOfFacts(context);
std::vector<uint32_t> result; std::vector<uint32_t> result;
for (auto& data_descriptor : synonymous_.GetAllKnownValues()) { for (auto& data_descriptor : synonymous_.GetAllKnownValues()) {
if (data_descriptor->index().empty()) { if (data_descriptor->index().empty()) {
@ -1209,10 +1205,7 @@ FactManager::DataSynonymAndIdEquationFacts ::GetIdsForWhichSynonymsAreKnown(
bool FactManager::DataSynonymAndIdEquationFacts::IsSynonymous( bool FactManager::DataSynonymAndIdEquationFacts::IsSynonymous(
const protobufs::DataDescriptor& data_descriptor1, const protobufs::DataDescriptor& data_descriptor1,
const protobufs::DataDescriptor& data_descriptor2, const protobufs::DataDescriptor& data_descriptor2) const {
opt::IRContext* context) const {
const_cast<FactManager::DataSynonymAndIdEquationFacts*>(this)
->ComputeClosureOfFacts(context);
return synonymous_.Exists(data_descriptor1) && return synonymous_.Exists(data_descriptor1) &&
synonymous_.Exists(data_descriptor2) && synonymous_.Exists(data_descriptor2) &&
synonymous_.IsEquivalent(data_descriptor1, data_descriptor2); synonymous_.IsEquivalent(data_descriptor1, data_descriptor2);
@ -1394,31 +1387,27 @@ FactManager::GetConstantUniformFactsAndTypes() const {
return uniform_constant_facts_->GetConstantUniformFactsAndTypes(); return uniform_constant_facts_->GetConstantUniformFactsAndTypes();
} }
std::vector<uint32_t> FactManager::GetIdsForWhichSynonymsAreKnown( std::vector<uint32_t> FactManager::GetIdsForWhichSynonymsAreKnown() const {
opt::IRContext* context) const { return data_synonym_and_id_equation_facts_->GetIdsForWhichSynonymsAreKnown();
return data_synonym_and_id_equation_facts_->GetIdsForWhichSynonymsAreKnown(
context);
} }
std::vector<const protobufs::DataDescriptor*> std::vector<const protobufs::DataDescriptor*>
FactManager::GetSynonymsForDataDescriptor( FactManager::GetSynonymsForDataDescriptor(
const protobufs::DataDescriptor& data_descriptor, const protobufs::DataDescriptor& data_descriptor) const {
opt::IRContext* context) const {
return data_synonym_and_id_equation_facts_->GetSynonymsForDataDescriptor( return data_synonym_and_id_equation_facts_->GetSynonymsForDataDescriptor(
data_descriptor, context); data_descriptor);
} }
std::vector<const protobufs::DataDescriptor*> FactManager::GetSynonymsForId( std::vector<const protobufs::DataDescriptor*> FactManager::GetSynonymsForId(
uint32_t id, opt::IRContext* context) const { uint32_t id) const {
return GetSynonymsForDataDescriptor(MakeDataDescriptor(id, {}), context); return GetSynonymsForDataDescriptor(MakeDataDescriptor(id, {}));
} }
bool FactManager::IsSynonymous( bool FactManager::IsSynonymous(
const protobufs::DataDescriptor& data_descriptor1, const protobufs::DataDescriptor& data_descriptor1,
const protobufs::DataDescriptor& data_descriptor2, const protobufs::DataDescriptor& data_descriptor2) const {
opt::IRContext* context) const { return data_synonym_and_id_equation_facts_->IsSynonymous(data_descriptor1,
return data_synonym_and_id_equation_facts_->IsSynonymous( data_descriptor2);
data_descriptor1, data_descriptor2, context);
} }
bool FactManager::BlockIsDead(uint32_t block_id) const { bool FactManager::BlockIsDead(uint32_t block_id) const {
@ -1463,5 +1452,11 @@ void FactManager::AddFactIdEquation(uint32_t lhs_id, SpvOp opcode,
data_synonym_and_id_equation_facts_->AddFact(fact, context); data_synonym_and_id_equation_facts_->AddFact(fact, context);
} }
void FactManager::ComputeClosureOfFacts(
opt::IRContext* ir_context, uint32_t maximum_equivalence_class_size) {
data_synonym_and_id_equation_facts_->ComputeClosureOfFacts(
ir_context, maximum_equivalence_class_size);
}
} // namespace fuzz } // namespace fuzz
} // namespace spvtools } // namespace spvtools

View File

@ -76,6 +76,21 @@ class FactManager {
const std::vector<uint32_t>& rhs_id, const std::vector<uint32_t>& rhs_id,
opt::IRContext* context); opt::IRContext* context);
// Inspects all known facts and adds corollary facts; e.g. if we know that
// a.x == b.x and a.y == b.y, where a and b have vec2 type, we can record
// that a == b holds.
//
// This method is expensive, and should only be called (by applying a
// transformation) at the start of a fuzzer pass that depends on data
// synonym facts, rather than calling it every time a new data synonym fact
// is added.
//
// The parameter |maximum_equivalence_class_size| specifies the size beyond
// which equivalence classes should not be mined for new facts, to avoid
// excessively-long closure computations.
void ComputeClosureOfFacts(opt::IRContext* ir_context,
uint32_t maximum_equivalence_class_size);
// The fact manager is responsible for managing a few distinct categories of // The fact manager is responsible for managing a few distinct categories of
// facts. In principle there could be different fact managers for each kind // facts. In principle there could be different fact managers for each kind
// of fact, but in practice providing one 'go to' place for facts is // of fact, but in practice providing one 'go to' place for facts is
@ -125,25 +140,22 @@ class FactManager {
// Returns every id for which a fact of the form "this id is synonymous with // Returns every id for which a fact of the form "this id is synonymous with
// this piece of data" is known. // this piece of data" is known.
std::vector<uint32_t> GetIdsForWhichSynonymsAreKnown( std::vector<uint32_t> GetIdsForWhichSynonymsAreKnown() const;
opt::IRContext* context) const;
// Returns the equivalence class of all known synonyms of |id|, or an empty // Returns the equivalence class of all known synonyms of |id|, or an empty
// set if no synonyms are known. // set if no synonyms are known.
std::vector<const protobufs::DataDescriptor*> GetSynonymsForId( std::vector<const protobufs::DataDescriptor*> GetSynonymsForId(
uint32_t id, opt::IRContext* context) const; uint32_t id) const;
// Returns the equivalence class of all known synonyms of |data_descriptor|, // Returns the equivalence class of all known synonyms of |data_descriptor|,
// or empty if no synonyms are known. // or empty if no synonyms are known.
std::vector<const protobufs::DataDescriptor*> GetSynonymsForDataDescriptor( std::vector<const protobufs::DataDescriptor*> GetSynonymsForDataDescriptor(
const protobufs::DataDescriptor& data_descriptor, const protobufs::DataDescriptor& data_descriptor) const;
opt::IRContext* context) const;
// Returns true if and ony if |data_descriptor1| and |data_descriptor2| are // Returns true if and ony if |data_descriptor1| and |data_descriptor2| are
// known to be synonymous. // known to be synonymous.
bool IsSynonymous(const protobufs::DataDescriptor& data_descriptor1, bool IsSynonymous(const protobufs::DataDescriptor& data_descriptor1,
const protobufs::DataDescriptor& data_descriptor2, const protobufs::DataDescriptor& data_descriptor2) const;
opt::IRContext* context) const;
// End of id synonym facts // End of id synonym facts
//============================== //==============================

View File

@ -68,6 +68,7 @@ const std::pair<uint32_t, uint32_t> kChanceOfTogglingAccessChainInstruction = {
// Default limits for various quantities that are chosen during fuzzing. // Default limits for various quantities that are chosen during fuzzing.
// Keep them in alphabetical order. // Keep them in alphabetical order.
const uint32_t kDefaultMaxEquivalenceClassSizeForDataSynonymFactClosure = 1000;
const uint32_t kDefaultMaxLoopControlPartialCount = 100; const uint32_t kDefaultMaxLoopControlPartialCount = 100;
const uint32_t kDefaultMaxLoopControlPeelCount = 100; const uint32_t kDefaultMaxLoopControlPeelCount = 100;
const uint32_t kDefaultMaxLoopLimit = 20; const uint32_t kDefaultMaxLoopLimit = 20;
@ -89,6 +90,8 @@ FuzzerContext::FuzzerContext(RandomGenerator* random_generator,
uint32_t min_fresh_id) uint32_t min_fresh_id)
: random_generator_(random_generator), : random_generator_(random_generator),
next_fresh_id_(min_fresh_id), next_fresh_id_(min_fresh_id),
max_equivalence_class_size_for_data_synonym_fact_closure_(
kDefaultMaxEquivalenceClassSizeForDataSynonymFactClosure),
max_loop_control_partial_count_(kDefaultMaxLoopControlPartialCount), max_loop_control_partial_count_(kDefaultMaxLoopControlPartialCount),
max_loop_control_peel_count_(kDefaultMaxLoopControlPeelCount), max_loop_control_peel_count_(kDefaultMaxLoopControlPeelCount),
max_loop_limit_(kDefaultMaxLoopLimit), max_loop_limit_(kDefaultMaxLoopLimit),

View File

@ -183,12 +183,21 @@ class FuzzerContext {
uint32_t GetChanceOfTogglingAccessChainInstruction() { uint32_t GetChanceOfTogglingAccessChainInstruction() {
return chance_of_toggling_access_chain_instruction_; return chance_of_toggling_access_chain_instruction_;
} }
uint32_t GetRandomLoopControlPeelCount() {
return random_generator_->RandomUint32(max_loop_control_peel_count_); // Other functions to control transformations. Keep them in alphabetical
// order.
uint32_t GetMaximumEquivalenceClassSizeForDataSynonymFactClosure() {
return max_equivalence_class_size_for_data_synonym_fact_closure_;
}
uint32_t GetRandomIndexForAccessChain(uint32_t composite_size_bound) {
return random_generator_->RandomUint32(composite_size_bound);
} }
uint32_t GetRandomLoopControlPartialCount() { uint32_t GetRandomLoopControlPartialCount() {
return random_generator_->RandomUint32(max_loop_control_partial_count_); return random_generator_->RandomUint32(max_loop_control_partial_count_);
} }
uint32_t GetRandomLoopControlPeelCount() {
return random_generator_->RandomUint32(max_loop_control_peel_count_);
}
uint32_t GetRandomLoopLimit() { uint32_t GetRandomLoopLimit() {
return random_generator_->RandomUint32(max_loop_limit_); return random_generator_->RandomUint32(max_loop_limit_);
} }
@ -196,12 +205,6 @@ class FuzzerContext {
// Ensure that the array size is non-zero. // Ensure that the array size is non-zero.
return random_generator_->RandomUint32(max_new_array_size_limit_ - 1) + 1; return random_generator_->RandomUint32(max_new_array_size_limit_ - 1) + 1;
} }
// Other functions to control transformations. Keep them in alphabetical
// order.
uint32_t GetRandomIndexForAccessChain(uint32_t composite_size_bound) {
return random_generator_->RandomUint32(composite_size_bound);
}
bool GoDeeperInConstantObfuscation(uint32_t depth) { bool GoDeeperInConstantObfuscation(uint32_t depth) {
return go_deeper_in_constant_obfuscation_(depth, random_generator_); return go_deeper_in_constant_obfuscation_(depth, random_generator_);
} }
@ -251,6 +254,7 @@ class FuzzerContext {
// Limits associated with various quantities for which random values are // Limits associated with various quantities for which random values are
// chosen during fuzzing. // chosen during fuzzing.
// Keep them in alphabetical order. // Keep them in alphabetical order.
uint32_t max_equivalence_class_size_for_data_synonym_fact_closure_;
uint32_t max_loop_control_partial_count_; uint32_t max_loop_control_partial_count_;
uint32_t max_loop_control_peel_count_; uint32_t max_loop_control_peel_count_;
uint32_t max_loop_limit_; uint32_t max_loop_limit_;

View File

@ -19,6 +19,7 @@
#include "source/fuzz/id_use_descriptor.h" #include "source/fuzz/id_use_descriptor.h"
#include "source/fuzz/instruction_descriptor.h" #include "source/fuzz/instruction_descriptor.h"
#include "source/fuzz/transformation_composite_extract.h" #include "source/fuzz/transformation_composite_extract.h"
#include "source/fuzz/transformation_compute_data_synonym_fact_closure.h"
#include "source/fuzz/transformation_replace_id_with_synonym.h" #include "source/fuzz/transformation_replace_id_with_synonym.h"
namespace spvtools { namespace spvtools {
@ -34,10 +35,15 @@ FuzzerPassApplyIdSynonyms::FuzzerPassApplyIdSynonyms(
FuzzerPassApplyIdSynonyms::~FuzzerPassApplyIdSynonyms() = default; FuzzerPassApplyIdSynonyms::~FuzzerPassApplyIdSynonyms() = default;
void FuzzerPassApplyIdSynonyms::Apply() { void FuzzerPassApplyIdSynonyms::Apply() {
for (auto id_with_known_synonyms : // Compute a closure of data synonym facts, to enrich the pool of synonyms
GetTransformationContext() // that are available.
ApplyTransformation(TransformationComputeDataSynonymFactClosure(
GetFuzzerContext()
->GetMaximumEquivalenceClassSizeForDataSynonymFactClosure()));
for (auto id_with_known_synonyms : GetTransformationContext()
->GetFactManager() ->GetFactManager()
->GetIdsForWhichSynonymsAreKnown(GetIRContext())) { ->GetIdsForWhichSynonymsAreKnown()) {
// Gather up all uses of |id_with_known_synonym| as a regular id, and // Gather up all uses of |id_with_known_synonym| as a regular id, and
// subsequently iterate over these uses. We use this separation because, // subsequently iterate over these uses. We use this separation because,
// when considering a given use, we might apply a transformation that will // when considering a given use, we might apply a transformation that will
@ -79,7 +85,7 @@ void FuzzerPassApplyIdSynonyms::Apply() {
std::vector<const protobufs::DataDescriptor*> synonyms_to_try; std::vector<const protobufs::DataDescriptor*> synonyms_to_try;
for (auto& data_descriptor : for (auto& data_descriptor :
GetTransformationContext()->GetFactManager()->GetSynonymsForId( GetTransformationContext()->GetFactManager()->GetSynonymsForId(
id_with_known_synonyms, GetIRContext())) { id_with_known_synonyms)) {
protobufs::DataDescriptor descriptor_for_this_id = protobufs::DataDescriptor descriptor_for_this_id =
MakeDataDescriptor(id_with_known_synonyms, {}); MakeDataDescriptor(id_with_known_synonyms, {});
if (DataDescriptorEquals()(data_descriptor, &descriptor_for_this_id)) { if (DataDescriptorEquals()(data_descriptor, &descriptor_for_this_id)) {

View File

@ -373,6 +373,7 @@ message Transformation {
TransformationPermuteFunctionParameters permute_function_parameters = 42; TransformationPermuteFunctionParameters permute_function_parameters = 42;
TransformationToggleAccessChainInstruction toggle_access_chain_instruction = 43; TransformationToggleAccessChainInstruction toggle_access_chain_instruction = 43;
TransformationAddConstantNull add_constant_null = 44; TransformationAddConstantNull add_constant_null = 44;
TransformationComputeDataSynonymFactClosure compute_data_synonym_fact_closure = 45;
// Add additional option using the next available number. // Add additional option using the next available number.
} }
} }
@ -781,6 +782,19 @@ message TransformationCompositeExtract {
} }
message TransformationComputeDataSynonymFactClosure {
// A transformation that impacts the fact manager only, forcing a computation
// of the closure of data synonym facts, so that e.g. if the components of
// vectors v and w are known to be pairwise synonymous, it is deduced that v
// and w are themselves synonymous.
// When searching equivalence classes for implied facts, equivalence classes
// larger than this size will be skipped.
uint32 maximum_equivalence_class_size = 1;
}
message TransformationCopyObject { message TransformationCopyObject {
// A transformation that introduces an OpCopyObject instruction to make a // A transformation that introduces an OpCopyObject instruction to make a

View File

@ -41,6 +41,7 @@
#include "source/fuzz/transformation_add_type_vector.h" #include "source/fuzz/transformation_add_type_vector.h"
#include "source/fuzz/transformation_composite_construct.h" #include "source/fuzz/transformation_composite_construct.h"
#include "source/fuzz/transformation_composite_extract.h" #include "source/fuzz/transformation_composite_extract.h"
#include "source/fuzz/transformation_compute_data_synonym_fact_closure.h"
#include "source/fuzz/transformation_copy_object.h" #include "source/fuzz/transformation_copy_object.h"
#include "source/fuzz/transformation_equation_instruction.h" #include "source/fuzz/transformation_equation_instruction.h"
#include "source/fuzz/transformation_function_call.h" #include "source/fuzz/transformation_function_call.h"
@ -134,6 +135,10 @@ std::unique_ptr<Transformation> Transformation::FromMessage(
case protobufs::Transformation::TransformationCase::kCompositeExtract: case protobufs::Transformation::TransformationCase::kCompositeExtract:
return MakeUnique<TransformationCompositeExtract>( return MakeUnique<TransformationCompositeExtract>(
message.composite_extract()); message.composite_extract());
case protobufs::Transformation::TransformationCase::
kComputeDataSynonymFactClosure:
return MakeUnique<TransformationComputeDataSynonymFactClosure>(
message.compute_data_synonym_fact_closure());
case protobufs::Transformation::TransformationCase::kCopyObject: case protobufs::Transformation::TransformationCase::kCopyObject:
return MakeUnique<TransformationCopyObject>(message.copy_object()); return MakeUnique<TransformationCopyObject>(message.copy_object());
case protobufs::Transformation::TransformationCase::kEquationInstruction: case protobufs::Transformation::TransformationCase::kEquationInstruction:

View File

@ -0,0 +1,52 @@
// Copyright (c) 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "source/fuzz/transformation_compute_data_synonym_fact_closure.h"
namespace spvtools {
namespace fuzz {
TransformationComputeDataSynonymFactClosure::
TransformationComputeDataSynonymFactClosure(
const spvtools::fuzz::protobufs::
TransformationComputeDataSynonymFactClosure& message)
: message_(message) {}
TransformationComputeDataSynonymFactClosure::
TransformationComputeDataSynonymFactClosure(
uint32_t maximum_equivalence_class_size) {
message_.set_maximum_equivalence_class_size(maximum_equivalence_class_size);
}
bool TransformationComputeDataSynonymFactClosure::IsApplicable(
opt::IRContext* /*unused*/, const TransformationContext& /*unused*/) const {
return true;
}
void TransformationComputeDataSynonymFactClosure::Apply(
opt::IRContext* ir_context,
TransformationContext* transformation_context) const {
transformation_context->GetFactManager()->ComputeClosureOfFacts(
ir_context, message_.maximum_equivalence_class_size());
}
protobufs::Transformation
TransformationComputeDataSynonymFactClosure::ToMessage() const {
protobufs::Transformation result;
*result.mutable_compute_data_synonym_fact_closure() = message_;
return result;
}
} // namespace fuzz
} // namespace spvtools

View File

@ -0,0 +1,53 @@
// Copyright (c) 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SOURCE_FUZZ_TRANSFORMATION_COMPUTE_DATA_SYNONYM_FACT_CLOSURE_H_
#define SOURCE_FUZZ_TRANSFORMATION_COMPUTE_DATA_SYNONYM_FACT_CLOSURE_H_
#include "source/fuzz/protobufs/spirvfuzz_protobufs.h"
#include "source/fuzz/transformation.h"
#include "source/fuzz/transformation_context.h"
#include "source/opt/ir_context.h"
namespace spvtools {
namespace fuzz {
class TransformationComputeDataSynonymFactClosure : public Transformation {
public:
explicit TransformationComputeDataSynonymFactClosure(
const protobufs::TransformationComputeDataSynonymFactClosure& message);
explicit TransformationComputeDataSynonymFactClosure(
uint32_t maximum_equivalence_class_size);
// This transformation is trivially applicable.
bool IsApplicable(
opt::IRContext* ir_context,
const TransformationContext& transformation_context) const override;
// Forces the fact manager to compute a closure of data synonym facts, so that
// facts implied by existing facts are deduced.
void Apply(opt::IRContext* ir_context,
TransformationContext* transformation_context) const override;
protobufs::Transformation ToMessage() const override;
private:
protobufs::TransformationComputeDataSynonymFactClosure message_;
};
} // namespace fuzz
} // namespace spvtools
#endif // SOURCE_FUZZ_TRANSFORMATION_COMPUTE_DATA_SYNONYM_FACT_CLOSURE_H_

View File

@ -46,7 +46,7 @@ bool TransformationReplaceIdWithSynonym::IsApplicable(
MakeDataDescriptor(message_.synonymous_id(), {}); MakeDataDescriptor(message_.synonymous_id(), {});
if (!transformation_context.GetFactManager()->IsSynonymous( if (!transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(id_of_interest, {}), MakeDataDescriptor(id_of_interest, {}),
data_descriptor_for_synonymous_id, ir_context)) { data_descriptor_for_synonymous_id)) {
return false; return false;
} }

View File

@ -49,6 +49,7 @@ if (${SPIRV_BUILD_FUZZER})
transformation_add_type_vector_test.cpp transformation_add_type_vector_test.cpp
transformation_composite_construct_test.cpp transformation_composite_construct_test.cpp
transformation_composite_extract_test.cpp transformation_composite_extract_test.cpp
transformation_compute_data_synonym_fact_closure_test.cpp
transformation_copy_object_test.cpp transformation_copy_object_test.cpp
transformation_equation_instruction_test.cpp transformation_equation_instruction_test.cpp
transformation_function_call_test.cpp transformation_function_call_test.cpp

View File

@ -923,6 +923,8 @@ TEST(DataSynonymTransformationTest, VectorCompositeSynonyms) {
100, 100, {0, 1, 2}); 100, 100, {0, 1, 2});
ASSERT_TRUE(shuffle_1.IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(shuffle_1.IsApplicable(context.get(), transformation_context));
shuffle_1.Apply(context.get(), &transformation_context); shuffle_1.Apply(context.get(), &transformation_context);
fact_manager.ComputeClosureOfFacts(context.get(), 100);
auto replacement_1 = TransformationReplaceIdWithSynonym( auto replacement_1 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(20, instruction_descriptor_1, 0), 200); MakeIdUseDescriptor(20, instruction_descriptor_1, 0), 200);
ASSERT_TRUE( ASSERT_TRUE(
@ -951,6 +953,8 @@ TEST(DataSynonymTransformationTest, VectorCompositeSynonyms) {
101, 101, {0, 1}); 101, 101, {0, 1});
ASSERT_TRUE(shuffle_3.IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(shuffle_3.IsApplicable(context.get(), transformation_context));
shuffle_3.Apply(context.get(), &transformation_context); shuffle_3.Apply(context.get(), &transformation_context);
fact_manager.ComputeClosureOfFacts(context.get(), 100);
auto replacement_3 = TransformationReplaceIdWithSynonym( auto replacement_3 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(15, instruction_descriptor_3, 1), 202); MakeIdUseDescriptor(15, instruction_descriptor_3, 1), 202);
ASSERT_TRUE( ASSERT_TRUE(
@ -965,6 +969,8 @@ TEST(DataSynonymTransformationTest, VectorCompositeSynonyms) {
101, 101, {2, 3}); 101, 101, {2, 3});
ASSERT_TRUE(shuffle_4.IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(shuffle_4.IsApplicable(context.get(), transformation_context));
shuffle_4.Apply(context.get(), &transformation_context); shuffle_4.Apply(context.get(), &transformation_context);
fact_manager.ComputeClosureOfFacts(context.get(), 100);
auto replacement_4 = TransformationReplaceIdWithSynonym( auto replacement_4 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(19, instruction_descriptor_4, 0), 203); MakeIdUseDescriptor(19, instruction_descriptor_4, 0), 203);
ASSERT_TRUE( ASSERT_TRUE(
@ -995,6 +1001,8 @@ TEST(DataSynonymTransformationTest, VectorCompositeSynonyms) {
102, 102, {1, 2}); 102, 102, {1, 2});
ASSERT_TRUE(shuffle_6.IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(shuffle_6.IsApplicable(context.get(), transformation_context));
shuffle_6.Apply(context.get(), &transformation_context); shuffle_6.Apply(context.get(), &transformation_context);
fact_manager.ComputeClosureOfFacts(context.get(), 100);
auto replacement_6 = TransformationReplaceIdWithSynonym( auto replacement_6 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(15, instruction_descriptor_6, 0), 205); MakeIdUseDescriptor(15, instruction_descriptor_6, 0), 205);
ASSERT_TRUE( ASSERT_TRUE(
@ -1023,6 +1031,8 @@ TEST(DataSynonymTransformationTest, VectorCompositeSynonyms) {
103, 103, {1, 2, 3}); 103, 103, {1, 2, 3});
ASSERT_TRUE(shuffle_8.IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(shuffle_8.IsApplicable(context.get(), transformation_context));
shuffle_8.Apply(context.get(), &transformation_context); shuffle_8.Apply(context.get(), &transformation_context);
fact_manager.ComputeClosureOfFacts(context.get(), 100);
auto replacement_8 = TransformationReplaceIdWithSynonym( auto replacement_8 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(47, instruction_descriptor_8, 0), 207); MakeIdUseDescriptor(47, instruction_descriptor_8, 0), 207);
ASSERT_TRUE( ASSERT_TRUE(
@ -1064,6 +1074,8 @@ TEST(DataSynonymTransformationTest, VectorCompositeSynonyms) {
105, 105, {0, 1}); 105, 105, {0, 1});
ASSERT_TRUE(shuffle_11.IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(shuffle_11.IsApplicable(context.get(), transformation_context));
shuffle_11.Apply(context.get(), &transformation_context); shuffle_11.Apply(context.get(), &transformation_context);
fact_manager.ComputeClosureOfFacts(context.get(), 100);
auto replacement_11 = TransformationReplaceIdWithSynonym( auto replacement_11 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(38, instruction_descriptor_11, 1), 210); MakeIdUseDescriptor(38, instruction_descriptor_11, 1), 210);
ASSERT_TRUE( ASSERT_TRUE(

View File

@ -738,393 +738,6 @@ TEST(FactManagerTest, AmbiguousFact) {
uniform_buffer_element_descriptor)); uniform_buffer_element_descriptor));
} }
TEST(FactManagerTest, DataSynonymFacts) {
// The SPIR-V types and constants come from the following code. The body of
// the SPIR-V function then constructs a composite that is synonymous with
// myT.
//
// #version 310 es
//
// precision highp float;
//
// struct S {
// int a;
// uvec2 b;
// };
//
// struct T {
// bool c[5];
// mat4x2 d;
// S e;
// };
//
// void main() {
// T myT = T(bool[5](true, false, true, false, true),
// mat4x2(vec2(1.0, 2.0), vec2(3.0, 4.0),
// vec2(5.0, 6.0), vec2(7.0, 8.0)),
// S(10, uvec2(100u, 200u)));
// }
std::string shader = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main"
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
OpName %15 "S"
OpMemberName %15 0 "a"
OpMemberName %15 1 "b"
OpName %16 "T"
OpMemberName %16 0 "c"
OpMemberName %16 1 "d"
OpMemberName %16 2 "e"
OpName %18 "myT"
OpMemberDecorate %15 0 RelaxedPrecision
OpMemberDecorate %15 1 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeBool
%7 = OpTypeInt 32 0
%8 = OpConstant %7 5
%9 = OpTypeArray %6 %8
%10 = OpTypeFloat 32
%11 = OpTypeVector %10 2
%12 = OpTypeMatrix %11 4
%13 = OpTypeInt 32 1
%14 = OpTypeVector %7 2
%15 = OpTypeStruct %13 %14
%16 = OpTypeStruct %9 %12 %15
%17 = OpTypePointer Function %16
%19 = OpConstantTrue %6
%20 = OpConstantFalse %6
%21 = OpConstantComposite %9 %19 %20 %19 %20 %19
%22 = OpConstant %10 1
%23 = OpConstant %10 2
%24 = OpConstantComposite %11 %22 %23
%25 = OpConstant %10 3
%26 = OpConstant %10 4
%27 = OpConstantComposite %11 %25 %26
%28 = OpConstant %10 5
%29 = OpConstant %10 6
%30 = OpConstantComposite %11 %28 %29
%31 = OpConstant %10 7
%32 = OpConstant %10 8
%33 = OpConstantComposite %11 %31 %32
%34 = OpConstantComposite %12 %24 %27 %30 %33
%35 = OpConstant %13 10
%36 = OpConstant %7 100
%37 = OpConstant %7 200
%38 = OpConstantComposite %14 %36 %37
%39 = OpConstantComposite %15 %35 %38
%40 = OpConstantComposite %16 %21 %34 %39
%4 = OpFunction %2 None %3
%5 = OpLabel
%18 = OpVariable %17 Function
OpStore %18 %40
%100 = OpCompositeConstruct %9 %19 %20 %19 %20 %19
%101 = OpCompositeConstruct %11 %22 %23
%102 = OpCompositeConstruct %11 %25 %26
%103 = OpCompositeConstruct %11 %28 %29
%104 = OpCompositeConstruct %11 %31 %32
%105 = OpCompositeConstruct %12 %101 %102 %103 %104
%106 = OpCompositeConstruct %14 %36 %37
%107 = OpCompositeConstruct %15 %35 %106
%108 = OpCompositeConstruct %16 %100 %105 %107
OpReturn
OpFunctionEnd
)";
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto consumer = nullptr;
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
ASSERT_FALSE(fact_manager.IsSynonymous(
MakeDataDescriptor(24, {}), MakeDataDescriptor(101, {}), context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {0}),
MakeDataDescriptor(101, {0}),
context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {1}),
MakeDataDescriptor(101, {1}),
context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {0}),
MakeDataDescriptor(101, {1}),
context.get()));
fact_manager.AddFactDataSynonym(MakeDataDescriptor(24, {}),
MakeDataDescriptor(101, {}), context.get());
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(24, {}), MakeDataDescriptor(101, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {0}),
MakeDataDescriptor(101, {0}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {1}),
MakeDataDescriptor(101, {1}),
context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {0}),
MakeDataDescriptor(101, {1}),
context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(
MakeDataDescriptor(27, {}), MakeDataDescriptor(102, {}), context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {0}),
MakeDataDescriptor(102, {0}),
context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {1}),
MakeDataDescriptor(102, {1}),
context.get()));
fact_manager.AddFactDataSynonym(MakeDataDescriptor(27, {0}),
MakeDataDescriptor(102, {0}), context.get());
ASSERT_FALSE(fact_manager.IsSynonymous(
MakeDataDescriptor(27, {}), MakeDataDescriptor(102, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {0}),
MakeDataDescriptor(102, {0}),
context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {1}),
MakeDataDescriptor(102, {1}),
context.get()));
fact_manager.AddFactDataSynonym(MakeDataDescriptor(27, {1}),
MakeDataDescriptor(102, {1}), context.get());
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(27, {}), MakeDataDescriptor(102, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {0}),
MakeDataDescriptor(102, {0}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {1}),
MakeDataDescriptor(102, {1}),
context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(
MakeDataDescriptor(30, {}), MakeDataDescriptor(103, {}), context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(30, {0}),
MakeDataDescriptor(103, {0}),
context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(30, {1}),
MakeDataDescriptor(103, {1}),
context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(
MakeDataDescriptor(33, {}), MakeDataDescriptor(104, {}), context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {0}),
MakeDataDescriptor(104, {0}),
context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {1}),
MakeDataDescriptor(104, {1}),
context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(
MakeDataDescriptor(34, {}), MakeDataDescriptor(105, {}), context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {0}),
MakeDataDescriptor(105, {0}),
context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {1}),
MakeDataDescriptor(105, {1}),
context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {2}),
MakeDataDescriptor(105, {2}),
context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {3}),
MakeDataDescriptor(105, {3}),
context.get()));
fact_manager.AddFactDataSynonym(MakeDataDescriptor(30, {}),
MakeDataDescriptor(103, {}), context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(33, {}),
MakeDataDescriptor(104, {}), context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(34, {0}),
MakeDataDescriptor(105, {0}), context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(34, {1}),
MakeDataDescriptor(105, {1}), context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(34, {2}),
MakeDataDescriptor(105, {2}), context.get());
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(30, {}), MakeDataDescriptor(103, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(30, {0}),
MakeDataDescriptor(103, {0}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(30, {1}),
MakeDataDescriptor(103, {1}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(33, {}), MakeDataDescriptor(104, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {0}),
MakeDataDescriptor(104, {0}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {1}),
MakeDataDescriptor(104, {1}),
context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(
MakeDataDescriptor(34, {}), MakeDataDescriptor(105, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {0}),
MakeDataDescriptor(105, {0}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {1}),
MakeDataDescriptor(105, {1}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {2}),
MakeDataDescriptor(105, {2}),
context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {3}),
MakeDataDescriptor(105, {3}),
context.get()));
fact_manager.AddFactDataSynonym(MakeDataDescriptor(34, {3}),
MakeDataDescriptor(105, {3}), context.get());
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {0}),
MakeDataDescriptor(104, {0}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {3}),
MakeDataDescriptor(105, {3}),
context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(
MakeDataDescriptor(21, {}), MakeDataDescriptor(100, {}), context.get()));
fact_manager.AddFactDataSynonym(MakeDataDescriptor(21, {0}),
MakeDataDescriptor(100, {0}), context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(21, {1}),
MakeDataDescriptor(100, {1}), context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(21, {2}),
MakeDataDescriptor(100, {2}), context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(21, {3}),
MakeDataDescriptor(100, {3}), context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(21, {4}),
MakeDataDescriptor(100, {4}), context.get());
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(21, {}), MakeDataDescriptor(100, {}), context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(39, {0}),
MakeDataDescriptor(107, {0}),
context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(
MakeDataDescriptor(35, {}), MakeDataDescriptor(39, {0}), context.get()));
fact_manager.AddFactDataSynonym(MakeDataDescriptor(39, {0}),
MakeDataDescriptor(35, {}), context.get());
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(39, {0}),
MakeDataDescriptor(107, {0}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(35, {}), MakeDataDescriptor(39, {0}), context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(
MakeDataDescriptor(38, {0}), MakeDataDescriptor(36, {}), context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(
MakeDataDescriptor(38, {1}), MakeDataDescriptor(37, {}), context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(
MakeDataDescriptor(106, {0}), MakeDataDescriptor(36, {}), context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(
MakeDataDescriptor(106, {1}), MakeDataDescriptor(37, {}), context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(
MakeDataDescriptor(38, {}), MakeDataDescriptor(106, {}), context.get()));
fact_manager.AddFactDataSynonym(MakeDataDescriptor(38, {0}),
MakeDataDescriptor(36, {}), context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(106, {0}),
MakeDataDescriptor(36, {}), context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(38, {1}),
MakeDataDescriptor(37, {}), context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(106, {1}),
MakeDataDescriptor(37, {}), context.get());
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(38, {0}), MakeDataDescriptor(36, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(38, {1}), MakeDataDescriptor(37, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(106, {0}), MakeDataDescriptor(36, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(106, {1}), MakeDataDescriptor(37, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(38, {}), MakeDataDescriptor(106, {}), context.get()));
ASSERT_FALSE(fact_manager.IsSynonymous(
MakeDataDescriptor(40, {}), MakeDataDescriptor(108, {}), context.get()));
fact_manager.AddFactDataSynonym(MakeDataDescriptor(107, {0}),
MakeDataDescriptor(35, {}), context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(40, {0}),
MakeDataDescriptor(108, {0}), context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(40, {1}),
MakeDataDescriptor(108, {1}), context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(40, {2}),
MakeDataDescriptor(108, {2}), context.get());
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(40, {}), MakeDataDescriptor(108, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0}),
MakeDataDescriptor(108, {0}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1}),
MakeDataDescriptor(108, {1}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {2}),
MakeDataDescriptor(108, {2}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0, 0}),
MakeDataDescriptor(108, {0, 0}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0, 1}),
MakeDataDescriptor(108, {0, 1}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0, 2}),
MakeDataDescriptor(108, {0, 2}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0, 3}),
MakeDataDescriptor(108, {0, 3}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0, 4}),
MakeDataDescriptor(108, {0, 4}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 0}),
MakeDataDescriptor(108, {1, 0}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 1}),
MakeDataDescriptor(108, {1, 1}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 2}),
MakeDataDescriptor(108, {1, 2}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 3}),
MakeDataDescriptor(108, {1, 3}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 0, 0}),
MakeDataDescriptor(108, {1, 0, 0}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 1, 0}),
MakeDataDescriptor(108, {1, 1, 0}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 2, 0}),
MakeDataDescriptor(108, {1, 2, 0}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 3, 0}),
MakeDataDescriptor(108, {1, 3, 0}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 0, 1}),
MakeDataDescriptor(108, {1, 0, 1}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 1, 1}),
MakeDataDescriptor(108, {1, 1, 1}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 2, 1}),
MakeDataDescriptor(108, {1, 2, 1}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 3, 1}),
MakeDataDescriptor(108, {1, 3, 1}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {2, 0}),
MakeDataDescriptor(108, {2, 0}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {2, 1}),
MakeDataDescriptor(108, {2, 1}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {2, 1, 0}),
MakeDataDescriptor(108, {2, 1, 0}),
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {2, 1, 1}),
MakeDataDescriptor(108, {2, 1, 1}),
context.get()));
}
TEST(FactManagerTest, RecursiveAdditionOfFacts) { TEST(FactManagerTest, RecursiveAdditionOfFacts) {
std::string shader = R"( std::string shader = R"(
OpCapability Shader OpCapability Shader
@ -1157,20 +770,16 @@ TEST(FactManagerTest, RecursiveAdditionOfFacts) {
fact_manager.AddFactDataSynonym(MakeDataDescriptor(10, {}), fact_manager.AddFactDataSynonym(MakeDataDescriptor(10, {}),
MakeDataDescriptor(11, {2}), context.get()); MakeDataDescriptor(11, {2}), context.get());
ASSERT_TRUE(fact_manager.IsSynonymous( ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(10, {}),
MakeDataDescriptor(10, {}), MakeDataDescriptor(11, {2}), context.get())); MakeDataDescriptor(11, {2})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(10, {0}), ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(10, {0}),
MakeDataDescriptor(11, {2, 0}), MakeDataDescriptor(11, {2, 0})));
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(10, {1}), ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(10, {1}),
MakeDataDescriptor(11, {2, 1}), MakeDataDescriptor(11, {2, 1})));
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(10, {2}), ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(10, {2}),
MakeDataDescriptor(11, {2, 2}), MakeDataDescriptor(11, {2, 2})));
context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(10, {3}), ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(10, {3}),
MakeDataDescriptor(11, {2, 3}), MakeDataDescriptor(11, {2, 3})));
context.get()));
} }
TEST(FactManagerTest, LogicalNotEquationFacts) { TEST(FactManagerTest, LogicalNotEquationFacts) {
@ -1209,14 +818,14 @@ TEST(FactManagerTest, LogicalNotEquationFacts) {
fact_manager.AddFactIdEquation(14, SpvOpLogicalNot, {7}, context.get()); fact_manager.AddFactIdEquation(14, SpvOpLogicalNot, {7}, context.get());
fact_manager.AddFactIdEquation(17, SpvOpLogicalNot, {16}, context.get()); fact_manager.AddFactIdEquation(17, SpvOpLogicalNot, {16}, context.get());
ASSERT_TRUE(fact_manager.IsSynonymous( ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(15, {}),
MakeDataDescriptor(15, {}), MakeDataDescriptor(7, {}), context.get())); MakeDataDescriptor(7, {})));
ASSERT_TRUE(fact_manager.IsSynonymous( ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(17, {}),
MakeDataDescriptor(17, {}), MakeDataDescriptor(7, {}), context.get())); MakeDataDescriptor(7, {})));
ASSERT_TRUE(fact_manager.IsSynonymous( ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(15, {}),
MakeDataDescriptor(15, {}), MakeDataDescriptor(17, {}), context.get())); MakeDataDescriptor(17, {})));
ASSERT_TRUE(fact_manager.IsSynonymous( ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(16, {}),
MakeDataDescriptor(16, {}), MakeDataDescriptor(14, {}), context.get())); MakeDataDescriptor(14, {})));
} }
TEST(FactManagerTest, SignedNegateEquationFacts) { TEST(FactManagerTest, SignedNegateEquationFacts) {
@ -1249,8 +858,8 @@ TEST(FactManagerTest, SignedNegateEquationFacts) {
fact_manager.AddFactIdEquation(14, SpvOpSNegate, {7}, context.get()); fact_manager.AddFactIdEquation(14, SpvOpSNegate, {7}, context.get());
fact_manager.AddFactIdEquation(15, SpvOpSNegate, {14}, context.get()); fact_manager.AddFactIdEquation(15, SpvOpSNegate, {14}, context.get());
ASSERT_TRUE(fact_manager.IsSynonymous( ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(7, {}),
MakeDataDescriptor(7, {}), MakeDataDescriptor(15, {}), context.get())); MakeDataDescriptor(15, {})));
} }
TEST(FactManagerTest, AddSubNegateFacts1) { TEST(FactManagerTest, AddSubNegateFacts1) {
@ -1302,12 +911,12 @@ TEST(FactManagerTest, AddSubNegateFacts1) {
MakeDataDescriptor(22, {}), context.get()); MakeDataDescriptor(22, {}), context.get());
fact_manager.AddFactIdEquation(24, SpvOpSNegate, {23}, context.get()); fact_manager.AddFactIdEquation(24, SpvOpSNegate, {23}, context.get());
ASSERT_TRUE(fact_manager.IsSynonymous( ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(19, {}),
MakeDataDescriptor(19, {}), MakeDataDescriptor(15, {}), context.get())); MakeDataDescriptor(15, {})));
ASSERT_TRUE(fact_manager.IsSynonymous( ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(20, {}),
MakeDataDescriptor(20, {}), MakeDataDescriptor(16, {}), context.get())); MakeDataDescriptor(16, {})));
ASSERT_TRUE(fact_manager.IsSynonymous( ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {}),
MakeDataDescriptor(24, {}), MakeDataDescriptor(15, {}), context.get())); MakeDataDescriptor(15, {})));
} }
TEST(FactManagerTest, AddSubNegateFacts2) { TEST(FactManagerTest, AddSubNegateFacts2) {
@ -1347,30 +956,30 @@ TEST(FactManagerTest, AddSubNegateFacts2) {
fact_manager.AddFactIdEquation(14, SpvOpISub, {15, 16}, context.get()); fact_manager.AddFactIdEquation(14, SpvOpISub, {15, 16}, context.get());
fact_manager.AddFactIdEquation(17, SpvOpIAdd, {14, 16}, context.get()); fact_manager.AddFactIdEquation(17, SpvOpIAdd, {14, 16}, context.get());
ASSERT_TRUE(fact_manager.IsSynonymous( ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(17, {}),
MakeDataDescriptor(17, {}), MakeDataDescriptor(15, {}), context.get())); MakeDataDescriptor(15, {})));
fact_manager.AddFactIdEquation(18, SpvOpIAdd, {16, 14}, context.get()); fact_manager.AddFactIdEquation(18, SpvOpIAdd, {16, 14}, context.get());
ASSERT_TRUE(fact_manager.IsSynonymous( ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(18, {}),
MakeDataDescriptor(18, {}), MakeDataDescriptor(15, {}), context.get())); MakeDataDescriptor(15, {})));
ASSERT_TRUE(fact_manager.IsSynonymous( ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(17, {}),
MakeDataDescriptor(17, {}), MakeDataDescriptor(18, {}), context.get())); MakeDataDescriptor(18, {})));
fact_manager.AddFactIdEquation(19, SpvOpISub, {14, 15}, context.get()); fact_manager.AddFactIdEquation(19, SpvOpISub, {14, 15}, context.get());
fact_manager.AddFactIdEquation(20, SpvOpSNegate, {19}, context.get()); fact_manager.AddFactIdEquation(20, SpvOpSNegate, {19}, context.get());
ASSERT_TRUE(fact_manager.IsSynonymous( ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(20, {}),
MakeDataDescriptor(20, {}), MakeDataDescriptor(16, {}), context.get())); MakeDataDescriptor(16, {})));
fact_manager.AddFactIdEquation(21, SpvOpISub, {14, 19}, context.get()); fact_manager.AddFactIdEquation(21, SpvOpISub, {14, 19}, context.get());
ASSERT_TRUE(fact_manager.IsSynonymous( ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(21, {}),
MakeDataDescriptor(21, {}), MakeDataDescriptor(15, {}), context.get())); MakeDataDescriptor(15, {})));
fact_manager.AddFactIdEquation(22, SpvOpISub, {14, 18}, context.get()); fact_manager.AddFactIdEquation(22, SpvOpISub, {14, 18}, context.get());
fact_manager.AddFactIdEquation(23, SpvOpSNegate, {22}, context.get()); fact_manager.AddFactIdEquation(23, SpvOpSNegate, {22}, context.get());
ASSERT_TRUE(fact_manager.IsSynonymous( ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(23, {}),
MakeDataDescriptor(23, {}), MakeDataDescriptor(16, {}), context.get())); MakeDataDescriptor(16, {})));
} }
TEST(FactManagerTest, EquationAndEquivalenceFacts) { TEST(FactManagerTest, EquationAndEquivalenceFacts) {
@ -1415,34 +1024,34 @@ TEST(FactManagerTest, EquationAndEquivalenceFacts) {
MakeDataDescriptor(14, {}), context.get()); MakeDataDescriptor(14, {}), context.get());
fact_manager.AddFactIdEquation(17, SpvOpIAdd, {114, 16}, context.get()); fact_manager.AddFactIdEquation(17, SpvOpIAdd, {114, 16}, context.get());
ASSERT_TRUE(fact_manager.IsSynonymous( ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(17, {}),
MakeDataDescriptor(17, {}), MakeDataDescriptor(15, {}), context.get())); MakeDataDescriptor(15, {})));
fact_manager.AddFactIdEquation(18, SpvOpIAdd, {16, 114}, context.get()); fact_manager.AddFactIdEquation(18, SpvOpIAdd, {16, 114}, context.get());
ASSERT_TRUE(fact_manager.IsSynonymous( ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(18, {}),
MakeDataDescriptor(18, {}), MakeDataDescriptor(15, {}), context.get())); MakeDataDescriptor(15, {})));
ASSERT_TRUE(fact_manager.IsSynonymous( ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(17, {}),
MakeDataDescriptor(17, {}), MakeDataDescriptor(18, {}), context.get())); MakeDataDescriptor(18, {})));
fact_manager.AddFactIdEquation(19, SpvOpISub, {14, 15}, context.get()); fact_manager.AddFactIdEquation(19, SpvOpISub, {14, 15}, context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(119, {}), fact_manager.AddFactDataSynonym(MakeDataDescriptor(119, {}),
MakeDataDescriptor(19, {}), context.get()); MakeDataDescriptor(19, {}), context.get());
fact_manager.AddFactIdEquation(20, SpvOpSNegate, {119}, context.get()); fact_manager.AddFactIdEquation(20, SpvOpSNegate, {119}, context.get());
ASSERT_TRUE(fact_manager.IsSynonymous( ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(20, {}),
MakeDataDescriptor(20, {}), MakeDataDescriptor(16, {}), context.get())); MakeDataDescriptor(16, {})));
fact_manager.AddFactIdEquation(21, SpvOpISub, {14, 19}, context.get()); fact_manager.AddFactIdEquation(21, SpvOpISub, {14, 19}, context.get());
ASSERT_TRUE(fact_manager.IsSynonymous( ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(21, {}),
MakeDataDescriptor(21, {}), MakeDataDescriptor(15, {}), context.get())); MakeDataDescriptor(15, {})));
fact_manager.AddFactIdEquation(22, SpvOpISub, {14, 18}, context.get()); fact_manager.AddFactIdEquation(22, SpvOpISub, {14, 18}, context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(22, {}), fact_manager.AddFactDataSynonym(MakeDataDescriptor(22, {}),
MakeDataDescriptor(220, {}), context.get()); MakeDataDescriptor(220, {}), context.get());
fact_manager.AddFactIdEquation(23, SpvOpSNegate, {220}, context.get()); fact_manager.AddFactIdEquation(23, SpvOpSNegate, {220}, context.get());
ASSERT_TRUE(fact_manager.IsSynonymous( ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(23, {}),
MakeDataDescriptor(23, {}), MakeDataDescriptor(16, {}), context.get())); MakeDataDescriptor(16, {})));
} }
} // namespace } // namespace

View File

@ -148,11 +148,11 @@ TEST(TransformationCompositeConstructTest, ConstructArrays) {
make_vec2_array_length_3.Apply(context.get(), &transformation_context); make_vec2_array_length_3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(41, {}), MakeDataDescriptor(200, {0}), context.get())); MakeDataDescriptor(41, {}), MakeDataDescriptor(200, {0})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(45, {}), MakeDataDescriptor(200, {1}), context.get())); MakeDataDescriptor(45, {}), MakeDataDescriptor(200, {1})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(27, {}), MakeDataDescriptor(200, {2}), context.get())); MakeDataDescriptor(27, {}), MakeDataDescriptor(200, {2})));
// Make a float[2] // Make a float[2]
TransformationCompositeConstruct make_float_array_length_2( TransformationCompositeConstruct make_float_array_length_2(
@ -167,9 +167,9 @@ TEST(TransformationCompositeConstructTest, ConstructArrays) {
make_float_array_length_2.Apply(context.get(), &transformation_context); make_float_array_length_2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(24, {}), MakeDataDescriptor(201, {0}), context.get())); MakeDataDescriptor(24, {}), MakeDataDescriptor(201, {0})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(40, {}), MakeDataDescriptor(201, {1}), context.get())); MakeDataDescriptor(40, {}), MakeDataDescriptor(201, {1})));
// Make a bool[3] // Make a bool[3]
TransformationCompositeConstruct make_bool_array_length_3( TransformationCompositeConstruct make_bool_array_length_3(
@ -186,11 +186,11 @@ TEST(TransformationCompositeConstructTest, ConstructArrays) {
make_bool_array_length_3.Apply(context.get(), &transformation_context); make_bool_array_length_3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(33, {}), MakeDataDescriptor(202, {0}), context.get())); MakeDataDescriptor(33, {}), MakeDataDescriptor(202, {0})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(50, {}), MakeDataDescriptor(202, {1}), context.get())); MakeDataDescriptor(50, {}), MakeDataDescriptor(202, {1})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(50, {}), MakeDataDescriptor(202, {2}), context.get())); MakeDataDescriptor(50, {}), MakeDataDescriptor(202, {2})));
// make a uvec3[2][2] // make a uvec3[2][2]
TransformationCompositeConstruct make_uvec3_array_length_2_2( TransformationCompositeConstruct make_uvec3_array_length_2_2(
@ -205,10 +205,9 @@ TEST(TransformationCompositeConstructTest, ConstructArrays) {
make_uvec3_array_length_2_2.Apply(context.get(), &transformation_context); make_uvec3_array_length_2_2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(69, {}), MakeDataDescriptor(203, {0}), context.get())); MakeDataDescriptor(69, {}), MakeDataDescriptor(203, {0})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(100, {}), MakeDataDescriptor(203, {1}), MakeDataDescriptor(100, {}), MakeDataDescriptor(203, {1})));
context.get()));
std::string after_transformation = R"( std::string after_transformation = R"(
OpCapability Shader OpCapability Shader
@ -412,11 +411,11 @@ TEST(TransformationCompositeConstructTest, ConstructMatrices) {
make_mat34.Apply(context.get(), &transformation_context); make_mat34.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(25, {}), MakeDataDescriptor(200, {0}), context.get())); MakeDataDescriptor(25, {}), MakeDataDescriptor(200, {0})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(28, {}), MakeDataDescriptor(200, {1}), context.get())); MakeDataDescriptor(28, {}), MakeDataDescriptor(200, {1})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(31, {}), MakeDataDescriptor(200, {2}), context.get())); MakeDataDescriptor(31, {}), MakeDataDescriptor(200, {2})));
// make a mat4x3 // make a mat4x3
TransformationCompositeConstruct make_mat43( TransformationCompositeConstruct make_mat43(
@ -430,14 +429,13 @@ TEST(TransformationCompositeConstructTest, ConstructMatrices) {
make_mat43.Apply(context.get(), &transformation_context); make_mat43.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(11, {}), MakeDataDescriptor(201, {0}), context.get())); MakeDataDescriptor(11, {}), MakeDataDescriptor(201, {0})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(13, {}), MakeDataDescriptor(201, {1}), context.get())); MakeDataDescriptor(13, {}), MakeDataDescriptor(201, {1})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(16, {}), MakeDataDescriptor(201, {2}), context.get())); MakeDataDescriptor(16, {}), MakeDataDescriptor(201, {2})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(100, {}), MakeDataDescriptor(201, {3}), MakeDataDescriptor(100, {}), MakeDataDescriptor(201, {3})));
context.get()));
std::string after_transformation = R"( std::string after_transformation = R"(
OpCapability Shader OpCapability Shader
@ -626,9 +624,9 @@ TEST(TransformationCompositeConstructTest, ConstructStructs) {
make_inner.Apply(context.get(), &transformation_context); make_inner.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(25, {}), MakeDataDescriptor(200, {0}), context.get())); MakeDataDescriptor(25, {}), MakeDataDescriptor(200, {0})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(19, {}), MakeDataDescriptor(200, {1}), context.get())); MakeDataDescriptor(19, {}), MakeDataDescriptor(200, {1})));
// make an Outer // make an Outer
TransformationCompositeConstruct make_outer( TransformationCompositeConstruct make_outer(
@ -644,12 +642,11 @@ TEST(TransformationCompositeConstructTest, ConstructStructs) {
make_outer.Apply(context.get(), &transformation_context); make_outer.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(46, {}), MakeDataDescriptor(201, {0}), context.get())); MakeDataDescriptor(46, {}), MakeDataDescriptor(201, {0})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(200, {}), MakeDataDescriptor(201, {1}), MakeDataDescriptor(200, {}), MakeDataDescriptor(201, {1})));
context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(56, {}), MakeDataDescriptor(201, {2}), context.get())); MakeDataDescriptor(56, {}), MakeDataDescriptor(201, {2})));
std::string after_transformation = R"( std::string after_transformation = R"(
OpCapability Shader OpCapability Shader
@ -950,9 +947,9 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) {
make_vec2.Apply(context.get(), &transformation_context); make_vec2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(17, {}), MakeDataDescriptor(200, {0}), context.get())); MakeDataDescriptor(17, {}), MakeDataDescriptor(200, {0})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(11, {}), MakeDataDescriptor(200, {1}), context.get())); MakeDataDescriptor(11, {}), MakeDataDescriptor(200, {1})));
TransformationCompositeConstruct make_vec3( TransformationCompositeConstruct make_vec3(
25, {12, 32}, MakeInstructionDescriptor(35, SpvOpCompositeConstruct, 0), 25, {12, 32}, MakeInstructionDescriptor(35, SpvOpCompositeConstruct, 0),
@ -967,13 +964,11 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) {
make_vec3.Apply(context.get(), &transformation_context); make_vec3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(12, {0}), MakeDataDescriptor(201, {0}), MakeDataDescriptor(12, {0}), MakeDataDescriptor(201, {0})));
context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(12, {1}), MakeDataDescriptor(201, {1}), MakeDataDescriptor(12, {1}), MakeDataDescriptor(201, {1})));
context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(32, {}), MakeDataDescriptor(201, {2}), context.get())); MakeDataDescriptor(32, {}), MakeDataDescriptor(201, {2})));
TransformationCompositeConstruct make_vec4( TransformationCompositeConstruct make_vec4(
44, {32, 32, 10, 11}, MakeInstructionDescriptor(75, SpvOpAccessChain, 0), 44, {32, 32, 10, 11}, MakeInstructionDescriptor(75, SpvOpAccessChain, 0),
@ -988,13 +983,13 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) {
make_vec4.Apply(context.get(), &transformation_context); make_vec4.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(32, {}), MakeDataDescriptor(202, {0}), context.get())); MakeDataDescriptor(32, {}), MakeDataDescriptor(202, {0})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(32, {}), MakeDataDescriptor(202, {1}), context.get())); MakeDataDescriptor(32, {}), MakeDataDescriptor(202, {1})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(10, {}), MakeDataDescriptor(202, {2}), context.get())); MakeDataDescriptor(10, {}), MakeDataDescriptor(202, {2})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(11, {}), MakeDataDescriptor(202, {3}), context.get())); MakeDataDescriptor(11, {}), MakeDataDescriptor(202, {3})));
TransformationCompositeConstruct make_ivec2( TransformationCompositeConstruct make_ivec2(
51, {126, 120}, MakeInstructionDescriptor(128, SpvOpLoad, 0), 203); 51, {126, 120}, MakeInstructionDescriptor(128, SpvOpLoad, 0), 203);
@ -1007,11 +1002,9 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) {
make_ivec2.Apply(context.get(), &transformation_context); make_ivec2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(126, {}), MakeDataDescriptor(203, {0}), MakeDataDescriptor(126, {}), MakeDataDescriptor(203, {0})));
context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(120, {}), MakeDataDescriptor(203, {1}), MakeDataDescriptor(120, {}), MakeDataDescriptor(203, {1})));
context.get()));
TransformationCompositeConstruct make_ivec3( TransformationCompositeConstruct make_ivec3(
114, {56, 117, 56}, MakeInstructionDescriptor(66, SpvOpAccessChain, 0), 114, {56, 117, 56}, MakeInstructionDescriptor(66, SpvOpAccessChain, 0),
@ -1026,12 +1019,11 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) {
make_ivec3.Apply(context.get(), &transformation_context); make_ivec3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(56, {}), MakeDataDescriptor(204, {0}), context.get())); MakeDataDescriptor(56, {}), MakeDataDescriptor(204, {0})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(117, {}), MakeDataDescriptor(204, {1}), MakeDataDescriptor(117, {}), MakeDataDescriptor(204, {1})));
context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(56, {}), MakeDataDescriptor(204, {2}), context.get())); MakeDataDescriptor(56, {}), MakeDataDescriptor(204, {2})));
TransformationCompositeConstruct make_ivec4( TransformationCompositeConstruct make_ivec4(
122, {56, 117, 117, 117}, MakeInstructionDescriptor(66, SpvOpIAdd, 0), 122, {56, 117, 117, 117}, MakeInstructionDescriptor(66, SpvOpIAdd, 0),
@ -1046,16 +1038,13 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) {
make_ivec4.Apply(context.get(), &transformation_context); make_ivec4.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(56, {}), MakeDataDescriptor(205, {0}), context.get())); MakeDataDescriptor(56, {}), MakeDataDescriptor(205, {0})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(117, {}), MakeDataDescriptor(205, {1}), MakeDataDescriptor(117, {}), MakeDataDescriptor(205, {1})));
context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(117, {}), MakeDataDescriptor(205, {2}), MakeDataDescriptor(117, {}), MakeDataDescriptor(205, {2})));
context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(117, {}), MakeDataDescriptor(205, {3}), MakeDataDescriptor(117, {}), MakeDataDescriptor(205, {3})));
context.get()));
TransformationCompositeConstruct make_uvec2( TransformationCompositeConstruct make_uvec2(
86, {18, 38}, MakeInstructionDescriptor(133, SpvOpAccessChain, 0), 206); 86, {18, 38}, MakeInstructionDescriptor(133, SpvOpAccessChain, 0), 206);
@ -1067,9 +1056,9 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) {
make_uvec2.Apply(context.get(), &transformation_context); make_uvec2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(18, {}), MakeDataDescriptor(206, {0}), context.get())); MakeDataDescriptor(18, {}), MakeDataDescriptor(206, {0})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(38, {}), MakeDataDescriptor(206, {1}), context.get())); MakeDataDescriptor(38, {}), MakeDataDescriptor(206, {1})));
TransformationCompositeConstruct make_uvec3( TransformationCompositeConstruct make_uvec3(
59, {14, 18, 136}, MakeInstructionDescriptor(137, SpvOpReturn, 0), 207); 59, {14, 18, 136}, MakeInstructionDescriptor(137, SpvOpReturn, 0), 207);
@ -1082,12 +1071,11 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) {
make_uvec3.Apply(context.get(), &transformation_context); make_uvec3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(14, {}), MakeDataDescriptor(207, {0}), context.get())); MakeDataDescriptor(14, {}), MakeDataDescriptor(207, {0})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(18, {}), MakeDataDescriptor(207, {1}), context.get())); MakeDataDescriptor(18, {}), MakeDataDescriptor(207, {1})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(136, {}), MakeDataDescriptor(207, {2}), MakeDataDescriptor(136, {}), MakeDataDescriptor(207, {2})));
context.get()));
TransformationCompositeConstruct make_uvec4( TransformationCompositeConstruct make_uvec4(
131, {14, 18, 136, 136}, 131, {14, 18, 136, 136},
@ -1102,15 +1090,13 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) {
make_uvec4.Apply(context.get(), &transformation_context); make_uvec4.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(14, {}), MakeDataDescriptor(208, {0}), context.get())); MakeDataDescriptor(14, {}), MakeDataDescriptor(208, {0})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(18, {}), MakeDataDescriptor(208, {1}), context.get())); MakeDataDescriptor(18, {}), MakeDataDescriptor(208, {1})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(136, {}), MakeDataDescriptor(208, {2}), MakeDataDescriptor(136, {}), MakeDataDescriptor(208, {2})));
context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(136, {}), MakeDataDescriptor(208, {3}), MakeDataDescriptor(136, {}), MakeDataDescriptor(208, {3})));
context.get()));
TransformationCompositeConstruct make_bvec2( TransformationCompositeConstruct make_bvec2(
102, 102,
@ -1133,10 +1119,9 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) {
make_bvec2.Apply(context.get(), &transformation_context); make_bvec2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(111, {}), MakeDataDescriptor(209, {0}), MakeDataDescriptor(111, {}), MakeDataDescriptor(209, {0})));
context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(41, {}), MakeDataDescriptor(209, {1}), context.get())); MakeDataDescriptor(41, {}), MakeDataDescriptor(209, {1})));
TransformationCompositeConstruct make_bvec3( TransformationCompositeConstruct make_bvec3(
93, {108, 73}, MakeInstructionDescriptor(108, SpvOpStore, 0), 210); 93, {108, 73}, MakeInstructionDescriptor(108, SpvOpStore, 0), 210);
@ -1149,13 +1134,11 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) {
make_bvec3.Apply(context.get(), &transformation_context); make_bvec3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(108, {0}), MakeDataDescriptor(210, {0}), MakeDataDescriptor(108, {0}), MakeDataDescriptor(210, {0})));
context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(108, {1}), MakeDataDescriptor(210, {1}), MakeDataDescriptor(108, {1}), MakeDataDescriptor(210, {1})));
context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(73, {}), MakeDataDescriptor(210, {2}), context.get())); MakeDataDescriptor(73, {}), MakeDataDescriptor(210, {2})));
TransformationCompositeConstruct make_bvec4( TransformationCompositeConstruct make_bvec4(
70, {108, 108}, MakeInstructionDescriptor(108, SpvOpBranch, 0), 211); 70, {108, 108}, MakeInstructionDescriptor(108, SpvOpBranch, 0), 211);
@ -1168,17 +1151,13 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) {
make_bvec4.Apply(context.get(), &transformation_context); make_bvec4.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(108, {0}), MakeDataDescriptor(211, {0}), MakeDataDescriptor(108, {0}), MakeDataDescriptor(211, {0})));
context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(108, {1}), MakeDataDescriptor(211, {1}), MakeDataDescriptor(108, {1}), MakeDataDescriptor(211, {1})));
context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(108, {0}), MakeDataDescriptor(211, {2}), MakeDataDescriptor(108, {0}), MakeDataDescriptor(211, {2})));
context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(108, {1}), MakeDataDescriptor(211, {3}), MakeDataDescriptor(108, {1}), MakeDataDescriptor(211, {3})));
context.get()));
std::string after_transformation = R"( std::string after_transformation = R"(
OpCapability Shader OpCapability Shader

View File

@ -182,23 +182,17 @@ TEST(TransformationCompositeExtractTest, BasicTest) {
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(201, {}), MakeDataDescriptor(100, {2}), MakeDataDescriptor(201, {}), MakeDataDescriptor(100, {2})));
context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(202, {}), MakeDataDescriptor(104, {0, 2}), MakeDataDescriptor(202, {}), MakeDataDescriptor(104, {0, 2})));
context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(203, {}), MakeDataDescriptor(104, {0}), MakeDataDescriptor(203, {}), MakeDataDescriptor(104, {0})));
context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(204, {}), MakeDataDescriptor(101, {0}), MakeDataDescriptor(204, {}), MakeDataDescriptor(101, {0})));
context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(205, {}), MakeDataDescriptor(102, {2}), MakeDataDescriptor(205, {}), MakeDataDescriptor(102, {2})));
context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(206, {}), MakeDataDescriptor(103, {1}), MakeDataDescriptor(206, {}), MakeDataDescriptor(103, {1})));
context.get()));
std::string after_transformation = R"( std::string after_transformation = R"(
OpCapability Shader OpCapability Shader

View File

@ -0,0 +1,377 @@
// Copyright (c) 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "source/fuzz/transformation_compute_data_synonym_fact_closure.h"
#include "test/fuzz/fuzz_test_util.h"
namespace spvtools {
namespace fuzz {
namespace {
TEST(TransformationComputeDataSynonymFactClosureTest, DataSynonymFacts) {
// The SPIR-V types and constants come from the following code. The body of
// the SPIR-V function then constructs a composite that is synonymous with
// myT.
//
// #version 310 es
//
// precision highp float;
//
// struct S {
// int a;
// uvec2 b;
// };
//
// struct T {
// bool c[5];
// mat4x2 d;
// S e;
// };
//
// void main() {
// T myT = T(bool[5](true, false, true, false, true),
// mat4x2(vec2(1.0, 2.0), vec2(3.0, 4.0),
// vec2(5.0, 6.0), vec2(7.0, 8.0)),
// S(10, uvec2(100u, 200u)));
// }
std::string shader = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main"
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
OpName %15 "S"
OpMemberName %15 0 "a"
OpMemberName %15 1 "b"
OpName %16 "T"
OpMemberName %16 0 "c"
OpMemberName %16 1 "d"
OpMemberName %16 2 "e"
OpName %18 "myT"
OpMemberDecorate %15 0 RelaxedPrecision
OpMemberDecorate %15 1 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeBool
%7 = OpTypeInt 32 0
%8 = OpConstant %7 5
%9 = OpTypeArray %6 %8
%10 = OpTypeFloat 32
%11 = OpTypeVector %10 2
%12 = OpTypeMatrix %11 4
%13 = OpTypeInt 32 1
%14 = OpTypeVector %7 2
%15 = OpTypeStruct %13 %14
%16 = OpTypeStruct %9 %12 %15
%17 = OpTypePointer Function %16
%19 = OpConstantTrue %6
%20 = OpConstantFalse %6
%21 = OpConstantComposite %9 %19 %20 %19 %20 %19
%22 = OpConstant %10 1
%23 = OpConstant %10 2
%24 = OpConstantComposite %11 %22 %23
%25 = OpConstant %10 3
%26 = OpConstant %10 4
%27 = OpConstantComposite %11 %25 %26
%28 = OpConstant %10 5
%29 = OpConstant %10 6
%30 = OpConstantComposite %11 %28 %29
%31 = OpConstant %10 7
%32 = OpConstant %10 8
%33 = OpConstantComposite %11 %31 %32
%34 = OpConstantComposite %12 %24 %27 %30 %33
%35 = OpConstant %13 10
%36 = OpConstant %7 100
%37 = OpConstant %7 200
%38 = OpConstantComposite %14 %36 %37
%39 = OpConstantComposite %15 %35 %38
%40 = OpConstantComposite %16 %21 %34 %39
%4 = OpFunction %2 None %3
%5 = OpLabel
%18 = OpVariable %17 Function
OpStore %18 %40
%100 = OpCompositeConstruct %9 %19 %20 %19 %20 %19
%101 = OpCompositeConstruct %11 %22 %23
%102 = OpCompositeConstruct %11 %25 %26
%103 = OpCompositeConstruct %11 %28 %29
%104 = OpCompositeConstruct %11 %31 %32
%105 = OpCompositeConstruct %12 %101 %102 %103 %104
%106 = OpCompositeConstruct %14 %36 %37
%107 = OpCompositeConstruct %15 %35 %106
%108 = OpCompositeConstruct %16 %100 %105 %107
OpReturn
OpFunctionEnd
)";
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto consumer = nullptr;
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
spvtools::ValidatorOptions validator_options;
TransformationContext transformation_context(&fact_manager,
validator_options);
ASSERT_TRUE(TransformationComputeDataSynonymFactClosure(100).IsApplicable(
context.get(), transformation_context));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {}),
MakeDataDescriptor(101, {})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {0}),
MakeDataDescriptor(101, {0})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {1}),
MakeDataDescriptor(101, {1})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {0}),
MakeDataDescriptor(101, {1})));
fact_manager.AddFactDataSynonym(MakeDataDescriptor(24, {}),
MakeDataDescriptor(101, {}), context.get());
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {}),
MakeDataDescriptor(101, {})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {0}),
MakeDataDescriptor(101, {0})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {1}),
MakeDataDescriptor(101, {1})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {0}),
MakeDataDescriptor(101, {1})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {}),
MakeDataDescriptor(102, {})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {0}),
MakeDataDescriptor(102, {0})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {1}),
MakeDataDescriptor(102, {1})));
fact_manager.AddFactDataSynonym(MakeDataDescriptor(27, {0}),
MakeDataDescriptor(102, {0}), context.get());
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {}),
MakeDataDescriptor(102, {})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {0}),
MakeDataDescriptor(102, {0})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {1}),
MakeDataDescriptor(102, {1})));
fact_manager.AddFactDataSynonym(MakeDataDescriptor(27, {1}),
MakeDataDescriptor(102, {1}), context.get());
TransformationComputeDataSynonymFactClosure(100).Apply(
context.get(), &transformation_context);
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {}),
MakeDataDescriptor(102, {})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {0}),
MakeDataDescriptor(102, {0})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {1}),
MakeDataDescriptor(102, {1})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(30, {}),
MakeDataDescriptor(103, {})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(30, {0}),
MakeDataDescriptor(103, {0})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(30, {1}),
MakeDataDescriptor(103, {1})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {}),
MakeDataDescriptor(104, {})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {0}),
MakeDataDescriptor(104, {0})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {1}),
MakeDataDescriptor(104, {1})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {}),
MakeDataDescriptor(105, {})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {0}),
MakeDataDescriptor(105, {0})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {1}),
MakeDataDescriptor(105, {1})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {2}),
MakeDataDescriptor(105, {2})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {3}),
MakeDataDescriptor(105, {3})));
fact_manager.AddFactDataSynonym(MakeDataDescriptor(30, {}),
MakeDataDescriptor(103, {}), context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(33, {}),
MakeDataDescriptor(104, {}), context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(34, {0}),
MakeDataDescriptor(105, {0}), context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(34, {1}),
MakeDataDescriptor(105, {1}), context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(34, {2}),
MakeDataDescriptor(105, {2}), context.get());
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(30, {}),
MakeDataDescriptor(103, {})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(30, {0}),
MakeDataDescriptor(103, {0})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(30, {1}),
MakeDataDescriptor(103, {1})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {}),
MakeDataDescriptor(104, {})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {0}),
MakeDataDescriptor(104, {0})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {1}),
MakeDataDescriptor(104, {1})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {}),
MakeDataDescriptor(105, {})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {0}),
MakeDataDescriptor(105, {0})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {1}),
MakeDataDescriptor(105, {1})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {2}),
MakeDataDescriptor(105, {2})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {3}),
MakeDataDescriptor(105, {3})));
fact_manager.AddFactDataSynonym(MakeDataDescriptor(34, {3}),
MakeDataDescriptor(105, {3}), context.get());
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {0}),
MakeDataDescriptor(104, {0})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {3}),
MakeDataDescriptor(105, {3})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(21, {}),
MakeDataDescriptor(100, {})));
fact_manager.AddFactDataSynonym(MakeDataDescriptor(21, {0}),
MakeDataDescriptor(100, {0}), context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(21, {1}),
MakeDataDescriptor(100, {1}), context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(21, {2}),
MakeDataDescriptor(100, {2}), context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(21, {3}),
MakeDataDescriptor(100, {3}), context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(21, {4}),
MakeDataDescriptor(100, {4}), context.get());
TransformationComputeDataSynonymFactClosure(100).Apply(
context.get(), &transformation_context);
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(21, {}),
MakeDataDescriptor(100, {})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(39, {0}),
MakeDataDescriptor(107, {0})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(35, {}),
MakeDataDescriptor(39, {0})));
fact_manager.AddFactDataSynonym(MakeDataDescriptor(39, {0}),
MakeDataDescriptor(35, {}), context.get());
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(39, {0}),
MakeDataDescriptor(107, {0})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(35, {}),
MakeDataDescriptor(39, {0})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(38, {0}),
MakeDataDescriptor(36, {})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(38, {1}),
MakeDataDescriptor(37, {})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(106, {0}),
MakeDataDescriptor(36, {})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(106, {1}),
MakeDataDescriptor(37, {})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(38, {}),
MakeDataDescriptor(106, {})));
fact_manager.AddFactDataSynonym(MakeDataDescriptor(38, {0}),
MakeDataDescriptor(36, {}), context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(106, {0}),
MakeDataDescriptor(36, {}), context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(38, {1}),
MakeDataDescriptor(37, {}), context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(106, {1}),
MakeDataDescriptor(37, {}), context.get());
TransformationComputeDataSynonymFactClosure(100).Apply(
context.get(), &transformation_context);
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(38, {0}),
MakeDataDescriptor(36, {})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(38, {1}),
MakeDataDescriptor(37, {})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(106, {0}),
MakeDataDescriptor(36, {})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(106, {1}),
MakeDataDescriptor(37, {})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(38, {}),
MakeDataDescriptor(106, {})));
ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {}),
MakeDataDescriptor(108, {})));
fact_manager.AddFactDataSynonym(MakeDataDescriptor(107, {0}),
MakeDataDescriptor(35, {}), context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(40, {0}),
MakeDataDescriptor(108, {0}), context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(40, {1}),
MakeDataDescriptor(108, {1}), context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(40, {2}),
MakeDataDescriptor(108, {2}), context.get());
TransformationComputeDataSynonymFactClosure(100).Apply(
context.get(), &transformation_context);
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {}),
MakeDataDescriptor(108, {})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0}),
MakeDataDescriptor(108, {0})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1}),
MakeDataDescriptor(108, {1})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {2}),
MakeDataDescriptor(108, {2})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0, 0}),
MakeDataDescriptor(108, {0, 0})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0, 1}),
MakeDataDescriptor(108, {0, 1})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0, 2}),
MakeDataDescriptor(108, {0, 2})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0, 3}),
MakeDataDescriptor(108, {0, 3})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0, 4}),
MakeDataDescriptor(108, {0, 4})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 0}),
MakeDataDescriptor(108, {1, 0})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 1}),
MakeDataDescriptor(108, {1, 1})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 2}),
MakeDataDescriptor(108, {1, 2})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 3}),
MakeDataDescriptor(108, {1, 3})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 0, 0}),
MakeDataDescriptor(108, {1, 0, 0})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 1, 0}),
MakeDataDescriptor(108, {1, 1, 0})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 2, 0}),
MakeDataDescriptor(108, {1, 2, 0})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 3, 0}),
MakeDataDescriptor(108, {1, 3, 0})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 0, 1}),
MakeDataDescriptor(108, {1, 0, 1})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 1, 1}),
MakeDataDescriptor(108, {1, 1, 1})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 2, 1}),
MakeDataDescriptor(108, {1, 2, 1})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 3, 1}),
MakeDataDescriptor(108, {1, 3, 1})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {2, 0}),
MakeDataDescriptor(108, {2, 0})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {2, 1}),
MakeDataDescriptor(108, {2, 1})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {2, 1, 0}),
MakeDataDescriptor(108, {2, 1, 0})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {2, 1, 1}),
MakeDataDescriptor(108, {2, 1, 1})));
}
} // namespace
} // namespace fuzz
} // namespace spvtools

View File

@ -56,7 +56,7 @@ TEST(TransformationCopyObjectTest, CopyBooleanConstants) {
validator_options); validator_options);
ASSERT_EQ(0, transformation_context.GetFactManager() ASSERT_EQ(0, transformation_context.GetFactManager()
->GetIdsForWhichSynonymsAreKnown(context.get()) ->GetIdsForWhichSynonymsAreKnown()
.size()); .size());
{ {
@ -66,18 +66,17 @@ TEST(TransformationCopyObjectTest, CopyBooleanConstants) {
copy_true.Apply(context.get(), &transformation_context); copy_true.Apply(context.get(), &transformation_context);
std::vector<uint32_t> ids_for_which_synonyms_are_known = std::vector<uint32_t> ids_for_which_synonyms_are_known =
transformation_context.GetFactManager()->GetIdsForWhichSynonymsAreKnown( transformation_context.GetFactManager()
context.get()); ->GetIdsForWhichSynonymsAreKnown();
ASSERT_EQ(2, ids_for_which_synonyms_are_known.size()); ASSERT_EQ(2, ids_for_which_synonyms_are_known.size());
ASSERT_TRUE(std::find(ids_for_which_synonyms_are_known.begin(), ASSERT_TRUE(std::find(ids_for_which_synonyms_are_known.begin(),
ids_for_which_synonyms_are_known.end(), ids_for_which_synonyms_are_known.end(),
7) != ids_for_which_synonyms_are_known.end()); 7) != ids_for_which_synonyms_are_known.end());
ASSERT_EQ(2, transformation_context.GetFactManager() ASSERT_EQ(
->GetSynonymsForId(7, context.get()) 2, transformation_context.GetFactManager()->GetSynonymsForId(7).size());
.size());
protobufs::DataDescriptor descriptor_100 = MakeDataDescriptor(100, {}); protobufs::DataDescriptor descriptor_100 = MakeDataDescriptor(100, {});
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(7, {}), descriptor_100, context.get())); MakeDataDescriptor(7, {}), descriptor_100));
} }
{ {
@ -86,18 +85,17 @@ TEST(TransformationCopyObjectTest, CopyBooleanConstants) {
ASSERT_TRUE(copy_false.IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(copy_false.IsApplicable(context.get(), transformation_context));
copy_false.Apply(context.get(), &transformation_context); copy_false.Apply(context.get(), &transformation_context);
std::vector<uint32_t> ids_for_which_synonyms_are_known = std::vector<uint32_t> ids_for_which_synonyms_are_known =
transformation_context.GetFactManager()->GetIdsForWhichSynonymsAreKnown( transformation_context.GetFactManager()
context.get()); ->GetIdsForWhichSynonymsAreKnown();
ASSERT_EQ(4, ids_for_which_synonyms_are_known.size()); ASSERT_EQ(4, ids_for_which_synonyms_are_known.size());
ASSERT_TRUE(std::find(ids_for_which_synonyms_are_known.begin(), ASSERT_TRUE(std::find(ids_for_which_synonyms_are_known.begin(),
ids_for_which_synonyms_are_known.end(), ids_for_which_synonyms_are_known.end(),
8) != ids_for_which_synonyms_are_known.end()); 8) != ids_for_which_synonyms_are_known.end());
ASSERT_EQ(2, transformation_context.GetFactManager() ASSERT_EQ(
->GetSynonymsForId(8, context.get()) 2, transformation_context.GetFactManager()->GetSynonymsForId(8).size());
.size());
protobufs::DataDescriptor descriptor_101 = MakeDataDescriptor(101, {}); protobufs::DataDescriptor descriptor_101 = MakeDataDescriptor(101, {});
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(8, {}), descriptor_101, context.get())); MakeDataDescriptor(8, {}), descriptor_101));
} }
{ {
@ -107,18 +105,18 @@ TEST(TransformationCopyObjectTest, CopyBooleanConstants) {
copy_false_again.IsApplicable(context.get(), transformation_context)); copy_false_again.IsApplicable(context.get(), transformation_context));
copy_false_again.Apply(context.get(), &transformation_context); copy_false_again.Apply(context.get(), &transformation_context);
std::vector<uint32_t> ids_for_which_synonyms_are_known = std::vector<uint32_t> ids_for_which_synonyms_are_known =
transformation_context.GetFactManager()->GetIdsForWhichSynonymsAreKnown( transformation_context.GetFactManager()
context.get()); ->GetIdsForWhichSynonymsAreKnown();
ASSERT_EQ(5, ids_for_which_synonyms_are_known.size()); ASSERT_EQ(5, ids_for_which_synonyms_are_known.size());
ASSERT_TRUE(std::find(ids_for_which_synonyms_are_known.begin(), ASSERT_TRUE(std::find(ids_for_which_synonyms_are_known.begin(),
ids_for_which_synonyms_are_known.end(), ids_for_which_synonyms_are_known.end(),
101) != ids_for_which_synonyms_are_known.end()); 101) != ids_for_which_synonyms_are_known.end());
ASSERT_EQ(3, transformation_context.GetFactManager() ASSERT_EQ(
->GetSynonymsForId(101, context.get()) 3,
.size()); transformation_context.GetFactManager()->GetSynonymsForId(101).size());
protobufs::DataDescriptor descriptor_102 = MakeDataDescriptor(102, {}); protobufs::DataDescriptor descriptor_102 = MakeDataDescriptor(102, {});
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(101, {}), descriptor_102, context.get())); MakeDataDescriptor(101, {}), descriptor_102));
} }
{ {
@ -128,18 +126,17 @@ TEST(TransformationCopyObjectTest, CopyBooleanConstants) {
copy_true_again.IsApplicable(context.get(), transformation_context)); copy_true_again.IsApplicable(context.get(), transformation_context));
copy_true_again.Apply(context.get(), &transformation_context); copy_true_again.Apply(context.get(), &transformation_context);
std::vector<uint32_t> ids_for_which_synonyms_are_known = std::vector<uint32_t> ids_for_which_synonyms_are_known =
transformation_context.GetFactManager()->GetIdsForWhichSynonymsAreKnown( transformation_context.GetFactManager()
context.get()); ->GetIdsForWhichSynonymsAreKnown();
ASSERT_EQ(6, ids_for_which_synonyms_are_known.size()); ASSERT_EQ(6, ids_for_which_synonyms_are_known.size());
ASSERT_TRUE(std::find(ids_for_which_synonyms_are_known.begin(), ASSERT_TRUE(std::find(ids_for_which_synonyms_are_known.begin(),
ids_for_which_synonyms_are_known.end(), ids_for_which_synonyms_are_known.end(),
7) != ids_for_which_synonyms_are_known.end()); 7) != ids_for_which_synonyms_are_known.end());
ASSERT_EQ(3, transformation_context.GetFactManager() ASSERT_EQ(
->GetSynonymsForId(7, context.get()) 3, transformation_context.GetFactManager()->GetSynonymsForId(7).size());
.size());
protobufs::DataDescriptor descriptor_103 = MakeDataDescriptor(103, {}); protobufs::DataDescriptor descriptor_103 = MakeDataDescriptor(103, {});
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(7, {}), descriptor_103, context.get())); MakeDataDescriptor(7, {}), descriptor_103));
} }
std::string after_transformation = R"( std::string after_transformation = R"(

View File

@ -112,7 +112,7 @@ TEST(TransformationEquationInstructionTest, SignedNegate) {
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(15, {}), MakeDataDescriptor(7, {}), context.get())); MakeDataDescriptor(15, {}), MakeDataDescriptor(7, {})));
std::string after_transformation = R"( std::string after_transformation = R"(
OpCapability Shader OpCapability Shader
@ -203,7 +203,7 @@ TEST(TransformationEquationInstructionTest, LogicalNot) {
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(15, {}), MakeDataDescriptor(7, {}), context.get())); MakeDataDescriptor(15, {}), MakeDataDescriptor(7, {})));
std::string after_transformation = R"( std::string after_transformation = R"(
OpCapability Shader OpCapability Shader
@ -300,7 +300,7 @@ TEST(TransformationEquationInstructionTest, AddSubNegate1) {
transformation2.Apply(context.get(), &transformation_context); transformation2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(15, {}), MakeDataDescriptor(19, {}), context.get())); MakeDataDescriptor(15, {}), MakeDataDescriptor(19, {})));
auto transformation3 = TransformationEquationInstruction( auto transformation3 = TransformationEquationInstruction(
20, SpvOpISub, {14, 15}, return_instruction); 20, SpvOpISub, {14, 15}, return_instruction);
@ -309,7 +309,7 @@ TEST(TransformationEquationInstructionTest, AddSubNegate1) {
transformation3.Apply(context.get(), &transformation_context); transformation3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(20, {}), MakeDataDescriptor(16, {}), context.get())); MakeDataDescriptor(20, {}), MakeDataDescriptor(16, {})));
auto transformation4 = TransformationEquationInstruction( auto transformation4 = TransformationEquationInstruction(
22, SpvOpISub, {16, 14}, return_instruction); 22, SpvOpISub, {16, 14}, return_instruction);
@ -325,7 +325,7 @@ TEST(TransformationEquationInstructionTest, AddSubNegate1) {
transformation5.Apply(context.get(), &transformation_context); transformation5.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(24, {}), MakeDataDescriptor(15, {}), context.get())); MakeDataDescriptor(24, {}), MakeDataDescriptor(15, {})));
std::string after_transformation = R"( std::string after_transformation = R"(
OpCapability Shader OpCapability Shader
@ -403,7 +403,7 @@ TEST(TransformationEquationInstructionTest, AddSubNegate2) {
transformation2.Apply(context.get(), &transformation_context); transformation2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(17, {}), MakeDataDescriptor(15, {}), context.get())); MakeDataDescriptor(17, {}), MakeDataDescriptor(15, {})));
auto transformation3 = TransformationEquationInstruction( auto transformation3 = TransformationEquationInstruction(
18, SpvOpIAdd, {16, 14}, return_instruction); 18, SpvOpIAdd, {16, 14}, return_instruction);
@ -412,9 +412,9 @@ TEST(TransformationEquationInstructionTest, AddSubNegate2) {
transformation3.Apply(context.get(), &transformation_context); transformation3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(17, {}), MakeDataDescriptor(18, {}), context.get())); MakeDataDescriptor(17, {}), MakeDataDescriptor(18, {})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(18, {}), MakeDataDescriptor(15, {}), context.get())); MakeDataDescriptor(18, {}), MakeDataDescriptor(15, {})));
auto transformation4 = TransformationEquationInstruction( auto transformation4 = TransformationEquationInstruction(
19, SpvOpISub, {14, 15}, return_instruction); 19, SpvOpISub, {14, 15}, return_instruction);
@ -430,7 +430,7 @@ TEST(TransformationEquationInstructionTest, AddSubNegate2) {
transformation5.Apply(context.get(), &transformation_context); transformation5.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(20, {}), MakeDataDescriptor(16, {}), context.get())); MakeDataDescriptor(20, {}), MakeDataDescriptor(16, {})));
auto transformation6 = TransformationEquationInstruction( auto transformation6 = TransformationEquationInstruction(
21, SpvOpISub, {14, 19}, return_instruction); 21, SpvOpISub, {14, 19}, return_instruction);
@ -439,7 +439,7 @@ TEST(TransformationEquationInstructionTest, AddSubNegate2) {
transformation6.Apply(context.get(), &transformation_context); transformation6.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(21, {}), MakeDataDescriptor(15, {}), context.get())); MakeDataDescriptor(21, {}), MakeDataDescriptor(15, {})));
auto transformation7 = TransformationEquationInstruction( auto transformation7 = TransformationEquationInstruction(
22, SpvOpISub, {14, 18}, return_instruction); 22, SpvOpISub, {14, 18}, return_instruction);
@ -455,7 +455,7 @@ TEST(TransformationEquationInstructionTest, AddSubNegate2) {
transformation8.Apply(context.get(), &transformation_context); transformation8.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get())); ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(23, {}), MakeDataDescriptor(16, {}), context.get())); MakeDataDescriptor(23, {}), MakeDataDescriptor(16, {})));
std::string after_transformation = R"( std::string after_transformation = R"(
OpCapability Shader OpCapability Shader
@ -551,7 +551,7 @@ TEST(TransformationEquationInstructionTest, Miscellaneous1) {
)"; )";
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(570, {}), MakeDataDescriptor(113, {}), context.get())); MakeDataDescriptor(570, {}), MakeDataDescriptor(113, {})));
ASSERT_TRUE(IsEqual(env, after_transformation, context.get())); ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
} }
@ -621,7 +621,7 @@ TEST(TransformationEquationInstructionTest, Miscellaneous2) {
)"; )";
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(570, {}), MakeDataDescriptor(113, {}), context.get())); MakeDataDescriptor(570, {}), MakeDataDescriptor(113, {})));
ASSERT_TRUE(IsEqual(env, after_transformation, context.get())); ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
} }

View File

@ -250,10 +250,10 @@ TEST(TransformationVectorShuffle, BasicTest) {
transformation1.Apply(context.get(), &transformation_context); transformation1.Apply(context.get(), &transformation_context);
temp_dd = MakeDataDescriptor(200, {0}); temp_dd = MakeDataDescriptor(200, {0});
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(11, {}), temp_dd, context.get())); MakeDataDescriptor(11, {}), temp_dd));
temp_dd = MakeDataDescriptor(200, {1}); temp_dd = MakeDataDescriptor(200, {1});
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(10, {}), temp_dd, context.get())); MakeDataDescriptor(10, {}), temp_dd));
TransformationVectorShuffle transformation2( TransformationVectorShuffle transformation2(
MakeInstructionDescriptor(100, SpvOpReturn, 0), 201, 20, 12, MakeInstructionDescriptor(100, SpvOpReturn, 0), 201, 20, 12,
@ -263,10 +263,10 @@ TEST(TransformationVectorShuffle, BasicTest) {
transformation2.Apply(context.get(), &transformation_context); transformation2.Apply(context.get(), &transformation_context);
temp_dd = MakeDataDescriptor(201, {1}); temp_dd = MakeDataDescriptor(201, {1});
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(11, {}), temp_dd, context.get())); MakeDataDescriptor(11, {}), temp_dd));
temp_dd = MakeDataDescriptor(201, {2}); temp_dd = MakeDataDescriptor(201, {2});
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(11, {}), temp_dd, context.get())); MakeDataDescriptor(11, {}), temp_dd));
TransformationVectorShuffle transformation3( TransformationVectorShuffle transformation3(
MakeInstructionDescriptor(100, SpvOpReturn, 0), 202, 27, 35, {5, 4, 1}); MakeInstructionDescriptor(100, SpvOpReturn, 0), 202, 27, 35, {5, 4, 1});
@ -275,13 +275,13 @@ TEST(TransformationVectorShuffle, BasicTest) {
transformation3.Apply(context.get(), &transformation_context); transformation3.Apply(context.get(), &transformation_context);
temp_dd = MakeDataDescriptor(202, {0}); temp_dd = MakeDataDescriptor(202, {0});
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(26, {}), temp_dd, context.get())); MakeDataDescriptor(26, {}), temp_dd));
temp_dd = MakeDataDescriptor(202, {1}); temp_dd = MakeDataDescriptor(202, {1});
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(25, {}), temp_dd, context.get())); MakeDataDescriptor(25, {}), temp_dd));
temp_dd = MakeDataDescriptor(202, {2}); temp_dd = MakeDataDescriptor(202, {2});
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(26, {}), temp_dd, context.get())); MakeDataDescriptor(26, {}), temp_dd));
TransformationVectorShuffle transformation4( TransformationVectorShuffle transformation4(
MakeInstructionDescriptor(100, SpvOpReturn, 0), 203, 42, 46, {0, 1}); MakeInstructionDescriptor(100, SpvOpReturn, 0), 203, 42, 46, {0, 1});
@ -290,10 +290,10 @@ TEST(TransformationVectorShuffle, BasicTest) {
transformation4.Apply(context.get(), &transformation_context); transformation4.Apply(context.get(), &transformation_context);
temp_dd = MakeDataDescriptor(203, {0}); temp_dd = MakeDataDescriptor(203, {0});
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(40, {}), temp_dd, context.get())); MakeDataDescriptor(40, {}), temp_dd));
temp_dd = MakeDataDescriptor(203, {1}); temp_dd = MakeDataDescriptor(203, {1});
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(41, {}), temp_dd, context.get())); MakeDataDescriptor(41, {}), temp_dd));
TransformationVectorShuffle transformation5( TransformationVectorShuffle transformation5(
MakeInstructionDescriptor(100, SpvOpReturn, 0), 204, 42, 46, {2, 3, 4}); MakeInstructionDescriptor(100, SpvOpReturn, 0), 204, 42, 46, {2, 3, 4});
@ -302,13 +302,13 @@ TEST(TransformationVectorShuffle, BasicTest) {
transformation5.Apply(context.get(), &transformation_context); transformation5.Apply(context.get(), &transformation_context);
temp_dd = MakeDataDescriptor(204, {0}); temp_dd = MakeDataDescriptor(204, {0});
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(40, {}), temp_dd, context.get())); MakeDataDescriptor(40, {}), temp_dd));
temp_dd = MakeDataDescriptor(204, {1}); temp_dd = MakeDataDescriptor(204, {1});
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(41, {}), temp_dd, context.get())); MakeDataDescriptor(41, {}), temp_dd));
temp_dd = MakeDataDescriptor(204, {2}); temp_dd = MakeDataDescriptor(204, {2});
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(40, {}), temp_dd, context.get())); MakeDataDescriptor(40, {}), temp_dd));
TransformationVectorShuffle transformation6( TransformationVectorShuffle transformation6(
MakeInstructionDescriptor(100, SpvOpReturn, 0), 205, 42, 42, MakeInstructionDescriptor(100, SpvOpReturn, 0), 205, 42, 42,
@ -318,16 +318,16 @@ TEST(TransformationVectorShuffle, BasicTest) {
transformation6.Apply(context.get(), &transformation_context); transformation6.Apply(context.get(), &transformation_context);
temp_dd = MakeDataDescriptor(205, {0}); temp_dd = MakeDataDescriptor(205, {0});
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(40, {}), temp_dd, context.get())); MakeDataDescriptor(40, {}), temp_dd));
temp_dd = MakeDataDescriptor(205, {1}); temp_dd = MakeDataDescriptor(205, {1});
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(41, {}), temp_dd, context.get())); MakeDataDescriptor(41, {}), temp_dd));
temp_dd = MakeDataDescriptor(205, {2}); temp_dd = MakeDataDescriptor(205, {2});
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(40, {}), temp_dd, context.get())); MakeDataDescriptor(40, {}), temp_dd));
temp_dd = MakeDataDescriptor(205, {3}); temp_dd = MakeDataDescriptor(205, {3});
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(41, {}), temp_dd, context.get())); MakeDataDescriptor(41, {}), temp_dd));
// swizzle vec4 from vec4 and vec4 using some undefs // swizzle vec4 from vec4 and vec4 using some undefs
TransformationVectorShuffle transformation7( TransformationVectorShuffle transformation7(
@ -338,7 +338,7 @@ TEST(TransformationVectorShuffle, BasicTest) {
transformation7.Apply(context.get(), &transformation_context); transformation7.Apply(context.get(), &transformation_context);
temp_dd = MakeDataDescriptor(206, {1}); temp_dd = MakeDataDescriptor(206, {1});
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(56, {}), temp_dd, context.get())); MakeDataDescriptor(56, {}), temp_dd));
std::string after_transformation = R"( std::string after_transformation = R"(
OpCapability Shader OpCapability Shader