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_composite_construct.h
transformation_composite_extract.h
transformation_compute_data_synonym_fact_closure.h
transformation_context.h
transformation_copy_object.h
transformation_equation_instruction.h
@ -193,6 +194,7 @@ if(SPIRV_BUILD_FUZZER)
transformation_add_type_vector.cpp
transformation_composite_construct.cpp
transformation_composite_extract.cpp
transformation_compute_data_synonym_fact_closure.cpp
transformation_context.cpp
transformation_copy_object.cpp
transformation_equation_instruction.cpp

View File

@ -416,17 +416,18 @@ class FactManager::DataSynonymAndIdEquationFacts {
// See method in FactManager which delegates to this method.
std::vector<const protobufs::DataDescriptor*> GetSynonymsForDataDescriptor(
const protobufs::DataDescriptor& data_descriptor,
opt::IRContext* context) const;
const protobufs::DataDescriptor& data_descriptor) const;
// See method in FactManager which delegates to this method.
std::vector<uint32_t> GetIdsForWhichSynonymsAreKnown(
opt::IRContext* context) const;
std::vector<uint32_t> GetIdsForWhichSynonymsAreKnown() const;
// See method in FactManager which delegates to this method.
bool IsSynonymous(const protobufs::DataDescriptor& data_descriptor1,
const protobufs::DataDescriptor& data_descriptor2,
opt::IRContext* context) const;
const protobufs::DataDescriptor& data_descriptor2) const;
// See method in FactManager which delegates to this method.
void ComputeClosureOfFacts(opt::IRContext* context,
uint32_t maximum_equivalence_class_size);
private:
// Adds the synonym |dd1| = |dd2| to the set of managed facts, and recurses
@ -436,23 +437,10 @@ class FactManager::DataSynonymAndIdEquationFacts {
const protobufs::DataDescriptor& dd2,
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
// 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,
const protobufs::DataDescriptor& dd2) const;
const protobufs::DataDescriptor& dd2);
// Returns true if and only if |dd1| and |dd2| are valid data descriptors
// 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
// captured by this equivalence relation.
//
// 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>
EquivalenceRelation<protobufs::DataDescriptor, DataDescriptorHash,
DataDescriptorEquals>
synonymous_;
// 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
// no point computing this closure until a question regarding synonym facts is
// actually asked: if several facts are added in succession with no questions
// asked in between, we can avoid computing fact closures multiple times.
//
// This boolean tracks whether a closure computation is required - i.e.,
// 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;
// synonym facts by computing a closure of all known facts. However, this is
// an expensive operation, so it should be performed sparingly and only there
// is some chance of new facts being deduced. This boolean tracks whether a
// closure computation is required - i.e., whether a new fact has been added
// since the last time such a computation was performed.
bool closure_computation_required_ = false;
// 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
@ -503,12 +480,7 @@ class FactManager::DataSynonymAndIdEquationFacts {
// All data descriptors occurring in equations are required to be present in
// the |synonymous_| equivalence relation, and to be their own representatives
// in that relation.
//
// 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<
std::unordered_map<
const protobufs::DataDescriptor*,
std::unordered_set<Operation, OperationHash, OperationEquals>>
id_equations_;
@ -770,7 +742,17 @@ void FactManager::DataSynonymAndIdEquationFacts::AddDataSynonymFactRecursive(
// 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:
// 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 =
fuzzerutil::RepeatedFieldToVector(dd1.index());
extended_indices1.push_back(i);
@ -781,11 +763,21 @@ void FactManager::DataSynonymAndIdEquationFacts::AddDataSynonymFactRecursive(
MakeDataDescriptor(dd1.object(), std::move(extended_indices1)),
MakeDataDescriptor(dd2.object(), std::move(extended_indices2)),
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(
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
// data descriptors that describe objects of the same composite type, and that
// the composite type is comprised of k components.
@ -871,6 +863,13 @@ void FactManager::DataSynonymAndIdEquationFacts::ComputeClosureOfFacts(
synonymous_.GetEquivalenceClassRepresentatives()) {
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.
for (auto dd1_it = equivalence_class.begin();
dd1_it != equivalence_class.end(); ++dd1_it) {
@ -1059,7 +1058,7 @@ void FactManager::DataSynonymAndIdEquationFacts::ComputeClosureOfFacts(
void FactManager::DataSynonymAndIdEquationFacts::MakeEquivalent(
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
// equivalence relation.
for (const auto& dd : {dd1, dd2}) {
@ -1185,9 +1184,7 @@ bool FactManager::DataSynonymAndIdEquationFacts::
std::vector<const protobufs::DataDescriptor*>
FactManager::DataSynonymAndIdEquationFacts::GetSynonymsForDataDescriptor(
const protobufs::DataDescriptor& data_descriptor,
opt::IRContext* context) const {
ComputeClosureOfFacts(context);
const protobufs::DataDescriptor& data_descriptor) const {
if (synonymous_.Exists(data_descriptor)) {
return synonymous_.GetEquivalenceClass(data_descriptor);
}
@ -1195,9 +1192,8 @@ FactManager::DataSynonymAndIdEquationFacts::GetSynonymsForDataDescriptor(
}
std::vector<uint32_t>
FactManager::DataSynonymAndIdEquationFacts ::GetIdsForWhichSynonymsAreKnown(
opt::IRContext* context) const {
ComputeClosureOfFacts(context);
FactManager::DataSynonymAndIdEquationFacts::GetIdsForWhichSynonymsAreKnown()
const {
std::vector<uint32_t> result;
for (auto& data_descriptor : synonymous_.GetAllKnownValues()) {
if (data_descriptor->index().empty()) {
@ -1209,10 +1205,7 @@ FactManager::DataSynonymAndIdEquationFacts ::GetIdsForWhichSynonymsAreKnown(
bool FactManager::DataSynonymAndIdEquationFacts::IsSynonymous(
const protobufs::DataDescriptor& data_descriptor1,
const protobufs::DataDescriptor& data_descriptor2,
opt::IRContext* context) const {
const_cast<FactManager::DataSynonymAndIdEquationFacts*>(this)
->ComputeClosureOfFacts(context);
const protobufs::DataDescriptor& data_descriptor2) const {
return synonymous_.Exists(data_descriptor1) &&
synonymous_.Exists(data_descriptor2) &&
synonymous_.IsEquivalent(data_descriptor1, data_descriptor2);
@ -1394,31 +1387,27 @@ FactManager::GetConstantUniformFactsAndTypes() const {
return uniform_constant_facts_->GetConstantUniformFactsAndTypes();
}
std::vector<uint32_t> FactManager::GetIdsForWhichSynonymsAreKnown(
opt::IRContext* context) const {
return data_synonym_and_id_equation_facts_->GetIdsForWhichSynonymsAreKnown(
context);
std::vector<uint32_t> FactManager::GetIdsForWhichSynonymsAreKnown() const {
return data_synonym_and_id_equation_facts_->GetIdsForWhichSynonymsAreKnown();
}
std::vector<const protobufs::DataDescriptor*>
FactManager::GetSynonymsForDataDescriptor(
const protobufs::DataDescriptor& data_descriptor,
opt::IRContext* context) const {
const protobufs::DataDescriptor& data_descriptor) const {
return data_synonym_and_id_equation_facts_->GetSynonymsForDataDescriptor(
data_descriptor, context);
data_descriptor);
}
std::vector<const protobufs::DataDescriptor*> FactManager::GetSynonymsForId(
uint32_t id, opt::IRContext* context) const {
return GetSynonymsForDataDescriptor(MakeDataDescriptor(id, {}), context);
uint32_t id) const {
return GetSynonymsForDataDescriptor(MakeDataDescriptor(id, {}));
}
bool FactManager::IsSynonymous(
const protobufs::DataDescriptor& data_descriptor1,
const protobufs::DataDescriptor& data_descriptor2,
opt::IRContext* context) const {
return data_synonym_and_id_equation_facts_->IsSynonymous(
data_descriptor1, data_descriptor2, context);
const protobufs::DataDescriptor& data_descriptor2) const {
return data_synonym_and_id_equation_facts_->IsSynonymous(data_descriptor1,
data_descriptor2);
}
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);
}
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 spvtools

View File

@ -76,6 +76,21 @@ class FactManager {
const std::vector<uint32_t>& rhs_id,
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
// 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
@ -125,25 +140,22 @@ class FactManager {
// Returns every id for which a fact of the form "this id is synonymous with
// this piece of data" is known.
std::vector<uint32_t> GetIdsForWhichSynonymsAreKnown(
opt::IRContext* context) const;
std::vector<uint32_t> GetIdsForWhichSynonymsAreKnown() const;
// Returns the equivalence class of all known synonyms of |id|, or an empty
// set if no synonyms are known.
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|,
// or empty if no synonyms are known.
std::vector<const protobufs::DataDescriptor*> GetSynonymsForDataDescriptor(
const protobufs::DataDescriptor& data_descriptor,
opt::IRContext* context) const;
const protobufs::DataDescriptor& data_descriptor) const;
// Returns true if and ony if |data_descriptor1| and |data_descriptor2| are
// known to be synonymous.
bool IsSynonymous(const protobufs::DataDescriptor& data_descriptor1,
const protobufs::DataDescriptor& data_descriptor2,
opt::IRContext* context) const;
const protobufs::DataDescriptor& data_descriptor2) const;
// 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.
// Keep them in alphabetical order.
const uint32_t kDefaultMaxEquivalenceClassSizeForDataSynonymFactClosure = 1000;
const uint32_t kDefaultMaxLoopControlPartialCount = 100;
const uint32_t kDefaultMaxLoopControlPeelCount = 100;
const uint32_t kDefaultMaxLoopLimit = 20;
@ -89,6 +90,8 @@ FuzzerContext::FuzzerContext(RandomGenerator* random_generator,
uint32_t min_fresh_id)
: random_generator_(random_generator),
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_peel_count_(kDefaultMaxLoopControlPeelCount),
max_loop_limit_(kDefaultMaxLoopLimit),

View File

@ -183,12 +183,21 @@ class FuzzerContext {
uint32_t GetChanceOfTogglingAccessChainInstruction() {
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() {
return random_generator_->RandomUint32(max_loop_control_partial_count_);
}
uint32_t GetRandomLoopControlPeelCount() {
return random_generator_->RandomUint32(max_loop_control_peel_count_);
}
uint32_t GetRandomLoopLimit() {
return random_generator_->RandomUint32(max_loop_limit_);
}
@ -196,12 +205,6 @@ class FuzzerContext {
// Ensure that the array size is non-zero.
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) {
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
// chosen during fuzzing.
// 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_peel_count_;
uint32_t max_loop_limit_;

View File

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

View File

@ -373,6 +373,7 @@ message Transformation {
TransformationPermuteFunctionParameters permute_function_parameters = 42;
TransformationToggleAccessChainInstruction toggle_access_chain_instruction = 43;
TransformationAddConstantNull add_constant_null = 44;
TransformationComputeDataSynonymFactClosure compute_data_synonym_fact_closure = 45;
// 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 {
// 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_composite_construct.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_equation_instruction.h"
#include "source/fuzz/transformation_function_call.h"
@ -134,6 +135,10 @@ std::unique_ptr<Transformation> Transformation::FromMessage(
case protobufs::Transformation::TransformationCase::kCompositeExtract:
return MakeUnique<TransformationCompositeExtract>(
message.composite_extract());
case protobufs::Transformation::TransformationCase::
kComputeDataSynonymFactClosure:
return MakeUnique<TransformationComputeDataSynonymFactClosure>(
message.compute_data_synonym_fact_closure());
case protobufs::Transformation::TransformationCase::kCopyObject:
return MakeUnique<TransformationCopyObject>(message.copy_object());
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(), {});
if (!transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(id_of_interest, {}),
data_descriptor_for_synonymous_id, ir_context)) {
data_descriptor_for_synonymous_id)) {
return false;
}

View File

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

View File

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

View File

@ -738,393 +738,6 @@ TEST(FactManagerTest, AmbiguousFact) {
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) {
std::string shader = R"(
OpCapability Shader
@ -1157,20 +770,16 @@ TEST(FactManagerTest, RecursiveAdditionOfFacts) {
fact_manager.AddFactDataSynonym(MakeDataDescriptor(10, {}),
MakeDataDescriptor(11, {2}), context.get());
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(10, {}), MakeDataDescriptor(11, {2}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(10, {}),
MakeDataDescriptor(11, {2})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(10, {0}),
MakeDataDescriptor(11, {2, 0}),
context.get()));
MakeDataDescriptor(11, {2, 0})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(10, {1}),
MakeDataDescriptor(11, {2, 1}),
context.get()));
MakeDataDescriptor(11, {2, 1})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(10, {2}),
MakeDataDescriptor(11, {2, 2}),
context.get()));
MakeDataDescriptor(11, {2, 2})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(10, {3}),
MakeDataDescriptor(11, {2, 3}),
context.get()));
MakeDataDescriptor(11, {2, 3})));
}
TEST(FactManagerTest, LogicalNotEquationFacts) {
@ -1209,14 +818,14 @@ TEST(FactManagerTest, LogicalNotEquationFacts) {
fact_manager.AddFactIdEquation(14, SpvOpLogicalNot, {7}, context.get());
fact_manager.AddFactIdEquation(17, SpvOpLogicalNot, {16}, context.get());
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(15, {}), MakeDataDescriptor(7, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(17, {}), MakeDataDescriptor(7, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(15, {}), MakeDataDescriptor(17, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(16, {}), MakeDataDescriptor(14, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(15, {}),
MakeDataDescriptor(7, {})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(17, {}),
MakeDataDescriptor(7, {})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(15, {}),
MakeDataDescriptor(17, {})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(16, {}),
MakeDataDescriptor(14, {})));
}
TEST(FactManagerTest, SignedNegateEquationFacts) {
@ -1249,8 +858,8 @@ TEST(FactManagerTest, SignedNegateEquationFacts) {
fact_manager.AddFactIdEquation(14, SpvOpSNegate, {7}, context.get());
fact_manager.AddFactIdEquation(15, SpvOpSNegate, {14}, context.get());
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(7, {}), MakeDataDescriptor(15, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(7, {}),
MakeDataDescriptor(15, {})));
}
TEST(FactManagerTest, AddSubNegateFacts1) {
@ -1302,12 +911,12 @@ TEST(FactManagerTest, AddSubNegateFacts1) {
MakeDataDescriptor(22, {}), context.get());
fact_manager.AddFactIdEquation(24, SpvOpSNegate, {23}, context.get());
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(19, {}), MakeDataDescriptor(15, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(20, {}), MakeDataDescriptor(16, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(24, {}), MakeDataDescriptor(15, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(19, {}),
MakeDataDescriptor(15, {})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(20, {}),
MakeDataDescriptor(16, {})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {}),
MakeDataDescriptor(15, {})));
}
TEST(FactManagerTest, AddSubNegateFacts2) {
@ -1347,30 +956,30 @@ TEST(FactManagerTest, AddSubNegateFacts2) {
fact_manager.AddFactIdEquation(14, SpvOpISub, {15, 16}, context.get());
fact_manager.AddFactIdEquation(17, SpvOpIAdd, {14, 16}, context.get());
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(17, {}), MakeDataDescriptor(15, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(17, {}),
MakeDataDescriptor(15, {})));
fact_manager.AddFactIdEquation(18, SpvOpIAdd, {16, 14}, context.get());
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(18, {}), MakeDataDescriptor(15, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(17, {}), MakeDataDescriptor(18, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(18, {}),
MakeDataDescriptor(15, {})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(17, {}),
MakeDataDescriptor(18, {})));
fact_manager.AddFactIdEquation(19, SpvOpISub, {14, 15}, context.get());
fact_manager.AddFactIdEquation(20, SpvOpSNegate, {19}, context.get());
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(20, {}), MakeDataDescriptor(16, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(20, {}),
MakeDataDescriptor(16, {})));
fact_manager.AddFactIdEquation(21, SpvOpISub, {14, 19}, context.get());
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(21, {}), MakeDataDescriptor(15, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(21, {}),
MakeDataDescriptor(15, {})));
fact_manager.AddFactIdEquation(22, SpvOpISub, {14, 18}, context.get());
fact_manager.AddFactIdEquation(23, SpvOpSNegate, {22}, context.get());
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(23, {}), MakeDataDescriptor(16, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(23, {}),
MakeDataDescriptor(16, {})));
}
TEST(FactManagerTest, EquationAndEquivalenceFacts) {
@ -1415,34 +1024,34 @@ TEST(FactManagerTest, EquationAndEquivalenceFacts) {
MakeDataDescriptor(14, {}), context.get());
fact_manager.AddFactIdEquation(17, SpvOpIAdd, {114, 16}, context.get());
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(17, {}), MakeDataDescriptor(15, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(17, {}),
MakeDataDescriptor(15, {})));
fact_manager.AddFactIdEquation(18, SpvOpIAdd, {16, 114}, context.get());
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(18, {}), MakeDataDescriptor(15, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(17, {}), MakeDataDescriptor(18, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(18, {}),
MakeDataDescriptor(15, {})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(17, {}),
MakeDataDescriptor(18, {})));
fact_manager.AddFactIdEquation(19, SpvOpISub, {14, 15}, context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(119, {}),
MakeDataDescriptor(19, {}), context.get());
fact_manager.AddFactIdEquation(20, SpvOpSNegate, {119}, context.get());
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(20, {}), MakeDataDescriptor(16, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(20, {}),
MakeDataDescriptor(16, {})));
fact_manager.AddFactIdEquation(21, SpvOpISub, {14, 19}, context.get());
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(21, {}), MakeDataDescriptor(15, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(21, {}),
MakeDataDescriptor(15, {})));
fact_manager.AddFactIdEquation(22, SpvOpISub, {14, 18}, context.get());
fact_manager.AddFactDataSynonym(MakeDataDescriptor(22, {}),
MakeDataDescriptor(220, {}), context.get());
fact_manager.AddFactIdEquation(23, SpvOpSNegate, {220}, context.get());
ASSERT_TRUE(fact_manager.IsSynonymous(
MakeDataDescriptor(23, {}), MakeDataDescriptor(16, {}), context.get()));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(23, {}),
MakeDataDescriptor(16, {})));
}
} // namespace

View File

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

View File

@ -182,23 +182,17 @@ TEST(TransformationCompositeExtractTest, BasicTest) {
ASSERT_TRUE(IsValid(env, context.get()));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(201, {}), MakeDataDescriptor(100, {2}),
context.get()));
MakeDataDescriptor(201, {}), MakeDataDescriptor(100, {2})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(202, {}), MakeDataDescriptor(104, {0, 2}),
context.get()));
MakeDataDescriptor(202, {}), MakeDataDescriptor(104, {0, 2})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(203, {}), MakeDataDescriptor(104, {0}),
context.get()));
MakeDataDescriptor(203, {}), MakeDataDescriptor(104, {0})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(204, {}), MakeDataDescriptor(101, {0}),
context.get()));
MakeDataDescriptor(204, {}), MakeDataDescriptor(101, {0})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(205, {}), MakeDataDescriptor(102, {2}),
context.get()));
MakeDataDescriptor(205, {}), MakeDataDescriptor(102, {2})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(206, {}), MakeDataDescriptor(103, {1}),
context.get()));
MakeDataDescriptor(206, {}), MakeDataDescriptor(103, {1})));
std::string after_transformation = R"(
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);
ASSERT_EQ(0, transformation_context.GetFactManager()
->GetIdsForWhichSynonymsAreKnown(context.get())
->GetIdsForWhichSynonymsAreKnown()
.size());
{
@ -66,18 +66,17 @@ TEST(TransformationCopyObjectTest, CopyBooleanConstants) {
copy_true.Apply(context.get(), &transformation_context);
std::vector<uint32_t> ids_for_which_synonyms_are_known =
transformation_context.GetFactManager()->GetIdsForWhichSynonymsAreKnown(
context.get());
transformation_context.GetFactManager()
->GetIdsForWhichSynonymsAreKnown();
ASSERT_EQ(2, ids_for_which_synonyms_are_known.size());
ASSERT_TRUE(std::find(ids_for_which_synonyms_are_known.begin(),
ids_for_which_synonyms_are_known.end(),
7) != ids_for_which_synonyms_are_known.end());
ASSERT_EQ(2, transformation_context.GetFactManager()
->GetSynonymsForId(7, context.get())
.size());
ASSERT_EQ(
2, transformation_context.GetFactManager()->GetSynonymsForId(7).size());
protobufs::DataDescriptor descriptor_100 = MakeDataDescriptor(100, {});
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));
copy_false.Apply(context.get(), &transformation_context);
std::vector<uint32_t> ids_for_which_synonyms_are_known =
transformation_context.GetFactManager()->GetIdsForWhichSynonymsAreKnown(
context.get());
transformation_context.GetFactManager()
->GetIdsForWhichSynonymsAreKnown();
ASSERT_EQ(4, ids_for_which_synonyms_are_known.size());
ASSERT_TRUE(std::find(ids_for_which_synonyms_are_known.begin(),
ids_for_which_synonyms_are_known.end(),
8) != ids_for_which_synonyms_are_known.end());
ASSERT_EQ(2, transformation_context.GetFactManager()
->GetSynonymsForId(8, context.get())
.size());
ASSERT_EQ(
2, transformation_context.GetFactManager()->GetSynonymsForId(8).size());
protobufs::DataDescriptor descriptor_101 = MakeDataDescriptor(101, {});
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.Apply(context.get(), &transformation_context);
std::vector<uint32_t> ids_for_which_synonyms_are_known =
transformation_context.GetFactManager()->GetIdsForWhichSynonymsAreKnown(
context.get());
transformation_context.GetFactManager()
->GetIdsForWhichSynonymsAreKnown();
ASSERT_EQ(5, ids_for_which_synonyms_are_known.size());
ASSERT_TRUE(std::find(ids_for_which_synonyms_are_known.begin(),
ids_for_which_synonyms_are_known.end(),
101) != ids_for_which_synonyms_are_known.end());
ASSERT_EQ(3, transformation_context.GetFactManager()
->GetSynonymsForId(101, context.get())
.size());
ASSERT_EQ(
3,
transformation_context.GetFactManager()->GetSynonymsForId(101).size());
protobufs::DataDescriptor descriptor_102 = MakeDataDescriptor(102, {});
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.Apply(context.get(), &transformation_context);
std::vector<uint32_t> ids_for_which_synonyms_are_known =
transformation_context.GetFactManager()->GetIdsForWhichSynonymsAreKnown(
context.get());
transformation_context.GetFactManager()
->GetIdsForWhichSynonymsAreKnown();
ASSERT_EQ(6, ids_for_which_synonyms_are_known.size());
ASSERT_TRUE(std::find(ids_for_which_synonyms_are_known.begin(),
ids_for_which_synonyms_are_known.end(),
7) != ids_for_which_synonyms_are_known.end());
ASSERT_EQ(3, transformation_context.GetFactManager()
->GetSynonymsForId(7, context.get())
.size());
ASSERT_EQ(
3, transformation_context.GetFactManager()->GetSynonymsForId(7).size());
protobufs::DataDescriptor descriptor_103 = MakeDataDescriptor(103, {});
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(7, {}), descriptor_103, context.get()));
MakeDataDescriptor(7, {}), descriptor_103));
}
std::string after_transformation = R"(

View File

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

View File

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