spirv-fuzz: Add IdIsIrrelevant fact (#3561)
Part of #3177.
This PR adds a fact to the fact manager.
diff --git a/source/fuzz/fact_manager.cpp b/source/fuzz/fact_manager.cpp
index 320049a..eb66dfe 100644
--- a/source/fuzz/fact_manager.cpp
+++ b/source/fuzz/fact_manager.cpp
@@ -1343,32 +1343,49 @@
//==============================
//==============================
-// Irrelevant pointee value facts
+// Irrelevant value facts
// The purpose of this class is to group the fields and data used to represent
-// facts about pointers whose pointee values are irrelevant.
-class FactManager::IrrelevantPointeeValueFacts {
+// facts about various irrelevant values in the module.
+class FactManager::IrrelevantValueFacts {
public:
// See method in FactManager which delegates to this method.
void AddFact(const protobufs::FactPointeeValueIsIrrelevant& fact);
// See method in FactManager which delegates to this method.
+ void AddFact(const protobufs::FactIdIsIrrelevant& fact);
+
+ // See method in FactManager which delegates to this method.
bool PointeeValueIsIrrelevant(uint32_t pointer_id) const;
+ // See method in FactManager which delegates to this method.
+ bool IdIsIrrelevant(uint32_t pointer_id) const;
+
private:
- std::set<uint32_t> pointers_to_irrelevant_pointees_ids_;
+ std::unordered_set<uint32_t> pointers_to_irrelevant_pointees_ids_;
+ std::unordered_set<uint32_t> irrelevant_ids_;
};
-void FactManager::IrrelevantPointeeValueFacts::AddFact(
+void FactManager::IrrelevantValueFacts::AddFact(
const protobufs::FactPointeeValueIsIrrelevant& fact) {
pointers_to_irrelevant_pointees_ids_.insert(fact.pointer_id());
}
-bool FactManager::IrrelevantPointeeValueFacts::PointeeValueIsIrrelevant(
+void FactManager::IrrelevantValueFacts::AddFact(
+ const protobufs::FactIdIsIrrelevant& fact) {
+ irrelevant_ids_.insert(fact.result_id());
+}
+
+bool FactManager::IrrelevantValueFacts::PointeeValueIsIrrelevant(
uint32_t pointer_id) const {
return pointers_to_irrelevant_pointees_ids_.count(pointer_id) != 0;
}
+bool FactManager::IrrelevantValueFacts::IdIsIrrelevant(
+ uint32_t pointer_id) const {
+ return irrelevant_ids_.count(pointer_id) != 0;
+}
+
// End of arbitrarily-valued variable facts
//==============================
@@ -1378,8 +1395,7 @@
MakeUnique<DataSynonymAndIdEquationFacts>()),
dead_block_facts_(MakeUnique<DeadBlockFacts>()),
livesafe_function_facts_(MakeUnique<LivesafeFunctionFacts>()),
- irrelevant_pointee_value_facts_(
- MakeUnique<IrrelevantPointeeValueFacts>()) {}
+ irrelevant_value_facts_(MakeUnique<IrrelevantValueFacts>()) {}
FactManager::~FactManager() = default;
@@ -1420,6 +1436,8 @@
void FactManager::AddFactDataSynonym(const protobufs::DataDescriptor& data1,
const protobufs::DataDescriptor& data2,
opt::IRContext* context) {
+ // TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3550):
+ // assert that neither |data1| nor |data2| are irrelevant.
protobufs::FactDataSynonym fact;
*fact.mutable_data1() = data1;
*fact.mutable_data2() = data2;
@@ -1500,18 +1518,30 @@
}
bool FactManager::PointeeValueIsIrrelevant(uint32_t pointer_id) const {
- return irrelevant_pointee_value_facts_->PointeeValueIsIrrelevant(pointer_id);
+ return irrelevant_value_facts_->PointeeValueIsIrrelevant(pointer_id);
+}
+
+bool FactManager::IdIsIrrelevant(uint32_t result_id) const {
+ return irrelevant_value_facts_->IdIsIrrelevant(result_id);
}
void FactManager::AddFactValueOfPointeeIsIrrelevant(uint32_t pointer_id) {
protobufs::FactPointeeValueIsIrrelevant fact;
fact.set_pointer_id(pointer_id);
- irrelevant_pointee_value_facts_->AddFact(fact);
+ irrelevant_value_facts_->AddFact(fact);
+}
+
+void FactManager::AddFactIdIsIrrelevant(uint32_t result_id) {
+ protobufs::FactIdIsIrrelevant fact;
+ fact.set_result_id(result_id);
+ irrelevant_value_facts_->AddFact(fact);
}
void FactManager::AddFactIdEquation(uint32_t lhs_id, SpvOp opcode,
const std::vector<uint32_t>& rhs_id,
opt::IRContext* context) {
+ // TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3550):
+ // assert that elements of |rhs_id| and |lhs_id| are not irrelevant.
protobufs::FactIdEquation fact;
fact.set_lhs_id(lhs_id);
fact.set_opcode(opcode);
diff --git a/source/fuzz/fact_manager.h b/source/fuzz/fact_manager.h
index f520e42..f83e2ff 100644
--- a/source/fuzz/fact_manager.h
+++ b/source/fuzz/fact_manager.h
@@ -68,6 +68,10 @@
// is irrelevant: it does not affect the observable behaviour of the module.
void AddFactValueOfPointeeIsIrrelevant(uint32_t pointer_id);
+ // Records a fact that the |result_id| is irrelevant (i.e. it doesn't affect
+ // the semantics of the module)
+ 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]|
@@ -181,13 +185,16 @@
//==============================
//==============================
- // Querying facts about pointers with irrelevant pointee values
+ // Querying facts about irrelevant values
// Returns true if and ony if the value of the pointee associated with
// |pointer_id| is irrelevant.
bool PointeeValueIsIrrelevant(uint32_t pointer_id) const;
- // End of irrelevant pointee value facts
+ // Returns true iff there exists a fact that the |result_id| is irrelevant.
+ bool IdIsIrrelevant(uint32_t result_id) const;
+
+ // End of irrelevant value facts
//==============================
private:
@@ -213,10 +220,10 @@
std::unique_ptr<LivesafeFunctionFacts>
livesafe_function_facts_; // Unique pointer to internal data.
- class IrrelevantPointeeValueFacts; // Opaque class for management of
- // facts about pointers whose pointee values do not matter.
- std::unique_ptr<IrrelevantPointeeValueFacts>
- irrelevant_pointee_value_facts_; // Unique pointer to internal data.
+ class IrrelevantValueFacts; // Opaque class for management of
+ // facts about various irrelevant values in the module.
+ std::unique_ptr<IrrelevantValueFacts>
+ irrelevant_value_facts_; // Unique pointer to internal data.
};
} // namespace fuzz
diff --git a/source/fuzz/protobufs/spvtoolsfuzz.proto b/source/fuzz/protobufs/spvtoolsfuzz.proto
index f103fbb..e106608 100644
--- a/source/fuzz/protobufs/spvtoolsfuzz.proto
+++ b/source/fuzz/protobufs/spvtoolsfuzz.proto
@@ -170,6 +170,7 @@
FactFunctionIsLivesafe function_is_livesafe_fact = 4;
FactPointeeValueIsIrrelevant pointee_value_is_irrelevant_fact = 5;
FactIdEquation id_equation_fact = 6;
+ FactIdIsIrrelevant id_is_irrelevant = 7;
}
}
@@ -182,6 +183,7 @@
// can be made to this block.
uint32 block_id = 1;
+
}
message FactConstantUniform {
@@ -222,6 +224,7 @@
// functions.
uint32 function_id = 1;
+
}
message FactIdEquation {
@@ -249,6 +252,18 @@
}
+message FactIdIsIrrelevant {
+
+ // Records a fact that |result_id| is irrelevant (i.e. it's usage doesn't
+ // change the semantics of the module). This implies that a use of this id
+ // can later be replaced with some other id of the same type, or the
+ // definition of |result_id| can be changed so that it yields a different value.
+
+ // An irrelevant id.
+ uint32 result_id = 1;
+
+}
+
message FactPointeeValueIsIrrelevant {
// Records the fact that value of the data pointed to by a pointer id does
@@ -258,6 +273,7 @@
// A result id of pointer type
uint32 pointer_id = 1;
+
}
message AccessChainClampingInfo {
diff --git a/test/fuzz/fact_manager_test.cpp b/test/fuzz/fact_manager_test.cpp
index 623b6b3..bce10b9 100644
--- a/test/fuzz/fact_manager_test.cpp
+++ b/test/fuzz/fact_manager_test.cpp
@@ -1283,6 +1283,41 @@
ASSERT_FALSE(context->get_constant_mgr()->FindConstant(&constant_one));
}
+TEST(FactManagerTest, IdIsIrrelevant) {
+ std::string shader = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main"
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 320
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeInt 32 1
+ %12 = OpConstant %6 0
+ %13 = OpConstant %6 1
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ const auto env = SPV_ENV_UNIVERSAL_1_3;
+ const auto consumer = nullptr;
+ const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, context.get()));
+
+ FactManager fact_manager;
+
+ ASSERT_FALSE(fact_manager.IdIsIrrelevant(12));
+ ASSERT_FALSE(fact_manager.IdIsIrrelevant(13));
+
+ fact_manager.AddFactIdIsIrrelevant(12);
+
+ ASSERT_TRUE(fact_manager.IdIsIrrelevant(12));
+ ASSERT_FALSE(fact_manager.IdIsIrrelevant(13));
+}
+
} // namespace
} // namespace fuzz
} // namespace spvtools