spirv-fuzz: Refactor conditions in the fact manager (#3867)
Refactors conditions and names of some methods in the fact manager. Part of #3698.
diff --git a/source/fuzz/fact_manager/constant_uniform_facts.cpp b/source/fuzz/fact_manager/constant_uniform_facts.cpp
index 23e3829..a629c0d 100644
--- a/source/fuzz/fact_manager/constant_uniform_facts.cpp
+++ b/source/fuzz/fact_manager/constant_uniform_facts.cpp
@@ -163,7 +163,8 @@
return true;
}
-bool ConstantUniformFacts::AddFact(const protobufs::FactConstantUniform& fact) {
+bool ConstantUniformFacts::MaybeAddFact(
+ const protobufs::FactConstantUniform& fact) {
// Try to find a unique instruction that declares a variable such that the
// variable is decorated with the descriptor set and binding associated with
// the constant uniform fact.
diff --git a/source/fuzz/fact_manager/constant_uniform_facts.h b/source/fuzz/fact_manager/constant_uniform_facts.h
index a136a05..41d253e 100644
--- a/source/fuzz/fact_manager/constant_uniform_facts.h
+++ b/source/fuzz/fact_manager/constant_uniform_facts.h
@@ -31,7 +31,7 @@
explicit ConstantUniformFacts(opt::IRContext* ir_context);
// See method in FactManager which delegates to this method.
- bool AddFact(const protobufs::FactConstantUniform& fact);
+ bool MaybeAddFact(const protobufs::FactConstantUniform& fact);
// See method in FactManager which delegates to this method.
std::vector<uint32_t> GetConstantsAvailableFromUniformsForType(
diff --git a/source/fuzz/fact_manager/data_synonym_and_id_equation_facts.cpp b/source/fuzz/fact_manager/data_synonym_and_id_equation_facts.cpp
index 5fc2d7f..de16472 100644
--- a/source/fuzz/fact_manager/data_synonym_and_id_equation_facts.cpp
+++ b/source/fuzz/fact_manager/data_synonym_and_id_equation_facts.cpp
@@ -55,32 +55,39 @@
opt::IRContext* ir_context)
: ir_context_(ir_context) {}
-void DataSynonymAndIdEquationFacts::AddFact(
+bool DataSynonymAndIdEquationFacts::MaybeAddFact(
const protobufs::FactDataSynonym& fact,
const DeadBlockFacts& dead_block_facts,
const IrrelevantValueFacts& irrelevant_value_facts) {
- (void)dead_block_facts; // Keep release compilers happy.
- (void)irrelevant_value_facts; // Keep release compilers happy.
- assert(!irrelevant_value_facts.IdIsIrrelevant(fact.data1().object(),
- dead_block_facts) &&
- !irrelevant_value_facts.IdIsIrrelevant(fact.data2().object(),
- dead_block_facts) &&
- "Irrelevant ids cannot be synonymous with other ids.");
+ if (irrelevant_value_facts.IdIsIrrelevant(fact.data1().object(),
+ dead_block_facts) ||
+ irrelevant_value_facts.IdIsIrrelevant(fact.data2().object(),
+ dead_block_facts)) {
+ // Irrelevant ids cannot be synonymous with other ids.
+ return false;
+ }
// Add the fact, including all facts relating sub-components of the data
// descriptors that are involved.
AddDataSynonymFactRecursive(fact.data1(), fact.data2());
+ return true;
}
-void DataSynonymAndIdEquationFacts::AddFact(
+bool DataSynonymAndIdEquationFacts::MaybeAddFact(
const protobufs::FactIdEquation& fact,
const DeadBlockFacts& dead_block_facts,
const IrrelevantValueFacts& irrelevant_value_facts) {
- (void)dead_block_facts; // Keep release compilers happy.
- (void)irrelevant_value_facts; // Keep release compilers happy.
- assert(
- !irrelevant_value_facts.IdIsIrrelevant(fact.lhs_id(), dead_block_facts) &&
- "Irrelevant ids are not allowed.");
+ if (irrelevant_value_facts.IdIsIrrelevant(fact.lhs_id(), dead_block_facts)) {
+ // Irrelevant ids cannot participate in IdEquation facts.
+ return false;
+ }
+
+ for (auto id : fact.rhs_id()) {
+ if (irrelevant_value_facts.IdIsIrrelevant(id, dead_block_facts)) {
+ // Irrelevant ids cannot participate in IdEquation facts.
+ return false;
+ }
+ }
protobufs::DataDescriptor lhs_dd = MakeDataDescriptor(fact.lhs_id(), {});
@@ -91,9 +98,6 @@
// equation.
std::vector<const protobufs::DataDescriptor*> rhs_dds;
for (auto rhs_id : fact.rhs_id()) {
- assert(!irrelevant_value_facts.IdIsIrrelevant(rhs_id, dead_block_facts) &&
- "Irrelevant ids are not allowed.");
-
// Register a data descriptor based on this id in the equivalence relation
// if needed, and then record the equivalence class representative.
rhs_dds.push_back(RegisterDataDescriptor(MakeDataDescriptor(rhs_id, {})));
@@ -101,6 +105,7 @@
// Now add the fact.
AddEquationFactRecursive(lhs_dd, static_cast<SpvOp>(fact.opcode()), rhs_dds);
+ return true;
}
DataSynonymAndIdEquationFacts::OperationSet
diff --git a/source/fuzz/fact_manager/data_synonym_and_id_equation_facts.h b/source/fuzz/fact_manager/data_synonym_and_id_equation_facts.h
index e84632b..46f02d0 100644
--- a/source/fuzz/fact_manager/data_synonym_and_id_equation_facts.h
+++ b/source/fuzz/fact_manager/data_synonym_and_id_equation_facts.h
@@ -38,19 +38,21 @@
public:
explicit DataSynonymAndIdEquationFacts(opt::IRContext* ir_context);
- // See method in FactManager which delegates to this method.
- // |dead_block_facts| and |irrelevant_value_facts| are passed for consistency
- // checks.
- void AddFact(const protobufs::FactDataSynonym& fact,
- const DeadBlockFacts& dead_block_facts,
- const IrrelevantValueFacts& irrelevant_value_facts);
+ // See method in FactManager which delegates to this method. Returns true if
+ // neither |fact.data1()| nor |fact.data2()| contain an
+ // irrelevant id. Otherwise, returns false. |dead_block_facts| and
+ // |irrelevant_value_facts| are passed for consistency checks.
+ bool MaybeAddFact(const protobufs::FactDataSynonym& fact,
+ const DeadBlockFacts& dead_block_facts,
+ const IrrelevantValueFacts& irrelevant_value_facts);
- // See method in FactManager which delegates to this method.
- // |dead_block_facts| and |irrelevant_value_facts| are passed for consistency
- // checks.
- void AddFact(const protobufs::FactIdEquation& fact,
- const DeadBlockFacts& dead_block_facts,
- const IrrelevantValueFacts& irrelevant_value_facts);
+ // See method in FactManager which delegates to this method. Returns true if
+ // neither |fact.lhs_id()| nor any of |fact.rhs_id()| is irrelevant. Returns
+ // false otherwise. |dead_block_facts| and |irrelevant_value_facts| are passed
+ // for consistency checks.
+ bool MaybeAddFact(const protobufs::FactIdEquation& fact,
+ const DeadBlockFacts& dead_block_facts,
+ const IrrelevantValueFacts& irrelevant_value_facts);
// See method in FactManager which delegates to this method.
std::vector<const protobufs::DataDescriptor*> GetSynonymsForId(
diff --git a/source/fuzz/fact_manager/dead_block_facts.cpp b/source/fuzz/fact_manager/dead_block_facts.cpp
index 5f4f8bc..f3e0ef8 100644
--- a/source/fuzz/fact_manager/dead_block_facts.cpp
+++ b/source/fuzz/fact_manager/dead_block_facts.cpp
@@ -14,12 +14,22 @@
#include "source/fuzz/fact_manager/dead_block_facts.h"
+#include "source/fuzz/fuzzer_util.h"
+
namespace spvtools {
namespace fuzz {
namespace fact_manager {
-void DeadBlockFacts::AddFact(const protobufs::FactBlockIsDead& fact) {
+DeadBlockFacts::DeadBlockFacts(opt::IRContext* ir_context)
+ : ir_context_(ir_context) {}
+
+bool DeadBlockFacts::MaybeAddFact(const protobufs::FactBlockIsDead& fact) {
+ if (!fuzzerutil::MaybeFindBlock(ir_context_, fact.block_id())) {
+ return false;
+ }
+
dead_block_ids_.insert(fact.block_id());
+ return true;
}
bool DeadBlockFacts::BlockIsDead(uint32_t block_id) const {
diff --git a/source/fuzz/fact_manager/dead_block_facts.h b/source/fuzz/fact_manager/dead_block_facts.h
index b2da90b..8ac5c3c 100644
--- a/source/fuzz/fact_manager/dead_block_facts.h
+++ b/source/fuzz/fact_manager/dead_block_facts.h
@@ -18,6 +18,7 @@
#include <unordered_set>
#include "source/fuzz/protobufs/spirvfuzz_protobufs.h"
+#include "source/opt/ir_context.h"
namespace spvtools {
namespace fuzz {
@@ -27,8 +28,12 @@
// facts about data blocks.
class DeadBlockFacts {
public:
- // See method in FactManager which delegates to this method.
- void AddFact(const protobufs::FactBlockIsDead& fact);
+ explicit DeadBlockFacts(opt::IRContext* ir_context);
+
+ // Marks |fact.block_id()| as being dead. Returns true if |fact.block_id()|
+ // represents a result id of some OpLabel instruction in |ir_context_|.
+ // Returns false otherwise.
+ bool MaybeAddFact(const protobufs::FactBlockIsDead& fact);
// See method in FactManager which delegates to this method.
bool BlockIsDead(uint32_t block_id) const;
@@ -38,6 +43,7 @@
private:
std::unordered_set<uint32_t> dead_block_ids_;
+ opt::IRContext* ir_context_;
};
} // namespace fact_manager
diff --git a/source/fuzz/fact_manager/fact_manager.cpp b/source/fuzz/fact_manager/fact_manager.cpp
index 425b0cc..29050e9 100644
--- a/source/fuzz/fact_manager/fact_manager.cpp
+++ b/source/fuzz/fact_manager/fact_manager.cpp
@@ -90,38 +90,49 @@
FactManager::FactManager(opt::IRContext* ir_context)
: constant_uniform_facts_(ir_context),
data_synonym_and_id_equation_facts_(ir_context),
- dead_block_facts_(),
- livesafe_function_facts_(),
+ dead_block_facts_(ir_context),
+ livesafe_function_facts_(ir_context),
irrelevant_value_facts_(ir_context) {}
-void FactManager::AddFacts(const MessageConsumer& message_consumer,
- const protobufs::FactSequence& initial_facts) {
- for (auto& fact : initial_facts.fact()) {
- if (!AddFact(fact)) {
+void FactManager::AddInitialFacts(const MessageConsumer& message_consumer,
+ const protobufs::FactSequence& facts) {
+ for (auto& fact : facts.fact()) {
+ if (!MaybeAddFact(fact)) {
auto message = "Invalid fact " + ToString(fact) + " ignored.";
message_consumer(SPV_MSG_WARNING, nullptr, {}, message.c_str());
}
}
}
-bool FactManager::AddFact(const fuzz::protobufs::Fact& fact) {
+bool FactManager::MaybeAddFact(const fuzz::protobufs::Fact& fact) {
switch (fact.fact_case()) {
- case protobufs::Fact::kConstantUniformFact:
- return constant_uniform_facts_.AddFact(fact.constant_uniform_fact());
- case protobufs::Fact::kDataSynonymFact:
- data_synonym_and_id_equation_facts_.AddFact(
- fact.data_synonym_fact(), dead_block_facts_, irrelevant_value_facts_);
- return true;
case protobufs::Fact::kBlockIsDeadFact:
- dead_block_facts_.AddFact(fact.block_is_dead_fact());
- return true;
+ return dead_block_facts_.MaybeAddFact(fact.block_is_dead_fact());
+ case protobufs::Fact::kConstantUniformFact:
+ return constant_uniform_facts_.MaybeAddFact(fact.constant_uniform_fact());
+ case protobufs::Fact::kDataSynonymFact:
+ return data_synonym_and_id_equation_facts_.MaybeAddFact(
+ fact.data_synonym_fact(), dead_block_facts_, irrelevant_value_facts_);
case protobufs::Fact::kFunctionIsLivesafeFact:
- livesafe_function_facts_.AddFact(fact.function_is_livesafe_fact());
- return true;
- default:
- assert(false && "Unknown fact type.");
+ return livesafe_function_facts_.MaybeAddFact(
+ fact.function_is_livesafe_fact());
+ case protobufs::Fact::kIdEquationFact:
+ return data_synonym_and_id_equation_facts_.MaybeAddFact(
+ fact.id_equation_fact(), dead_block_facts_, irrelevant_value_facts_);
+ case protobufs::Fact::kIdIsIrrelevant:
+ return irrelevant_value_facts_.MaybeAddFact(
+ fact.id_is_irrelevant(), data_synonym_and_id_equation_facts_);
+ case protobufs::Fact::kPointeeValueIsIrrelevantFact:
+ return irrelevant_value_facts_.MaybeAddFact(
+ fact.pointee_value_is_irrelevant_fact(),
+ data_synonym_and_id_equation_facts_);
+ case protobufs::Fact::FACT_NOT_SET:
+ assert(false && "The fact must be set");
return false;
}
+
+ assert(false && "Unreachable");
+ return false;
}
void FactManager::AddFactDataSynonym(const protobufs::DataDescriptor& data1,
@@ -129,8 +140,10 @@
protobufs::FactDataSynonym fact;
*fact.mutable_data1() = data1;
*fact.mutable_data2() = data2;
- data_synonym_and_id_equation_facts_.AddFact(fact, dead_block_facts_,
- irrelevant_value_facts_);
+ auto success = data_synonym_and_id_equation_facts_.MaybeAddFact(
+ fact, dead_block_facts_, irrelevant_value_facts_);
+ (void)success; // Keep compilers happy in release mode.
+ assert(success && "Unable to create DataSynonym fact");
}
std::vector<uint32_t> FactManager::GetConstantsAvailableFromUniformsForType(
@@ -190,7 +203,9 @@
void FactManager::AddFactBlockIsDead(uint32_t block_id) {
protobufs::FactBlockIsDead fact;
fact.set_block_id(block_id);
- dead_block_facts_.AddFact(fact);
+ auto success = dead_block_facts_.MaybeAddFact(fact);
+ (void)success; // Keep compilers happy in release mode.
+ assert(success && "|block_id| is invalid");
}
bool FactManager::FunctionIsLivesafe(uint32_t function_id) const {
@@ -200,7 +215,9 @@
void FactManager::AddFactFunctionIsLivesafe(uint32_t function_id) {
protobufs::FactFunctionIsLivesafe fact;
fact.set_function_id(function_id);
- livesafe_function_facts_.AddFact(fact);
+ auto success = livesafe_function_facts_.MaybeAddFact(fact);
+ (void)success; // Keep compilers happy in release mode.
+ assert(success && "|function_id| is invalid");
}
bool FactManager::PointeeValueIsIrrelevant(uint32_t pointer_id) const {
@@ -218,13 +235,19 @@
void FactManager::AddFactValueOfPointeeIsIrrelevant(uint32_t pointer_id) {
protobufs::FactPointeeValueIsIrrelevant fact;
fact.set_pointer_id(pointer_id);
- irrelevant_value_facts_.AddFact(fact, data_synonym_and_id_equation_facts_);
+ auto success = irrelevant_value_facts_.MaybeAddFact(
+ fact, data_synonym_and_id_equation_facts_);
+ (void)success; // Keep compilers happy in release mode.
+ assert(success && "|pointer_id| is invalid");
}
void FactManager::AddFactIdIsIrrelevant(uint32_t result_id) {
protobufs::FactIdIsIrrelevant fact;
fact.set_result_id(result_id);
- irrelevant_value_facts_.AddFact(fact, data_synonym_and_id_equation_facts_);
+ auto success = irrelevant_value_facts_.MaybeAddFact(
+ fact, data_synonym_and_id_equation_facts_);
+ (void)success; // Keep compilers happy in release mode.
+ assert(success && "|result_id| is invalid");
}
void FactManager::AddFactIdEquation(uint32_t lhs_id, SpvOp opcode,
@@ -235,8 +258,10 @@
for (auto an_rhs_id : rhs_id) {
fact.add_rhs_id(an_rhs_id);
}
- data_synonym_and_id_equation_facts_.AddFact(fact, dead_block_facts_,
- irrelevant_value_facts_);
+ auto success = data_synonym_and_id_equation_facts_.MaybeAddFact(
+ fact, dead_block_facts_, irrelevant_value_facts_);
+ (void)success; // Keep compilers happy in release mode.
+ assert(success && "Can't create IdIsIrrelevant fact");
}
void FactManager::ComputeClosureOfFacts(
diff --git a/source/fuzz/fact_manager/fact_manager.h b/source/fuzz/fact_manager/fact_manager.h
index d3758b1..78769c1 100644
--- a/source/fuzz/fact_manager/fact_manager.h
+++ b/source/fuzz/fact_manager/fact_manager.h
@@ -45,24 +45,27 @@
explicit FactManager(opt::IRContext* ir_context);
// Adds all the facts from |facts|, checking them for validity with respect to
- // |context|. Warnings about invalid facts are communicated via
+ // |ir_context_|. Warnings about invalid facts are communicated via
// |message_consumer|; such facts are otherwise ignored.
- void AddFacts(const MessageConsumer& message_consumer,
- const protobufs::FactSequence& facts);
+ void AddInitialFacts(const MessageConsumer& message_consumer,
+ const protobufs::FactSequence& facts);
- // Checks the fact for validity with respect to |context|. Returns false,
- // with no side effects, if the fact is invalid. Otherwise adds |fact| to the
+ // Checks the fact for validity with respect to |ir_context_|. Returns false,
+ // with no side effects, if the fact is invalid. Otherwise adds |fact| to the
// fact manager.
- bool AddFact(const protobufs::Fact& fact);
+ bool MaybeAddFact(const protobufs::Fact& fact);
- // Record the fact that |data1| and |data2| are synonymous.
+ // Record the fact that |data1| and |data2| are synonymous. Neither |data1|
+ // nor |data2| may contain an irrelevant id.
void AddFactDataSynonym(const protobufs::DataDescriptor& data1,
const protobufs::DataDescriptor& data2);
- // Records the fact that |block_id| is dead.
+ // Records the fact that |block_id| is dead. |block_id| must be a result id
+ // of some OpLabel instruction in the |ir_context_|.
void AddFactBlockIsDead(uint32_t block_id);
- // Records the fact that |function_id| is livesafe.
+ // Records the fact that |function_id| is livesafe. |function_id| must be a
+ // result id of some non-entry-point function in the module.
void AddFactFunctionIsLivesafe(uint32_t function_id);
// Records the fact that the value of the pointee associated with |pointer_id|
@@ -72,13 +75,14 @@
// Records a fact that the |result_id| is irrelevant (i.e. it doesn't affect
// the semantics of the module).
- // |result_id| must exist in the module and actually be a pointer.
+ // |result_id| must exist in the module and it may not be a pointer.
void AddFactIdIsIrrelevant(uint32_t result_id);
// Records the fact that |lhs_id| is defined by the equation:
//
// |lhs_id| = |opcode| |rhs_id[0]| ... |rhs_id[N-1]|
//
+ // Neither |lhs_id| nor any of |rhs_id| may be irrelevant.
void AddFactIdEquation(uint32_t lhs_id, SpvOp opcode,
const std::vector<uint32_t>& rhs_id);
@@ -117,7 +121,7 @@
uint32_t type_id) const;
// Provides details of all uniform elements that are known to be equal to the
- // constant associated with |constant_id| in |ir_context|.
+ // constant associated with |constant_id| in |ir_context_|.
std::vector<protobufs::UniformBufferElementDescriptor>
GetUniformDescriptorsForConstant(uint32_t constant_id) const;
diff --git a/source/fuzz/fact_manager/irrelevant_value_facts.cpp b/source/fuzz/fact_manager/irrelevant_value_facts.cpp
index ac5ad8b..07836ad 100644
--- a/source/fuzz/fact_manager/irrelevant_value_facts.cpp
+++ b/source/fuzz/fact_manager/irrelevant_value_facts.cpp
@@ -27,36 +27,52 @@
IrrelevantValueFacts::IrrelevantValueFacts(opt::IRContext* ir_context)
: ir_context_(ir_context) {}
-void IrrelevantValueFacts::AddFact(
+bool IrrelevantValueFacts::MaybeAddFact(
const protobufs::FactPointeeValueIsIrrelevant& fact,
const DataSynonymAndIdEquationFacts& data_synonym_and_id_equation_facts) {
- (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 = ir_context_->get_def_use_mgr()->GetDef(fact.pointer_id());
- assert(pointer_def && "The id must exist in the module.");
- auto type = ir_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.");
+ const auto* inst = ir_context_->get_def_use_mgr()->GetDef(fact.pointer_id());
+ if (!inst || !inst->type_id()) {
+ // The id must exist in the module and have type id.
+ return false;
+ }
+
+ if (!ir_context_->get_type_mgr()->GetType(inst->type_id())->AsPointer()) {
+ // The id must be a pointer.
+ return false;
+ }
+
+ if (!data_synonym_and_id_equation_facts.GetSynonymsForId(fact.pointer_id())
+ .empty()) {
+ // Irrelevant id cannot participate in DataSynonym facts.
+ return false;
+ }
pointers_to_irrelevant_pointees_ids_.insert(fact.pointer_id());
+ return true;
}
-void IrrelevantValueFacts::AddFact(
+bool IrrelevantValueFacts::MaybeAddFact(
const protobufs::FactIdIsIrrelevant& fact,
const DataSynonymAndIdEquationFacts& data_synonym_and_id_equation_facts) {
- (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 = ir_context_->get_def_use_mgr()->GetDef(fact.result_id());
- assert(pointer_def && "The id must exist in the module.");
- auto type = ir_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.");
+ const auto* inst = ir_context_->get_def_use_mgr()->GetDef(fact.result_id());
+ if (!inst || !inst->type_id()) {
+ // The id must exist in the module and have type id.
+ return false;
+ }
+
+ if (ir_context_->get_type_mgr()->GetType(inst->type_id())->AsPointer()) {
+ // The id may not be a pointer.
+ return false;
+ }
+
+ if (!data_synonym_and_id_equation_facts.GetSynonymsForId(fact.result_id())
+ .empty()) {
+ // Irrelevant id cannot participate in DataSynonym facts.
+ return false;
+ }
irrelevant_ids_.insert(fact.result_id());
+ return true;
}
bool IrrelevantValueFacts::PointeeValueIsIrrelevant(uint32_t pointer_id) const {
diff --git a/source/fuzz/fact_manager/irrelevant_value_facts.h b/source/fuzz/fact_manager/irrelevant_value_facts.h
index ad70e6b..9faddc0 100644
--- a/source/fuzz/fact_manager/irrelevant_value_facts.h
+++ b/source/fuzz/fact_manager/irrelevant_value_facts.h
@@ -35,17 +35,21 @@
public:
explicit IrrelevantValueFacts(opt::IRContext* ir_context);
- // See method in FactManager which delegates to this method.
- // |data_synonym_and_id_equation_facts| and |context| are passed for
- // consistency checks.
- void AddFact(
+ // See method in FactManager which delegates to this method. Returns true if
+ // |fact.pointer_id()| is a result id of pointer type in the |ir_context_| and
+ // |fact.pointer_id()| does not participate in DataSynonym facts. Returns
+ // false otherwise. |data_synonym_and_id_equation_facts| and |context| are
+ // passed for consistency checks.
+ bool MaybeAddFact(
const protobufs::FactPointeeValueIsIrrelevant& fact,
const DataSynonymAndIdEquationFacts& data_synonym_and_id_equation_facts);
- // See method in FactManager which delegates to this method.
- // |data_synonym_and_id_equation_facts| and |context| are passed for
- // consistency checks.
- void AddFact(
+ // See method in FactManager which delegates to this method. Returns true if
+ // |fact.result_id()| is a result id of non-pointer type in the |ir_context_|
+ // and |fact.result_id()| does not participate in DataSynonym facts. Returns
+ // false otherwise. |data_synonym_and_id_equation_facts| and |context| are
+ // passed for consistency checks.
+ bool MaybeAddFact(
const protobufs::FactIdIsIrrelevant& fact,
const DataSynonymAndIdEquationFacts& data_synonym_and_id_equation_facts);
diff --git a/source/fuzz/fact_manager/livesafe_function_facts.cpp b/source/fuzz/fact_manager/livesafe_function_facts.cpp
index 6f36afb..553ac57 100644
--- a/source/fuzz/fact_manager/livesafe_function_facts.cpp
+++ b/source/fuzz/fact_manager/livesafe_function_facts.cpp
@@ -14,13 +14,27 @@
#include "source/fuzz/fact_manager/livesafe_function_facts.h"
+#include "source/fuzz/fuzzer_util.h"
+
namespace spvtools {
namespace fuzz {
namespace fact_manager {
-void LivesafeFunctionFacts::AddFact(
+LivesafeFunctionFacts::LivesafeFunctionFacts(opt::IRContext* ir_context)
+ : ir_context_(ir_context) {}
+
+bool LivesafeFunctionFacts::MaybeAddFact(
const protobufs::FactFunctionIsLivesafe& fact) {
+ if (!fuzzerutil::FindFunction(ir_context_, fact.function_id())) {
+ return false;
+ }
+
+ if (fuzzerutil::FunctionIsEntryPoint(ir_context_, fact.function_id())) {
+ return false;
+ }
+
livesafe_function_ids_.insert(fact.function_id());
+ return true;
}
bool LivesafeFunctionFacts::FunctionIsLivesafe(uint32_t function_id) const {
diff --git a/source/fuzz/fact_manager/livesafe_function_facts.h b/source/fuzz/fact_manager/livesafe_function_facts.h
index 8c48506..2156d64 100644
--- a/source/fuzz/fact_manager/livesafe_function_facts.h
+++ b/source/fuzz/fact_manager/livesafe_function_facts.h
@@ -18,6 +18,7 @@
#include <unordered_set>
#include "source/fuzz/protobufs/spirvfuzz_protobufs.h"
+#include "source/opt/ir_context.h"
namespace spvtools {
namespace fuzz {
@@ -27,14 +28,19 @@
// facts about livesafe functions.
class LivesafeFunctionFacts {
public:
- // See method in FactManager which delegates to this method.
- void AddFact(const protobufs::FactFunctionIsLivesafe& fact);
+ explicit LivesafeFunctionFacts(opt::IRContext* ir_context);
+
+ // See method in FactManager which delegates to this method. Returns true if
+ // |fact.function_id()| is a result id of some non-entry-point function in
+ // |ir_context_|. Returns false otherwise.
+ bool MaybeAddFact(const protobufs::FactFunctionIsLivesafe& fact);
// See method in FactManager which delegates to this method.
bool FunctionIsLivesafe(uint32_t function_id) const;
private:
std::unordered_set<uint32_t> livesafe_function_ids_;
+ opt::IRContext* ir_context_;
};
} // namespace fact_manager
diff --git a/source/fuzz/force_render_red.cpp b/source/fuzz/force_render_red.cpp
index f9ef36d..fd0587a 100644
--- a/source/fuzz/force_render_red.cpp
+++ b/source/fuzz/force_render_red.cpp
@@ -185,7 +185,7 @@
TransformationContext transformation_context(
MakeUnique<FactManager>(ir_context.get()), validator_options);
for (auto& fact : initial_facts.fact()) {
- transformation_context.GetFactManager()->AddFact(fact);
+ transformation_context.GetFactManager()->MaybeAddFact(fact);
}
auto entry_point_function =
diff --git a/source/fuzz/fuzzer.cpp b/source/fuzz/fuzzer.cpp
index 9680dda..37260ca 100644
--- a/source/fuzz/fuzzer.cpp
+++ b/source/fuzz/fuzzer.cpp
@@ -216,8 +216,8 @@
transformation_context_ = MakeUnique<TransformationContext>(
MakeUnique<FactManager>(ir_context_.get()), validator_options_);
- transformation_context_->GetFactManager()->AddFacts(consumer_,
- initial_facts_);
+ transformation_context_->GetFactManager()->AddInitialFacts(consumer_,
+ initial_facts_);
RepeatedPassInstances pass_instances{};
diff --git a/source/fuzz/replayer.cpp b/source/fuzz/replayer.cpp
index 4636a20..81d36b8 100644
--- a/source/fuzz/replayer.cpp
+++ b/source/fuzz/replayer.cpp
@@ -108,7 +108,8 @@
MakeUnique<TransformationContext>(
MakeUnique<FactManager>(ir_context.get()), validator_options_,
MakeUnique<CounterOverflowIdSource>(first_overflow_id));
- transformation_context->GetFactManager()->AddFacts(consumer_, initial_facts_);
+ transformation_context->GetFactManager()->AddInitialFacts(consumer_,
+ initial_facts_);
// We track the largest id bound observed, to ensure that it only increases
// as transformations are applied.
diff --git a/source/fuzz/transformation_add_dead_block.cpp b/source/fuzz/transformation_add_dead_block.cpp
index 4ff22cb..3d77a80 100644
--- a/source/fuzz/transformation_add_dead_block.cpp
+++ b/source/fuzz/transformation_add_dead_block.cpp
@@ -157,10 +157,6 @@
enclosing_function->InsertBasicBlockAfter(std::move(new_block),
existing_block);
- // Record the fact that the new block is dead.
- transformation_context->GetFactManager()->AddFactBlockIsDead(
- message_.fresh_id());
-
// Fix up OpPhi instructions in the successor block, so that the values they
// yield when control has transferred from the new block are the same as if
// control had transferred from |message_.existing_block|. This is guaranteed
@@ -181,6 +177,10 @@
// Do not rely on any existing analysis results since the control flow graph
// of the module has changed.
ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone);
+
+ // Record the fact that the new block is dead.
+ transformation_context->GetFactManager()->AddFactBlockIsDead(
+ message_.fresh_id());
}
protobufs::Transformation TransformationAddDeadBlock::ToMessage() const {
diff --git a/source/fuzz/transformation_add_function.cpp b/source/fuzz/transformation_add_function.cpp
index 52c7f5f..aea2d08 100644
--- a/source/fuzz/transformation_add_function.cpp
+++ b/source/fuzz/transformation_add_function.cpp
@@ -173,11 +173,15 @@
success = TryToMakeFunctionLivesafe(ir_context, *transformation_context);
assert(success && "It should be possible to make the function livesafe.");
(void)(success); // Keep release builds happy.
+ }
+ ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone);
+ assert(message_.instruction(0).opcode() == SpvOpFunction &&
+ "The first instruction of an 'add function' transformation must be "
+ "OpFunction.");
+
+ if (message_.is_livesafe()) {
// Inform the fact manager that the function is livesafe.
- assert(message_.instruction(0).opcode() == SpvOpFunction &&
- "The first instruction of an 'add function' transformation must be "
- "OpFunction.");
transformation_context->GetFactManager()->AddFactFunctionIsLivesafe(
message_.instruction(0).result_id());
} else {
@@ -189,7 +193,6 @@
}
}
}
- 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
diff --git a/source/fuzz/transformation_outline_function.cpp b/source/fuzz/transformation_outline_function.cpp
index 764e888..a2cef7a 100644
--- a/source/fuzz/transformation_outline_function.cpp
+++ b/source/fuzz/transformation_outline_function.cpp
@@ -358,14 +358,6 @@
region_input_ids, region_output_ids, input_id_to_fresh_id_map, ir_context,
transformation_context);
- // If the original function was livesafe, the new function should also be
- // livesafe.
- if (transformation_context->GetFactManager()->FunctionIsLivesafe(
- original_region_entry_block->GetParent()->result_id())) {
- transformation_context->GetFactManager()->AddFactFunctionIsLivesafe(
- message_.new_function_id());
- }
-
// Adapt the region to be outlined so that its input ids are replaced with the
// ids of the outlined function's input parameters, and so that output ids
// are similarly remapped.
@@ -375,10 +367,10 @@
// Fill out the body of the outlined function according to the region that is
// being outlined.
- PopulateOutlinedFunction(
- *original_region_entry_block, *original_region_exit_block, region_blocks,
- region_output_ids, output_id_to_fresh_id_map, ir_context,
- outlined_function.get(), transformation_context);
+ PopulateOutlinedFunction(*original_region_entry_block,
+ *original_region_exit_block, region_blocks,
+ region_output_ids, output_id_to_fresh_id_map,
+ ir_context, outlined_function.get());
// Collapse the region that has been outlined into a function down to a single
// block that calls said function.
@@ -389,11 +381,28 @@
std::move(cloned_exit_block_terminator), original_region_entry_block);
// Add the outlined function to the module.
+ const auto* outlined_function_ptr = outlined_function.get();
ir_context->module()->AddFunction(std::move(outlined_function));
// Major surgery has been conducted on the module, so invalidate all analyses.
ir_context->InvalidateAnalysesExceptFor(
opt::IRContext::Analysis::kAnalysisNone);
+
+ // If the original function was livesafe, the new function should also be
+ // livesafe.
+ if (transformation_context->GetFactManager()->FunctionIsLivesafe(
+ original_region_entry_block->GetParent()->result_id())) {
+ transformation_context->GetFactManager()->AddFactFunctionIsLivesafe(
+ message_.new_function_id());
+ }
+
+ // Record the fact that all blocks in the outlined region are dead if the
+ // first block is dead.
+ if (transformation_context->GetFactManager()->BlockIsDead(
+ original_region_entry_block->id())) {
+ transformation_context->GetFactManager()->AddFactBlockIsDead(
+ outlined_function_ptr->entry()->id());
+ }
}
protobufs::Transformation TransformationOutlineFunction::ToMessage() const {
@@ -750,8 +759,7 @@
const std::set<opt::BasicBlock*>& region_blocks,
const std::vector<uint32_t>& region_output_ids,
const std::map<uint32_t, uint32_t>& output_id_to_fresh_id_map,
- opt::IRContext* ir_context, opt::Function* outlined_function,
- TransformationContext* transformation_context) const {
+ opt::IRContext* ir_context, opt::Function* outlined_function) const {
// When we create the exit block for the outlined region, we use this pointer
// to track of it so that we can manipulate it later.
opt::BasicBlock* outlined_region_exit_block = nullptr;
@@ -765,14 +773,6 @@
opt::Instruction::OperandList()));
outlined_region_entry_block->SetParent(outlined_function);
- // If the original region's entry block was dead, the outlined region's entry
- // block is also dead.
- if (transformation_context->GetFactManager()->BlockIsDead(
- original_region_entry_block.id())) {
- transformation_context->GetFactManager()->AddFactBlockIsDead(
- outlined_region_entry_block->id());
- }
-
if (&original_region_entry_block == &original_region_exit_block) {
outlined_region_exit_block = outlined_region_entry_block.get();
}
@@ -879,7 +879,7 @@
}
void TransformationOutlineFunction::ShrinkOriginalRegion(
- opt::IRContext* ir_context, std::set<opt::BasicBlock*>& region_blocks,
+ opt::IRContext* ir_context, const std::set<opt::BasicBlock*>& region_blocks,
const std::vector<uint32_t>& region_input_ids,
const std::vector<uint32_t>& region_output_ids,
const std::map<uint32_t, uint32_t>& output_id_to_type_id,
diff --git a/source/fuzz/transformation_outline_function.h b/source/fuzz/transformation_outline_function.h
index fda1ba0..6bc7d7e 100644
--- a/source/fuzz/transformation_outline_function.h
+++ b/source/fuzz/transformation_outline_function.h
@@ -189,8 +189,7 @@
const std::set<opt::BasicBlock*>& region_blocks,
const std::vector<uint32_t>& region_output_ids,
const std::map<uint32_t, uint32_t>& output_id_to_fresh_id_map,
- opt::IRContext* ir_context, opt::Function* outlined_function,
- TransformationContext* transformation_context) const;
+ opt::IRContext* ir_context, opt::Function* outlined_function) const;
// Shrinks the outlined region, given by |region_blocks|, down to the single
// block |original_region_entry_block|. This block is itself shrunk to just
@@ -209,7 +208,8 @@
// function is called, this information cannot be gotten from the def-use
// manager.
void ShrinkOriginalRegion(
- opt::IRContext* ir_context, std::set<opt::BasicBlock*>& region_blocks,
+ opt::IRContext* ir_context,
+ const std::set<opt::BasicBlock*>& region_blocks,
const std::vector<uint32_t>& region_input_ids,
const std::vector<uint32_t>& region_output_ids,
const std::map<uint32_t, uint32_t>& output_id_to_type_id,
diff --git a/source/fuzz/transformation_split_block.cpp b/source/fuzz/transformation_split_block.cpp
index d8a3dc8..b383c40 100644
--- a/source/fuzz/transformation_split_block.cpp
+++ b/source/fuzz/transformation_split_block.cpp
@@ -124,6 +124,10 @@
phi_inst->SetInOperand(1, {block_to_split->id()});
});
+ // Invalidate all analyses
+ ir_context->InvalidateAnalysesExceptFor(
+ opt::IRContext::Analysis::kAnalysisNone);
+
// If the block being split was dead, the new block arising from the split is
// also dead.
if (transformation_context->GetFactManager()->BlockIsDead(
@@ -131,10 +135,6 @@
transformation_context->GetFactManager()->AddFactBlockIsDead(
message_.fresh_id());
}
-
- // Invalidate all analyses
- ir_context->InvalidateAnalysesExceptFor(
- opt::IRContext::Analysis::kAnalysisNone);
}
protobufs::Transformation TransformationSplitBlock::ToMessage() const {
diff --git a/test/fuzz/data_synonym_transformation_test.cpp b/test/fuzz/data_synonym_transformation_test.cpp
index 723eb4d..2345ff6 100644
--- a/test/fuzz/data_synonym_transformation_test.cpp
+++ b/test/fuzz/data_synonym_transformation_test.cpp
@@ -125,19 +125,20 @@
spvtools::ValidatorOptions validator_options;
TransformationContext transformation_context(
MakeUnique<FactManager>(context.get()), validator_options);
- transformation_context.GetFactManager()->AddFact(
+
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(12, {}, 100, {0}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(13, {}, 100, {1}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(22, {}, 100, {2}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(28, {}, 101, {0}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(23, {}, 101, {1}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(32, {}, 101, {2}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(23, {}, 101, {3}));
// Replace %12 with %100[0] in '%25 = OpAccessChain %24 %20 %12'
@@ -411,11 +412,12 @@
spvtools::ValidatorOptions validator_options;
TransformationContext transformation_context(
MakeUnique<FactManager>(context.get()), validator_options);
- transformation_context.GetFactManager()->AddFact(
+
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(23, {}, 100, {0}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(25, {}, 100, {1}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(50, {}, 100, {2}));
// Replace %23 with %100[0] in '%26 = OpFAdd %7 %23 %25'
@@ -579,19 +581,20 @@
spvtools::ValidatorOptions validator_options;
TransformationContext transformation_context(
MakeUnique<FactManager>(context.get()), validator_options);
- transformation_context.GetFactManager()->AddFact(
+
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(16, {}, 100, {0}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(45, {}, 100, {1}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(27, {}, 101, {0}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(36, {}, 101, {1}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(27, {}, 101, {2}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(22, {}, 102, {0}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(15, {}, 102, {1}));
// Replace %45 with %100[1] in '%46 = OpCompositeConstruct %32 %35 %45'
@@ -867,45 +870,46 @@
spvtools::ValidatorOptions validator_options;
TransformationContext transformation_context(
MakeUnique<FactManager>(context.get()), validator_options);
- transformation_context.GetFactManager()->AddFact(
+
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(20, {0}, 100, {0}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(20, {1}, 100, {1}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(20, {2}, 100, {2}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(54, {}, 100, {3}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(15, {0}, 101, {0}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(15, {1}, 101, {1}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(19, {0}, 101, {2}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(19, {1}, 101, {3}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(27, {}, 102, {0}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(15, {0}, 102, {1}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(15, {1}, 102, {2}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(33, {}, 103, {0}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(47, {0}, 103, {1}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(47, {1}, 103, {2}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(47, {2}, 103, {3}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(42, {}, 104, {0}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(45, {}, 104, {1}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(38, {0}, 105, {0}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(38, {1}, 105, {1}));
- transformation_context.GetFactManager()->AddFact(
+ transformation_context.GetFactManager()->MaybeAddFact(
MakeSynonymFact(46, {}, 105, {2}));
// Replace %20 with %100[0:2] in '%80 = OpCopyObject %16 %20'
diff --git a/test/fuzz/fact_manager_test.cpp b/test/fuzz/fact_manager_test.cpp
index 995b64c..8322c7c 100644
--- a/test/fuzz/fact_manager_test.cpp
+++ b/test/fuzz/fact_manager_test.cpp
@@ -45,7 +45,7 @@
descriptor;
protobufs::Fact fact;
*fact.mutable_constant_uniform_fact() = constant_uniform_fact;
- return fact_manager->AddFact(fact);
+ return fact_manager->MaybeAddFact(fact);
}
TEST(FactManagerTest, ConstantsAvailableViaUniforms) {
diff --git a/test/fuzz/fuzzer_pass_add_opphi_synonyms_test.cpp b/test/fuzz/fuzzer_pass_add_opphi_synonyms_test.cpp
index 666180b..0e10a42 100644
--- a/test/fuzz/fuzzer_pass_add_opphi_synonyms_test.cpp
+++ b/test/fuzz/fuzzer_pass_add_opphi_synonyms_test.cpp
@@ -32,21 +32,21 @@
// Adds synonym facts to the fact manager.
void SetUpIdSynonyms(FactManager* fact_manager) {
// Synonyms {9, 11, 15, 16, 21, 22}
- fact_manager->AddFact(MakeSynonymFact(11, 9));
- fact_manager->AddFact(MakeSynonymFact(15, 9));
- fact_manager->AddFact(MakeSynonymFact(16, 9));
- fact_manager->AddFact(MakeSynonymFact(21, 9));
- fact_manager->AddFact(MakeSynonymFact(22, 9));
+ fact_manager->MaybeAddFact(MakeSynonymFact(11, 9));
+ fact_manager->MaybeAddFact(MakeSynonymFact(15, 9));
+ fact_manager->MaybeAddFact(MakeSynonymFact(16, 9));
+ fact_manager->MaybeAddFact(MakeSynonymFact(21, 9));
+ fact_manager->MaybeAddFact(MakeSynonymFact(22, 9));
// Synonyms {10, 23}
- fact_manager->AddFact(MakeSynonymFact(10, 23));
+ fact_manager->MaybeAddFact(MakeSynonymFact(10, 23));
// Synonyms {14, 27}
- fact_manager->AddFact(MakeSynonymFact(14, 27));
+ fact_manager->MaybeAddFact(MakeSynonymFact(14, 27));
// Synonyms {24, 26, 30}
- fact_manager->AddFact(MakeSynonymFact(26, 24));
- fact_manager->AddFact(MakeSynonymFact(30, 24));
+ fact_manager->MaybeAddFact(MakeSynonymFact(26, 24));
+ fact_manager->MaybeAddFact(MakeSynonymFact(30, 24));
}
// Returns true if the given lists have the same elements, regardless of their
diff --git a/test/fuzz/transformation_add_opphi_synonym_test.cpp b/test/fuzz/transformation_add_opphi_synonym_test.cpp
index 8715125..a6f067f 100644
--- a/test/fuzz/transformation_add_opphi_synonym_test.cpp
+++ b/test/fuzz/transformation_add_opphi_synonym_test.cpp
@@ -31,12 +31,12 @@
// Adds synonym facts to the fact manager.
void SetUpIdSynonyms(FactManager* fact_manager) {
- fact_manager->AddFact(MakeSynonymFact(11, 9));
- fact_manager->AddFact(MakeSynonymFact(13, 9));
- fact_manager->AddFact(MakeSynonymFact(14, 9));
- fact_manager->AddFact(MakeSynonymFact(19, 9));
- fact_manager->AddFact(MakeSynonymFact(20, 9));
- fact_manager->AddFact(MakeSynonymFact(10, 21));
+ fact_manager->MaybeAddFact(MakeSynonymFact(11, 9));
+ fact_manager->MaybeAddFact(MakeSynonymFact(13, 9));
+ fact_manager->MaybeAddFact(MakeSynonymFact(14, 9));
+ fact_manager->MaybeAddFact(MakeSynonymFact(19, 9));
+ fact_manager->MaybeAddFact(MakeSynonymFact(20, 9));
+ fact_manager->MaybeAddFact(MakeSynonymFact(10, 21));
}
TEST(TransformationAddOpPhiSynonymTest, Inapplicable) {
@@ -89,7 +89,8 @@
TransformationContext transformation_context(
MakeUnique<FactManager>(context.get()), validator_options);
SetUpIdSynonyms(transformation_context.GetFactManager());
- transformation_context.GetFactManager()->AddFact(MakeSynonymFact(23, 24));
+ transformation_context.GetFactManager()->MaybeAddFact(
+ MakeSynonymFact(23, 24));
// %13 is not a block label.
ASSERT_FALSE(TransformationAddOpPhiSynonym(13, {{}}, 100)
@@ -211,8 +212,8 @@
SetUpIdSynonyms(transformation_context.GetFactManager());
// Add some further synonym facts.
- transformation_context.GetFactManager()->AddFact(MakeSynonymFact(28, 9));
- transformation_context.GetFactManager()->AddFact(MakeSynonymFact(30, 9));
+ transformation_context.GetFactManager()->MaybeAddFact(MakeSynonymFact(28, 9));
+ transformation_context.GetFactManager()->MaybeAddFact(MakeSynonymFact(30, 9));
auto transformation1 = TransformationAddOpPhiSynonym(17, {{{15, 13}}}, 100);
ASSERT_TRUE(
@@ -356,8 +357,9 @@
TransformationContext transformation_context(
MakeUnique<FactManager>(context.get()), validator_options);
// Declare synonyms
- transformation_context.GetFactManager()->AddFact(MakeSynonymFact(3, 15));
- transformation_context.GetFactManager()->AddFact(MakeSynonymFact(12, 16));
+ transformation_context.GetFactManager()->MaybeAddFact(MakeSynonymFact(3, 15));
+ transformation_context.GetFactManager()->MaybeAddFact(
+ MakeSynonymFact(12, 16));
// Remove the VariablePointers capability.
context.get()->get_feature_mgr()->RemoveCapability(
diff --git a/test/fuzz/transformation_replace_constant_with_uniform_test.cpp b/test/fuzz/transformation_replace_constant_with_uniform_test.cpp
index 507e98f..1e084e7 100644
--- a/test/fuzz/transformation_replace_constant_with_uniform_test.cpp
+++ b/test/fuzz/transformation_replace_constant_with_uniform_test.cpp
@@ -31,7 +31,7 @@
descriptor;
protobufs::Fact fact;
*fact.mutable_constant_uniform_fact() = constant_uniform_fact;
- return transformation_context->GetFactManager()->AddFact(fact);
+ return transformation_context->GetFactManager()->MaybeAddFact(fact);
}
TEST(TransformationReplaceConstantWithUniformTest, BasicReplacements) {
diff --git a/test/fuzz/transformation_replace_id_with_synonym_test.cpp b/test/fuzz/transformation_replace_id_with_synonym_test.cpp
index c200b2f..85cdd53 100644
--- a/test/fuzz/transformation_replace_id_with_synonym_test.cpp
+++ b/test/fuzz/transformation_replace_id_with_synonym_test.cpp
@@ -200,17 +200,17 @@
// Equips the fact manager with synonym facts for the above shader.
void SetUpIdSynonyms(FactManager* fact_manager) {
- fact_manager->AddFact(MakeSynonymFact(15, 200));
- fact_manager->AddFact(MakeSynonymFact(15, 201));
- fact_manager->AddFact(MakeSynonymFact(15, 202));
- fact_manager->AddFact(MakeSynonymFact(55, 203));
- fact_manager->AddFact(MakeSynonymFact(54, 204));
- fact_manager->AddFact(MakeSynonymFact(74, 205));
- fact_manager->AddFact(MakeSynonymFact(78, 206));
- fact_manager->AddFact(MakeSynonymFact(84, 207));
- fact_manager->AddFact(MakeSynonymFact(33, 208));
- fact_manager->AddFact(MakeSynonymFact(12, 209));
- fact_manager->AddFact(MakeSynonymFact(19, 210));
+ fact_manager->MaybeAddFact(MakeSynonymFact(15, 200));
+ fact_manager->MaybeAddFact(MakeSynonymFact(15, 201));
+ fact_manager->MaybeAddFact(MakeSynonymFact(15, 202));
+ fact_manager->MaybeAddFact(MakeSynonymFact(55, 203));
+ fact_manager->MaybeAddFact(MakeSynonymFact(54, 204));
+ fact_manager->MaybeAddFact(MakeSynonymFact(74, 205));
+ fact_manager->MaybeAddFact(MakeSynonymFact(78, 206));
+ fact_manager->MaybeAddFact(MakeSynonymFact(84, 207));
+ fact_manager->MaybeAddFact(MakeSynonymFact(33, 208));
+ fact_manager->MaybeAddFact(MakeSynonymFact(12, 209));
+ fact_manager->MaybeAddFact(MakeSynonymFact(19, 210));
}
TEST(TransformationReplaceIdWithSynonymTest, IllegalTransformations) {
@@ -520,8 +520,10 @@
spvtools::ValidatorOptions validator_options;
TransformationContext transformation_context(
MakeUnique<FactManager>(context.get()), validator_options);
- transformation_context.GetFactManager()->AddFact(MakeSynonymFact(10, 100));
- transformation_context.GetFactManager()->AddFact(MakeSynonymFact(8, 101));
+ transformation_context.GetFactManager()->MaybeAddFact(
+ MakeSynonymFact(10, 100));
+ transformation_context.GetFactManager()->MaybeAddFact(
+ MakeSynonymFact(8, 101));
// Replace %10 with %100 in:
// %11 = OpLoad %6 %10
@@ -650,7 +652,8 @@
spvtools::ValidatorOptions validator_options;
TransformationContext transformation_context(
MakeUnique<FactManager>(context.get()), validator_options);
- transformation_context.GetFactManager()->AddFact(MakeSynonymFact(14, 100));
+ transformation_context.GetFactManager()->MaybeAddFact(
+ MakeSynonymFact(14, 100));
// Replace %14 with %100 in:
// %16 = OpFunctionCall %2 %10 %14
@@ -815,19 +818,32 @@
MakeUnique<FactManager>(context.get()), validator_options);
// Add synonym facts corresponding to the OpCopyObject operations that have
// been applied to all constants in the module.
- transformation_context.GetFactManager()->AddFact(MakeSynonymFact(16, 100));
- transformation_context.GetFactManager()->AddFact(MakeSynonymFact(21, 101));
- transformation_context.GetFactManager()->AddFact(MakeSynonymFact(17, 102));
- transformation_context.GetFactManager()->AddFact(MakeSynonymFact(57, 103));
- transformation_context.GetFactManager()->AddFact(MakeSynonymFact(18, 104));
- transformation_context.GetFactManager()->AddFact(MakeSynonymFact(40, 105));
- transformation_context.GetFactManager()->AddFact(MakeSynonymFact(32, 106));
- transformation_context.GetFactManager()->AddFact(MakeSynonymFact(43, 107));
- transformation_context.GetFactManager()->AddFact(MakeSynonymFact(55, 108));
- transformation_context.GetFactManager()->AddFact(MakeSynonymFact(8, 109));
- transformation_context.GetFactManager()->AddFact(MakeSynonymFact(47, 110));
- transformation_context.GetFactManager()->AddFact(MakeSynonymFact(28, 111));
- transformation_context.GetFactManager()->AddFact(MakeSynonymFact(45, 112));
+ transformation_context.GetFactManager()->MaybeAddFact(
+ MakeSynonymFact(16, 100));
+ transformation_context.GetFactManager()->MaybeAddFact(
+ MakeSynonymFact(21, 101));
+ transformation_context.GetFactManager()->MaybeAddFact(
+ MakeSynonymFact(17, 102));
+ transformation_context.GetFactManager()->MaybeAddFact(
+ MakeSynonymFact(57, 103));
+ transformation_context.GetFactManager()->MaybeAddFact(
+ MakeSynonymFact(18, 104));
+ transformation_context.GetFactManager()->MaybeAddFact(
+ MakeSynonymFact(40, 105));
+ transformation_context.GetFactManager()->MaybeAddFact(
+ MakeSynonymFact(32, 106));
+ transformation_context.GetFactManager()->MaybeAddFact(
+ MakeSynonymFact(43, 107));
+ transformation_context.GetFactManager()->MaybeAddFact(
+ MakeSynonymFact(55, 108));
+ transformation_context.GetFactManager()->MaybeAddFact(
+ MakeSynonymFact(8, 109));
+ transformation_context.GetFactManager()->MaybeAddFact(
+ MakeSynonymFact(47, 110));
+ transformation_context.GetFactManager()->MaybeAddFact(
+ MakeSynonymFact(28, 111));
+ transformation_context.GetFactManager()->MaybeAddFact(
+ MakeSynonymFact(45, 112));
// Replacements of the form %16 -> %100
@@ -1300,9 +1316,11 @@
TransformationContext transformation_context(
MakeUnique<FactManager>(context.get()), validator_options);
// Add synonym fact relating %50 and %12.
- transformation_context.GetFactManager()->AddFact(MakeSynonymFact(50, 12));
+ transformation_context.GetFactManager()->MaybeAddFact(
+ MakeSynonymFact(50, 12));
// Add synonym fact relating %51 and %14.
- transformation_context.GetFactManager()->AddFact(MakeSynonymFact(51, 14));
+ transformation_context.GetFactManager()->MaybeAddFact(
+ MakeSynonymFact(51, 14));
// Not legal because the index being replaced is a struct index.
ASSERT_FALSE(
@@ -1409,7 +1427,8 @@
TransformationContext transformation_context(
MakeUnique<FactManager>(context.get()), validator_options);
// Add synonym fact relating %100 and %9.
- transformation_context.GetFactManager()->AddFact(MakeSynonymFact(100, 9));
+ transformation_context.GetFactManager()->MaybeAddFact(
+ MakeSynonymFact(100, 9));
// Not legal the Sample argument of OpImageTexelPointer needs to be a zero
// constant.
@@ -1469,7 +1488,8 @@
MakeUnique<FactManager>(context.get()), validator_options);
// Add synonym fact relating %10 and %13 (equivalent integer constant with
// different signedness).
- transformation_context.GetFactManager()->AddFact(MakeSynonymFact(10, 13));
+ transformation_context.GetFactManager()->MaybeAddFact(
+ MakeSynonymFact(10, 13));
// Legal because OpSNegate always considers the integer as signed
auto replacement1 = TransformationReplaceIdWithSynonym(
@@ -1611,7 +1631,8 @@
MakeUnique<FactManager>(context.get()), validator_options);
// Add synonym fact relating %10 and %13 (equivalent integer vectors with
// different signedness).
- transformation_context.GetFactManager()->AddFact(MakeSynonymFact(14, 15));
+ transformation_context.GetFactManager()->MaybeAddFact(
+ MakeSynonymFact(14, 15));
// Legal because OpIAdd does not consider the signedness of the operands
auto replacement1 = TransformationReplaceIdWithSynonym(
@@ -1630,7 +1651,8 @@
// Add synonym fact relating %12 and %13 (equivalent integer constants with
// different signedness).
- transformation_context.GetFactManager()->AddFact(MakeSynonymFact(12, 13));
+ transformation_context.GetFactManager()->MaybeAddFact(
+ MakeSynonymFact(12, 13));
// Legal because the indices of OpAccessChain are always treated as signed
auto replacement2 = TransformationReplaceIdWithSynonym(