mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-30 06:50:06 +00:00
spirv-fuzz: Pass submanagers to other submanagers when necessary (#3796)
This PR changes the fact manager so that, when calling some of the functions in submanagers, passes references to other submanagers if necessary (e.g. to make consistency checks). In particular: - DataSynonymAndIdEquationFacts is passed to the AddFactIdIsIrrelevant function of IrrelevantValueFacts - IrrelevantValueFacts is passed to the AddFact functions of DataSynonymAndIdEquationFacts The IRContext is also passed when necessary and the calls to the corresponding functions in FactManager were updated to be valid and always use an updated context. Fixes #3550.
This commit is contained in:
parent
f62357e7b8
commit
1e1c308ded
@ -52,9 +52,13 @@ bool DataSynonymAndIdEquationFacts::OperationEquals::operator()(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DataSynonymAndIdEquationFacts::AddFact(
|
void DataSynonymAndIdEquationFacts::AddFact(
|
||||||
const protobufs::FactDataSynonym& fact, opt::IRContext* context) {
|
const protobufs::FactDataSynonym& fact,
|
||||||
// TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3550)
|
const IrrelevantValueFacts& irrelevant_value_facts,
|
||||||
// Assert that ids are not irrelevant.
|
opt::IRContext* context) {
|
||||||
|
(void)irrelevant_value_facts; // Keep release compilers happy.
|
||||||
|
assert(!irrelevant_value_facts.IdIsIrrelevant(fact.data1().object()) &&
|
||||||
|
!irrelevant_value_facts.IdIsIrrelevant(fact.data2().object()) &&
|
||||||
|
"Irrelevant ids cannot be synonymous with other ids.");
|
||||||
|
|
||||||
// Add the fact, including all facts relating sub-components of the data
|
// Add the fact, including all facts relating sub-components of the data
|
||||||
// descriptors that are involved.
|
// descriptors that are involved.
|
||||||
@ -62,9 +66,12 @@ void DataSynonymAndIdEquationFacts::AddFact(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DataSynonymAndIdEquationFacts::AddFact(
|
void DataSynonymAndIdEquationFacts::AddFact(
|
||||||
const protobufs::FactIdEquation& fact, opt::IRContext* context) {
|
const protobufs::FactIdEquation& fact,
|
||||||
// TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3550)
|
const IrrelevantValueFacts& irrelevant_value_facts,
|
||||||
// Assert that ids are not irrelevant.
|
opt::IRContext* context) {
|
||||||
|
(void)irrelevant_value_facts; // Keep release compilers happy.
|
||||||
|
assert(!irrelevant_value_facts.IdIsIrrelevant(fact.lhs_id()) &&
|
||||||
|
"Irrelevant ids are not allowed.");
|
||||||
|
|
||||||
protobufs::DataDescriptor lhs_dd = MakeDataDescriptor(fact.lhs_id(), {});
|
protobufs::DataDescriptor lhs_dd = MakeDataDescriptor(fact.lhs_id(), {});
|
||||||
|
|
||||||
@ -75,8 +82,8 @@ void DataSynonymAndIdEquationFacts::AddFact(
|
|||||||
// equation.
|
// equation.
|
||||||
std::vector<const protobufs::DataDescriptor*> rhs_dds;
|
std::vector<const protobufs::DataDescriptor*> rhs_dds;
|
||||||
for (auto rhs_id : fact.rhs_id()) {
|
for (auto rhs_id : fact.rhs_id()) {
|
||||||
// TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3550)
|
assert(!irrelevant_value_facts.IdIsIrrelevant(rhs_id) &&
|
||||||
// Assert that ids are not irrelevant.
|
"Irrelevant ids are not allowed.");
|
||||||
|
|
||||||
// Register a data descriptor based on this id in the equivalence relation
|
// Register a data descriptor based on this id in the equivalence relation
|
||||||
// if needed, and then record the equivalence class representative.
|
// if needed, and then record the equivalence class representative.
|
||||||
@ -828,6 +835,11 @@ bool DataSynonymAndIdEquationFacts::DataDescriptorsAreWellFormedAndComparable(
|
|||||||
get_bit_count_for_numeric_type(*type_b));
|
get_bit_count_for_numeric_type(*type_b));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<const protobufs::DataDescriptor*>
|
||||||
|
DataSynonymAndIdEquationFacts::GetSynonymsForId(uint32_t id) const {
|
||||||
|
return GetSynonymsForDataDescriptor(MakeDataDescriptor(id, {}));
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<const protobufs::DataDescriptor*>
|
std::vector<const protobufs::DataDescriptor*>
|
||||||
DataSynonymAndIdEquationFacts::GetSynonymsForDataDescriptor(
|
DataSynonymAndIdEquationFacts::GetSynonymsForDataDescriptor(
|
||||||
const protobufs::DataDescriptor& data_descriptor) const {
|
const protobufs::DataDescriptor& data_descriptor) const {
|
||||||
|
@ -27,15 +27,28 @@ namespace spvtools {
|
|||||||
namespace fuzz {
|
namespace fuzz {
|
||||||
namespace fact_manager {
|
namespace fact_manager {
|
||||||
|
|
||||||
|
// Forward reference to the IrrelevantValueFacts class.
|
||||||
|
class IrrelevantValueFacts;
|
||||||
|
|
||||||
// The purpose of this class is to group the fields and data used to represent
|
// The purpose of this class is to group the fields and data used to represent
|
||||||
// facts about data synonyms and id equations.
|
// facts about data synonyms and id equations.
|
||||||
class DataSynonymAndIdEquationFacts {
|
class DataSynonymAndIdEquationFacts {
|
||||||
public:
|
public:
|
||||||
// See method in FactManager which delegates to this method.
|
// See method in FactManager which delegates to this method.
|
||||||
void AddFact(const protobufs::FactDataSynonym& fact, opt::IRContext* context);
|
// |irrelevant_value_facts| is passed for consistency checks.
|
||||||
|
void AddFact(const protobufs::FactDataSynonym& fact,
|
||||||
|
const IrrelevantValueFacts& irrelevant_value_facts,
|
||||||
|
opt::IRContext* context);
|
||||||
|
|
||||||
// See method in FactManager which delegates to this method.
|
// See method in FactManager which delegates to this method.
|
||||||
void AddFact(const protobufs::FactIdEquation& fact, opt::IRContext* context);
|
// |irrelevant_value_facts| is passed for consistency checks.
|
||||||
|
void AddFact(const protobufs::FactIdEquation& fact,
|
||||||
|
const IrrelevantValueFacts& irrelevant_value_facts,
|
||||||
|
opt::IRContext* context);
|
||||||
|
|
||||||
|
// See method in FactManager which delegates to this method.
|
||||||
|
std::vector<const protobufs::DataDescriptor*> GetSynonymsForId(
|
||||||
|
uint32_t id) const;
|
||||||
|
|
||||||
// See method in FactManager which delegates to this method.
|
// See method in FactManager which delegates to this method.
|
||||||
std::vector<const protobufs::DataDescriptor*> GetSynonymsForDataDescriptor(
|
std::vector<const protobufs::DataDescriptor*> GetSynonymsForDataDescriptor(
|
||||||
|
@ -105,8 +105,8 @@ bool FactManager::AddFact(const fuzz::protobufs::Fact& fact,
|
|||||||
return constant_uniform_facts_.AddFact(fact.constant_uniform_fact(),
|
return constant_uniform_facts_.AddFact(fact.constant_uniform_fact(),
|
||||||
context);
|
context);
|
||||||
case protobufs::Fact::kDataSynonymFact:
|
case protobufs::Fact::kDataSynonymFact:
|
||||||
data_synonym_and_id_equation_facts_.AddFact(fact.data_synonym_fact(),
|
data_synonym_and_id_equation_facts_.AddFact(
|
||||||
context);
|
fact.data_synonym_fact(), irrelevant_value_facts_, context);
|
||||||
return true;
|
return true;
|
||||||
case protobufs::Fact::kBlockIsDeadFact:
|
case protobufs::Fact::kBlockIsDeadFact:
|
||||||
dead_block_facts_.AddFact(fact.block_is_dead_fact());
|
dead_block_facts_.AddFact(fact.block_is_dead_fact());
|
||||||
@ -126,7 +126,8 @@ void FactManager::AddFactDataSynonym(const protobufs::DataDescriptor& data1,
|
|||||||
protobufs::FactDataSynonym fact;
|
protobufs::FactDataSynonym fact;
|
||||||
*fact.mutable_data1() = data1;
|
*fact.mutable_data1() = data1;
|
||||||
*fact.mutable_data2() = data2;
|
*fact.mutable_data2() = data2;
|
||||||
data_synonym_and_id_equation_facts_.AddFact(fact, context);
|
data_synonym_and_id_equation_facts_.AddFact(fact, irrelevant_value_facts_,
|
||||||
|
context);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint32_t> FactManager::GetConstantsAvailableFromUniformsForType(
|
std::vector<uint32_t> FactManager::GetConstantsAvailableFromUniformsForType(
|
||||||
@ -172,7 +173,7 @@ FactManager::GetSynonymsForDataDescriptor(
|
|||||||
|
|
||||||
std::vector<const protobufs::DataDescriptor*> FactManager::GetSynonymsForId(
|
std::vector<const protobufs::DataDescriptor*> FactManager::GetSynonymsForId(
|
||||||
uint32_t id) const {
|
uint32_t id) const {
|
||||||
return GetSynonymsForDataDescriptor(MakeDataDescriptor(id, {}));
|
return data_synonym_and_id_equation_facts_.GetSynonymsForId(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FactManager::IsSynonymous(
|
bool FactManager::IsSynonymous(
|
||||||
@ -214,16 +215,20 @@ const std::unordered_set<uint32_t>& FactManager::GetIrrelevantIds() const {
|
|||||||
return irrelevant_value_facts_.GetIrrelevantIds();
|
return irrelevant_value_facts_.GetIrrelevantIds();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FactManager::AddFactValueOfPointeeIsIrrelevant(uint32_t pointer_id) {
|
void FactManager::AddFactValueOfPointeeIsIrrelevant(uint32_t pointer_id,
|
||||||
|
opt::IRContext* context) {
|
||||||
protobufs::FactPointeeValueIsIrrelevant fact;
|
protobufs::FactPointeeValueIsIrrelevant fact;
|
||||||
fact.set_pointer_id(pointer_id);
|
fact.set_pointer_id(pointer_id);
|
||||||
irrelevant_value_facts_.AddFact(fact);
|
irrelevant_value_facts_.AddFact(fact, data_synonym_and_id_equation_facts_,
|
||||||
|
context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FactManager::AddFactIdIsIrrelevant(uint32_t result_id) {
|
void FactManager::AddFactIdIsIrrelevant(uint32_t result_id,
|
||||||
|
opt::IRContext* context) {
|
||||||
protobufs::FactIdIsIrrelevant fact;
|
protobufs::FactIdIsIrrelevant fact;
|
||||||
fact.set_result_id(result_id);
|
fact.set_result_id(result_id);
|
||||||
irrelevant_value_facts_.AddFact(fact);
|
irrelevant_value_facts_.AddFact(fact, data_synonym_and_id_equation_facts_,
|
||||||
|
context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FactManager::AddFactIdEquation(uint32_t lhs_id, SpvOp opcode,
|
void FactManager::AddFactIdEquation(uint32_t lhs_id, SpvOp opcode,
|
||||||
@ -235,7 +240,8 @@ void FactManager::AddFactIdEquation(uint32_t lhs_id, SpvOp opcode,
|
|||||||
for (auto an_rhs_id : rhs_id) {
|
for (auto an_rhs_id : rhs_id) {
|
||||||
fact.add_rhs_id(an_rhs_id);
|
fact.add_rhs_id(an_rhs_id);
|
||||||
}
|
}
|
||||||
data_synonym_and_id_equation_facts_.AddFact(fact, context);
|
data_synonym_and_id_equation_facts_.AddFact(fact, irrelevant_value_facts_,
|
||||||
|
context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FactManager::ComputeClosureOfFacts(
|
void FactManager::ComputeClosureOfFacts(
|
||||||
|
@ -66,11 +66,14 @@ class FactManager {
|
|||||||
|
|
||||||
// Records the fact that the value of the pointee associated with |pointer_id|
|
// Records the fact that the value of the pointee associated with |pointer_id|
|
||||||
// is irrelevant: it does not affect the observable behaviour of the module.
|
// is irrelevant: it does not affect the observable behaviour of the module.
|
||||||
void AddFactValueOfPointeeIsIrrelevant(uint32_t pointer_id);
|
// |pointer_id| must exist in the module and actually be a pointer.
|
||||||
|
void AddFactValueOfPointeeIsIrrelevant(uint32_t pointer_id,
|
||||||
|
opt::IRContext* context);
|
||||||
|
|
||||||
// Records a fact that the |result_id| is irrelevant (i.e. it doesn't affect
|
// Records a fact that the |result_id| is irrelevant (i.e. it doesn't affect
|
||||||
// the semantics of the module)
|
// the semantics of the module).
|
||||||
void AddFactIdIsIrrelevant(uint32_t result_id);
|
// |result_id| must exist in the module and actually be a pointer.
|
||||||
|
void AddFactIdIsIrrelevant(uint32_t result_id, opt::IRContext* context);
|
||||||
|
|
||||||
// Records the fact that |lhs_id| is defined by the equation:
|
// Records the fact that |lhs_id| is defined by the equation:
|
||||||
//
|
//
|
||||||
|
@ -15,25 +15,43 @@
|
|||||||
#include "source/fuzz/fact_manager/irrelevant_value_facts.h"
|
#include "source/fuzz/fact_manager/irrelevant_value_facts.h"
|
||||||
|
|
||||||
#include "source/fuzz/data_descriptor.h"
|
#include "source/fuzz/data_descriptor.h"
|
||||||
#include "source/fuzz/fuzzer_util.h"
|
#include "source/fuzz/fact_manager/data_synonym_and_id_equation_facts.h"
|
||||||
|
#include "source/opt/ir_context.h"
|
||||||
|
|
||||||
namespace spvtools {
|
namespace spvtools {
|
||||||
namespace fuzz {
|
namespace fuzz {
|
||||||
namespace fact_manager {
|
namespace fact_manager {
|
||||||
|
|
||||||
void IrrelevantValueFacts::AddFact(
|
void IrrelevantValueFacts::AddFact(
|
||||||
const protobufs::FactPointeeValueIsIrrelevant& fact) {
|
const protobufs::FactPointeeValueIsIrrelevant& fact,
|
||||||
// TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3550)
|
const DataSynonymAndIdEquationFacts& data_synonym_and_id_equation_facts,
|
||||||
// Assert that the id does not participate in DataSynonym facts and is a
|
opt::IRContext* context) {
|
||||||
// pointer.
|
(void)data_synonym_and_id_equation_facts; // Keep release compilers happy.
|
||||||
|
assert(data_synonym_and_id_equation_facts.GetSynonymsForId(fact.pointer_id())
|
||||||
|
.empty() &&
|
||||||
|
"The id cannot participate in DataSynonym facts.");
|
||||||
|
auto pointer_def = context->get_def_use_mgr()->GetDef(fact.pointer_id());
|
||||||
|
assert(pointer_def && "The id must exist in the module.");
|
||||||
|
auto type = context->get_type_mgr()->GetType(pointer_def->type_id());
|
||||||
|
(void)type; // Keep release compilers happy.
|
||||||
|
assert(type && type->AsPointer() && "The id must be a pointer.");
|
||||||
|
|
||||||
pointers_to_irrelevant_pointees_ids_.insert(fact.pointer_id());
|
pointers_to_irrelevant_pointees_ids_.insert(fact.pointer_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
void IrrelevantValueFacts::AddFact(const protobufs::FactIdIsIrrelevant& fact) {
|
void IrrelevantValueFacts::AddFact(
|
||||||
// TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3550)
|
const protobufs::FactIdIsIrrelevant& fact,
|
||||||
// Assert that the id does not participate in DataSynonym facts and is not a
|
const DataSynonymAndIdEquationFacts& data_synonym_and_id_equation_facts,
|
||||||
// pointer.
|
opt::IRContext* context) {
|
||||||
|
(void)data_synonym_and_id_equation_facts; // Keep release compilers happy.
|
||||||
|
assert(data_synonym_and_id_equation_facts.GetSynonymsForId(fact.result_id())
|
||||||
|
.empty() &&
|
||||||
|
"The id cannot participate in DataSynonym facts.");
|
||||||
|
auto pointer_def = context->get_def_use_mgr()->GetDef(fact.result_id());
|
||||||
|
assert(pointer_def && "The id must exist in the module.");
|
||||||
|
auto type = context->get_type_mgr()->GetType(pointer_def->type_id());
|
||||||
|
(void)type; // Keep release compilers happy.
|
||||||
|
assert(type && !type->AsPointer() && "The id must not be a pointer.");
|
||||||
|
|
||||||
irrelevant_ids_.insert(fact.result_id());
|
irrelevant_ids_.insert(fact.result_id());
|
||||||
}
|
}
|
||||||
|
@ -24,15 +24,28 @@ namespace spvtools {
|
|||||||
namespace fuzz {
|
namespace fuzz {
|
||||||
namespace fact_manager {
|
namespace fact_manager {
|
||||||
|
|
||||||
|
// Forward reference to the DataSynonymAndIdEquationFacts class.
|
||||||
|
class DataSynonymAndIdEquationFacts;
|
||||||
|
|
||||||
// The purpose of this class is to group the fields and data used to represent
|
// The purpose of this class is to group the fields and data used to represent
|
||||||
// facts about various irrelevant values in the module.
|
// facts about various irrelevant values in the module.
|
||||||
class IrrelevantValueFacts {
|
class IrrelevantValueFacts {
|
||||||
public:
|
public:
|
||||||
// See method in FactManager which delegates to this method.
|
// See method in FactManager which delegates to this method.
|
||||||
void AddFact(const protobufs::FactPointeeValueIsIrrelevant& fact);
|
// |data_synonym_and_id_equation_facts| and |context| are passed for
|
||||||
|
// consistency checks.
|
||||||
|
void AddFact(
|
||||||
|
const protobufs::FactPointeeValueIsIrrelevant& fact,
|
||||||
|
const DataSynonymAndIdEquationFacts& data_synonym_and_id_equation_facts,
|
||||||
|
opt::IRContext* context);
|
||||||
|
|
||||||
// See method in FactManager which delegates to this method.
|
// See method in FactManager which delegates to this method.
|
||||||
void AddFact(const protobufs::FactIdIsIrrelevant& fact);
|
// |data_synonym_and_id_equation_facts| and |context| are passed for
|
||||||
|
// consistency checks.
|
||||||
|
void AddFact(
|
||||||
|
const protobufs::FactIdIsIrrelevant& fact,
|
||||||
|
const DataSynonymAndIdEquationFacts& data_synonym_and_id_equation_facts,
|
||||||
|
opt::IRContext* context);
|
||||||
|
|
||||||
// See method in FactManager which delegates to this method.
|
// See method in FactManager which delegates to this method.
|
||||||
bool PointeeValueIsIrrelevant(uint32_t pointer_id) const;
|
bool PointeeValueIsIrrelevant(uint32_t pointer_id) const;
|
||||||
|
@ -339,7 +339,7 @@ void TransformationAccessChain::Apply(
|
|||||||
if (transformation_context->GetFactManager()->PointeeValueIsIrrelevant(
|
if (transformation_context->GetFactManager()->PointeeValueIsIrrelevant(
|
||||||
message_.pointer_id())) {
|
message_.pointer_id())) {
|
||||||
transformation_context->GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
transformation_context->GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
message_.fresh_id());
|
message_.fresh_id(), ir_context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ void TransformationAddConstantBoolean::Apply(
|
|||||||
|
|
||||||
if (message_.is_irrelevant()) {
|
if (message_.is_irrelevant()) {
|
||||||
transformation_context->GetFactManager()->AddFactIdIsIrrelevant(
|
transformation_context->GetFactManager()->AddFactIdIsIrrelevant(
|
||||||
message_.fresh_id());
|
message_.fresh_id(), ir_context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ void TransformationAddConstantComposite::Apply(
|
|||||||
|
|
||||||
if (message_.is_irrelevant()) {
|
if (message_.is_irrelevant()) {
|
||||||
transformation_context->GetFactManager()->AddFactIdIsIrrelevant(
|
transformation_context->GetFactManager()->AddFactIdIsIrrelevant(
|
||||||
message_.fresh_id());
|
message_.fresh_id(), ir_context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ void TransformationAddConstantScalar::Apply(
|
|||||||
|
|
||||||
if (message_.is_irrelevant()) {
|
if (message_.is_irrelevant()) {
|
||||||
transformation_context->GetFactManager()->AddFactIdIsIrrelevant(
|
transformation_context->GetFactManager()->AddFactIdIsIrrelevant(
|
||||||
message_.fresh_id());
|
message_.fresh_id(), ir_context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,6 +132,10 @@ void TransformationAddCopyMemory::Apply(
|
|||||||
|
|
||||||
fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id());
|
fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id());
|
||||||
|
|
||||||
|
// Make sure our changes are analyzed
|
||||||
|
ir_context->InvalidateAnalysesExceptFor(
|
||||||
|
opt::IRContext::Analysis::kAnalysisNone);
|
||||||
|
|
||||||
// Even though the copy memory instruction will - at least temporarily - lead
|
// Even though the copy memory instruction will - at least temporarily - lead
|
||||||
// to the destination and source pointers referring to identical values, this
|
// to the destination and source pointers referring to identical values, this
|
||||||
// fact is not guaranteed to hold throughout execution of the SPIR-V code
|
// fact is not guaranteed to hold throughout execution of the SPIR-V code
|
||||||
@ -139,11 +143,7 @@ void TransformationAddCopyMemory::Apply(
|
|||||||
// about the destination pointer, and record this fact so that the destination
|
// about the destination pointer, and record this fact so that the destination
|
||||||
// pointer can be used freely by other fuzzer passes.
|
// pointer can be used freely by other fuzzer passes.
|
||||||
transformation_context->GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
transformation_context->GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
message_.fresh_id());
|
message_.fresh_id(), ir_context);
|
||||||
|
|
||||||
// Make sure our changes are analyzed
|
|
||||||
ir_context->InvalidateAnalysesExceptFor(
|
|
||||||
opt::IRContext::Analysis::kAnalysisNone);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protobufs::Transformation TransformationAddCopyMemory::ToMessage() const {
|
protobufs::Transformation TransformationAddCopyMemory::ToMessage() const {
|
||||||
|
@ -168,30 +168,6 @@ void TransformationAddFunction::Apply(
|
|||||||
(void)(success); // Keep release builds happy (otherwise they may complain
|
(void)(success); // Keep release builds happy (otherwise they may complain
|
||||||
// that |success| is not used).
|
// that |success| is not used).
|
||||||
|
|
||||||
// Record the fact that all pointer parameters and variables declared in the
|
|
||||||
// function should be regarded as having irrelevant values. This allows other
|
|
||||||
// passes to store arbitrarily to such variables, and to pass them freely as
|
|
||||||
// parameters to other functions knowing that it is OK if they get
|
|
||||||
// over-written.
|
|
||||||
for (auto& instruction : message_.instruction()) {
|
|
||||||
switch (instruction.opcode()) {
|
|
||||||
case SpvOpFunctionParameter:
|
|
||||||
if (ir_context->get_def_use_mgr()
|
|
||||||
->GetDef(instruction.result_type_id())
|
|
||||||
->opcode() == SpvOpTypePointer) {
|
|
||||||
transformation_context->GetFactManager()
|
|
||||||
->AddFactValueOfPointeeIsIrrelevant(instruction.result_id());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SpvOpVariable:
|
|
||||||
transformation_context->GetFactManager()
|
|
||||||
->AddFactValueOfPointeeIsIrrelevant(instruction.result_id());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message_.is_livesafe()) {
|
if (message_.is_livesafe()) {
|
||||||
// Make the function livesafe, which also should succeed.
|
// Make the function livesafe, which also should succeed.
|
||||||
success = TryToMakeFunctionLivesafe(ir_context, *transformation_context);
|
success = TryToMakeFunctionLivesafe(ir_context, *transformation_context);
|
||||||
@ -214,6 +190,32 @@ void TransformationAddFunction::Apply(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone);
|
ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone);
|
||||||
|
|
||||||
|
// Record the fact that all pointer parameters and variables declared in the
|
||||||
|
// function should be regarded as having irrelevant values. This allows other
|
||||||
|
// passes to store arbitrarily to such variables, and to pass them freely as
|
||||||
|
// parameters to other functions knowing that it is OK if they get
|
||||||
|
// over-written.
|
||||||
|
for (auto& instruction : message_.instruction()) {
|
||||||
|
switch (instruction.opcode()) {
|
||||||
|
case SpvOpFunctionParameter:
|
||||||
|
if (ir_context->get_def_use_mgr()
|
||||||
|
->GetDef(instruction.result_type_id())
|
||||||
|
->opcode() == SpvOpTypePointer) {
|
||||||
|
transformation_context->GetFactManager()
|
||||||
|
->AddFactValueOfPointeeIsIrrelevant(instruction.result_id(),
|
||||||
|
ir_context);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SpvOpVariable:
|
||||||
|
transformation_context->GetFactManager()
|
||||||
|
->AddFactValueOfPointeeIsIrrelevant(instruction.result_id(),
|
||||||
|
ir_context);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protobufs::Transformation TransformationAddFunction::ToMessage() const {
|
protobufs::Transformation TransformationAddFunction::ToMessage() const {
|
||||||
|
@ -98,15 +98,15 @@ void TransformationAddGlobalVariable::Apply(
|
|||||||
static_cast<SpvStorageClass>(message_.storage_class()),
|
static_cast<SpvStorageClass>(message_.storage_class()),
|
||||||
message_.initializer_id());
|
message_.initializer_id());
|
||||||
|
|
||||||
if (message_.value_is_irrelevant()) {
|
|
||||||
transformation_context->GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
|
||||||
message_.fresh_id());
|
|
||||||
}
|
|
||||||
|
|
||||||
// We have added an instruction to the module, so need to be careful about the
|
// We have added an instruction to the module, so need to be careful about the
|
||||||
// validity of existing analyses.
|
// validity of existing analyses.
|
||||||
ir_context->InvalidateAnalysesExceptFor(
|
ir_context->InvalidateAnalysesExceptFor(
|
||||||
opt::IRContext::Analysis::kAnalysisNone);
|
opt::IRContext::Analysis::kAnalysisNone);
|
||||||
|
|
||||||
|
if (message_.value_is_irrelevant()) {
|
||||||
|
transformation_context->GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
|
message_.fresh_id(), ir_context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protobufs::Transformation TransformationAddGlobalVariable::ToMessage() const {
|
protobufs::Transformation TransformationAddGlobalVariable::ToMessage() const {
|
||||||
|
@ -74,11 +74,12 @@ void TransformationAddLocalVariable::Apply(
|
|||||||
message_.type_id(), message_.function_id(),
|
message_.type_id(), message_.function_id(),
|
||||||
message_.initializer_id());
|
message_.initializer_id());
|
||||||
|
|
||||||
|
ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone);
|
||||||
|
|
||||||
if (message_.value_is_irrelevant()) {
|
if (message_.value_is_irrelevant()) {
|
||||||
transformation_context->GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
transformation_context->GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
message_.fresh_id());
|
message_.fresh_id(), ir_context);
|
||||||
}
|
}
|
||||||
ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protobufs::Transformation TransformationAddLocalVariable::ToMessage() const {
|
protobufs::Transformation TransformationAddLocalVariable::ToMessage() const {
|
||||||
|
@ -125,20 +125,6 @@ void TransformationAddParameter::Apply(
|
|||||||
|
|
||||||
fuzzerutil::UpdateModuleIdBound(ir_context, message_.parameter_fresh_id());
|
fuzzerutil::UpdateModuleIdBound(ir_context, message_.parameter_fresh_id());
|
||||||
|
|
||||||
// If the |new_parameter_type_id| is not a pointer type, mark id as
|
|
||||||
// irrelevant so that we can replace its use with some other id. If the
|
|
||||||
// |new_parameter_type_id| is a pointer type, we cannot mark it with
|
|
||||||
// IdIsIrrelevant, because this pointer might be replaced by a pointer from
|
|
||||||
// original shader. This would change the semantics of the module. In the case
|
|
||||||
// of a pointer type we mark it with PointeeValueIsIrrelevant.
|
|
||||||
if (new_parameter_type->kind() != opt::analysis::Type::kPointer) {
|
|
||||||
transformation_context->GetFactManager()->AddFactIdIsIrrelevant(
|
|
||||||
message_.parameter_fresh_id());
|
|
||||||
} else {
|
|
||||||
transformation_context->GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
|
||||||
message_.parameter_fresh_id());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fix all OpFunctionCall instructions.
|
// Fix all OpFunctionCall instructions.
|
||||||
for (auto* inst : fuzzerutil::GetCallers(ir_context, function->result_id())) {
|
for (auto* inst : fuzzerutil::GetCallers(ir_context, function->result_id())) {
|
||||||
inst->AddOperand(
|
inst->AddOperand(
|
||||||
@ -167,9 +153,25 @@ void TransformationAddParameter::Apply(
|
|||||||
old_function_type->GetSingleWordInOperand(0), parameter_type_ids);
|
old_function_type->GetSingleWordInOperand(0), parameter_type_ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto new_parameter_kind = new_parameter_type->kind();
|
||||||
|
|
||||||
// Make sure our changes are analyzed.
|
// Make sure our changes are analyzed.
|
||||||
ir_context->InvalidateAnalysesExceptFor(
|
ir_context->InvalidateAnalysesExceptFor(
|
||||||
opt::IRContext::Analysis::kAnalysisNone);
|
opt::IRContext::Analysis::kAnalysisNone);
|
||||||
|
|
||||||
|
// If the |new_parameter_type_id| is not a pointer type, mark id as
|
||||||
|
// irrelevant so that we can replace its use with some other id. If the
|
||||||
|
// |new_parameter_type_id| is a pointer type, we cannot mark it with
|
||||||
|
// IdIsIrrelevant, because this pointer might be replaced by a pointer from
|
||||||
|
// original shader. This would change the semantics of the module. In the case
|
||||||
|
// of a pointer type we mark it with PointeeValueIsIrrelevant.
|
||||||
|
if (new_parameter_kind != opt::analysis::Type::kPointer) {
|
||||||
|
transformation_context->GetFactManager()->AddFactIdIsIrrelevant(
|
||||||
|
message_.parameter_fresh_id(), ir_context);
|
||||||
|
} else {
|
||||||
|
transformation_context->GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
|
message_.parameter_fresh_id(), ir_context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protobufs::Transformation TransformationAddParameter::ToMessage() const {
|
protobufs::Transformation TransformationAddParameter::ToMessage() const {
|
||||||
|
@ -109,7 +109,7 @@ void TransformationAddSynonym::Apply(
|
|||||||
message_.result_id()) &&
|
message_.result_id()) &&
|
||||||
new_synonym_type->AsPointer()) {
|
new_synonym_type->AsPointer()) {
|
||||||
transformation_context->GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
transformation_context->GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
message_.synonym_fresh_id());
|
message_.synonym_fresh_id(), ir_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark two ids as synonymous.
|
// Mark two ids as synonymous.
|
||||||
|
@ -632,16 +632,27 @@ TransformationOutlineFunction::PrepareFunctionPrototype(
|
|||||||
// Add one parameter to the function for each input id, using the fresh ids
|
// Add one parameter to the function for each input id, using the fresh ids
|
||||||
// provided in |input_id_to_fresh_id_map|, or overflow ids if needed.
|
// provided in |input_id_to_fresh_id_map|, or overflow ids if needed.
|
||||||
for (auto id : region_input_ids) {
|
for (auto id : region_input_ids) {
|
||||||
|
uint32_t fresh_id = input_id_to_fresh_id_map.at(id);
|
||||||
outlined_function->AddParameter(MakeUnique<opt::Instruction>(
|
outlined_function->AddParameter(MakeUnique<opt::Instruction>(
|
||||||
ir_context, SpvOpFunctionParameter,
|
ir_context, SpvOpFunctionParameter,
|
||||||
ir_context->get_def_use_mgr()->GetDef(id)->type_id(),
|
ir_context->get_def_use_mgr()->GetDef(id)->type_id(), fresh_id,
|
||||||
input_id_to_fresh_id_map.at(id), opt::Instruction::OperandList()));
|
opt::Instruction::OperandList()));
|
||||||
|
|
||||||
|
// Analyse the use of the new parameter instruction.
|
||||||
|
outlined_function->ForEachParam(
|
||||||
|
[fresh_id, ir_context](opt::Instruction* inst) {
|
||||||
|
if (inst->result_id() == fresh_id) {
|
||||||
|
ir_context->AnalyzeDefUse(inst);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// If the input id is an irrelevant-valued variable, the same should be true
|
// If the input id is an irrelevant-valued variable, the same should be true
|
||||||
// of the corresponding parameter.
|
// of the corresponding parameter.
|
||||||
if (transformation_context->GetFactManager()->PointeeValueIsIrrelevant(
|
if (transformation_context->GetFactManager()->PointeeValueIsIrrelevant(
|
||||||
id)) {
|
id)) {
|
||||||
transformation_context->GetFactManager()
|
transformation_context->GetFactManager()
|
||||||
->AddFactValueOfPointeeIsIrrelevant(input_id_to_fresh_id_map.at(id));
|
->AddFactValueOfPointeeIsIrrelevant(input_id_to_fresh_id_map.at(id),
|
||||||
|
ir_context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,14 +99,6 @@ void TransformationReplaceParameterWithGlobal::Apply(
|
|||||||
fuzzerutil::MaybeGetZeroConstant(ir_context, *transformation_context,
|
fuzzerutil::MaybeGetZeroConstant(ir_context, *transformation_context,
|
||||||
param_inst->type_id(), false));
|
param_inst->type_id(), false));
|
||||||
|
|
||||||
// Mark the global variable's pointee as irrelevant if replaced parameter is
|
|
||||||
// irrelevant.
|
|
||||||
if (transformation_context->GetFactManager()->IdIsIrrelevant(
|
|
||||||
message_.parameter_id())) {
|
|
||||||
transformation_context->GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
|
||||||
message_.global_variable_fresh_id());
|
|
||||||
}
|
|
||||||
|
|
||||||
auto* function = fuzzerutil::GetFunctionFromParameterId(
|
auto* function = fuzzerutil::GetFunctionFromParameterId(
|
||||||
ir_context, message_.parameter_id());
|
ir_context, message_.parameter_id());
|
||||||
assert(function && "Function must exist");
|
assert(function && "Function must exist");
|
||||||
@ -188,6 +180,14 @@ void TransformationReplaceParameterWithGlobal::Apply(
|
|||||||
// Make sure our changes are analyzed
|
// Make sure our changes are analyzed
|
||||||
ir_context->InvalidateAnalysesExceptFor(
|
ir_context->InvalidateAnalysesExceptFor(
|
||||||
opt::IRContext::Analysis::kAnalysisNone);
|
opt::IRContext::Analysis::kAnalysisNone);
|
||||||
|
|
||||||
|
// Mark the pointee of the global variable storing the parameter's value as
|
||||||
|
// irrelevant if replaced parameter is irrelevant.
|
||||||
|
if (transformation_context->GetFactManager()->IdIsIrrelevant(
|
||||||
|
message_.parameter_id())) {
|
||||||
|
transformation_context->GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
|
message_.global_variable_fresh_id(), ir_context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protobufs::Transformation TransformationReplaceParameterWithGlobal::ToMessage()
|
protobufs::Transformation TransformationReplaceParameterWithGlobal::ToMessage()
|
||||||
|
@ -1370,7 +1370,7 @@ TEST(FactManagerTest, IdIsIrrelevant) {
|
|||||||
ASSERT_FALSE(fact_manager.IdIsIrrelevant(12));
|
ASSERT_FALSE(fact_manager.IdIsIrrelevant(12));
|
||||||
ASSERT_FALSE(fact_manager.IdIsIrrelevant(13));
|
ASSERT_FALSE(fact_manager.IdIsIrrelevant(13));
|
||||||
|
|
||||||
fact_manager.AddFactIdIsIrrelevant(12);
|
fact_manager.AddFactIdIsIrrelevant(12, context.get());
|
||||||
|
|
||||||
ASSERT_TRUE(fact_manager.IdIsIrrelevant(12));
|
ASSERT_TRUE(fact_manager.IdIsIrrelevant(12));
|
||||||
ASSERT_FALSE(fact_manager.IdIsIrrelevant(13));
|
ASSERT_FALSE(fact_manager.IdIsIrrelevant(13));
|
||||||
@ -1406,12 +1406,12 @@ TEST(FactManagerTest, GetIrrelevantIds) {
|
|||||||
ASSERT_TRUE(fact_manager.GetIrrelevantIds() ==
|
ASSERT_TRUE(fact_manager.GetIrrelevantIds() ==
|
||||||
std::unordered_set<uint32_t>({}));
|
std::unordered_set<uint32_t>({}));
|
||||||
|
|
||||||
fact_manager.AddFactIdIsIrrelevant(12);
|
fact_manager.AddFactIdIsIrrelevant(12, context.get());
|
||||||
|
|
||||||
ASSERT_TRUE(fact_manager.GetIrrelevantIds() ==
|
ASSERT_TRUE(fact_manager.GetIrrelevantIds() ==
|
||||||
std::unordered_set<uint32_t>({12}));
|
std::unordered_set<uint32_t>({12}));
|
||||||
|
|
||||||
fact_manager.AddFactIdIsIrrelevant(13);
|
fact_manager.AddFactIdIsIrrelevant(13, context.get());
|
||||||
|
|
||||||
ASSERT_TRUE(fact_manager.GetIrrelevantIds() ==
|
ASSERT_TRUE(fact_manager.GetIrrelevantIds() ==
|
||||||
std::unordered_set<uint32_t>({12, 13}));
|
std::unordered_set<uint32_t>({12, 13}));
|
||||||
|
@ -123,7 +123,7 @@ TEST(TransformationAccessChainTest, BasicTest) {
|
|||||||
validator_options);
|
validator_options);
|
||||||
|
|
||||||
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
54);
|
54, context.get());
|
||||||
|
|
||||||
// Bad: id is not fresh
|
// Bad: id is not fresh
|
||||||
ASSERT_FALSE(TransformationAccessChain(
|
ASSERT_FALSE(TransformationAccessChain(
|
||||||
|
@ -75,7 +75,7 @@ TEST(TransformationAddSynonymTest, NotApplicable) {
|
|||||||
TransformationContext transformation_context(&fact_manager,
|
TransformationContext transformation_context(&fact_manager,
|
||||||
validator_options);
|
validator_options);
|
||||||
|
|
||||||
fact_manager.AddFactIdIsIrrelevant(24);
|
fact_manager.AddFactIdIsIrrelevant(24, context.get());
|
||||||
|
|
||||||
auto insert_before = MakeInstructionDescriptor(22, SpvOpReturn, 0);
|
auto insert_before = MakeInstructionDescriptor(22, SpvOpReturn, 0);
|
||||||
|
|
||||||
@ -1300,7 +1300,8 @@ TEST(TransformationAddSynonymTest, PropagateIrrelevantPointeeFact) {
|
|||||||
TransformationContext transformation_context(&fact_manager,
|
TransformationContext transformation_context(&fact_manager,
|
||||||
validator_options);
|
validator_options);
|
||||||
|
|
||||||
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(8);
|
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
|
8, context.get());
|
||||||
|
|
||||||
TransformationAddSynonym transformation1(
|
TransformationAddSynonym transformation1(
|
||||||
8, protobufs::TransformationAddSynonym::COPY_OBJECT, 100,
|
8, protobufs::TransformationAddSynonym::COPY_OBJECT, 100,
|
||||||
|
@ -1515,7 +1515,7 @@ TEST(TransformationCompositeConstructTest, DontAddSynonymsForIrrelevantIds) {
|
|||||||
TransformationContext transformation_context(&fact_manager,
|
TransformationContext transformation_context(&fact_manager,
|
||||||
validator_options);
|
validator_options);
|
||||||
|
|
||||||
fact_manager.AddFactIdIsIrrelevant(25);
|
fact_manager.AddFactIdIsIrrelevant(25, context.get());
|
||||||
|
|
||||||
TransformationCompositeConstruct transformation(
|
TransformationCompositeConstruct transformation(
|
||||||
32, {25, 28, 31}, MakeInstructionDescriptor(31, SpvOpReturn, 0), 200);
|
32, {25, 28, 31}, MakeInstructionDescriptor(31, SpvOpReturn, 0), 200);
|
||||||
|
@ -569,7 +569,7 @@ TEST(TransformationCompositeExtractTest, DontAddSynonymsForIrrelevantIds) {
|
|||||||
TransformationContext transformation_context(&fact_manager,
|
TransformationContext transformation_context(&fact_manager,
|
||||||
validator_options);
|
validator_options);
|
||||||
|
|
||||||
fact_manager.AddFactIdIsIrrelevant(100);
|
fact_manager.AddFactIdIsIrrelevant(100, context.get());
|
||||||
TransformationCompositeExtract transformation(
|
TransformationCompositeExtract transformation(
|
||||||
MakeInstructionDescriptor(36, SpvOpConvertFToS, 0), 201, 100, {2});
|
MakeInstructionDescriptor(36, SpvOpConvertFToS, 0), 201, 100, {2});
|
||||||
ASSERT_TRUE(
|
ASSERT_TRUE(
|
||||||
|
@ -365,7 +365,7 @@ TEST(TransformationCompositeInsertTest, IrrelevantCompositeNoSynonyms) {
|
|||||||
validator_options);
|
validator_options);
|
||||||
|
|
||||||
// Add fact that the composite is irrelevant.
|
// Add fact that the composite is irrelevant.
|
||||||
fact_manager.AddFactIdIsIrrelevant(30);
|
fact_manager.AddFactIdIsIrrelevant(30, context.get());
|
||||||
|
|
||||||
auto transformation_good_1 = TransformationCompositeInsert(
|
auto transformation_good_1 = TransformationCompositeInsert(
|
||||||
MakeInstructionDescriptor(30, SpvOpStore, 0), 50, 30, 11, {1, 0, 0});
|
MakeInstructionDescriptor(30, SpvOpStore, 0), 50, 30, 11, {1, 0, 0});
|
||||||
@ -470,7 +470,7 @@ TEST(TransformationCompositeInsertTest, IrrelevantObjectSomeSynonyms) {
|
|||||||
validator_options);
|
validator_options);
|
||||||
|
|
||||||
// Add fact that the object is irrelevant.
|
// Add fact that the object is irrelevant.
|
||||||
fact_manager.AddFactIdIsIrrelevant(11);
|
fact_manager.AddFactIdIsIrrelevant(11, context.get());
|
||||||
|
|
||||||
auto transformation_good_1 = TransformationCompositeInsert(
|
auto transformation_good_1 = TransformationCompositeInsert(
|
||||||
MakeInstructionDescriptor(30, SpvOpStore, 0), 50, 30, 11, {1, 0, 0});
|
MakeInstructionDescriptor(30, SpvOpStore, 0), 50, 30, 11, {1, 0, 0});
|
||||||
|
@ -1578,10 +1578,10 @@ TEST(TransformationEquationInstructionTest, HandlesIrrelevantIds) {
|
|||||||
transformation.IsApplicable(context.get(), transformation_context));
|
transformation.IsApplicable(context.get(), transformation_context));
|
||||||
|
|
||||||
// Handles irrelevant ids.
|
// Handles irrelevant ids.
|
||||||
fact_manager.AddFactIdIsIrrelevant(16);
|
fact_manager.AddFactIdIsIrrelevant(16, context.get());
|
||||||
ASSERT_FALSE(
|
ASSERT_FALSE(
|
||||||
transformation.IsApplicable(context.get(), transformation_context));
|
transformation.IsApplicable(context.get(), transformation_context));
|
||||||
fact_manager.AddFactIdIsIrrelevant(15);
|
fact_manager.AddFactIdIsIrrelevant(15, context.get());
|
||||||
ASSERT_FALSE(
|
ASSERT_FALSE(
|
||||||
transformation.IsApplicable(context.get(), transformation_context));
|
transformation.IsApplicable(context.get(), transformation_context));
|
||||||
}
|
}
|
||||||
|
@ -147,23 +147,23 @@ TEST(TransformationFunctionCallTest, BasicTest) {
|
|||||||
transformation_context.GetFactManager()->AddFactFunctionIsLivesafe(21);
|
transformation_context.GetFactManager()->AddFactFunctionIsLivesafe(21);
|
||||||
transformation_context.GetFactManager()->AddFactFunctionIsLivesafe(200);
|
transformation_context.GetFactManager()->AddFactFunctionIsLivesafe(200);
|
||||||
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
71);
|
71, context.get());
|
||||||
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
72);
|
72, context.get());
|
||||||
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
19);
|
19, context.get());
|
||||||
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
20);
|
20, context.get());
|
||||||
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
23);
|
23, context.get());
|
||||||
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
44);
|
44, context.get());
|
||||||
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
46);
|
46, context.get());
|
||||||
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
51);
|
51, context.get());
|
||||||
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
52);
|
52, context.get());
|
||||||
|
|
||||||
// Livesafe functions with argument types: 21(7, 13), 200(7, 13)
|
// Livesafe functions with argument types: 21(7, 13), 200(7, 13)
|
||||||
// Non-livesafe functions with argument types: 4(), 10(7), 17(7, 13), 24(7)
|
// Non-livesafe functions with argument types: 4(), 10(7), 17(7, 13), 24(7)
|
||||||
|
@ -90,15 +90,15 @@ TEST(TransformationLoadTest, BasicTest) {
|
|||||||
validator_options);
|
validator_options);
|
||||||
|
|
||||||
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
27);
|
27, context.get());
|
||||||
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
11);
|
11, context.get());
|
||||||
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
46);
|
46, context.get());
|
||||||
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
16);
|
16, context.get());
|
||||||
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
52);
|
52, context.get());
|
||||||
|
|
||||||
transformation_context.GetFactManager()->AddFactBlockIsDead(36);
|
transformation_context.GetFactManager()->AddFactBlockIsDead(36);
|
||||||
|
|
||||||
|
@ -84,8 +84,8 @@ TEST(TransformationMutatePointerTest, BasicTest) {
|
|||||||
TransformationContext transformation_context(&fact_manager,
|
TransformationContext transformation_context(&fact_manager,
|
||||||
validator_options);
|
validator_options);
|
||||||
|
|
||||||
fact_manager.AddFactIdIsIrrelevant(35);
|
fact_manager.AddFactIdIsIrrelevant(35, context.get());
|
||||||
fact_manager.AddFactIdIsIrrelevant(39);
|
fact_manager.AddFactIdIsIrrelevant(39, context.get());
|
||||||
|
|
||||||
const auto insert_before = MakeInstructionDescriptor(26, SpvOpReturn, 0);
|
const auto insert_before = MakeInstructionDescriptor(26, SpvOpReturn, 0);
|
||||||
|
|
||||||
@ -140,7 +140,7 @@ TEST(TransformationMutatePointerTest, BasicTest) {
|
|||||||
26, 70, MakeInstructionDescriptor(26, SpvOpAccessChain, 0))
|
26, 70, MakeInstructionDescriptor(26, SpvOpAccessChain, 0))
|
||||||
.IsApplicable(context.get(), transformation_context));
|
.IsApplicable(context.get(), transformation_context));
|
||||||
|
|
||||||
fact_manager.AddFactIdIsIrrelevant(40);
|
fact_manager.AddFactIdIsIrrelevant(40, context.get());
|
||||||
|
|
||||||
uint32_t fresh_id = 70;
|
uint32_t fresh_id = 70;
|
||||||
uint32_t pointer_ids[] = {
|
uint32_t pointer_ids[] = {
|
||||||
@ -274,7 +274,7 @@ TEST(TransformationMutatePointerTest, HandlesUnreachableBlocks) {
|
|||||||
TransformationContext transformation_context(&fact_manager,
|
TransformationContext transformation_context(&fact_manager,
|
||||||
validator_options);
|
validator_options);
|
||||||
|
|
||||||
fact_manager.AddFactIdIsIrrelevant(7);
|
fact_manager.AddFactIdIsIrrelevant(7, context.get());
|
||||||
|
|
||||||
ASSERT_FALSE(
|
ASSERT_FALSE(
|
||||||
context->GetDominatorAnalysis(context->GetFunction(4))->IsReachable(10));
|
context->GetDominatorAnalysis(context->GetFunction(4))->IsReachable(10));
|
||||||
|
@ -2033,9 +2033,9 @@ TEST(TransformationOutlineFunctionTest, OutlineLivesafe) {
|
|||||||
|
|
||||||
transformation_context.GetFactManager()->AddFactFunctionIsLivesafe(30);
|
transformation_context.GetFactManager()->AddFactFunctionIsLivesafe(30);
|
||||||
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
200);
|
200, context.get());
|
||||||
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
201);
|
201, context.get());
|
||||||
|
|
||||||
TransformationOutlineFunction transformation(
|
TransformationOutlineFunction transformation(
|
||||||
/*entry_block*/ 198,
|
/*entry_block*/ 198,
|
||||||
@ -2429,9 +2429,10 @@ TEST(TransformationOutlineFunctionTest,
|
|||||||
TransformationContext transformation_context(&fact_manager,
|
TransformationContext transformation_context(&fact_manager,
|
||||||
validator_options);
|
validator_options);
|
||||||
|
|
||||||
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(9);
|
|
||||||
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
14);
|
9, context.get());
|
||||||
|
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
|
14, context.get());
|
||||||
|
|
||||||
TransformationOutlineFunction transformation(
|
TransformationOutlineFunction transformation(
|
||||||
/*entry_block*/ 50,
|
/*entry_block*/ 50,
|
||||||
|
@ -682,7 +682,7 @@ TEST(TransformationPushIdThroughVariableTest, DontAddSynonymsForIrrelevantIds) {
|
|||||||
// Tests the reference shader validity.
|
// Tests the reference shader validity.
|
||||||
ASSERT_TRUE(IsValid(env, context.get()));
|
ASSERT_TRUE(IsValid(env, context.get()));
|
||||||
|
|
||||||
fact_manager.AddFactIdIsIrrelevant(21);
|
fact_manager.AddFactIdIsIrrelevant(21, context.get());
|
||||||
|
|
||||||
uint32_t value_id = 21;
|
uint32_t value_id = 21;
|
||||||
uint32_t value_synonym_id = 62;
|
uint32_t value_synonym_id = 62;
|
||||||
|
@ -814,7 +814,7 @@ TEST(TransformationRecordSynonymousConstantsTest, FirstIrrelevantConstant) {
|
|||||||
ASSERT_TRUE(TransformationRecordSynonymousConstants(7, 8).IsApplicable(
|
ASSERT_TRUE(TransformationRecordSynonymousConstants(7, 8).IsApplicable(
|
||||||
context.get(), transformation_context));
|
context.get(), transformation_context));
|
||||||
|
|
||||||
fact_manager.AddFactIdIsIrrelevant(7);
|
fact_manager.AddFactIdIsIrrelevant(7, context.get());
|
||||||
ASSERT_FALSE(TransformationRecordSynonymousConstants(7, 8).IsApplicable(
|
ASSERT_FALSE(TransformationRecordSynonymousConstants(7, 8).IsApplicable(
|
||||||
context.get(), transformation_context));
|
context.get(), transformation_context));
|
||||||
}
|
}
|
||||||
@ -851,7 +851,7 @@ TEST(TransformationRecordSynonymousConstantsTest, SecondIrrelevantConstant) {
|
|||||||
ASSERT_TRUE(TransformationRecordSynonymousConstants(7, 8).IsApplicable(
|
ASSERT_TRUE(TransformationRecordSynonymousConstants(7, 8).IsApplicable(
|
||||||
context.get(), transformation_context));
|
context.get(), transformation_context));
|
||||||
|
|
||||||
fact_manager.AddFactIdIsIrrelevant(8);
|
fact_manager.AddFactIdIsIrrelevant(8, context.get());
|
||||||
ASSERT_FALSE(TransformationRecordSynonymousConstants(7, 8).IsApplicable(
|
ASSERT_FALSE(TransformationRecordSynonymousConstants(7, 8).IsApplicable(
|
||||||
context.get(), transformation_context));
|
context.get(), transformation_context));
|
||||||
}
|
}
|
||||||
|
@ -61,11 +61,12 @@ const std::string shader = R"(
|
|||||||
OpFunctionEnd
|
OpFunctionEnd
|
||||||
)";
|
)";
|
||||||
|
|
||||||
void SetUpIrrelevantIdFacts(FactManager* fact_manager) {
|
void SetUpIrrelevantIdFacts(FactManager* fact_manager,
|
||||||
fact_manager->AddFactIdIsIrrelevant(17);
|
opt::IRContext* context) {
|
||||||
fact_manager->AddFactIdIsIrrelevant(23);
|
fact_manager->AddFactIdIsIrrelevant(17, context);
|
||||||
fact_manager->AddFactIdIsIrrelevant(24);
|
fact_manager->AddFactIdIsIrrelevant(23, context);
|
||||||
fact_manager->AddFactIdIsIrrelevant(25);
|
fact_manager->AddFactIdIsIrrelevant(24, context);
|
||||||
|
fact_manager->AddFactIdIsIrrelevant(25, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TransformationReplaceIrrelevantIdTest, Inapplicable) {
|
TEST(TransformationReplaceIrrelevantIdTest, Inapplicable) {
|
||||||
@ -79,7 +80,8 @@ TEST(TransformationReplaceIrrelevantIdTest, Inapplicable) {
|
|||||||
TransformationContext transformation_context(&fact_manager,
|
TransformationContext transformation_context(&fact_manager,
|
||||||
validator_options);
|
validator_options);
|
||||||
|
|
||||||
SetUpIrrelevantIdFacts(transformation_context.GetFactManager());
|
SetUpIrrelevantIdFacts(transformation_context.GetFactManager(),
|
||||||
|
context.get());
|
||||||
|
|
||||||
auto instruction_21_descriptor =
|
auto instruction_21_descriptor =
|
||||||
MakeInstructionDescriptor(21, SpvOpAccessChain, 0);
|
MakeInstructionDescriptor(21, SpvOpAccessChain, 0);
|
||||||
@ -132,7 +134,8 @@ TEST(TransformationReplaceIrrelevantIdTest, Apply) {
|
|||||||
TransformationContext transformation_context(&fact_manager,
|
TransformationContext transformation_context(&fact_manager,
|
||||||
validator_options);
|
validator_options);
|
||||||
|
|
||||||
SetUpIrrelevantIdFacts(transformation_context.GetFactManager());
|
SetUpIrrelevantIdFacts(transformation_context.GetFactManager(),
|
||||||
|
context.get());
|
||||||
|
|
||||||
auto instruction_24_descriptor = MakeInstructionDescriptor(24, SpvOpIAdd, 0);
|
auto instruction_24_descriptor = MakeInstructionDescriptor(24, SpvOpIAdd, 0);
|
||||||
|
|
||||||
|
@ -330,7 +330,7 @@ TEST(TransformationReplaceParameterWithGlobalTest,
|
|||||||
TransformationContext transformation_context(&fact_manager,
|
TransformationContext transformation_context(&fact_manager,
|
||||||
validator_options);
|
validator_options);
|
||||||
|
|
||||||
fact_manager.AddFactIdIsIrrelevant(10);
|
fact_manager.AddFactIdIsIrrelevant(10, context.get());
|
||||||
|
|
||||||
{
|
{
|
||||||
TransformationReplaceParameterWithGlobal transformation(20, 10, 21);
|
TransformationReplaceParameterWithGlobal transformation(20, 10, 21);
|
||||||
|
@ -99,19 +99,19 @@ TEST(TransformationStoreTest, BasicTest) {
|
|||||||
validator_options);
|
validator_options);
|
||||||
|
|
||||||
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
27);
|
27, context.get());
|
||||||
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
11);
|
11, context.get());
|
||||||
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
46);
|
46, context.get());
|
||||||
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
16);
|
16, context.get());
|
||||||
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
52);
|
52, context.get());
|
||||||
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
81);
|
81, context.get());
|
||||||
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
|
||||||
82);
|
82, context.get());
|
||||||
|
|
||||||
transformation_context.GetFactManager()->AddFactBlockIsDead(36);
|
transformation_context.GetFactManager()->AddFactBlockIsDead(36);
|
||||||
|
|
||||||
|
@ -693,7 +693,7 @@ TEST(TransformationVectorShuffle, HandlesIrrelevantIds2) {
|
|||||||
TransformationContext transformation_context(&fact_manager,
|
TransformationContext transformation_context(&fact_manager,
|
||||||
validator_options);
|
validator_options);
|
||||||
|
|
||||||
fact_manager.AddFactIdIsIrrelevant(112);
|
fact_manager.AddFactIdIsIrrelevant(112, context.get());
|
||||||
TransformationVectorShuffle transformation(
|
TransformationVectorShuffle transformation(
|
||||||
MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 12, 112, {2, 0});
|
MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 12, 112, {2, 0});
|
||||||
ASSERT_TRUE(
|
ASSERT_TRUE(
|
||||||
|
Loading…
Reference in New Issue
Block a user