mirror of
https://gitee.com/openharmony/third_party_spirv-tools
synced 2024-11-24 07:49:46 +00:00
spirv-fuzz: Improve transformation test oracles (#4207)
To help ensure that optimizations that do less cautious invalidation of analyses are implemented correctly, this change adds checks to the tests of various transformations to ensure that analyses such as def-use are up to date.
This commit is contained in:
parent
edb8399b0f
commit
3d39517961
@ -90,19 +90,34 @@ TEST(TransformationAddTypeArrayTest, BasicTest) {
|
||||
ASSERT_FALSE(TransformationAddTypeArray(100, 11, 17)
|
||||
.IsApplicable(context.get(), transformation_context));
|
||||
|
||||
TransformationAddTypeArray transformations[] = {
|
||||
{
|
||||
// %100 = OpTypeArray %10 %16
|
||||
TransformationAddTypeArray(100, 10, 16),
|
||||
|
||||
// %101 = OpTypeArray %7 %12
|
||||
TransformationAddTypeArray(101, 7, 12)};
|
||||
|
||||
for (auto& transformation : transformations) {
|
||||
TransformationAddTypeArray transformation(100, 10, 16);
|
||||
ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(100));
|
||||
ASSERT_EQ(nullptr, context->get_type_mgr()->GetType(100));
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
ApplyAndCheckFreshIds(transformation, context.get(),
|
||||
&transformation_context);
|
||||
ASSERT_EQ(SpvOpTypeArray,
|
||||
context->get_def_use_mgr()->GetDef(100)->opcode());
|
||||
ASSERT_NE(nullptr, context->get_type_mgr()->GetType(100)->AsArray());
|
||||
}
|
||||
|
||||
{
|
||||
// %101 = OpTypeArray %7 %12
|
||||
TransformationAddTypeArray transformation(101, 7, 12);
|
||||
ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(101));
|
||||
ASSERT_EQ(nullptr, context->get_type_mgr()->GetType(101));
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
ApplyAndCheckFreshIds(transformation, context.get(),
|
||||
&transformation_context);
|
||||
ASSERT_EQ(SpvOpTypeArray,
|
||||
context->get_def_use_mgr()->GetDef(100)->opcode());
|
||||
ASSERT_NE(nullptr, context->get_type_mgr()->GetType(100)->AsArray());
|
||||
}
|
||||
|
||||
ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
|
||||
kConsoleMessageConsumer));
|
||||
|
||||
|
@ -52,9 +52,13 @@ TEST(TransformationAddTypeBooleanTest, BasicTest) {
|
||||
context.get(), transformation_context));
|
||||
|
||||
auto add_type_bool = TransformationAddTypeBoolean(100);
|
||||
ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(100));
|
||||
ASSERT_EQ(nullptr, context->get_type_mgr()->GetType(100));
|
||||
ASSERT_TRUE(
|
||||
add_type_bool.IsApplicable(context.get(), transformation_context));
|
||||
ApplyAndCheckFreshIds(add_type_bool, context.get(), &transformation_context);
|
||||
ASSERT_EQ(SpvOpTypeBool, context->get_def_use_mgr()->GetDef(100)->opcode());
|
||||
ASSERT_NE(nullptr, context->get_type_mgr()->GetType(100)->AsBool());
|
||||
ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
|
||||
kConsoleMessageConsumer));
|
||||
|
||||
|
@ -103,15 +103,27 @@ TEST(TransformationAddTypeFloatTest, Apply) {
|
||||
MakeUnique<FactManager>(context.get()), validator_options);
|
||||
// Adds 16-bit float type.
|
||||
auto transformation = TransformationAddTypeFloat(6, 16);
|
||||
ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(6));
|
||||
ASSERT_EQ(nullptr, context->get_type_mgr()->GetType(6));
|
||||
ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
|
||||
ASSERT_EQ(SpvOpTypeFloat, context->get_def_use_mgr()->GetDef(6)->opcode());
|
||||
ASSERT_NE(nullptr, context->get_type_mgr()->GetType(6)->AsFloat());
|
||||
|
||||
// Adds 32-bit float type.
|
||||
transformation = TransformationAddTypeFloat(7, 32);
|
||||
ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(7));
|
||||
ASSERT_EQ(nullptr, context->get_type_mgr()->GetType(7));
|
||||
ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
|
||||
ASSERT_EQ(SpvOpTypeFloat, context->get_def_use_mgr()->GetDef(7)->opcode());
|
||||
ASSERT_NE(nullptr, context->get_type_mgr()->GetType(7)->AsFloat());
|
||||
|
||||
// Adds 64-bit float type.
|
||||
transformation = TransformationAddTypeFloat(8, 64);
|
||||
ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(8));
|
||||
ASSERT_EQ(nullptr, context->get_type_mgr()->GetType(8));
|
||||
ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
|
||||
ASSERT_EQ(SpvOpTypeFloat, context->get_def_use_mgr()->GetDef(8)->opcode());
|
||||
ASSERT_NE(nullptr, context->get_type_mgr()->GetType(8)->AsFloat());
|
||||
|
||||
std::string variant_shader = R"(
|
||||
OpCapability Shader
|
||||
|
@ -118,8 +118,14 @@ TEST(TransformationAddTypeIntTest, Apply) {
|
||||
TransformationContext transformation_context(
|
||||
MakeUnique<FactManager>(context.get()), validator_options);
|
||||
// Adds signed 8-bit integer type.
|
||||
// For this transformation we also check that the def-use manager and type
|
||||
// manager are updated appropriately.
|
||||
auto transformation = TransformationAddTypeInt(6, 8, true);
|
||||
ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(6));
|
||||
ASSERT_EQ(nullptr, context->get_type_mgr()->GetType(6));
|
||||
ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
|
||||
ASSERT_EQ(SpvOpTypeInt, context->get_def_use_mgr()->GetDef(6)->opcode());
|
||||
ASSERT_NE(nullptr, context->get_type_mgr()->GetType(6)->AsInteger());
|
||||
|
||||
// Adds signed 16-bit integer type.
|
||||
transformation = TransformationAddTypeInt(7, 16, true);
|
||||
|
@ -63,10 +63,21 @@ TEST(TransformationAddTypeMatrixTest, BasicTest) {
|
||||
ASSERT_FALSE(TransformationAddTypeMatrix(100, 11, 2)
|
||||
.IsApplicable(context.get(), transformation_context));
|
||||
|
||||
TransformationAddTypeMatrix transformations[] = {
|
||||
{
|
||||
// %100 = OpTypeMatrix %8 2
|
||||
TransformationAddTypeMatrix(100, 8, 2),
|
||||
TransformationAddTypeMatrix transformation(100, 8, 2);
|
||||
ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(100));
|
||||
ASSERT_EQ(nullptr, context->get_type_mgr()->GetType(100));
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
ApplyAndCheckFreshIds(transformation, context.get(),
|
||||
&transformation_context);
|
||||
ASSERT_EQ(SpvOpTypeMatrix,
|
||||
context->get_def_use_mgr()->GetDef(100)->opcode());
|
||||
ASSERT_NE(nullptr, context->get_type_mgr()->GetType(100)->AsMatrix());
|
||||
}
|
||||
|
||||
TransformationAddTypeMatrix transformations[] = {
|
||||
// %101 = OpTypeMatrix %8 3
|
||||
TransformationAddTypeMatrix(101, 8, 3),
|
||||
|
||||
|
@ -133,10 +133,24 @@ TEST(TransformationAddTypePointerTest, BasicTest) {
|
||||
ASSERT_FALSE(bad_result_id_is_not_fresh.IsApplicable(context.get(),
|
||||
transformation_context));
|
||||
|
||||
{
|
||||
auto& transformation = good_new_private_pointer_to_t;
|
||||
ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(101));
|
||||
ASSERT_EQ(nullptr, context->get_type_mgr()->GetType(101));
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
ApplyAndCheckFreshIds(transformation, context.get(),
|
||||
&transformation_context);
|
||||
ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(
|
||||
context.get(), validator_options, kConsoleMessageConsumer));
|
||||
ASSERT_EQ(SpvOpTypePointer,
|
||||
context->get_def_use_mgr()->GetDef(101)->opcode());
|
||||
ASSERT_NE(nullptr, context->get_type_mgr()->GetType(101)->AsPointer());
|
||||
}
|
||||
|
||||
for (auto& transformation :
|
||||
{good_new_private_pointer_to_t, good_new_uniform_pointer_to_t,
|
||||
good_another_function_pointer_to_s, good_new_uniform_pointer_to_s,
|
||||
good_another_private_pointer_to_float,
|
||||
{good_new_uniform_pointer_to_t, good_another_function_pointer_to_s,
|
||||
good_new_uniform_pointer_to_s, good_another_private_pointer_to_float,
|
||||
good_new_private_pointer_to_private_pointer_to_float,
|
||||
good_new_uniform_pointer_to_vec2,
|
||||
good_new_private_pointer_to_uniform_pointer_to_vec2}) {
|
||||
|
@ -63,10 +63,21 @@ TEST(TransformationAddTypeStructTest, BasicTest) {
|
||||
ASSERT_FALSE(TransformationAddTypeStruct(100, {3}).IsApplicable(
|
||||
context.get(), transformation_context));
|
||||
|
||||
TransformationAddTypeStruct transformations[] = {
|
||||
{
|
||||
// %100 = OpTypeStruct %6 %7 %8 %9 %10 %11
|
||||
TransformationAddTypeStruct(100, {6, 7, 8, 9, 10, 11}),
|
||||
TransformationAddTypeStruct transformation(100, {6, 7, 8, 9, 10, 11});
|
||||
ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(100));
|
||||
ASSERT_EQ(nullptr, context->get_type_mgr()->GetType(100));
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
ApplyAndCheckFreshIds(transformation, context.get(),
|
||||
&transformation_context);
|
||||
ASSERT_EQ(SpvOpTypeStruct,
|
||||
context->get_def_use_mgr()->GetDef(100)->opcode());
|
||||
ASSERT_NE(nullptr, context->get_type_mgr()->GetType(100)->AsStruct());
|
||||
}
|
||||
|
||||
TransformationAddTypeStruct transformations[] = {
|
||||
// %101 = OpTypeStruct
|
||||
TransformationAddTypeStruct(101, {}),
|
||||
|
||||
|
@ -57,10 +57,21 @@ TEST(TransformationAddTypeVectorTest, BasicTest) {
|
||||
ASSERT_FALSE(TransformationAddTypeVector(100, 1, 2).IsApplicable(
|
||||
context.get(), transformation_context));
|
||||
|
||||
TransformationAddTypeVector transformations[] = {
|
||||
{
|
||||
// %100 = OpTypeVector %6 2
|
||||
TransformationAddTypeVector(100, 6, 2),
|
||||
TransformationAddTypeVector transformation(100, 6, 2);
|
||||
ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(100));
|
||||
ASSERT_EQ(nullptr, context->get_type_mgr()->GetType(100));
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
ApplyAndCheckFreshIds(transformation, context.get(),
|
||||
&transformation_context);
|
||||
ASSERT_EQ(SpvOpTypeVector,
|
||||
context->get_def_use_mgr()->GetDef(100)->opcode());
|
||||
ASSERT_NE(nullptr, context->get_type_mgr()->GetType(100)->AsVector());
|
||||
}
|
||||
|
||||
TransformationAddTypeVector transformations[] = {
|
||||
// %101 = OpTypeVector %7 3
|
||||
TransformationAddTypeVector(101, 7, 3),
|
||||
|
||||
|
@ -146,8 +146,19 @@ TEST(TransformationCompositeConstructTest, ConstructArrays) {
|
||||
transformation_context));
|
||||
ASSERT_FALSE(make_vec2_array_length_3_bad.IsApplicable(
|
||||
context.get(), transformation_context));
|
||||
ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(200));
|
||||
ASSERT_EQ(nullptr, context->get_instr_block(200));
|
||||
uint32_t num_uses_of_41_before = context->get_def_use_mgr()->NumUses(41);
|
||||
uint32_t num_uses_of_45_before = context->get_def_use_mgr()->NumUses(45);
|
||||
uint32_t num_uses_of_27_before = context->get_def_use_mgr()->NumUses(27);
|
||||
ApplyAndCheckFreshIds(make_vec2_array_length_3, context.get(),
|
||||
&transformation_context);
|
||||
ASSERT_EQ(SpvOpCompositeConstruct,
|
||||
context->get_def_use_mgr()->GetDef(200)->opcode());
|
||||
ASSERT_EQ(34, context->get_instr_block(200)->id());
|
||||
ASSERT_EQ(num_uses_of_41_before + 1, context->get_def_use_mgr()->NumUses(41));
|
||||
ASSERT_EQ(num_uses_of_45_before + 1, context->get_def_use_mgr()->NumUses(45));
|
||||
ASSERT_EQ(num_uses_of_27_before + 1, context->get_def_use_mgr()->NumUses(27));
|
||||
ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
|
||||
kConsoleMessageConsumer));
|
||||
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
|
||||
|
@ -143,10 +143,18 @@ TEST(TransformationCompositeExtractTest, BasicTest) {
|
||||
|
||||
TransformationCompositeExtract transformation_1(
|
||||
MakeInstructionDescriptor(36, SpvOpConvertFToS, 0), 201, 100, {2});
|
||||
ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(201));
|
||||
ASSERT_EQ(nullptr, context->get_instr_block(201));
|
||||
uint32_t num_uses_of_100_before = context->get_def_use_mgr()->NumUses(100);
|
||||
ASSERT_TRUE(
|
||||
transformation_1.IsApplicable(context.get(), transformation_context));
|
||||
ApplyAndCheckFreshIds(transformation_1, context.get(),
|
||||
&transformation_context);
|
||||
ASSERT_EQ(SpvOpCompositeExtract,
|
||||
context->get_def_use_mgr()->GetDef(201)->opcode());
|
||||
ASSERT_EQ(15, context->get_instr_block(201)->id());
|
||||
ASSERT_EQ(num_uses_of_100_before + 1,
|
||||
context->get_def_use_mgr()->NumUses(100));
|
||||
ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
|
||||
kConsoleMessageConsumer));
|
||||
|
||||
|
@ -102,8 +102,12 @@ TEST(TransformationEquationInstructionTest, SignedNegate) {
|
||||
14, SpvOpSNegate, {7}, return_instruction);
|
||||
ASSERT_TRUE(
|
||||
transformation1.IsApplicable(context.get(), transformation_context));
|
||||
ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(14));
|
||||
ASSERT_EQ(nullptr, context->get_instr_block(14));
|
||||
ApplyAndCheckFreshIds(transformation1, context.get(),
|
||||
&transformation_context);
|
||||
ASSERT_EQ(SpvOpSNegate, context->get_def_use_mgr()->GetDef(14)->opcode());
|
||||
ASSERT_EQ(13, context->get_instr_block(14)->id());
|
||||
ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
|
||||
kConsoleMessageConsumer));
|
||||
|
||||
|
@ -105,6 +105,23 @@ TEST(TransformationPermutePhiOperandsTest, BasicTest) {
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
|
||||
|
||||
// Check that the def-use manager knows that the phi instruction's ids have
|
||||
// been permuted.
|
||||
std::vector<std::pair<uint32_t, uint32_t>> phi_operand_to_new_operand_index =
|
||||
{{20, 4}, {16, 5}, {24, 2}, {21, 3}};
|
||||
for (std::pair<uint32_t, uint32_t>& entry :
|
||||
phi_operand_to_new_operand_index) {
|
||||
context->get_def_use_mgr()->WhileEachUse(
|
||||
entry.first,
|
||||
[&entry](opt::Instruction* inst, uint32_t operand_index) -> bool {
|
||||
if (inst->result_id() == 25) {
|
||||
EXPECT_EQ(entry.second, operand_index);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
std::string after_transformation = R"(
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
|
@ -303,10 +303,18 @@ TEST(TransformationReplaceIdWithSynonymTest, LegalTransformations) {
|
||||
auto global_constant_synonym = TransformationReplaceIdWithSynonym(
|
||||
MakeIdUseDescriptor(19, MakeInstructionDescriptor(47, SpvOpStore, 0), 1),
|
||||
210);
|
||||
uint32_t num_uses_of_original_id_before_replacement =
|
||||
context->get_def_use_mgr()->NumUses(19);
|
||||
uint32_t num_uses_of_synonym_before_replacement =
|
||||
context->get_def_use_mgr()->NumUses(210);
|
||||
ASSERT_TRUE(global_constant_synonym.IsApplicable(context.get(),
|
||||
transformation_context));
|
||||
ApplyAndCheckFreshIds(global_constant_synonym, context.get(),
|
||||
&transformation_context);
|
||||
ASSERT_EQ(num_uses_of_original_id_before_replacement - 1,
|
||||
context->get_def_use_mgr()->NumUses(19));
|
||||
ASSERT_EQ(num_uses_of_synonym_before_replacement + 1,
|
||||
context->get_def_use_mgr()->NumUses(210));
|
||||
ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
|
||||
kConsoleMessageConsumer));
|
||||
|
||||
|
@ -958,8 +958,8 @@ TEST(TransformationSetLoopControlTest, CheckSPIRVVersionsRespected) {
|
||||
context.get(), validator_options, kConsoleMessageConsumer));
|
||||
TransformationContext transformation_context(
|
||||
MakeUnique<FactManager>(context.get()), validator_options);
|
||||
TransformationSetLoopControl peel_count(
|
||||
10, SpvLoopControlPeelCountMask, 4, 0);
|
||||
TransformationSetLoopControl peel_count(10, SpvLoopControlPeelCountMask, 4,
|
||||
0);
|
||||
TransformationSetLoopControl partial_count(
|
||||
10, SpvLoopControlPartialCountMask, 0, 4);
|
||||
|
||||
|
@ -91,9 +91,31 @@ TEST(TransformationSwapConditionalBranchOperandsTest, BasicTest) {
|
||||
|
||||
TransformationSwapConditionalBranchOperands transformation(
|
||||
MakeInstructionDescriptor(15, SpvOpBranchConditional, 0), 26);
|
||||
ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(26));
|
||||
ASSERT_EQ(nullptr, context->get_instr_block(26));
|
||||
ASSERT_TRUE(
|
||||
transformation.IsApplicable(context.get(), transformation_context));
|
||||
ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
|
||||
ASSERT_EQ(SpvOpLogicalNot, context->get_def_use_mgr()->GetDef(26)->opcode());
|
||||
ASSERT_EQ(5, context->get_instr_block(26)->id());
|
||||
ASSERT_EQ(1, context->get_def_use_mgr()->NumUses(26));
|
||||
|
||||
// Check that the def-use manager knows that the conditional branch operands
|
||||
// have been swapped.
|
||||
std::vector<std::pair<uint32_t, uint32_t>> phi_operand_to_new_operand_index =
|
||||
{{16, 2}, {21, 1}};
|
||||
for (std::pair<uint32_t, uint32_t>& entry :
|
||||
phi_operand_to_new_operand_index) {
|
||||
context->get_def_use_mgr()->WhileEachUse(
|
||||
entry.first,
|
||||
[&entry](opt::Instruction* inst, uint32_t operand_index) -> bool {
|
||||
if (inst->opcode() == SpvOpBranchConditional) {
|
||||
EXPECT_EQ(entry.second, operand_index);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
std::string after_transformation = R"(
|
||||
OpCapability Shader
|
||||
|
Loading…
Reference in New Issue
Block a user