Squashed 'third_party/SPIRV-Tools/' changes from fd773eb50d6..55af3902fc2
55af3902fc2 Fix function use (#3372)
9cb2571a184 spirv-val: allow DebugInfoNone for DebugTypeComposite.Size (#3374)
4386ef4234e Add validation support for ImageGatherBiasLodAMD (#3363)
b0264b87ffb Fix validation failure on OpDecorationGroup (#3365)
4410272bdda Remove deprecated interfaces from instrument passes (#3361)
50b15578866 Preserve debug info in inline pass (#3349)
4dbe18b0c86 Reject folding comparisons with unfoldable types. (#3370)
55193b06e5e Improve build instructions for fuzzer (#3364)
3c47dac2820 Add unrolling to performance passes (#3082)
2b987c49a4e Handle OpConstantNull in ssa-rewrite (#3362)
95df4c9643c Add in a bunch of missed files to the BUILD.gn (#3360)
90930cb3115 Remove stale entries from BUILD.gn (#3358)
18ba3d9a353 allow cross compiling for Windows Store, UWP, etc. (#3330)
2f69ea849aa spirv-fuzz: Remove FuzzerPassAddUsefulConstructs (#3341)
522561619a9 Add support for StorageBuffer (#3348)
b75dbf82a69 Prevent Effcee install his things when build spirv-tools with testing enabled (#3256)
85c7e7956bf Don't register edges twice in merge return (#3350)
bd0a2da946c Revert "Revert "[spirv-opt] refactor inlining pass (#3328)" (#3342)" (#3345)
31182763704 spirv-reduce: Remove unused struct members (#3329)
a6b0e132ecc Add adjust branch weights transformation (#3336)
d4fac3451b7 Revert "[spirv-opt] refactor inlining pass (#3328)" (#3342)
233246bc9c5 [spirv-opt] refactor inlining pass (#3328)
2992386ebea spirv-reduce: Remove unused uniforms and similar (#3321)
a9f2a145e65 spirv-fuzz: Fix to fact manager (#3339)
045a26e6e37 spirv-fuzz: Get rid of unnecessary template method (#3340)
63fa9114a93 Do merge return if the return is not at the end of the function. (#3337)
c8590c18bd0 Preserve debug info for wrap-opkill (#3331)
d2b48621949 Validate ShaderCallKHR memory scope (#3332)
2e1d208ed9d spirv-fuzz: Do not allow adding stores to read-only pointers (#3316)
54fb17b2d30 reduce: increase default step limit (#3327)
49842b88eec Generalize IsReadOnlyVariable() to apply to pointers (#3325)
49ca250b44c Delete nullptr in function bb list immedietly (#3326)
d0a87194f7b Set DebugScope for termination instructions (#3323)
f278b467dfd spirv-fuzz: Do not outline regions that end with a loop header (#3312)
23d68608b00 vscode: Handle '|' chains on BitEnum / ValueEnum (#3309)
42268740c95 Add debug information analysis (#3305)
eed48ae479d Add spvtools::opt::Operand::AsLiteralUint64 (#3320)
94d6002dc53 spirv-fuzz: Pass on validator options during shrinking (#3317)
88faf63ad3c spirv-fuzz: Clamp statically out-of-bounds accesses in code donation (#3315)
b74199a22d4 spirv-fuzz: Fix memory management in the fact manager (#3313)
d158ffe5405 spirv-fuzz: Do not replace the Sample argument in OpImageTexelPointer (#3311)
5547553a0c7 Allow various validation options to be passed to spirv-opt (#3314)
30ffe62e257 typo fix: in README.md exectuable->executable (#3306)
67f4838659f spirv-fuzz: Make handling of synonym facts more efficient (#3301)
61b7de3c39f Remove unreachable code. (#3304)
ed96301c6c4 spirv-fuzz: Fix to outliner (#3302)
c018fc6ae66 spirv-fuzz: Do not outline regions that produce pointer outputs (#3291)
f460cca9dca spirv-fuzz: Handle OpRuntimeArray when replacing ids with synonyms (#3292)
2f180468a71 spirv-fuzz: Handle image storage class in donation (#3290)
f82d47003e7 spirv-fuzz: Respect rules for OpSampledImage (#3287)
7ce2db1763b spirv-fuzz: Fix comment. (#3300)
7d65bce0bbe Sampled images as read-only storage (#3295)
2a2bdbd5d72 Remove implicit fallthrough (#3298)
49566448944 Add tests for recently added command line option (#3297)
ca5751590ed If SPIRV-Headers is in our tree, include it as subproject (#3299)
e70d25f6fa5 Struct CFG analysus and single block loop (#3293)
000040e707a Preserve debug info in eliminate-dead-functions (#3251)
c531099eb34 Update acorn version (#3294)
34be23373b9 Handle more cases in dead member elim (#3289)
d0490ef080c Fix pch macro to ignore clang-cl (#3283)
538512e8e89 spirv-fuzz: Improve the handling of equation facts (#3281)
183e3242a36 spirv-fuzz: Handle more general SPIR-V in donation (#3280)
4af38c49bfe spirv-fuzz: Improve support for compute shaders in donation (#3277)
e95fbfb1f50 spirv-fuzz: Transformation to add OpConstantNull (#3273)
5d491a7ed66 spirv-fuzz: Handle isomorphic types property in composite construction (#3262)
bfd25ace084 spirv-fuzz: Limit adding of new variables to 'basic' types (#3257)
f28cdeff16f spirv-fuzz: Only replace regular ids with synonyms (#3255)
8d4261bc440 spirv-fuzz: Introduce TransformationContext (#3272)
2fdea57d19d spirv-fuzz: Add validator options (#3254)
af01d57b5e3 Update dominates to check for null nodes (#3271)
f20c0d7971c Set wrapped kill basic block's parent (#3269)
c37c94929bf Validate Buffer and BufferBlock apply only to struct types (#3259)
git-subtree-dir: third_party/SPIRV-Tools
git-subtree-split: 55af3902fc24db889b0ef8010a83efca04a6352c
diff --git a/test/fuzz/CMakeLists.txt b/test/fuzz/CMakeLists.txt
index 99a78fd..dca142a 100644
--- a/test/fuzz/CMakeLists.txt
+++ b/test/fuzz/CMakeLists.txt
@@ -21,12 +21,13 @@
equivalence_relation_test.cpp
fact_manager_test.cpp
fuzz_test_util.cpp
- fuzzer_pass_add_useful_constructs_test.cpp
+ fuzzer_pass_construct_composites_test.cpp
fuzzer_pass_donate_modules_test.cpp
instruction_descriptor_test.cpp
transformation_access_chain_test.cpp
transformation_add_constant_boolean_test.cpp
transformation_add_constant_composite_test.cpp
+ transformation_add_constant_null_test.cpp
transformation_add_constant_scalar_test.cpp
transformation_add_dead_block_test.cpp
transformation_add_dead_break_test.cpp
@@ -45,8 +46,10 @@
transformation_add_type_pointer_test.cpp
transformation_add_type_struct_test.cpp
transformation_add_type_vector_test.cpp
+ transformation_adjust_branch_weights_test.cpp
transformation_composite_construct_test.cpp
transformation_composite_extract_test.cpp
+ transformation_compute_data_synonym_fact_closure_test.cpp
transformation_copy_object_test.cpp
transformation_equation_instruction_test.cpp
transformation_function_call_test.cpp
diff --git a/test/fuzz/data_synonym_transformation_test.cpp b/test/fuzz/data_synonym_transformation_test.cpp
index 21ea068..66ce769 100644
--- a/test/fuzz/data_synonym_transformation_test.cpp
+++ b/test/fuzz/data_synonym_transformation_test.cpp
@@ -123,13 +123,24 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
- fact_manager.AddFact(MakeSynonymFact(12, {}, 100, {0}), context.get());
- fact_manager.AddFact(MakeSynonymFact(13, {}, 100, {1}), context.get());
- fact_manager.AddFact(MakeSynonymFact(22, {}, 100, {2}), context.get());
- fact_manager.AddFact(MakeSynonymFact(28, {}, 101, {0}), context.get());
- fact_manager.AddFact(MakeSynonymFact(23, {}, 101, {1}), context.get());
- fact_manager.AddFact(MakeSynonymFact(32, {}, 101, {2}), context.get());
- fact_manager.AddFact(MakeSynonymFact(23, {}, 101, {3}), context.get());
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(12, {}, 100, {0}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(13, {}, 100, {1}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(22, {}, 100, {2}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(28, {}, 101, {0}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(23, {}, 101, {1}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(32, {}, 101, {2}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(23, {}, 101, {3}), context.get());
// Replace %12 with %100[0] in '%25 = OpAccessChain %24 %20 %12'
auto instruction_descriptor_1 =
@@ -139,13 +150,16 @@
// Bad: id already in use
auto bad_extract_1 = TransformationCompositeExtract(
MakeInstructionDescriptor(25, SpvOpAccessChain, 0), 25, 100, {0});
- ASSERT_TRUE(good_extract_1.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(bad_extract_1.IsApplicable(context.get(), fact_manager));
- good_extract_1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ good_extract_1.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ bad_extract_1.IsApplicable(context.get(), transformation_context));
+ good_extract_1.Apply(context.get(), &transformation_context);
auto replacement_1 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(12, instruction_descriptor_1, 1), 102);
- ASSERT_TRUE(replacement_1.IsApplicable(context.get(), fact_manager));
- replacement_1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement_1.IsApplicable(context.get(), transformation_context));
+ replacement_1.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replace %13 with %100[1] in 'OpStore %15 %13'
@@ -153,12 +167,14 @@
auto good_extract_2 =
TransformationCompositeExtract(instruction_descriptor_2, 103, 100, {1});
// No bad example provided here.
- ASSERT_TRUE(good_extract_2.IsApplicable(context.get(), fact_manager));
- good_extract_2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ good_extract_2.IsApplicable(context.get(), transformation_context));
+ good_extract_2.Apply(context.get(), &transformation_context);
auto replacement_2 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(13, instruction_descriptor_2, 1), 103);
- ASSERT_TRUE(replacement_2.IsApplicable(context.get(), fact_manager));
- replacement_2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement_2.IsApplicable(context.get(), transformation_context));
+ replacement_2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replace %22 with %100[2] in '%23 = OpConvertSToF %16 %22'
@@ -166,16 +182,19 @@
MakeInstructionDescriptor(23, SpvOpConvertSToF, 0);
auto good_extract_3 =
TransformationCompositeExtract(instruction_descriptor_3, 104, 100, {2});
- ASSERT_TRUE(good_extract_3.IsApplicable(context.get(), fact_manager));
- good_extract_3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ good_extract_3.IsApplicable(context.get(), transformation_context));
+ good_extract_3.Apply(context.get(), &transformation_context);
auto replacement_3 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(22, instruction_descriptor_3, 0), 104);
// Bad: wrong input operand index
auto bad_replacement_3 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(22, instruction_descriptor_3, 1), 104);
- ASSERT_TRUE(replacement_3.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(bad_replacement_3.IsApplicable(context.get(), fact_manager));
- replacement_3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement_3.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ bad_replacement_3.IsApplicable(context.get(), transformation_context));
+ replacement_3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replace %28 with %101[0] in 'OpStore %33 %28'
@@ -185,13 +204,16 @@
// Bad: instruction descriptor does not identify an appropriate instruction
auto bad_extract_4 = TransformationCompositeExtract(
MakeInstructionDescriptor(33, SpvOpCopyObject, 0), 105, 101, {0});
- ASSERT_TRUE(good_extract_4.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(bad_extract_4.IsApplicable(context.get(), fact_manager));
- good_extract_4.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ good_extract_4.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ bad_extract_4.IsApplicable(context.get(), transformation_context));
+ good_extract_4.Apply(context.get(), &transformation_context);
auto replacement_4 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(28, instruction_descriptor_4, 1), 105);
- ASSERT_TRUE(replacement_4.IsApplicable(context.get(), fact_manager));
- replacement_4.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement_4.IsApplicable(context.get(), transformation_context));
+ replacement_4.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replace %23 with %101[1] in '%50 = OpCopyObject %16 %23'
@@ -199,16 +221,19 @@
MakeInstructionDescriptor(50, SpvOpCopyObject, 0);
auto good_extract_5 =
TransformationCompositeExtract(instruction_descriptor_5, 106, 101, {1});
- ASSERT_TRUE(good_extract_5.IsApplicable(context.get(), fact_manager));
- good_extract_5.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ good_extract_5.IsApplicable(context.get(), transformation_context));
+ good_extract_5.Apply(context.get(), &transformation_context);
auto replacement_5 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(23, instruction_descriptor_5, 0), 106);
// Bad: wrong synonym fact being used
auto bad_replacement_5 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(23, instruction_descriptor_5, 0), 105);
- ASSERT_TRUE(replacement_5.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(bad_replacement_5.IsApplicable(context.get(), fact_manager));
- replacement_5.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement_5.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ bad_replacement_5.IsApplicable(context.get(), transformation_context));
+ replacement_5.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replace %32 with %101[2] in 'OpStore %33 %32'
@@ -218,13 +243,16 @@
// Bad: id 1001 does not exist
auto bad_extract_6 =
TransformationCompositeExtract(instruction_descriptor_6, 107, 1001, {2});
- ASSERT_TRUE(good_extract_6.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(bad_extract_6.IsApplicable(context.get(), fact_manager));
- good_extract_6.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ good_extract_6.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ bad_extract_6.IsApplicable(context.get(), transformation_context));
+ good_extract_6.Apply(context.get(), &transformation_context);
auto replacement_6 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(32, instruction_descriptor_6, 1), 107);
- ASSERT_TRUE(replacement_6.IsApplicable(context.get(), fact_manager));
- replacement_6.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement_6.IsApplicable(context.get(), transformation_context));
+ replacement_6.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replace %23 with %101[3] in '%51 = OpCopyObject %16 %23'
@@ -232,16 +260,19 @@
MakeInstructionDescriptor(51, SpvOpCopyObject, 0);
auto good_extract_7 =
TransformationCompositeExtract(instruction_descriptor_7, 108, 101, {3});
- ASSERT_TRUE(good_extract_7.IsApplicable(context.get(), fact_manager));
- good_extract_7.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ good_extract_7.IsApplicable(context.get(), transformation_context));
+ good_extract_7.Apply(context.get(), &transformation_context);
auto replacement_7 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(23, instruction_descriptor_7, 0), 108);
// Bad: use id 0 is invalid
auto bad_replacement_7 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(0, instruction_descriptor_7, 0), 108);
- ASSERT_TRUE(replacement_7.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(bad_replacement_7.IsApplicable(context.get(), fact_manager));
- replacement_7.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement_7.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ bad_replacement_7.IsApplicable(context.get(), transformation_context));
+ replacement_7.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
const std::string after_transformation = R"(
@@ -380,32 +411,41 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
- fact_manager.AddFact(MakeSynonymFact(23, {}, 100, {0}), context.get());
- fact_manager.AddFact(MakeSynonymFact(25, {}, 100, {1}), context.get());
- fact_manager.AddFact(MakeSynonymFact(50, {}, 100, {2}), context.get());
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(23, {}, 100, {0}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(25, {}, 100, {1}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(50, {}, 100, {2}), context.get());
// Replace %23 with %100[0] in '%26 = OpFAdd %7 %23 %25'
auto instruction_descriptor_1 = MakeInstructionDescriptor(26, SpvOpFAdd, 0);
auto extract_1 =
TransformationCompositeExtract(instruction_descriptor_1, 101, 100, {0});
- ASSERT_TRUE(extract_1.IsApplicable(context.get(), fact_manager));
- extract_1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(extract_1.IsApplicable(context.get(), transformation_context));
+ extract_1.Apply(context.get(), &transformation_context);
auto replacement_1 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(23, instruction_descriptor_1, 0), 101);
- ASSERT_TRUE(replacement_1.IsApplicable(context.get(), fact_manager));
- replacement_1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement_1.IsApplicable(context.get(), transformation_context));
+ replacement_1.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replace %25 with %100[1] in '%26 = OpFAdd %7 %23 %25'
auto instruction_descriptor_2 = MakeInstructionDescriptor(26, SpvOpFAdd, 0);
auto extract_2 =
TransformationCompositeExtract(instruction_descriptor_2, 102, 100, {1});
- ASSERT_TRUE(extract_2.IsApplicable(context.get(), fact_manager));
- extract_2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(extract_2.IsApplicable(context.get(), transformation_context));
+ extract_2.Apply(context.get(), &transformation_context);
auto replacement_2 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(25, instruction_descriptor_2, 1), 102);
- ASSERT_TRUE(replacement_2.IsApplicable(context.get(), fact_manager));
- replacement_2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement_2.IsApplicable(context.get(), transformation_context));
+ replacement_2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
const std::string after_transformation = R"(
@@ -541,26 +581,37 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
- fact_manager.AddFact(MakeSynonymFact(16, {}, 100, {0}), context.get());
- fact_manager.AddFact(MakeSynonymFact(45, {}, 100, {1}), context.get());
- fact_manager.AddFact(MakeSynonymFact(27, {}, 101, {0}), context.get());
- fact_manager.AddFact(MakeSynonymFact(36, {}, 101, {1}), context.get());
- fact_manager.AddFact(MakeSynonymFact(27, {}, 101, {2}), context.get());
- fact_manager.AddFact(MakeSynonymFact(22, {}, 102, {0}), context.get());
- fact_manager.AddFact(MakeSynonymFact(15, {}, 102, {1}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(16, {}, 100, {0}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(45, {}, 100, {1}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(27, {}, 101, {0}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(36, {}, 101, {1}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(27, {}, 101, {2}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(22, {}, 102, {0}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(15, {}, 102, {1}), context.get());
// Replace %45 with %100[1] in '%46 = OpCompositeConstruct %32 %35 %45'
auto instruction_descriptor_1 =
MakeInstructionDescriptor(46, SpvOpCompositeConstruct, 0);
auto extract_1 =
TransformationCompositeExtract(instruction_descriptor_1, 201, 100, {1});
- ASSERT_TRUE(extract_1.IsApplicable(context.get(), fact_manager));
- extract_1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(extract_1.IsApplicable(context.get(), transformation_context));
+ extract_1.Apply(context.get(), &transformation_context);
auto replacement_1 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(45, instruction_descriptor_1, 1), 201);
- ASSERT_TRUE(replacement_1.IsApplicable(context.get(), fact_manager));
- replacement_1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement_1.IsApplicable(context.get(), transformation_context));
+ replacement_1.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replace second occurrence of %27 with %101[0] in '%28 =
@@ -569,12 +620,13 @@
MakeInstructionDescriptor(28, SpvOpCompositeConstruct, 0);
auto extract_2 =
TransformationCompositeExtract(instruction_descriptor_2, 202, 101, {0});
- ASSERT_TRUE(extract_2.IsApplicable(context.get(), fact_manager));
- extract_2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(extract_2.IsApplicable(context.get(), transformation_context));
+ extract_2.Apply(context.get(), &transformation_context);
auto replacement_2 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(27, instruction_descriptor_2, 1), 202);
- ASSERT_TRUE(replacement_2.IsApplicable(context.get(), fact_manager));
- replacement_2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement_2.IsApplicable(context.get(), transformation_context));
+ replacement_2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replace %36 with %101[1] in '%45 = OpCompositeConstruct %31 %36 %41 %44'
@@ -582,12 +634,13 @@
MakeInstructionDescriptor(45, SpvOpCompositeConstruct, 0);
auto extract_3 =
TransformationCompositeExtract(instruction_descriptor_3, 203, 101, {1});
- ASSERT_TRUE(extract_3.IsApplicable(context.get(), fact_manager));
- extract_3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(extract_3.IsApplicable(context.get(), transformation_context));
+ extract_3.Apply(context.get(), &transformation_context);
auto replacement_3 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(36, instruction_descriptor_3, 0), 203);
- ASSERT_TRUE(replacement_3.IsApplicable(context.get(), fact_manager));
- replacement_3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement_3.IsApplicable(context.get(), transformation_context));
+ replacement_3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replace first occurrence of %27 with %101[2] in '%28 = OpCompositeConstruct
@@ -596,24 +649,26 @@
MakeInstructionDescriptor(28, SpvOpCompositeConstruct, 0);
auto extract_4 =
TransformationCompositeExtract(instruction_descriptor_4, 204, 101, {2});
- ASSERT_TRUE(extract_4.IsApplicable(context.get(), fact_manager));
- extract_4.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(extract_4.IsApplicable(context.get(), transformation_context));
+ extract_4.Apply(context.get(), &transformation_context);
auto replacement_4 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(27, instruction_descriptor_4, 0), 204);
- ASSERT_TRUE(replacement_4.IsApplicable(context.get(), fact_manager));
- replacement_4.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement_4.IsApplicable(context.get(), transformation_context));
+ replacement_4.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replace %22 with %102[0] in 'OpStore %23 %22'
auto instruction_descriptor_5 = MakeInstructionDescriptor(23, SpvOpStore, 0);
auto extract_5 =
TransformationCompositeExtract(instruction_descriptor_5, 205, 102, {0});
- ASSERT_TRUE(extract_5.IsApplicable(context.get(), fact_manager));
- extract_5.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(extract_5.IsApplicable(context.get(), transformation_context));
+ extract_5.Apply(context.get(), &transformation_context);
auto replacement_5 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(22, instruction_descriptor_5, 1), 205);
- ASSERT_TRUE(replacement_5.IsApplicable(context.get(), fact_manager));
- replacement_5.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement_5.IsApplicable(context.get(), transformation_context));
+ replacement_5.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
const std::string after_transformation = R"(
@@ -816,38 +871,65 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
- fact_manager.AddFact(MakeSynonymFact(20, {0}, 100, {0}), context.get());
- fact_manager.AddFact(MakeSynonymFact(20, {1}, 100, {1}), context.get());
- fact_manager.AddFact(MakeSynonymFact(20, {2}, 100, {2}), context.get());
- fact_manager.AddFact(MakeSynonymFact(54, {}, 100, {3}), context.get());
- fact_manager.AddFact(MakeSynonymFact(15, {0}, 101, {0}), context.get());
- fact_manager.AddFact(MakeSynonymFact(15, {1}, 101, {1}), context.get());
- fact_manager.AddFact(MakeSynonymFact(19, {0}, 101, {2}), context.get());
- fact_manager.AddFact(MakeSynonymFact(19, {1}, 101, {3}), context.get());
- fact_manager.AddFact(MakeSynonymFact(27, {}, 102, {0}), context.get());
- fact_manager.AddFact(MakeSynonymFact(15, {0}, 102, {1}), context.get());
- fact_manager.AddFact(MakeSynonymFact(15, {1}, 102, {2}), context.get());
- fact_manager.AddFact(MakeSynonymFact(33, {}, 103, {0}), context.get());
- fact_manager.AddFact(MakeSynonymFact(47, {0}, 103, {1}), context.get());
- fact_manager.AddFact(MakeSynonymFact(47, {1}, 103, {2}), context.get());
- fact_manager.AddFact(MakeSynonymFact(47, {2}, 103, {3}), context.get());
- fact_manager.AddFact(MakeSynonymFact(42, {}, 104, {0}), context.get());
- fact_manager.AddFact(MakeSynonymFact(45, {}, 104, {1}), context.get());
- fact_manager.AddFact(MakeSynonymFact(38, {0}, 105, {0}), context.get());
- fact_manager.AddFact(MakeSynonymFact(38, {1}, 105, {1}), context.get());
- fact_manager.AddFact(MakeSynonymFact(46, {}, 105, {2}), context.get());
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(20, {0}, 100, {0}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(20, {1}, 100, {1}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(20, {2}, 100, {2}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(54, {}, 100, {3}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(15, {0}, 101, {0}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(15, {1}, 101, {1}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(19, {0}, 101, {2}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(19, {1}, 101, {3}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(27, {}, 102, {0}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(15, {0}, 102, {1}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(15, {1}, 102, {2}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(33, {}, 103, {0}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(47, {0}, 103, {1}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(47, {1}, 103, {2}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(47, {2}, 103, {3}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(42, {}, 104, {0}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(45, {}, 104, {1}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(38, {0}, 105, {0}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(38, {1}, 105, {1}), context.get());
+ transformation_context.GetFactManager()->AddFact(
+ MakeSynonymFact(46, {}, 105, {2}), context.get());
// Replace %20 with %100[0:2] in '%80 = OpCopyObject %16 %20'
auto instruction_descriptor_1 =
MakeInstructionDescriptor(80, SpvOpCopyObject, 0);
auto shuffle_1 = TransformationVectorShuffle(instruction_descriptor_1, 200,
100, 100, {0, 1, 2});
- ASSERT_TRUE(shuffle_1.IsApplicable(context.get(), fact_manager));
- shuffle_1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(shuffle_1.IsApplicable(context.get(), transformation_context));
+ shuffle_1.Apply(context.get(), &transformation_context);
+ fact_manager.ComputeClosureOfFacts(context.get(), 100);
+
auto replacement_1 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(20, instruction_descriptor_1, 0), 200);
- ASSERT_TRUE(replacement_1.IsApplicable(context.get(), fact_manager));
- replacement_1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement_1.IsApplicable(context.get(), transformation_context));
+ replacement_1.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replace %54 with %100[3] in '%56 = OpFOrdNotEqual %30 %54 %55'
@@ -856,24 +938,28 @@
auto extract_2 =
TransformationCompositeExtract(instruction_descriptor_2, 201, 100, {3});
- ASSERT_TRUE(extract_2.IsApplicable(context.get(), fact_manager));
- extract_2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(extract_2.IsApplicable(context.get(), transformation_context));
+ extract_2.Apply(context.get(), &transformation_context);
auto replacement_2 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(54, instruction_descriptor_2, 0), 201);
- ASSERT_TRUE(replacement_2.IsApplicable(context.get(), fact_manager));
- replacement_2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement_2.IsApplicable(context.get(), transformation_context));
+ replacement_2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replace %15 with %101[0:1] in 'OpStore %12 %15'
auto instruction_descriptor_3 = MakeInstructionDescriptor(64, SpvOpStore, 0);
auto shuffle_3 = TransformationVectorShuffle(instruction_descriptor_3, 202,
101, 101, {0, 1});
- ASSERT_TRUE(shuffle_3.IsApplicable(context.get(), fact_manager));
- shuffle_3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(shuffle_3.IsApplicable(context.get(), transformation_context));
+ shuffle_3.Apply(context.get(), &transformation_context);
+ fact_manager.ComputeClosureOfFacts(context.get(), 100);
+
auto replacement_3 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(15, instruction_descriptor_3, 1), 202);
- ASSERT_TRUE(replacement_3.IsApplicable(context.get(), fact_manager));
- replacement_3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement_3.IsApplicable(context.get(), transformation_context));
+ replacement_3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replace %19 with %101[2:3] in '%81 = OpVectorShuffle %16 %19 %19 0 0 1'
@@ -881,12 +967,15 @@
MakeInstructionDescriptor(81, SpvOpVectorShuffle, 0);
auto shuffle_4 = TransformationVectorShuffle(instruction_descriptor_4, 203,
101, 101, {2, 3});
- ASSERT_TRUE(shuffle_4.IsApplicable(context.get(), fact_manager));
- shuffle_4.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(shuffle_4.IsApplicable(context.get(), transformation_context));
+ shuffle_4.Apply(context.get(), &transformation_context);
+ fact_manager.ComputeClosureOfFacts(context.get(), 100);
+
auto replacement_4 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(19, instruction_descriptor_4, 0), 203);
- ASSERT_TRUE(replacement_4.IsApplicable(context.get(), fact_manager));
- replacement_4.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement_4.IsApplicable(context.get(), transformation_context));
+ replacement_4.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replace %27 with %102[0] in '%82 = OpCompositeConstruct %21 %26 %27 %28
@@ -896,12 +985,13 @@
auto extract_5 =
TransformationCompositeExtract(instruction_descriptor_5, 204, 102, {0});
- ASSERT_TRUE(extract_5.IsApplicable(context.get(), fact_manager));
- extract_5.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(extract_5.IsApplicable(context.get(), transformation_context));
+ extract_5.Apply(context.get(), &transformation_context);
auto replacement_5 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(27, instruction_descriptor_5, 1), 204);
- ASSERT_TRUE(replacement_5.IsApplicable(context.get(), fact_manager));
- replacement_5.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement_5.IsApplicable(context.get(), transformation_context));
+ replacement_5.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replace %15 with %102[1:2] in '%83 = OpCopyObject %10 %15'
@@ -909,12 +999,15 @@
MakeInstructionDescriptor(83, SpvOpCopyObject, 0);
auto shuffle_6 = TransformationVectorShuffle(instruction_descriptor_6, 205,
102, 102, {1, 2});
- ASSERT_TRUE(shuffle_6.IsApplicable(context.get(), fact_manager));
- shuffle_6.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(shuffle_6.IsApplicable(context.get(), transformation_context));
+ shuffle_6.Apply(context.get(), &transformation_context);
+ fact_manager.ComputeClosureOfFacts(context.get(), 100);
+
auto replacement_6 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(15, instruction_descriptor_6, 0), 205);
- ASSERT_TRUE(replacement_6.IsApplicable(context.get(), fact_manager));
- replacement_6.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement_6.IsApplicable(context.get(), transformation_context));
+ replacement_6.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replace %33 with %103[0] in '%86 = OpCopyObject %30 %33'
@@ -922,12 +1015,13 @@
MakeInstructionDescriptor(86, SpvOpCopyObject, 0);
auto extract_7 =
TransformationCompositeExtract(instruction_descriptor_7, 206, 103, {0});
- ASSERT_TRUE(extract_7.IsApplicable(context.get(), fact_manager));
- extract_7.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(extract_7.IsApplicable(context.get(), transformation_context));
+ extract_7.Apply(context.get(), &transformation_context);
auto replacement_7 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(33, instruction_descriptor_7, 0), 206);
- ASSERT_TRUE(replacement_7.IsApplicable(context.get(), fact_manager));
- replacement_7.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement_7.IsApplicable(context.get(), transformation_context));
+ replacement_7.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replace %47 with %103[1:3] in '%84 = OpCopyObject %39 %47'
@@ -935,12 +1029,15 @@
MakeInstructionDescriptor(84, SpvOpCopyObject, 0);
auto shuffle_8 = TransformationVectorShuffle(instruction_descriptor_8, 207,
103, 103, {1, 2, 3});
- ASSERT_TRUE(shuffle_8.IsApplicable(context.get(), fact_manager));
- shuffle_8.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(shuffle_8.IsApplicable(context.get(), transformation_context));
+ shuffle_8.Apply(context.get(), &transformation_context);
+ fact_manager.ComputeClosureOfFacts(context.get(), 100);
+
auto replacement_8 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(47, instruction_descriptor_8, 0), 207);
- ASSERT_TRUE(replacement_8.IsApplicable(context.get(), fact_manager));
- replacement_8.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement_8.IsApplicable(context.get(), transformation_context));
+ replacement_8.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replace %42 with %104[0] in '%85 = OpCopyObject %30 %42'
@@ -948,12 +1045,13 @@
MakeInstructionDescriptor(85, SpvOpCopyObject, 0);
auto extract_9 =
TransformationCompositeExtract(instruction_descriptor_9, 208, 104, {0});
- ASSERT_TRUE(extract_9.IsApplicable(context.get(), fact_manager));
- extract_9.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(extract_9.IsApplicable(context.get(), transformation_context));
+ extract_9.Apply(context.get(), &transformation_context);
auto replacement_9 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(42, instruction_descriptor_9, 0), 208);
- ASSERT_TRUE(replacement_9.IsApplicable(context.get(), fact_manager));
- replacement_9.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement_9.IsApplicable(context.get(), transformation_context));
+ replacement_9.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replace %45 with %104[1] in '%63 = OpLogicalOr %30 %45 %46'
@@ -961,24 +1059,28 @@
MakeInstructionDescriptor(63, SpvOpLogicalOr, 0);
auto extract_10 =
TransformationCompositeExtract(instruction_descriptor_10, 209, 104, {1});
- ASSERT_TRUE(extract_10.IsApplicable(context.get(), fact_manager));
- extract_10.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(extract_10.IsApplicable(context.get(), transformation_context));
+ extract_10.Apply(context.get(), &transformation_context);
auto replacement_10 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(45, instruction_descriptor_10, 0), 209);
- ASSERT_TRUE(replacement_10.IsApplicable(context.get(), fact_manager));
- replacement_10.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement_10.IsApplicable(context.get(), transformation_context));
+ replacement_10.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replace %38 with %105[0:1] in 'OpStore %36 %38'
auto instruction_descriptor_11 = MakeInstructionDescriptor(85, SpvOpStore, 0);
auto shuffle_11 = TransformationVectorShuffle(instruction_descriptor_11, 210,
105, 105, {0, 1});
- ASSERT_TRUE(shuffle_11.IsApplicable(context.get(), fact_manager));
- shuffle_11.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(shuffle_11.IsApplicable(context.get(), transformation_context));
+ shuffle_11.Apply(context.get(), &transformation_context);
+ fact_manager.ComputeClosureOfFacts(context.get(), 100);
+
auto replacement_11 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(38, instruction_descriptor_11, 1), 210);
- ASSERT_TRUE(replacement_11.IsApplicable(context.get(), fact_manager));
- replacement_11.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement_11.IsApplicable(context.get(), transformation_context));
+ replacement_11.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replace %46 with %105[2] in '%62 = OpLogicalAnd %30 %45 %46'
@@ -986,12 +1088,13 @@
MakeInstructionDescriptor(62, SpvOpLogicalAnd, 0);
auto extract_12 =
TransformationCompositeExtract(instruction_descriptor_12, 211, 105, {2});
- ASSERT_TRUE(extract_12.IsApplicable(context.get(), fact_manager));
- extract_12.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(extract_12.IsApplicable(context.get(), transformation_context));
+ extract_12.Apply(context.get(), &transformation_context);
auto replacement_12 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(46, instruction_descriptor_12, 1), 211);
- ASSERT_TRUE(replacement_12.IsApplicable(context.get(), fact_manager));
- replacement_12.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement_12.IsApplicable(context.get(), transformation_context));
+ replacement_12.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
const std::string after_transformation = R"(
diff --git a/test/fuzz/equivalence_relation_test.cpp b/test/fuzz/equivalence_relation_test.cpp
index 3f2ea58..280aa3a 100644
--- a/test/fuzz/equivalence_relation_test.cpp
+++ b/test/fuzz/equivalence_relation_test.cpp
@@ -47,6 +47,10 @@
EquivalenceRelation<uint32_t, UInt32Hash, UInt32Equals> relation;
ASSERT_TRUE(relation.GetAllKnownValues().empty());
+ for (uint32_t element = 0; element < 100; element++) {
+ relation.Register(element);
+ }
+
for (uint32_t element = 2; element < 80; element += 2) {
relation.MakeEquivalent(0, element);
relation.MakeEquivalent(element - 1, element + 1);
@@ -123,6 +127,11 @@
EquivalenceRelation<uint32_t, UInt32Hash, UInt32Equals> relation2;
for (uint32_t i = 0; i < 1000; ++i) {
+ relation1.Register(i);
+ relation2.Register(i);
+ }
+
+ for (uint32_t i = 0; i < 1000; ++i) {
if (i >= 10) {
relation1.MakeEquivalent(i, i - 10);
relation2.MakeEquivalent(i, i - 10);
diff --git a/test/fuzz/fact_manager_test.cpp b/test/fuzz/fact_manager_test.cpp
index 2c79f12..8b1e0c4 100644
--- a/test/fuzz/fact_manager_test.cpp
+++ b/test/fuzz/fact_manager_test.cpp
@@ -738,393 +738,6 @@
uniform_buffer_element_descriptor));
}
-TEST(FactManagerTest, DataSynonymFacts) {
- // The SPIR-V types and constants come from the following code. The body of
- // the SPIR-V function then constructs a composite that is synonymous with
- // myT.
- //
- // #version 310 es
- //
- // precision highp float;
- //
- // struct S {
- // int a;
- // uvec2 b;
- // };
- //
- // struct T {
- // bool c[5];
- // mat4x2 d;
- // S e;
- // };
- //
- // void main() {
- // T myT = T(bool[5](true, false, true, false, true),
- // mat4x2(vec2(1.0, 2.0), vec2(3.0, 4.0),
- // vec2(5.0, 6.0), vec2(7.0, 8.0)),
- // S(10, uvec2(100u, 200u)));
- // }
-
- std::string shader = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %4 "main"
- OpExecutionMode %4 OriginUpperLeft
- OpSource ESSL 310
- OpName %4 "main"
- OpName %15 "S"
- OpMemberName %15 0 "a"
- OpMemberName %15 1 "b"
- OpName %16 "T"
- OpMemberName %16 0 "c"
- OpMemberName %16 1 "d"
- OpMemberName %16 2 "e"
- OpName %18 "myT"
- OpMemberDecorate %15 0 RelaxedPrecision
- OpMemberDecorate %15 1 RelaxedPrecision
- %2 = OpTypeVoid
- %3 = OpTypeFunction %2
- %6 = OpTypeBool
- %7 = OpTypeInt 32 0
- %8 = OpConstant %7 5
- %9 = OpTypeArray %6 %8
- %10 = OpTypeFloat 32
- %11 = OpTypeVector %10 2
- %12 = OpTypeMatrix %11 4
- %13 = OpTypeInt 32 1
- %14 = OpTypeVector %7 2
- %15 = OpTypeStruct %13 %14
- %16 = OpTypeStruct %9 %12 %15
- %17 = OpTypePointer Function %16
- %19 = OpConstantTrue %6
- %20 = OpConstantFalse %6
- %21 = OpConstantComposite %9 %19 %20 %19 %20 %19
- %22 = OpConstant %10 1
- %23 = OpConstant %10 2
- %24 = OpConstantComposite %11 %22 %23
- %25 = OpConstant %10 3
- %26 = OpConstant %10 4
- %27 = OpConstantComposite %11 %25 %26
- %28 = OpConstant %10 5
- %29 = OpConstant %10 6
- %30 = OpConstantComposite %11 %28 %29
- %31 = OpConstant %10 7
- %32 = OpConstant %10 8
- %33 = OpConstantComposite %11 %31 %32
- %34 = OpConstantComposite %12 %24 %27 %30 %33
- %35 = OpConstant %13 10
- %36 = OpConstant %7 100
- %37 = OpConstant %7 200
- %38 = OpConstantComposite %14 %36 %37
- %39 = OpConstantComposite %15 %35 %38
- %40 = OpConstantComposite %16 %21 %34 %39
- %4 = OpFunction %2 None %3
- %5 = OpLabel
- %18 = OpVariable %17 Function
- OpStore %18 %40
- %100 = OpCompositeConstruct %9 %19 %20 %19 %20 %19
- %101 = OpCompositeConstruct %11 %22 %23
- %102 = OpCompositeConstruct %11 %25 %26
- %103 = OpCompositeConstruct %11 %28 %29
- %104 = OpCompositeConstruct %11 %31 %32
- %105 = OpCompositeConstruct %12 %101 %102 %103 %104
- %106 = OpCompositeConstruct %14 %36 %37
- %107 = OpCompositeConstruct %15 %35 %106
- %108 = OpCompositeConstruct %16 %100 %105 %107
- OpReturn
- OpFunctionEnd
- )";
-
- const auto env = SPV_ENV_UNIVERSAL_1_3;
- const auto consumer = nullptr;
- const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
- ASSERT_TRUE(IsValid(env, context.get()));
-
- FactManager fact_manager;
-
- ASSERT_FALSE(fact_manager.IsSynonymous(
- MakeDataDescriptor(24, {}), MakeDataDescriptor(101, {}), context.get()));
- ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {0}),
- MakeDataDescriptor(101, {0}),
- context.get()));
- ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {1}),
- MakeDataDescriptor(101, {1}),
- context.get()));
- ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {0}),
- MakeDataDescriptor(101, {1}),
- context.get()));
-
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(24, {}),
- MakeDataDescriptor(101, {}), context.get());
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(24, {}), MakeDataDescriptor(101, {}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {0}),
- MakeDataDescriptor(101, {0}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {1}),
- MakeDataDescriptor(101, {1}),
- context.get()));
- ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {0}),
- MakeDataDescriptor(101, {1}),
- context.get()));
-
- ASSERT_FALSE(fact_manager.IsSynonymous(
- MakeDataDescriptor(27, {}), MakeDataDescriptor(102, {}), context.get()));
- ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {0}),
- MakeDataDescriptor(102, {0}),
- context.get()));
- ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {1}),
- MakeDataDescriptor(102, {1}),
- context.get()));
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(27, {0}),
- MakeDataDescriptor(102, {0}), context.get());
- ASSERT_FALSE(fact_manager.IsSynonymous(
- MakeDataDescriptor(27, {}), MakeDataDescriptor(102, {}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {0}),
- MakeDataDescriptor(102, {0}),
- context.get()));
- ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {1}),
- MakeDataDescriptor(102, {1}),
- context.get()));
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(27, {1}),
- MakeDataDescriptor(102, {1}), context.get());
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(27, {}), MakeDataDescriptor(102, {}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {0}),
- MakeDataDescriptor(102, {0}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {1}),
- MakeDataDescriptor(102, {1}),
- context.get()));
-
- ASSERT_FALSE(fact_manager.IsSynonymous(
- MakeDataDescriptor(30, {}), MakeDataDescriptor(103, {}), context.get()));
- ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(30, {0}),
- MakeDataDescriptor(103, {0}),
- context.get()));
- ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(30, {1}),
- MakeDataDescriptor(103, {1}),
- context.get()));
- ASSERT_FALSE(fact_manager.IsSynonymous(
- MakeDataDescriptor(33, {}), MakeDataDescriptor(104, {}), context.get()));
- ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {0}),
- MakeDataDescriptor(104, {0}),
- context.get()));
- ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {1}),
- MakeDataDescriptor(104, {1}),
- context.get()));
- ASSERT_FALSE(fact_manager.IsSynonymous(
- MakeDataDescriptor(34, {}), MakeDataDescriptor(105, {}), context.get()));
- ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {0}),
- MakeDataDescriptor(105, {0}),
- context.get()));
- ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {1}),
- MakeDataDescriptor(105, {1}),
- context.get()));
- ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {2}),
- MakeDataDescriptor(105, {2}),
- context.get()));
- ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {3}),
- MakeDataDescriptor(105, {3}),
- context.get()));
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(30, {}),
- MakeDataDescriptor(103, {}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(33, {}),
- MakeDataDescriptor(104, {}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(34, {0}),
- MakeDataDescriptor(105, {0}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(34, {1}),
- MakeDataDescriptor(105, {1}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(34, {2}),
- MakeDataDescriptor(105, {2}), context.get());
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(30, {}), MakeDataDescriptor(103, {}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(30, {0}),
- MakeDataDescriptor(103, {0}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(30, {1}),
- MakeDataDescriptor(103, {1}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(33, {}), MakeDataDescriptor(104, {}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {0}),
- MakeDataDescriptor(104, {0}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {1}),
- MakeDataDescriptor(104, {1}),
- context.get()));
- ASSERT_FALSE(fact_manager.IsSynonymous(
- MakeDataDescriptor(34, {}), MakeDataDescriptor(105, {}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {0}),
- MakeDataDescriptor(105, {0}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {1}),
- MakeDataDescriptor(105, {1}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {2}),
- MakeDataDescriptor(105, {2}),
- context.get()));
- ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {3}),
- MakeDataDescriptor(105, {3}),
- context.get()));
-
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(34, {3}),
- MakeDataDescriptor(105, {3}), context.get());
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {0}),
- MakeDataDescriptor(104, {0}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {3}),
- MakeDataDescriptor(105, {3}),
- context.get()));
-
- ASSERT_FALSE(fact_manager.IsSynonymous(
- MakeDataDescriptor(21, {}), MakeDataDescriptor(100, {}), context.get()));
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(21, {0}),
- MakeDataDescriptor(100, {0}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(21, {1}),
- MakeDataDescriptor(100, {1}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(21, {2}),
- MakeDataDescriptor(100, {2}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(21, {3}),
- MakeDataDescriptor(100, {3}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(21, {4}),
- MakeDataDescriptor(100, {4}), context.get());
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(21, {}), MakeDataDescriptor(100, {}), context.get()));
-
- ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(39, {0}),
- MakeDataDescriptor(107, {0}),
- context.get()));
- ASSERT_FALSE(fact_manager.IsSynonymous(
- MakeDataDescriptor(35, {}), MakeDataDescriptor(39, {0}), context.get()));
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(39, {0}),
- MakeDataDescriptor(35, {}), context.get());
- ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(39, {0}),
- MakeDataDescriptor(107, {0}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(35, {}), MakeDataDescriptor(39, {0}), context.get()));
-
- ASSERT_FALSE(fact_manager.IsSynonymous(
- MakeDataDescriptor(38, {0}), MakeDataDescriptor(36, {}), context.get()));
- ASSERT_FALSE(fact_manager.IsSynonymous(
- MakeDataDescriptor(38, {1}), MakeDataDescriptor(37, {}), context.get()));
- ASSERT_FALSE(fact_manager.IsSynonymous(
- MakeDataDescriptor(106, {0}), MakeDataDescriptor(36, {}), context.get()));
- ASSERT_FALSE(fact_manager.IsSynonymous(
- MakeDataDescriptor(106, {1}), MakeDataDescriptor(37, {}), context.get()));
- ASSERT_FALSE(fact_manager.IsSynonymous(
- MakeDataDescriptor(38, {}), MakeDataDescriptor(106, {}), context.get()));
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(38, {0}),
- MakeDataDescriptor(36, {}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(106, {0}),
- MakeDataDescriptor(36, {}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(38, {1}),
- MakeDataDescriptor(37, {}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(106, {1}),
- MakeDataDescriptor(37, {}), context.get());
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(38, {0}), MakeDataDescriptor(36, {}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(38, {1}), MakeDataDescriptor(37, {}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(106, {0}), MakeDataDescriptor(36, {}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(106, {1}), MakeDataDescriptor(37, {}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(38, {}), MakeDataDescriptor(106, {}), context.get()));
-
- ASSERT_FALSE(fact_manager.IsSynonymous(
- MakeDataDescriptor(40, {}), MakeDataDescriptor(108, {}), context.get()));
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(107, {0}),
- MakeDataDescriptor(35, {}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(40, {0}),
- MakeDataDescriptor(108, {0}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(40, {1}),
- MakeDataDescriptor(108, {1}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(40, {2}),
- MakeDataDescriptor(108, {2}), context.get());
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(40, {}), MakeDataDescriptor(108, {}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0}),
- MakeDataDescriptor(108, {0}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1}),
- MakeDataDescriptor(108, {1}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {2}),
- MakeDataDescriptor(108, {2}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0, 0}),
- MakeDataDescriptor(108, {0, 0}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0, 1}),
- MakeDataDescriptor(108, {0, 1}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0, 2}),
- MakeDataDescriptor(108, {0, 2}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0, 3}),
- MakeDataDescriptor(108, {0, 3}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0, 4}),
- MakeDataDescriptor(108, {0, 4}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 0}),
- MakeDataDescriptor(108, {1, 0}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 1}),
- MakeDataDescriptor(108, {1, 1}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 2}),
- MakeDataDescriptor(108, {1, 2}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 3}),
- MakeDataDescriptor(108, {1, 3}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 0, 0}),
- MakeDataDescriptor(108, {1, 0, 0}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 1, 0}),
- MakeDataDescriptor(108, {1, 1, 0}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 2, 0}),
- MakeDataDescriptor(108, {1, 2, 0}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 3, 0}),
- MakeDataDescriptor(108, {1, 3, 0}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 0, 1}),
- MakeDataDescriptor(108, {1, 0, 1}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 1, 1}),
- MakeDataDescriptor(108, {1, 1, 1}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 2, 1}),
- MakeDataDescriptor(108, {1, 2, 1}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 3, 1}),
- MakeDataDescriptor(108, {1, 3, 1}),
- context.get()));
-
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {2, 0}),
- MakeDataDescriptor(108, {2, 0}),
- context.get()));
-
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {2, 1}),
- MakeDataDescriptor(108, {2, 1}),
- context.get()));
-
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {2, 1, 0}),
- MakeDataDescriptor(108, {2, 1, 0}),
- context.get()));
-
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {2, 1, 1}),
- MakeDataDescriptor(108, {2, 1, 1}),
- context.get()));
-}
-
TEST(FactManagerTest, RecursiveAdditionOfFacts) {
std::string shader = R"(
OpCapability Shader
@@ -1157,20 +770,16 @@
fact_manager.AddFactDataSynonym(MakeDataDescriptor(10, {}),
MakeDataDescriptor(11, {2}), context.get());
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(10, {}), MakeDataDescriptor(11, {2}), context.get()));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(10, {}),
+ MakeDataDescriptor(11, {2})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(10, {0}),
- MakeDataDescriptor(11, {2, 0}),
- context.get()));
+ MakeDataDescriptor(11, {2, 0})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(10, {1}),
- MakeDataDescriptor(11, {2, 1}),
- context.get()));
+ MakeDataDescriptor(11, {2, 1})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(10, {2}),
- MakeDataDescriptor(11, {2, 2}),
- context.get()));
+ MakeDataDescriptor(11, {2, 2})));
ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(10, {3}),
- MakeDataDescriptor(11, {2, 3}),
- context.get()));
+ MakeDataDescriptor(11, {2, 3})));
}
TEST(FactManagerTest, LogicalNotEquationFacts) {
@@ -1209,14 +818,14 @@
fact_manager.AddFactIdEquation(14, SpvOpLogicalNot, {7}, context.get());
fact_manager.AddFactIdEquation(17, SpvOpLogicalNot, {16}, context.get());
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(15, {}), MakeDataDescriptor(7, {}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(17, {}), MakeDataDescriptor(7, {}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(15, {}), MakeDataDescriptor(17, {}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(16, {}), MakeDataDescriptor(14, {}), context.get()));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(15, {}),
+ MakeDataDescriptor(7, {})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(17, {}),
+ MakeDataDescriptor(7, {})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(15, {}),
+ MakeDataDescriptor(17, {})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(16, {}),
+ MakeDataDescriptor(14, {})));
}
TEST(FactManagerTest, SignedNegateEquationFacts) {
@@ -1249,8 +858,8 @@
fact_manager.AddFactIdEquation(14, SpvOpSNegate, {7}, context.get());
fact_manager.AddFactIdEquation(15, SpvOpSNegate, {14}, context.get());
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(7, {}), MakeDataDescriptor(15, {}), context.get()));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(7, {}),
+ MakeDataDescriptor(15, {})));
}
TEST(FactManagerTest, AddSubNegateFacts1) {
@@ -1302,12 +911,12 @@
MakeDataDescriptor(22, {}), context.get());
fact_manager.AddFactIdEquation(24, SpvOpSNegate, {23}, context.get());
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(19, {}), MakeDataDescriptor(15, {}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(20, {}), MakeDataDescriptor(16, {}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(24, {}), MakeDataDescriptor(15, {}), context.get()));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(19, {}),
+ MakeDataDescriptor(15, {})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(20, {}),
+ MakeDataDescriptor(16, {})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {}),
+ MakeDataDescriptor(15, {})));
}
TEST(FactManagerTest, AddSubNegateFacts2) {
@@ -1347,30 +956,158 @@
fact_manager.AddFactIdEquation(14, SpvOpISub, {15, 16}, context.get());
fact_manager.AddFactIdEquation(17, SpvOpIAdd, {14, 16}, context.get());
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(17, {}), MakeDataDescriptor(15, {}), context.get()));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(17, {}),
+ MakeDataDescriptor(15, {})));
fact_manager.AddFactIdEquation(18, SpvOpIAdd, {16, 14}, context.get());
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(18, {}), MakeDataDescriptor(15, {}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(17, {}), MakeDataDescriptor(18, {}), context.get()));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(18, {}),
+ MakeDataDescriptor(15, {})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(17, {}),
+ MakeDataDescriptor(18, {})));
fact_manager.AddFactIdEquation(19, SpvOpISub, {14, 15}, context.get());
fact_manager.AddFactIdEquation(20, SpvOpSNegate, {19}, context.get());
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(20, {}), MakeDataDescriptor(16, {}), context.get()));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(20, {}),
+ MakeDataDescriptor(16, {})));
fact_manager.AddFactIdEquation(21, SpvOpISub, {14, 19}, context.get());
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(21, {}), MakeDataDescriptor(15, {}), context.get()));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(21, {}),
+ MakeDataDescriptor(15, {})));
fact_manager.AddFactIdEquation(22, SpvOpISub, {14, 18}, context.get());
fact_manager.AddFactIdEquation(23, SpvOpSNegate, {22}, context.get());
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(23, {}), MakeDataDescriptor(16, {}), context.get()));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(23, {}),
+ MakeDataDescriptor(16, {})));
+}
+
+TEST(FactManagerTest, EquationAndEquivalenceFacts) {
+ std::string shader = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %12 "main"
+ OpExecutionMode %12 OriginUpperLeft
+ OpSource ESSL 310
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeInt 32 1
+ %15 = OpConstant %6 24
+ %16 = OpConstant %6 37
+ %12 = OpFunction %2 None %3
+ %13 = OpLabel
+ %14 = OpISub %6 %15 %16
+ %114 = OpCopyObject %6 %14
+ %17 = OpIAdd %6 %114 %16 ; ==> synonymous(%17, %15)
+ %18 = OpIAdd %6 %16 %114 ; ==> synonymous(%17, %18, %15)
+ %19 = OpISub %6 %114 %15
+ %119 = OpCopyObject %6 %19
+ %20 = OpSNegate %6 %119 ; ==> synonymous(%20, %16)
+ %21 = OpISub %6 %14 %19 ; ==> synonymous(%21, %15)
+ %22 = OpISub %6 %14 %18
+ %220 = OpCopyObject %6 %22
+ %23 = OpSNegate %6 %220 ; ==> synonymous(%23, %16)
+ 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;
+
+ fact_manager.AddFactIdEquation(14, SpvOpISub, {15, 16}, context.get());
+ fact_manager.AddFactDataSynonym(MakeDataDescriptor(114, {}),
+ MakeDataDescriptor(14, {}), context.get());
+ fact_manager.AddFactIdEquation(17, SpvOpIAdd, {114, 16}, context.get());
+
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(17, {}),
+ MakeDataDescriptor(15, {})));
+
+ fact_manager.AddFactIdEquation(18, SpvOpIAdd, {16, 114}, context.get());
+
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(18, {}),
+ MakeDataDescriptor(15, {})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(17, {}),
+ MakeDataDescriptor(18, {})));
+
+ fact_manager.AddFactIdEquation(19, SpvOpISub, {14, 15}, context.get());
+ fact_manager.AddFactDataSynonym(MakeDataDescriptor(119, {}),
+ MakeDataDescriptor(19, {}), context.get());
+ fact_manager.AddFactIdEquation(20, SpvOpSNegate, {119}, context.get());
+
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(20, {}),
+ MakeDataDescriptor(16, {})));
+
+ fact_manager.AddFactIdEquation(21, SpvOpISub, {14, 19}, context.get());
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(21, {}),
+ MakeDataDescriptor(15, {})));
+
+ fact_manager.AddFactIdEquation(22, SpvOpISub, {14, 18}, context.get());
+ fact_manager.AddFactDataSynonym(MakeDataDescriptor(22, {}),
+ MakeDataDescriptor(220, {}), context.get());
+ fact_manager.AddFactIdEquation(23, SpvOpSNegate, {220}, context.get());
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(23, {}),
+ MakeDataDescriptor(16, {})));
+}
+
+TEST(FactManagerTest, CheckingFactsDoesNotAddConstants) {
+ std::string shader = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main"
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 320
+ OpMemberDecorate %9 0 Offset 0
+ OpDecorate %9 Block
+ OpDecorate %11 DescriptorSet 0
+ OpDecorate %11 Binding 0
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeInt 32 1
+ %7 = OpTypePointer Function %6
+ %9 = OpTypeStruct %6
+ %10 = OpTypePointer Uniform %9
+ %11 = OpVariable %10 Uniform
+ %12 = OpConstant %6 0
+ %13 = OpTypePointer Uniform %6
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ %8 = OpVariable %7 Function
+ %14 = OpAccessChain %13 %11 %12
+ %15 = OpLoad %6 %14
+ OpStore %8 %15
+ 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;
+
+ // 8[0] == int(1)
+ ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), {1},
+ MakeUniformBufferElementDescriptor(0, 0, {0})));
+
+ // Although 8[0] has the value 1, we do not have the constant 1 in the module.
+ // We thus should not find any constants available from uniforms for int type.
+ // Furthermore, the act of looking for appropriate constants should not change
+ // which constants are known to the constant manager.
+ auto int_type = context->get_type_mgr()->GetType(6)->AsInteger();
+ opt::analysis::IntConstant constant_one(int_type, {1});
+ ASSERT_FALSE(context->get_constant_mgr()->FindConstant(&constant_one));
+ auto available_constants =
+ fact_manager.GetConstantsAvailableFromUniformsForType(context.get(), 6);
+ ASSERT_EQ(0, available_constants.size());
+ ASSERT_TRUE(IsEqual(env, shader, context.get()));
+ ASSERT_FALSE(context->get_constant_mgr()->FindConstant(&constant_one));
}
} // namespace
diff --git a/test/fuzz/fuzzer_pass_add_useful_constructs_test.cpp b/test/fuzz/fuzzer_pass_add_useful_constructs_test.cpp
deleted file mode 100644
index 89f006e..0000000
--- a/test/fuzz/fuzzer_pass_add_useful_constructs_test.cpp
+++ /dev/null
@@ -1,393 +0,0 @@
-// Copyright (c) 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "source/fuzz/fuzzer_pass_add_useful_constructs.h"
-#include "source/fuzz/pseudo_random_generator.h"
-#include "source/fuzz/uniform_buffer_element_descriptor.h"
-#include "test/fuzz/fuzz_test_util.h"
-
-namespace spvtools {
-namespace fuzz {
-namespace {
-
-bool AddFactHelper(
- FactManager* fact_manager, opt::IRContext* context, uint32_t word,
- const protobufs::UniformBufferElementDescriptor& descriptor) {
- protobufs::FactConstantUniform constant_uniform_fact;
- constant_uniform_fact.add_constant_word(word);
- *constant_uniform_fact.mutable_uniform_buffer_element_descriptor() =
- descriptor;
- protobufs::Fact fact;
- *fact.mutable_constant_uniform_fact() = constant_uniform_fact;
- return fact_manager->AddFact(fact, context);
-}
-
-TEST(FuzzerPassAddUsefulConstructsTest, CheckBasicStuffIsAdded) {
- // The SPIR-V came from the following empty GLSL shader:
- //
- // #version 450
- //
- // void main()
- // {
- // }
-
- std::string shader = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %4 "main"
- OpExecutionMode %4 OriginUpperLeft
- OpSource GLSL 450
- OpName %4 "main"
- %2 = OpTypeVoid
- %3 = OpTypeFunction %2
- %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;
- FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0).get(), 100);
- protobufs::TransformationSequence transformation_sequence;
-
- FuzzerPassAddUsefulConstructs pass(context.get(), &fact_manager,
- &fuzzer_context, &transformation_sequence);
- pass.Apply();
- ASSERT_TRUE(IsValid(env, context.get()));
-
- std::string after = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %4 "main"
- OpExecutionMode %4 OriginUpperLeft
- OpSource GLSL 450
- OpName %4 "main"
- %2 = OpTypeVoid
- %3 = OpTypeFunction %2
- %100 = OpTypeBool
- %101 = OpTypeInt 32 1
- %102 = OpTypeInt 32 0
- %103 = OpTypeFloat 32
- %104 = OpConstantTrue %100
- %105 = OpConstantFalse %100
- %106 = OpConstant %101 0
- %107 = OpConstant %101 1
- %108 = OpConstant %102 0
- %109 = OpConstant %102 1
- %110 = OpConstant %103 0
- %111 = OpConstant %103 1
- %4 = OpFunction %2 None %3
- %5 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- ASSERT_TRUE(IsEqual(env, after, context.get()));
-}
-
-TEST(FuzzerPassAddUsefulConstructsTest,
- CheckTypesIndicesAndConstantsAddedForUniformFacts) {
- // The SPIR-V came from the following GLSL shader:
- //
- // #version 450
- //
- // struct S {
- // int x;
- // float y;
- // int z;
- // int w;
- // };
- //
- // uniform buf {
- // S s;
- // uint w[10];
- // };
- //
- // void main() {
- // }
-
- std::string shader = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %4 "main"
- OpExecutionMode %4 OriginUpperLeft
- OpSource GLSL 450
- OpName %4 "main"
- OpName %8 "S"
- OpMemberName %8 0 "x"
- OpMemberName %8 1 "y"
- OpMemberName %8 2 "z"
- OpMemberName %8 3 "w"
- OpName %12 "buf"
- OpMemberName %12 0 "s"
- OpMemberName %12 1 "w"
- OpName %14 ""
- OpMemberDecorate %8 0 Offset 0
- OpMemberDecorate %8 1 Offset 4
- OpMemberDecorate %8 2 Offset 8
- OpMemberDecorate %8 3 Offset 12
- OpDecorate %11 ArrayStride 16
- OpMemberDecorate %12 0 Offset 0
- OpMemberDecorate %12 1 Offset 16
- OpDecorate %12 Block
- OpDecorate %14 DescriptorSet 0
- OpDecorate %14 Binding 0
- %2 = OpTypeVoid
- %3 = OpTypeFunction %2
- %6 = OpTypeInt 32 1
- %7 = OpTypeFloat 32
- %8 = OpTypeStruct %6 %7 %6 %6
- %9 = OpTypeInt 32 0
- %10 = OpConstant %9 10
- %11 = OpTypeArray %9 %10
- %12 = OpTypeStruct %8 %11
- %13 = OpTypePointer Uniform %12
- %14 = OpVariable %13 Uniform
- %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;
- FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0).get(), 100);
- protobufs::TransformationSequence transformation_sequence;
-
- // Add some uniform facts.
-
- // buf.s.x == 200
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 200,
- MakeUniformBufferElementDescriptor(0, 0, {0, 0})));
-
- // buf.s.y == 0.5
- const float float_value = 0.5;
- uint32_t float_value_as_uint;
- memcpy(&float_value_as_uint, &float_value, sizeof(float_value));
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), float_value_as_uint,
- MakeUniformBufferElementDescriptor(0, 0, {0, 1})));
-
- // buf.s.z == 300
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 300,
- MakeUniformBufferElementDescriptor(0, 0, {0, 2})));
-
- // buf.s.w == 400
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 400,
- MakeUniformBufferElementDescriptor(0, 0, {0, 3})));
-
- // buf.w[6] = 22
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 22,
- MakeUniformBufferElementDescriptor(0, 0, {1, 6})));
-
- // buf.w[8] = 23
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 23,
- MakeUniformBufferElementDescriptor(0, 0, {1, 8})));
-
- // Assert some things about the module that are not true prior to adding the
- // pass
-
- {
- // No uniform int pointer
- opt::analysis::Integer temp_type_signed_int(32, true);
- opt::analysis::Integer* registered_type_signed_int =
- context->get_type_mgr()
- ->GetRegisteredType(&temp_type_signed_int)
- ->AsInteger();
- opt::analysis::Pointer type_pointer_uniform_signed_int(
- registered_type_signed_int, SpvStorageClassUniform);
- ASSERT_EQ(0,
- context->get_type_mgr()->GetId(&type_pointer_uniform_signed_int));
-
- // No uniform uint pointer
- opt::analysis::Integer temp_type_unsigned_int(32, false);
- opt::analysis::Integer* registered_type_unsigned_int =
- context->get_type_mgr()
- ->GetRegisteredType(&temp_type_unsigned_int)
- ->AsInteger();
- opt::analysis::Pointer type_pointer_uniform_unsigned_int(
- registered_type_unsigned_int, SpvStorageClassUniform);
- ASSERT_EQ(
- 0, context->get_type_mgr()->GetId(&type_pointer_uniform_unsigned_int));
-
- // No uniform float pointer
- opt::analysis::Float temp_type_float(32);
- opt::analysis::Float* registered_type_float =
- context->get_type_mgr()->GetRegisteredType(&temp_type_float)->AsFloat();
- opt::analysis::Pointer type_pointer_uniform_float(registered_type_float,
- SpvStorageClassUniform);
- ASSERT_EQ(0, context->get_type_mgr()->GetId(&type_pointer_uniform_float));
-
- // No int constants 200, 300 nor 400
- opt::analysis::IntConstant int_constant_200(registered_type_signed_int,
- {200});
- opt::analysis::IntConstant int_constant_300(registered_type_signed_int,
- {300});
- opt::analysis::IntConstant int_constant_400(registered_type_signed_int,
- {400});
- ASSERT_EQ(nullptr,
- context->get_constant_mgr()->FindConstant(&int_constant_200));
- ASSERT_EQ(nullptr,
- context->get_constant_mgr()->FindConstant(&int_constant_300));
- ASSERT_EQ(nullptr,
- context->get_constant_mgr()->FindConstant(&int_constant_400));
-
- // No float constant 0.5
- opt::analysis::FloatConstant float_constant_zero_point_five(
- registered_type_float, {float_value_as_uint});
- ASSERT_EQ(nullptr, context->get_constant_mgr()->FindConstant(
- &float_constant_zero_point_five));
-
- // No uint constant 22
- opt::analysis::IntConstant uint_constant_22(registered_type_unsigned_int,
- {22});
- ASSERT_EQ(nullptr,
- context->get_constant_mgr()->FindConstant(&uint_constant_22));
-
- // No uint constant 23
- opt::analysis::IntConstant uint_constant_23(registered_type_unsigned_int,
- {23});
- ASSERT_EQ(nullptr,
- context->get_constant_mgr()->FindConstant(&uint_constant_23));
-
- // No int constants 0, 1, 2, 3, 6, 8
- opt::analysis::IntConstant int_constant_0(registered_type_signed_int, {0});
- opt::analysis::IntConstant int_constant_1(registered_type_signed_int, {1});
- opt::analysis::IntConstant int_constant_2(registered_type_signed_int, {2});
- opt::analysis::IntConstant int_constant_3(registered_type_signed_int, {3});
- opt::analysis::IntConstant int_constant_6(registered_type_signed_int, {6});
- opt::analysis::IntConstant int_constant_8(registered_type_signed_int, {8});
- ASSERT_EQ(nullptr,
- context->get_constant_mgr()->FindConstant(&int_constant_0));
- ASSERT_EQ(nullptr,
- context->get_constant_mgr()->FindConstant(&int_constant_1));
- ASSERT_EQ(nullptr,
- context->get_constant_mgr()->FindConstant(&int_constant_2));
- ASSERT_EQ(nullptr,
- context->get_constant_mgr()->FindConstant(&int_constant_3));
- ASSERT_EQ(nullptr,
- context->get_constant_mgr()->FindConstant(&int_constant_6));
- ASSERT_EQ(nullptr,
- context->get_constant_mgr()->FindConstant(&int_constant_8));
- }
-
- FuzzerPassAddUsefulConstructs pass(context.get(), &fact_manager,
- &fuzzer_context, &transformation_sequence);
- pass.Apply();
- ASSERT_TRUE(IsValid(env, context.get()));
-
- // Now assert some things about the module that should be true following the
- // pass.
-
- // We reconstruct all necessary types and constants to guard against the type
- // and constant managers for the module having been invalidated.
-
- {
- // Uniform int pointer now present
- opt::analysis::Integer temp_type_signed_int(32, true);
- opt::analysis::Integer* registered_type_signed_int =
- context->get_type_mgr()
- ->GetRegisteredType(&temp_type_signed_int)
- ->AsInteger();
- opt::analysis::Pointer type_pointer_uniform_signed_int(
- registered_type_signed_int, SpvStorageClassUniform);
- ASSERT_NE(0,
- context->get_type_mgr()->GetId(&type_pointer_uniform_signed_int));
-
- // Uniform uint pointer now present
- opt::analysis::Integer temp_type_unsigned_int(32, false);
- opt::analysis::Integer* registered_type_unsigned_int =
- context->get_type_mgr()
- ->GetRegisteredType(&temp_type_unsigned_int)
- ->AsInteger();
- opt::analysis::Pointer type_pointer_uniform_unsigned_int(
- registered_type_unsigned_int, SpvStorageClassUniform);
- ASSERT_NE(
- 0, context->get_type_mgr()->GetId(&type_pointer_uniform_unsigned_int));
-
- // Uniform float pointer now present
- opt::analysis::Float temp_type_float(32);
- opt::analysis::Float* registered_type_float =
- context->get_type_mgr()->GetRegisteredType(&temp_type_float)->AsFloat();
- opt::analysis::Pointer type_pointer_uniform_float(registered_type_float,
- SpvStorageClassUniform);
- ASSERT_NE(0, context->get_type_mgr()->GetId(&type_pointer_uniform_float));
-
- // int constants 200, 300, 400 now present
- opt::analysis::IntConstant int_constant_200(registered_type_signed_int,
- {200});
- opt::analysis::IntConstant int_constant_300(registered_type_signed_int,
- {300});
- opt::analysis::IntConstant int_constant_400(registered_type_signed_int,
- {400});
- ASSERT_NE(nullptr,
- context->get_constant_mgr()->FindConstant(&int_constant_200));
- ASSERT_NE(nullptr,
- context->get_constant_mgr()->FindConstant(&int_constant_300));
- ASSERT_NE(nullptr,
- context->get_constant_mgr()->FindConstant(&int_constant_400));
-
- // float constant 0.5 now present
- opt::analysis::FloatConstant float_constant_zero_point_five(
- registered_type_float, {float_value_as_uint});
- ASSERT_NE(nullptr, context->get_constant_mgr()->FindConstant(
- &float_constant_zero_point_five));
-
- // uint constant 22 now present
- opt::analysis::IntConstant uint_constant_22(registered_type_unsigned_int,
- {22});
- ASSERT_NE(nullptr,
- context->get_constant_mgr()->FindConstant(&uint_constant_22));
-
- // uint constant 23 now present
- opt::analysis::IntConstant uint_constant_23(registered_type_unsigned_int,
- {23});
- ASSERT_NE(nullptr,
- context->get_constant_mgr()->FindConstant(&uint_constant_23));
-
- // int constants 0, 1, 2, 3, 6, 8 now present
- opt::analysis::IntConstant int_constant_0(registered_type_signed_int, {0});
- opt::analysis::IntConstant int_constant_1(registered_type_signed_int, {1});
- opt::analysis::IntConstant int_constant_2(registered_type_signed_int, {2});
- opt::analysis::IntConstant int_constant_3(registered_type_signed_int, {3});
- opt::analysis::IntConstant int_constant_6(registered_type_signed_int, {6});
- opt::analysis::IntConstant int_constant_8(registered_type_signed_int, {8});
- ASSERT_NE(nullptr,
- context->get_constant_mgr()->FindConstant(&int_constant_0));
- ASSERT_NE(nullptr,
- context->get_constant_mgr()->FindConstant(&int_constant_1));
- ASSERT_NE(nullptr,
- context->get_constant_mgr()->FindConstant(&int_constant_2));
- ASSERT_NE(nullptr,
- context->get_constant_mgr()->FindConstant(&int_constant_3));
- ASSERT_NE(nullptr,
- context->get_constant_mgr()->FindConstant(&int_constant_6));
- ASSERT_NE(nullptr,
- context->get_constant_mgr()->FindConstant(&int_constant_8));
- }
-}
-
-} // namespace
-} // namespace fuzz
-} // namespace spvtools
diff --git a/test/fuzz/fuzzer_pass_construct_composites_test.cpp b/test/fuzz/fuzzer_pass_construct_composites_test.cpp
new file mode 100644
index 0000000..cc21f74
--- /dev/null
+++ b/test/fuzz/fuzzer_pass_construct_composites_test.cpp
@@ -0,0 +1,187 @@
+// Copyright (c) 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "source/fuzz/fuzzer_pass_construct_composites.h"
+#include "source/fuzz/pseudo_random_generator.h"
+#include "test/fuzz/fuzz_test_util.h"
+
+namespace spvtools {
+namespace fuzz {
+namespace {
+
+TEST(FuzzerPassConstructCompositesTest, IsomorphicStructs) {
+ // This test declares various isomorphic structs, and a struct that is made up
+ // of these isomorphic structs. The pass to construct composites is then
+ // applied several times to check that no issues arise related to using a
+ // value of one struct type when a value of an isomorphic struct type is
+ // required.
+
+ std::string shader = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main"
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeFloat 32
+ %7 = OpConstant %6 0
+ %8 = OpTypeStruct %6 %6 %6
+ %9 = OpTypeStruct %6 %6 %6
+ %10 = OpTypeStruct %6 %6 %6
+ %11 = OpTypeStruct %6 %6 %6
+ %12 = OpTypeStruct %6 %6 %6
+ %13 = OpTypeStruct %8 %9 %10 %11 %12
+ %14 = OpConstantComposite %8 %7 %7 %7
+ %15 = OpConstantComposite %9 %7 %7 %7
+ %16 = OpConstantComposite %10 %7 %7 %7
+ %17 = OpConstantComposite %11 %7 %7 %7
+ %18 = OpConstantComposite %12 %7 %7 %7
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ OpNop
+ OpNop
+ OpNop
+ OpNop
+ OpNop
+ OpNop
+ OpNop
+ OpNop
+ OpNop
+ OpNop
+ OpNop
+ OpNop
+ OpNop
+ OpNop
+ OpNop
+ OpNop
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ const auto env = SPV_ENV_UNIVERSAL_1_3;
+ const auto consumer = nullptr;
+
+ auto prng = MakeUnique<PseudoRandomGenerator>(0);
+
+ for (uint32_t i = 0; i < 10; i++) {
+ const auto context =
+ BuildModule(env, consumer, shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, context.get()));
+
+ FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ FuzzerContext fuzzer_context(prng.get(), 100);
+ protobufs::TransformationSequence transformation_sequence;
+
+ FuzzerPassConstructComposites fuzzer_pass(
+ context.get(), &transformation_context, &fuzzer_context,
+ &transformation_sequence);
+
+ fuzzer_pass.Apply();
+
+ // We just check that the result is valid.
+ ASSERT_TRUE(IsValid(env, context.get()));
+ }
+}
+
+TEST(FuzzerPassConstructCompositesTest, IsomorphicArrays) {
+ // This test declares various isomorphic arrays, and a struct that is made up
+ // of these isomorphic arrays. The pass to construct composites is then
+ // applied several times to check that no issues arise related to using a
+ // value of one array type when a value of an isomorphic array type is
+ // required.
+
+ std::string shader = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main"
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeFloat 32
+ %50 = OpTypeInt 32 0
+ %51 = OpConstant %50 3
+ %7 = OpConstant %6 0
+ %8 = OpTypeArray %6 %51
+ %9 = OpTypeArray %6 %51
+ %10 = OpTypeArray %6 %51
+ %11 = OpTypeArray %6 %51
+ %12 = OpTypeArray %6 %51
+ %13 = OpTypeStruct %8 %9 %10 %11 %12
+ %14 = OpConstantComposite %8 %7 %7 %7
+ %15 = OpConstantComposite %9 %7 %7 %7
+ %16 = OpConstantComposite %10 %7 %7 %7
+ %17 = OpConstantComposite %11 %7 %7 %7
+ %18 = OpConstantComposite %12 %7 %7 %7
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ OpNop
+ OpNop
+ OpNop
+ OpNop
+ OpNop
+ OpNop
+ OpNop
+ OpNop
+ OpNop
+ OpNop
+ OpNop
+ OpNop
+ OpNop
+ OpNop
+ OpNop
+ OpNop
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ const auto env = SPV_ENV_UNIVERSAL_1_3;
+ const auto consumer = nullptr;
+
+ auto prng = MakeUnique<PseudoRandomGenerator>(0);
+
+ for (uint32_t i = 0; i < 10; i++) {
+ const auto context =
+ BuildModule(env, consumer, shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, context.get()));
+
+ FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ FuzzerContext fuzzer_context(prng.get(), 100);
+ protobufs::TransformationSequence transformation_sequence;
+
+ FuzzerPassConstructComposites fuzzer_pass(
+ context.get(), &transformation_context, &fuzzer_context,
+ &transformation_sequence);
+
+ fuzzer_pass.Apply();
+
+ // We just check that the result is valid.
+ ASSERT_TRUE(IsValid(env, context.get()));
+ }
+}
+
+} // namespace
+} // namespace fuzz
+} // namespace spvtools
diff --git a/test/fuzz/fuzzer_pass_donate_modules_test.cpp b/test/fuzz/fuzzer_pass_donate_modules_test.cpp
index dc7ba3a..0833c1d 100644
--- a/test/fuzz/fuzzer_pass_donate_modules_test.cpp
+++ b/test/fuzz/fuzzer_pass_donate_modules_test.cpp
@@ -194,14 +194,17 @@
ASSERT_TRUE(IsValid(env, donor_context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
- auto prng = MakeUnique<PseudoRandomGenerator>(0);
- FuzzerContext fuzzer_context(prng.get(), 100);
+ PseudoRandomGenerator prng(0);
+ FuzzerContext fuzzer_context(&prng, 100);
protobufs::TransformationSequence transformation_sequence;
- FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), &fact_manager,
- &fuzzer_context, &transformation_sequence,
- {});
+ FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
+ &transformation_context, &fuzzer_context,
+ &transformation_sequence, {});
fuzzer_pass.DonateSingleModule(donor_context.get(), false);
@@ -269,13 +272,17 @@
ASSERT_TRUE(IsValid(env, donor_context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
- FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0).get(), 100);
+ PseudoRandomGenerator prng(0);
+ FuzzerContext fuzzer_context(&prng, 100);
protobufs::TransformationSequence transformation_sequence;
- FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), &fact_manager,
- &fuzzer_context, &transformation_sequence,
- {});
+ FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
+ &transformation_context, &fuzzer_context,
+ &transformation_sequence, {});
fuzzer_pass.DonateSingleModule(donor_context.get(), false);
@@ -393,13 +400,17 @@
ASSERT_TRUE(IsValid(env, donor_context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
- FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0).get(), 100);
+ PseudoRandomGenerator prng(0);
+ FuzzerContext fuzzer_context(&prng, 100);
protobufs::TransformationSequence transformation_sequence;
- FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), &fact_manager,
- &fuzzer_context, &transformation_sequence,
- {});
+ FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
+ &transformation_context, &fuzzer_context,
+ &transformation_sequence, {});
fuzzer_pass.DonateSingleModule(donor_context.get(), false);
@@ -481,13 +492,17 @@
ASSERT_TRUE(IsValid(env, donor_context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
- FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0).get(), 100);
+ PseudoRandomGenerator prng(0);
+ FuzzerContext fuzzer_context(&prng, 100);
protobufs::TransformationSequence transformation_sequence;
- FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), &fact_manager,
- &fuzzer_context, &transformation_sequence,
- {});
+ FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
+ &transformation_context, &fuzzer_context,
+ &transformation_sequence, {});
fuzzer_pass.DonateSingleModule(donor_context.get(), false);
@@ -496,6 +511,993 @@
ASSERT_TRUE(IsValid(env, recipient_context.get()));
}
+TEST(FuzzerPassDonateModulesTest, DonateOpConstantNull) {
+ std::string recipient_shader = R"(
+ OpCapability Shader
+ OpCapability ImageQuery
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main"
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 320
+ OpSourceExtension "GL_EXT_samplerless_texture_functions"
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ std::string donor_shader = R"(
+ OpCapability Shader
+ OpCapability ImageQuery
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main"
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 320
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeFloat 32
+ %7 = OpTypePointer Private %6
+ %8 = OpConstantNull %7
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ const auto env = SPV_ENV_UNIVERSAL_1_3;
+ const auto consumer = nullptr;
+ const auto recipient_context =
+ BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, recipient_context.get()));
+
+ const auto donor_context =
+ BuildModule(env, consumer, donor_shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, donor_context.get()));
+
+ FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ PseudoRandomGenerator prng(0);
+ FuzzerContext fuzzer_context(&prng, 100);
+ protobufs::TransformationSequence transformation_sequence;
+
+ FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
+ &transformation_context, &fuzzer_context,
+ &transformation_sequence, {});
+
+ fuzzer_pass.DonateSingleModule(donor_context.get(), false);
+
+ // We just check that the result is valid. Checking to what it should be
+ // exactly equal to would be very fragile.
+ ASSERT_TRUE(IsValid(env, recipient_context.get()));
+}
+
+TEST(FuzzerPassDonateModulesTest, DonateCodeThatUsesImages) {
+ std::string recipient_shader = R"(
+ OpCapability Shader
+ OpCapability ImageQuery
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main"
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 320
+ OpSourceExtension "GL_EXT_samplerless_texture_functions"
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ std::string donor_shader = R"(
+ OpCapability Shader
+ OpCapability ImageQuery
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main"
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 320
+ OpSourceExtension "GL_EXT_samplerless_texture_functions"
+ OpName %4 "main"
+ OpName %10 "mySampler"
+ OpName %21 "myTexture"
+ OpName %33 "v"
+ OpDecorate %10 RelaxedPrecision
+ OpDecorate %10 DescriptorSet 0
+ OpDecorate %10 Binding 0
+ OpDecorate %11 RelaxedPrecision
+ OpDecorate %21 RelaxedPrecision
+ OpDecorate %21 DescriptorSet 0
+ OpDecorate %21 Binding 1
+ OpDecorate %22 RelaxedPrecision
+ OpDecorate %34 RelaxedPrecision
+ OpDecorate %40 RelaxedPrecision
+ OpDecorate %42 RelaxedPrecision
+ OpDecorate %43 RelaxedPrecision
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeFloat 32
+ %7 = OpTypeImage %6 2D 0 0 0 1 Unknown
+ %8 = OpTypeSampledImage %7
+ %9 = OpTypePointer UniformConstant %8
+ %10 = OpVariable %9 UniformConstant
+ %12 = OpTypeInt 32 1
+ %13 = OpConstant %12 2
+ %15 = OpTypeVector %12 2
+ %17 = OpTypeInt 32 0
+ %18 = OpConstant %17 0
+ %20 = OpTypePointer UniformConstant %7
+ %21 = OpVariable %20 UniformConstant
+ %23 = OpConstant %12 1
+ %25 = OpConstant %17 1
+ %27 = OpTypeBool
+ %31 = OpTypeVector %6 4
+ %32 = OpTypePointer Function %31
+ %35 = OpConstantComposite %15 %23 %23
+ %36 = OpConstant %12 3
+ %37 = OpConstant %12 4
+ %38 = OpConstantComposite %15 %36 %37
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ %33 = OpVariable %32 Function
+ %11 = OpLoad %8 %10
+ %14 = OpImage %7 %11
+ %16 = OpImageQuerySizeLod %15 %14 %13
+ %19 = OpCompositeExtract %12 %16 0
+ %22 = OpLoad %7 %21
+ %24 = OpImageQuerySizeLod %15 %22 %23
+ %26 = OpCompositeExtract %12 %24 1
+ %28 = OpSGreaterThan %27 %19 %26
+ OpSelectionMerge %30 None
+ OpBranchConditional %28 %29 %41
+ %29 = OpLabel
+ %34 = OpLoad %8 %10
+ %39 = OpImage %7 %34
+ %40 = OpImageFetch %31 %39 %35 Lod|ConstOffset %13 %38
+ OpStore %33 %40
+ OpBranch %30
+ %41 = OpLabel
+ %42 = OpLoad %7 %21
+ %43 = OpImageFetch %31 %42 %35 Lod|ConstOffset %13 %38
+ OpStore %33 %43
+ OpBranch %30
+ %30 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ const auto env = SPV_ENV_UNIVERSAL_1_3;
+ const auto consumer = nullptr;
+ const auto recipient_context =
+ BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, recipient_context.get()));
+
+ const auto donor_context =
+ BuildModule(env, consumer, donor_shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, donor_context.get()));
+
+ FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ PseudoRandomGenerator prng(0);
+ FuzzerContext fuzzer_context(&prng, 100);
+ protobufs::TransformationSequence transformation_sequence;
+
+ FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
+ &transformation_context, &fuzzer_context,
+ &transformation_sequence, {});
+
+ fuzzer_pass.DonateSingleModule(donor_context.get(), false);
+
+ // We just check that the result is valid. Checking to what it should be
+ // exactly equal to would be very fragile.
+ ASSERT_TRUE(IsValid(env, recipient_context.get()));
+}
+
+TEST(FuzzerPassDonateModulesTest, DonateCodeThatUsesSampler) {
+ std::string recipient_shader = R"(
+ OpCapability Shader
+ OpCapability ImageQuery
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main"
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 320
+ OpSourceExtension "GL_EXT_samplerless_texture_functions"
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ std::string donor_shader = R"(
+ OpCapability Shader
+ OpCapability ImageQuery
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main"
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 320
+ OpDecorate %16 DescriptorSet 0
+ OpDecorate %16 Binding 0
+ OpDecorate %12 DescriptorSet 0
+ OpDecorate %12 Binding 64
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %23 = OpTypeFloat 32
+ %6 = OpTypeImage %23 2D 2 0 0 1 Unknown
+ %47 = OpTypePointer UniformConstant %6
+ %12 = OpVariable %47 UniformConstant
+ %15 = OpTypeSampler
+ %55 = OpTypePointer UniformConstant %15
+ %17 = OpTypeSampledImage %6
+ %16 = OpVariable %55 UniformConstant
+ %37 = OpTypeVector %23 4
+ %109 = OpConstant %23 0
+ %66 = OpConstantComposite %37 %109 %109 %109 %109
+ %56 = OpTypeBool
+ %54 = OpConstantTrue %56
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ OpBranch %50
+ %50 = OpLabel
+ %51 = OpPhi %37 %66 %5 %111 %53
+ OpLoopMerge %52 %53 None
+ OpBranchConditional %54 %53 %52
+ %53 = OpLabel
+ %106 = OpLoad %6 %12
+ %107 = OpLoad %15 %16
+ %110 = OpSampledImage %17 %106 %107
+ %111 = OpImageSampleImplicitLod %37 %110 %66 Bias %109
+ OpBranch %50
+ %52 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ const auto env = SPV_ENV_UNIVERSAL_1_3;
+ const auto consumer = nullptr;
+ const auto recipient_context =
+ BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, recipient_context.get()));
+
+ const auto donor_context =
+ BuildModule(env, consumer, donor_shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, donor_context.get()));
+
+ FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ PseudoRandomGenerator prng(0);
+ FuzzerContext fuzzer_context(&prng, 100);
+ protobufs::TransformationSequence transformation_sequence;
+
+ FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
+ &transformation_context, &fuzzer_context,
+ &transformation_sequence, {});
+
+ fuzzer_pass.DonateSingleModule(donor_context.get(), false);
+
+ // We just check that the result is valid. Checking to what it should be
+ // exactly equal to would be very fragile.
+ ASSERT_TRUE(IsValid(env, recipient_context.get()));
+}
+
+TEST(FuzzerPassDonateModulesTest, DonateCodeThatUsesImageStructField) {
+ std::string recipient_shader = R"(
+ OpCapability Shader
+ OpCapability ImageQuery
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main"
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 320
+ OpSourceExtension "GL_EXT_samplerless_texture_functions"
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ std::string donor_shader = R"(
+ OpCapability Shader
+ OpCapability ImageQuery
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main"
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 320
+ OpSourceExtension "GL_EXT_samplerless_texture_functions"
+ OpName %4 "main"
+ OpName %10 "mySampler"
+ OpName %21 "myTexture"
+ OpName %33 "v"
+ OpDecorate %10 RelaxedPrecision
+ OpDecorate %10 DescriptorSet 0
+ OpDecorate %10 Binding 0
+ OpDecorate %11 RelaxedPrecision
+ OpDecorate %21 RelaxedPrecision
+ OpDecorate %21 DescriptorSet 0
+ OpDecorate %21 Binding 1
+ OpDecorate %22 RelaxedPrecision
+ OpDecorate %34 RelaxedPrecision
+ OpDecorate %40 RelaxedPrecision
+ OpDecorate %42 RelaxedPrecision
+ OpDecorate %43 RelaxedPrecision
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeFloat 32
+ %7 = OpTypeImage %6 2D 0 0 0 1 Unknown
+ %8 = OpTypeSampledImage %7
+ %9 = OpTypePointer UniformConstant %8
+ %10 = OpVariable %9 UniformConstant
+ %12 = OpTypeInt 32 1
+ %13 = OpConstant %12 2
+ %15 = OpTypeVector %12 2
+ %17 = OpTypeInt 32 0
+ %18 = OpConstant %17 0
+ %20 = OpTypePointer UniformConstant %7
+ %21 = OpVariable %20 UniformConstant
+ %23 = OpConstant %12 1
+ %25 = OpConstant %17 1
+ %27 = OpTypeBool
+ %31 = OpTypeVector %6 4
+ %32 = OpTypePointer Function %31
+ %35 = OpConstantComposite %15 %23 %23
+ %36 = OpConstant %12 3
+ %37 = OpConstant %12 4
+ %38 = OpConstantComposite %15 %36 %37
+ %201 = OpTypeStruct %7 %7
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ %33 = OpVariable %32 Function
+ %11 = OpLoad %8 %10
+ %14 = OpImage %7 %11
+ %22 = OpLoad %7 %21
+ %200 = OpCompositeConstruct %201 %14 %22
+ %202 = OpCompositeExtract %7 %200 0
+ %203 = OpCompositeExtract %7 %200 1
+ %24 = OpImageQuerySizeLod %15 %203 %23
+ %16 = OpImageQuerySizeLod %15 %202 %13
+ %26 = OpCompositeExtract %12 %24 1
+ %19 = OpCompositeExtract %12 %16 0
+ %28 = OpSGreaterThan %27 %19 %26
+ OpSelectionMerge %30 None
+ OpBranchConditional %28 %29 %41
+ %29 = OpLabel
+ %34 = OpLoad %8 %10
+ %39 = OpImage %7 %34
+ %40 = OpImageFetch %31 %39 %35 Lod|ConstOffset %13 %38
+ OpStore %33 %40
+ OpBranch %30
+ %41 = OpLabel
+ %42 = OpLoad %7 %21
+ %43 = OpImageFetch %31 %42 %35 Lod|ConstOffset %13 %38
+ OpStore %33 %43
+ OpBranch %30
+ %30 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ const auto env = SPV_ENV_UNIVERSAL_1_3;
+ const auto consumer = nullptr;
+ const auto recipient_context =
+ BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, recipient_context.get()));
+
+ const auto donor_context =
+ BuildModule(env, consumer, donor_shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, donor_context.get()));
+
+ FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ PseudoRandomGenerator prng(0);
+ FuzzerContext fuzzer_context(&prng, 100);
+ protobufs::TransformationSequence transformation_sequence;
+
+ FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
+ &transformation_context, &fuzzer_context,
+ &transformation_sequence, {});
+
+ fuzzer_pass.DonateSingleModule(donor_context.get(), false);
+
+ // We just check that the result is valid. Checking to what it should be
+ // exactly equal to would be very fragile.
+ ASSERT_TRUE(IsValid(env, recipient_context.get()));
+}
+
+TEST(FuzzerPassDonateModulesTest, DonateCodeThatUsesImageFunctionParameter) {
+ std::string recipient_shader = R"(
+ OpCapability Shader
+ OpCapability ImageQuery
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main"
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 320
+ OpSourceExtension "GL_EXT_samplerless_texture_functions"
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ std::string donor_shader = R"(
+ OpCapability Shader
+ OpCapability ImageQuery
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main"
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 320
+ OpSourceExtension "GL_EXT_samplerless_texture_functions"
+ OpName %4 "main"
+ OpName %10 "mySampler"
+ OpName %21 "myTexture"
+ OpName %33 "v"
+ OpDecorate %10 RelaxedPrecision
+ OpDecorate %10 DescriptorSet 0
+ OpDecorate %10 Binding 0
+ OpDecorate %11 RelaxedPrecision
+ OpDecorate %21 RelaxedPrecision
+ OpDecorate %21 DescriptorSet 0
+ OpDecorate %21 Binding 1
+ OpDecorate %22 RelaxedPrecision
+ OpDecorate %34 RelaxedPrecision
+ OpDecorate %40 RelaxedPrecision
+ OpDecorate %42 RelaxedPrecision
+ OpDecorate %43 RelaxedPrecision
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeFloat 32
+ %7 = OpTypeImage %6 2D 0 0 0 1 Unknown
+ %8 = OpTypeSampledImage %7
+ %9 = OpTypePointer UniformConstant %8
+ %10 = OpVariable %9 UniformConstant
+ %12 = OpTypeInt 32 1
+ %13 = OpConstant %12 2
+ %15 = OpTypeVector %12 2
+ %17 = OpTypeInt 32 0
+ %18 = OpConstant %17 0
+ %20 = OpTypePointer UniformConstant %7
+ %21 = OpVariable %20 UniformConstant
+ %23 = OpConstant %12 1
+ %25 = OpConstant %17 1
+ %27 = OpTypeBool
+ %31 = OpTypeVector %6 4
+ %32 = OpTypePointer Function %31
+ %35 = OpConstantComposite %15 %23 %23
+ %36 = OpConstant %12 3
+ %37 = OpConstant %12 4
+ %38 = OpConstantComposite %15 %36 %37
+ %201 = OpTypeFunction %15 %7 %12
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ %33 = OpVariable %32 Function
+ %11 = OpLoad %8 %10
+ %14 = OpImage %7 %11
+ %16 = OpFunctionCall %15 %200 %14 %13
+ %19 = OpCompositeExtract %12 %16 0
+ %22 = OpLoad %7 %21
+ %24 = OpImageQuerySizeLod %15 %22 %23
+ %26 = OpCompositeExtract %12 %24 1
+ %28 = OpSGreaterThan %27 %19 %26
+ OpSelectionMerge %30 None
+ OpBranchConditional %28 %29 %41
+ %29 = OpLabel
+ %34 = OpLoad %8 %10
+ %39 = OpImage %7 %34
+ %40 = OpImageFetch %31 %39 %35 Lod|ConstOffset %13 %38
+ OpStore %33 %40
+ OpBranch %30
+ %41 = OpLabel
+ %42 = OpLoad %7 %21
+ %43 = OpImageFetch %31 %42 %35 Lod|ConstOffset %13 %38
+ OpStore %33 %43
+ OpBranch %30
+ %30 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ %200 = OpFunction %15 None %201
+ %202 = OpFunctionParameter %7
+ %203 = OpFunctionParameter %12
+ %204 = OpLabel
+ %205 = OpImageQuerySizeLod %15 %202 %203
+ OpReturnValue %205
+ OpFunctionEnd
+ )";
+
+ const auto env = SPV_ENV_UNIVERSAL_1_3;
+ const auto consumer = nullptr;
+ const auto recipient_context =
+ BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, recipient_context.get()));
+
+ const auto donor_context =
+ BuildModule(env, consumer, donor_shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, donor_context.get()));
+
+ FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ PseudoRandomGenerator prng(0);
+ FuzzerContext fuzzer_context(&prng, 100);
+ protobufs::TransformationSequence transformation_sequence;
+
+ FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
+ &transformation_context, &fuzzer_context,
+ &transformation_sequence, {});
+
+ fuzzer_pass.DonateSingleModule(donor_context.get(), false);
+
+ // We just check that the result is valid. Checking to what it should be
+ // exactly equal to would be very fragile.
+ ASSERT_TRUE(IsValid(env, recipient_context.get()));
+}
+
+TEST(FuzzerPassDonateModulesTest, DonateShaderWithImageStorageClass) {
+ std::string recipient_shader = R"(
+ OpCapability Shader
+ OpCapability ImageQuery
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main"
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 320
+ OpSourceExtension "GL_EXT_samplerless_texture_functions"
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ std::string donor_shader = R"(
+ OpCapability Shader
+ OpCapability SampledBuffer
+ OpCapability ImageBuffer
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "MainPSPacked"
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %18 DescriptorSet 0
+ OpDecorate %18 Binding 128
+ %49 = OpTypeInt 32 0
+ %50 = OpTypeFloat 32
+ %58 = OpConstant %50 1
+ %66 = OpConstant %49 0
+ %87 = OpTypeVector %50 2
+ %88 = OpConstantComposite %87 %58 %58
+ %17 = OpTypeImage %49 2D 2 0 0 2 R32ui
+ %118 = OpTypePointer UniformConstant %17
+ %123 = OpTypeVector %49 2
+ %132 = OpTypeVoid
+ %133 = OpTypeFunction %132
+ %142 = OpTypePointer Image %49
+ %18 = OpVariable %118 UniformConstant
+ %2 = OpFunction %132 None %133
+ %153 = OpLabel
+ %495 = OpConvertFToU %123 %88
+ %501 = OpImageTexelPointer %142 %18 %495 %66
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ const auto env = SPV_ENV_UNIVERSAL_1_3;
+ const auto consumer = nullptr;
+ const auto recipient_context =
+ BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, recipient_context.get()));
+
+ const auto donor_context =
+ BuildModule(env, consumer, donor_shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, donor_context.get()));
+
+ FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ PseudoRandomGenerator prng(0);
+ FuzzerContext fuzzer_context(&prng, 100);
+ protobufs::TransformationSequence transformation_sequence;
+
+ FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
+ &transformation_context, &fuzzer_context,
+ &transformation_sequence, {});
+
+ fuzzer_pass.DonateSingleModule(donor_context.get(), true);
+
+ // We just check that the result is valid. Checking to what it should be
+ // exactly equal to would be very fragile.
+ ASSERT_TRUE(IsValid(env, recipient_context.get()));
+}
+
+TEST(FuzzerPassDonateModulesTest, DonateComputeShaderWithRuntimeArray) {
+ std::string recipient_shader = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %4 "main"
+ OpExecutionMode %4 LocalSize 1 1 1
+ OpSource ESSL 310
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ std::string donor_shader = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %4 "main"
+ OpExecutionMode %4 LocalSize 1 1 1
+ OpSource ESSL 310
+ OpDecorate %9 ArrayStride 4
+ OpMemberDecorate %10 0 Offset 0
+ OpDecorate %10 BufferBlock
+ OpDecorate %12 DescriptorSet 0
+ OpDecorate %12 Binding 0
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeInt 32 1
+ %7 = OpTypePointer Function %6
+ %9 = OpTypeRuntimeArray %6
+ %10 = OpTypeStruct %9
+ %11 = OpTypePointer Uniform %10
+ %12 = OpVariable %11 Uniform
+ %13 = OpTypeInt 32 0
+ %16 = OpConstant %6 0
+ %18 = OpConstant %6 1
+ %20 = OpTypePointer Uniform %6
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ %8 = OpVariable %7 Function
+ %14 = OpArrayLength %13 %12 0
+ %15 = OpBitcast %6 %14
+ OpStore %8 %15
+ %17 = OpLoad %6 %8
+ %19 = OpISub %6 %17 %18
+ %21 = OpAccessChain %20 %12 %16 %19
+ OpStore %21 %16
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ const auto env = SPV_ENV_UNIVERSAL_1_3;
+ const auto consumer = nullptr;
+ const auto recipient_context =
+ BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, recipient_context.get()));
+
+ const auto donor_context =
+ BuildModule(env, consumer, donor_shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, donor_context.get()));
+
+ FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ PseudoRandomGenerator prng(0);
+ FuzzerContext fuzzer_context(&prng, 100);
+ protobufs::TransformationSequence transformation_sequence;
+
+ FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
+ &transformation_context, &fuzzer_context,
+ &transformation_sequence, {});
+
+ fuzzer_pass.DonateSingleModule(donor_context.get(), false);
+
+ // We just check that the result is valid. Checking to what it should be
+ // exactly equal to would be very fragile.
+ ASSERT_TRUE(IsValid(env, recipient_context.get()));
+}
+
+TEST(FuzzerPassDonateModulesTest, DonateComputeShaderWithRuntimeArrayLivesafe) {
+ std::string recipient_shader = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %4 "main"
+ OpExecutionMode %4 LocalSize 1 1 1
+ OpSource ESSL 310
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ std::string donor_shader = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %4 "main"
+ OpExecutionMode %4 LocalSize 1 1 1
+ OpSource ESSL 310
+ OpDecorate %16 ArrayStride 4
+ OpMemberDecorate %17 0 Offset 0
+ OpDecorate %17 BufferBlock
+ OpDecorate %19 DescriptorSet 0
+ OpDecorate %19 Binding 0
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeInt 32 1
+ %7 = OpTypePointer Function %6
+ %9 = OpConstant %6 0
+ %16 = OpTypeRuntimeArray %6
+ %17 = OpTypeStruct %16
+ %18 = OpTypePointer Uniform %17
+ %19 = OpVariable %18 Uniform
+ %20 = OpTypeInt 32 0
+ %23 = OpTypeBool
+ %26 = OpConstant %6 32
+ %27 = OpTypePointer Uniform %6
+ %30 = OpConstant %6 1
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ %8 = OpVariable %7 Function
+ OpStore %8 %9
+ OpBranch %10
+ %10 = OpLabel
+ OpLoopMerge %12 %13 None
+ OpBranch %14
+ %14 = OpLabel
+ %15 = OpLoad %6 %8
+ %21 = OpArrayLength %20 %19 0
+ %22 = OpBitcast %6 %21
+ %24 = OpSLessThan %23 %15 %22
+ OpBranchConditional %24 %11 %12
+ %11 = OpLabel
+ %25 = OpLoad %6 %8
+ %28 = OpAccessChain %27 %19 %9 %25
+ OpStore %28 %26
+ OpBranch %13
+ %13 = OpLabel
+ %29 = OpLoad %6 %8
+ %31 = OpIAdd %6 %29 %30
+ OpStore %8 %31
+ OpBranch %10
+ %12 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ const auto env = SPV_ENV_UNIVERSAL_1_3;
+ const auto consumer = nullptr;
+ const auto recipient_context =
+ BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, recipient_context.get()));
+
+ const auto donor_context =
+ BuildModule(env, consumer, donor_shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, donor_context.get()));
+
+ FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ PseudoRandomGenerator prng(0);
+ FuzzerContext fuzzer_context(&prng, 100);
+ protobufs::TransformationSequence transformation_sequence;
+
+ FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
+ &transformation_context, &fuzzer_context,
+ &transformation_sequence, {});
+
+ fuzzer_pass.DonateSingleModule(donor_context.get(), true);
+
+ // We just check that the result is valid. Checking to what it should be
+ // exactly equal to would be very fragile.
+ ASSERT_TRUE(IsValid(env, recipient_context.get()));
+}
+
+TEST(FuzzerPassDonateModulesTest, DonateComputeShaderWithWorkgroupVariables) {
+ std::string recipient_shader = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %4 "main"
+ OpExecutionMode %4 LocalSize 1 1 1
+ OpSource ESSL 310
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ std::string donor_shader = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %4 "main"
+ OpExecutionMode %4 LocalSize 1 1 1
+ OpSource ESSL 310
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeInt 32 1
+ %7 = OpTypePointer Workgroup %6
+ %8 = OpVariable %7 Workgroup
+ %9 = OpConstant %6 2
+ %10 = OpVariable %7 Workgroup
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ OpStore %8 %9
+ %11 = OpLoad %6 %8
+ OpStore %10 %11
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ const auto env = SPV_ENV_UNIVERSAL_1_3;
+ const auto consumer = nullptr;
+ const auto recipient_context =
+ BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, recipient_context.get()));
+
+ const auto donor_context =
+ BuildModule(env, consumer, donor_shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, donor_context.get()));
+
+ FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ PseudoRandomGenerator prng(0);
+ FuzzerContext fuzzer_context(&prng, 100);
+ protobufs::TransformationSequence transformation_sequence;
+
+ FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
+ &transformation_context, &fuzzer_context,
+ &transformation_sequence, {});
+
+ fuzzer_pass.DonateSingleModule(donor_context.get(), true);
+
+ // We just check that the result is valid. Checking to what it should be
+ // exactly equal to would be very fragile.
+ ASSERT_TRUE(IsValid(env, recipient_context.get()));
+}
+
+TEST(FuzzerPassDonateModulesTest, DonateComputeShaderWithAtomics) {
+ std::string recipient_shader = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %4 "main"
+ OpExecutionMode %4 LocalSize 1 1 1
+ OpSource ESSL 310
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ std::string donor_shader = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %4 "main"
+ OpExecutionMode %4 LocalSize 1 1 1
+ OpSource ESSL 310
+ OpMemberDecorate %9 0 Offset 0
+ OpDecorate %9 BufferBlock
+ OpDecorate %11 DescriptorSet 0
+ OpDecorate %11 Binding 0
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeInt 32 0
+ %7 = OpTypePointer Function %6
+ %9 = OpTypeStruct %6
+ %10 = OpTypePointer Uniform %9
+ %11 = OpVariable %10 Uniform
+ %12 = OpTypeInt 32 1
+ %13 = OpConstant %12 0
+ %14 = OpTypePointer Uniform %6
+ %16 = OpConstant %6 1
+ %17 = OpConstant %6 0
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ %8 = OpVariable %7 Function
+ %15 = OpAccessChain %14 %11 %13
+ %18 = OpAtomicIAdd %6 %15 %16 %17 %16
+ OpStore %8 %18
+ %19 = OpAccessChain %14 %11 %13
+ %20 = OpLoad %6 %8
+ %21 = OpAtomicUMin %6 %19 %16 %17 %20
+ OpStore %8 %21
+ %22 = OpAccessChain %14 %11 %13
+ %23 = OpLoad %6 %8
+ %24 = OpAtomicUMax %6 %22 %16 %17 %23
+ OpStore %8 %24
+ %25 = OpAccessChain %14 %11 %13
+ %26 = OpLoad %6 %8
+ %27 = OpAtomicAnd %6 %25 %16 %17 %26
+ OpStore %8 %27
+ %28 = OpAccessChain %14 %11 %13
+ %29 = OpLoad %6 %8
+ %30 = OpAtomicOr %6 %28 %16 %17 %29
+ OpStore %8 %30
+ %31 = OpAccessChain %14 %11 %13
+ %32 = OpLoad %6 %8
+ %33 = OpAtomicXor %6 %31 %16 %17 %32
+ OpStore %8 %33
+ %34 = OpAccessChain %14 %11 %13
+ %35 = OpLoad %6 %8
+ %36 = OpAtomicExchange %6 %34 %16 %17 %35
+ OpStore %8 %36
+ %37 = OpAccessChain %14 %11 %13
+ %38 = OpLoad %6 %8
+ %39 = OpAtomicCompareExchange %6 %37 %16 %17 %17 %16 %38
+ OpStore %8 %39
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ const auto env = SPV_ENV_UNIVERSAL_1_3;
+ const auto consumer = nullptr;
+ const auto recipient_context =
+ BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, recipient_context.get()));
+
+ const auto donor_context =
+ BuildModule(env, consumer, donor_shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, donor_context.get()));
+
+ FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ PseudoRandomGenerator prng(0);
+ FuzzerContext fuzzer_context(&prng, 100);
+ protobufs::TransformationSequence transformation_sequence;
+
+ FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
+ &transformation_context, &fuzzer_context,
+ &transformation_sequence, {});
+
+ fuzzer_pass.DonateSingleModule(donor_context.get(), true);
+
+ // We just check that the result is valid. Checking to what it should be
+ // exactly equal to would be very fragile.
+ ASSERT_TRUE(IsValid(env, recipient_context.get()));
+}
+
TEST(FuzzerPassDonateModulesTest, Miscellaneous1) {
std::string recipient_shader = R"(
OpCapability Shader
@@ -658,13 +1660,16 @@
ASSERT_TRUE(IsValid(env, donor_context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0).get(), 100);
protobufs::TransformationSequence transformation_sequence;
- FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), &fact_manager,
- &fuzzer_context, &transformation_sequence,
- {});
+ FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
+ &transformation_context, &fuzzer_context,
+ &transformation_sequence, {});
fuzzer_pass.DonateSingleModule(donor_context.get(), false);
diff --git a/test/fuzz/fuzzer_replayer_test.cpp b/test/fuzz/fuzzer_replayer_test.cpp
index b91393e..1e7c643 100644
--- a/test/fuzz/fuzzer_replayer_test.cpp
+++ b/test/fuzz/fuzzer_replayer_test.cpp
@@ -1553,6 +1553,47 @@
OpFunctionEnd
)";
+// Some miscellaneous SPIR-V.
+
+const std::string kTestShader6 = R"(
+ OpCapability Shader
+ OpCapability SampledBuffer
+ OpCapability ImageBuffer
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %40 %41
+ OpExecutionMode %2 OriginUpperLeft
+ OpSource GLSL 450
+ OpDecorate %40 DescriptorSet 0
+ OpDecorate %40 Binding 69
+ OpDecorate %41 DescriptorSet 0
+ OpDecorate %41 Binding 1
+ %54 = OpTypeFloat 32
+ %76 = OpTypeVector %54 4
+ %55 = OpConstant %54 0
+ %56 = OpTypeVector %54 3
+ %94 = OpTypeVector %54 2
+ %112 = OpConstantComposite %94 %55 %55
+ %57 = OpConstantComposite %56 %55 %55 %55
+ %15 = OpTypeImage %54 2D 2 0 0 1 Unknown
+ %114 = OpTypePointer UniformConstant %15
+ %38 = OpTypeSampler
+ %125 = OpTypePointer UniformConstant %38
+ %132 = OpTypeVoid
+ %133 = OpTypeFunction %132
+ %45 = OpTypeSampledImage %15
+ %40 = OpVariable %114 UniformConstant
+ %41 = OpVariable %125 UniformConstant
+ %2 = OpFunction %132 None %133
+ %164 = OpLabel
+ %184 = OpLoad %15 %40
+ %213 = OpLoad %38 %41
+ %216 = OpSampledImage %45 %184 %213
+ %217 = OpImageSampleImplicitLod %76 %216 %112 Bias %55
+ OpReturn
+ OpFunctionEnd
+ )";
+
void AddConstantUniformFact(protobufs::FactSequence* facts,
uint32_t descriptor_set, uint32_t binding,
std::vector<uint32_t>&& indices, uint32_t value) {
@@ -1591,7 +1632,7 @@
std::vector<fuzzerutil::ModuleSupplier> donor_suppliers;
for (auto donor : {&kTestShader1, &kTestShader2, &kTestShader3, &kTestShader4,
- &kTestShader5}) {
+ &kTestShader5, &kTestShader6}) {
donor_suppliers.emplace_back([donor]() {
return BuildModule(env, kConsoleMessageConsumer, *donor,
kFuzzAssembleOption);
@@ -1602,8 +1643,9 @@
std::vector<uint32_t> fuzzer_binary_out;
protobufs::TransformationSequence fuzzer_transformation_sequence_out;
- Fuzzer fuzzer(env, seed, true);
- fuzzer.SetMessageConsumer(kSilentConsumer);
+ spvtools::ValidatorOptions validator_options;
+ Fuzzer fuzzer(env, seed, true, validator_options);
+ fuzzer.SetMessageConsumer(kConsoleMessageConsumer);
auto fuzzer_result_status =
fuzzer.Run(binary_in, initial_facts, donor_suppliers,
&fuzzer_binary_out, &fuzzer_transformation_sequence_out);
@@ -1613,8 +1655,8 @@
std::vector<uint32_t> replayer_binary_out;
protobufs::TransformationSequence replayer_transformation_sequence_out;
- Replayer replayer(env, false);
- replayer.SetMessageConsumer(kSilentConsumer);
+ Replayer replayer(env, false, validator_options);
+ replayer.SetMessageConsumer(kConsoleMessageConsumer);
auto replayer_result_status = replayer.Run(
binary_in, initial_facts, fuzzer_transformation_sequence_out,
&replayer_binary_out, &replayer_transformation_sequence_out);
@@ -1681,6 +1723,13 @@
kNumFuzzerRuns);
}
+TEST(FuzzerReplayerTest, Miscellaneous6) {
+ // Do some fuzzer runs, starting from an initial seed of 57 (seed value chosen
+ // arbitrarily).
+ RunFuzzerAndReplayer(kTestShader6, protobufs::FactSequence(), 57,
+ kNumFuzzerRuns);
+}
+
} // namespace
} // namespace fuzz
} // namespace spvtools
diff --git a/test/fuzz/fuzzer_shrinker_test.cpp b/test/fuzz/fuzzer_shrinker_test.cpp
index c906a1e..24b4460 100644
--- a/test/fuzz/fuzzer_shrinker_test.cpp
+++ b/test/fuzz/fuzzer_shrinker_test.cpp
@@ -979,15 +979,19 @@
// The |step_limit| parameter restricts the number of steps that the shrinker
// will try; it can be set to something small for a faster (but less thorough)
// test.
+//
+// The |validator_options| parameter provides validator options that should be
+// used during shrinking.
void RunAndCheckShrinker(
const spv_target_env& target_env, const std::vector<uint32_t>& binary_in,
const protobufs::FactSequence& initial_facts,
const protobufs::TransformationSequence& transformation_sequence_in,
const Shrinker::InterestingnessFunction& interestingness_function,
const std::vector<uint32_t>& expected_binary_out,
- uint32_t expected_transformations_out_size, uint32_t step_limit) {
+ uint32_t expected_transformations_out_size, uint32_t step_limit,
+ spv_validator_options validator_options) {
// Run the shrinker.
- Shrinker shrinker(target_env, step_limit, false);
+ Shrinker shrinker(target_env, step_limit, false, validator_options);
shrinker.SetMessageConsumer(kSilentConsumer);
std::vector<uint32_t> binary_out;
@@ -1035,7 +1039,8 @@
// Run the fuzzer and check that it successfully yields a valid binary.
std::vector<uint32_t> fuzzer_binary_out;
protobufs::TransformationSequence fuzzer_transformation_sequence_out;
- Fuzzer fuzzer(env, seed, true);
+ spvtools::ValidatorOptions validator_options;
+ Fuzzer fuzzer(env, seed, true, validator_options);
fuzzer.SetMessageConsumer(kSilentConsumer);
auto fuzzer_result_status =
fuzzer.Run(binary_in, initial_facts, donor_suppliers, &fuzzer_binary_out,
@@ -1048,9 +1053,10 @@
// With the AlwaysInteresting test, we should quickly shrink to the original
// binary with no transformations remaining.
- RunAndCheckShrinker(
- env, binary_in, initial_facts, fuzzer_transformation_sequence_out,
- AlwaysInteresting().AsFunction(), binary_in, 0, kReasonableStepLimit);
+ RunAndCheckShrinker(env, binary_in, initial_facts,
+ fuzzer_transformation_sequence_out,
+ AlwaysInteresting().AsFunction(), binary_in, 0,
+ kReasonableStepLimit, validator_options);
// With the OnlyInterestingFirstTime test, no shrinking should be achieved.
RunAndCheckShrinker(
@@ -1058,14 +1064,14 @@
OnlyInterestingFirstTime().AsFunction(), fuzzer_binary_out,
static_cast<uint32_t>(
fuzzer_transformation_sequence_out.transformation_size()),
- kReasonableStepLimit);
+ kReasonableStepLimit, validator_options);
// The PingPong test is unpredictable; passing an empty expected binary
// means that we don't check anything beyond that shrinking completes
// successfully.
- RunAndCheckShrinker(env, binary_in, initial_facts,
- fuzzer_transformation_sequence_out,
- PingPong().AsFunction(), {}, 0, kSmallStepLimit);
+ RunAndCheckShrinker(
+ env, binary_in, initial_facts, fuzzer_transformation_sequence_out,
+ PingPong().AsFunction(), {}, 0, kSmallStepLimit, validator_options);
// The InterestingThenRandom test is unpredictable; passing an empty
// expected binary means that we do not check anything about shrinking
@@ -1073,7 +1079,7 @@
RunAndCheckShrinker(
env, binary_in, initial_facts, fuzzer_transformation_sequence_out,
InterestingThenRandom(PseudoRandomGenerator(seed)).AsFunction(), {}, 0,
- kSmallStepLimit);
+ kSmallStepLimit, validator_options);
}
TEST(FuzzerShrinkerTest, Miscellaneous1) {
diff --git a/test/fuzz/transformation_access_chain_test.cpp b/test/fuzz/transformation_access_chain_test.cpp
index 516d371..443c31c 100644
--- a/test/fuzz/transformation_access_chain_test.cpp
+++ b/test/fuzz/transformation_access_chain_test.cpp
@@ -118,169 +118,194 @@
// Indices 0-5 are in ids 80-85
FactManager fact_manager;
- fact_manager.AddFactValueOfPointeeIsIrrelevant(54);
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
+ 54);
// Bad: id is not fresh
ASSERT_FALSE(TransformationAccessChain(
43, 43, {80}, MakeInstructionDescriptor(24, SpvOpLoad, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: pointer id does not exist
ASSERT_FALSE(TransformationAccessChain(
100, 1000, {80}, MakeInstructionDescriptor(24, SpvOpLoad, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: pointer id is not a type
ASSERT_FALSE(TransformationAccessChain(
100, 5, {80}, MakeInstructionDescriptor(24, SpvOpLoad, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: pointer id is not a pointer
ASSERT_FALSE(TransformationAccessChain(
100, 23, {80}, MakeInstructionDescriptor(24, SpvOpLoad, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: index id does not exist
ASSERT_FALSE(TransformationAccessChain(
100, 43, {1000}, MakeInstructionDescriptor(24, SpvOpLoad, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: index id is not a constant
ASSERT_FALSE(TransformationAccessChain(
100, 43, {24}, MakeInstructionDescriptor(25, SpvOpIAdd, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: too many indices
ASSERT_FALSE(
TransformationAccessChain(100, 43, {80, 80, 80},
MakeInstructionDescriptor(24, SpvOpLoad, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: index id is out of bounds
ASSERT_FALSE(
TransformationAccessChain(100, 43, {80, 83},
MakeInstructionDescriptor(24, SpvOpLoad, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: attempt to insert before variable
ASSERT_FALSE(TransformationAccessChain(
100, 34, {}, MakeInstructionDescriptor(36, SpvOpVariable, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: pointer not available
ASSERT_FALSE(
TransformationAccessChain(
100, 43, {80}, MakeInstructionDescriptor(21, SpvOpAccessChain, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: instruction descriptor does not identify anything
ASSERT_FALSE(TransformationAccessChain(
100, 43, {80}, MakeInstructionDescriptor(24, SpvOpLoad, 100))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: pointer is null
ASSERT_FALSE(TransformationAccessChain(
100, 45, {80}, MakeInstructionDescriptor(24, SpvOpLoad, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: pointer is undef
ASSERT_FALSE(TransformationAccessChain(
100, 46, {80}, MakeInstructionDescriptor(24, SpvOpLoad, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: pointer to result type does not exist
ASSERT_FALSE(TransformationAccessChain(
100, 52, {0}, MakeInstructionDescriptor(24, SpvOpLoad, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
{
TransformationAccessChain transformation(
100, 43, {80}, MakeInstructionDescriptor(24, SpvOpLoad, 0));
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(100));
+ ASSERT_FALSE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(100));
}
{
TransformationAccessChain transformation(
101, 28, {81}, MakeInstructionDescriptor(42, SpvOpReturn, 0));
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(101));
+ ASSERT_FALSE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(101));
}
{
TransformationAccessChain transformation(
102, 36, {80, 81}, MakeInstructionDescriptor(37, SpvOpStore, 0));
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(102));
+ ASSERT_FALSE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(102));
}
{
TransformationAccessChain transformation(
103, 44, {}, MakeInstructionDescriptor(44, SpvOpStore, 0));
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(103));
+ ASSERT_FALSE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(103));
}
{
TransformationAccessChain transformation(
104, 13, {80}, MakeInstructionDescriptor(21, SpvOpAccessChain, 0));
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(104));
+ ASSERT_FALSE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(104));
}
{
TransformationAccessChain transformation(
105, 34, {}, MakeInstructionDescriptor(44, SpvOpStore, 1));
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(105));
+ ASSERT_FALSE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(105));
}
{
TransformationAccessChain transformation(
106, 38, {}, MakeInstructionDescriptor(40, SpvOpFunctionCall, 0));
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(106));
+ ASSERT_FALSE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(106));
}
{
TransformationAccessChain transformation(
107, 14, {}, MakeInstructionDescriptor(24, SpvOpLoad, 0));
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(107));
+ ASSERT_FALSE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(107));
}
{
TransformationAccessChain transformation(
108, 54, {85, 81, 81}, MakeInstructionDescriptor(24, SpvOpLoad, 0));
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(108));
+ ASSERT_TRUE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(108));
}
{
TransformationAccessChain transformation(
109, 48, {80, 80}, MakeInstructionDescriptor(24, SpvOpLoad, 0));
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(109));
+ ASSERT_FALSE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(109));
}
std::string after_transformation = R"(
@@ -401,19 +426,24 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
{
TransformationAccessChain transformation(
100, 11, {}, MakeInstructionDescriptor(5, SpvOpReturn, 0));
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
}
{
TransformationAccessChain transformation(
101, 12, {}, MakeInstructionDescriptor(5, SpvOpReturn, 0));
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
}
diff --git a/test/fuzz/transformation_add_constant_boolean_test.cpp b/test/fuzz/transformation_add_constant_boolean_test.cpp
index f51c46b..c603333 100644
--- a/test/fuzz/transformation_add_constant_boolean_test.cpp
+++ b/test/fuzz/transformation_add_constant_boolean_test.cpp
@@ -43,42 +43,47 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// True and false can both be added as neither is present.
ASSERT_TRUE(TransformationAddConstantBoolean(7, true).IsApplicable(
- context.get(), fact_manager));
+ context.get(), transformation_context));
ASSERT_TRUE(TransformationAddConstantBoolean(7, false).IsApplicable(
- context.get(), fact_manager));
+ context.get(), transformation_context));
// Id 5 is already taken.
ASSERT_FALSE(TransformationAddConstantBoolean(5, true).IsApplicable(
- context.get(), fact_manager));
+ context.get(), transformation_context));
auto add_true = TransformationAddConstantBoolean(7, true);
auto add_false = TransformationAddConstantBoolean(8, false);
- ASSERT_TRUE(add_true.IsApplicable(context.get(), fact_manager));
- add_true.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(add_true.IsApplicable(context.get(), transformation_context));
+ add_true.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Having added true, we cannot add it again with the same id.
- ASSERT_FALSE(add_true.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(add_true.IsApplicable(context.get(), transformation_context));
// But we can add it with a different id.
auto add_true_again = TransformationAddConstantBoolean(100, true);
- ASSERT_TRUE(add_true_again.IsApplicable(context.get(), fact_manager));
- add_true_again.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ add_true_again.IsApplicable(context.get(), transformation_context));
+ add_true_again.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(add_false.IsApplicable(context.get(), fact_manager));
- add_false.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(add_false.IsApplicable(context.get(), transformation_context));
+ add_false.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Having added false, we cannot add it again with the same id.
- ASSERT_FALSE(add_false.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(add_false.IsApplicable(context.get(), transformation_context));
// But we can add it with a different id.
auto add_false_again = TransformationAddConstantBoolean(101, false);
- ASSERT_TRUE(add_false_again.IsApplicable(context.get(), fact_manager));
- add_false_again.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ add_false_again.IsApplicable(context.get(), transformation_context));
+ add_false_again.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -128,12 +133,15 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Neither true nor false can be added as OpTypeBool is not present.
ASSERT_FALSE(TransformationAddConstantBoolean(6, true).IsApplicable(
- context.get(), fact_manager));
+ context.get(), transformation_context));
ASSERT_FALSE(TransformationAddConstantBoolean(6, false).IsApplicable(
- context.get(), fact_manager));
+ context.get(), transformation_context));
}
} // namespace
diff --git a/test/fuzz/transformation_add_constant_composite_test.cpp b/test/fuzz/transformation_add_constant_composite_test.cpp
index 5ce171b..021bf58 100644
--- a/test/fuzz/transformation_add_constant_composite_test.cpp
+++ b/test/fuzz/transformation_add_constant_composite_test.cpp
@@ -64,19 +64,22 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Too few ids
ASSERT_FALSE(TransformationAddConstantComposite(103, 8, {100, 101})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Too many ids
ASSERT_FALSE(TransformationAddConstantComposite(101, 7, {14, 15, 14})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Id already in use
ASSERT_FALSE(TransformationAddConstantComposite(40, 7, {11, 12})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// %39 is not a type
ASSERT_FALSE(TransformationAddConstantComposite(100, 39, {11, 12})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
TransformationAddConstantComposite transformations[] = {
// %100 = OpConstantComposite %7 %11 %12
@@ -101,8 +104,9 @@
TransformationAddConstantComposite(106, 35, {38, 39, 40})};
for (auto& transformation : transformations) {
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
}
ASSERT_TRUE(IsValid(env, context.get()));
diff --git a/test/fuzz/transformation_add_constant_null_test.cpp b/test/fuzz/transformation_add_constant_null_test.cpp
new file mode 100644
index 0000000..0bfee34
--- /dev/null
+++ b/test/fuzz/transformation_add_constant_null_test.cpp
@@ -0,0 +1,140 @@
+// Copyright (c) 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "source/fuzz/transformation_add_constant_null.h"
+#include "test/fuzz/fuzz_test_util.h"
+
+namespace spvtools {
+namespace fuzz {
+namespace {
+
+TEST(TransformationAddConstantNullTest, BasicTest) {
+ std::string shader = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main"
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeFloat 32
+ %7 = OpTypeInt 32 1
+ %8 = OpTypeVector %6 2
+ %9 = OpTypeVector %6 3
+ %10 = OpTypeVector %6 4
+ %11 = OpTypeVector %7 2
+ %20 = OpTypeSampler
+ %21 = OpTypeImage %6 2D 0 0 0 0 Rgba32f
+ %22 = OpTypeSampledImage %21
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ const auto env = SPV_ENV_UNIVERSAL_1_4;
+ const auto consumer = nullptr;
+ const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, context.get()));
+
+ FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ // Id already in use
+ ASSERT_FALSE(TransformationAddConstantNull(4, 11).IsApplicable(
+ context.get(), transformation_context));
+ // %1 is not a type
+ ASSERT_FALSE(TransformationAddConstantNull(100, 1).IsApplicable(
+ context.get(), transformation_context));
+
+ // %3 is a function type
+ ASSERT_FALSE(TransformationAddConstantNull(100, 3).IsApplicable(
+ context.get(), transformation_context));
+
+ // %20 is a sampler type
+ ASSERT_FALSE(TransformationAddConstantNull(100, 20).IsApplicable(
+ context.get(), transformation_context));
+
+ // %21 is an image type
+ ASSERT_FALSE(TransformationAddConstantNull(100, 21).IsApplicable(
+ context.get(), transformation_context));
+
+ // %22 is a sampled image type
+ ASSERT_FALSE(TransformationAddConstantNull(100, 22).IsApplicable(
+ context.get(), transformation_context));
+
+ TransformationAddConstantNull transformations[] = {
+ // %100 = OpConstantNull %6
+ TransformationAddConstantNull(100, 6),
+
+ // %101 = OpConstantNull %7
+ TransformationAddConstantNull(101, 7),
+
+ // %102 = OpConstantNull %8
+ TransformationAddConstantNull(102, 8),
+
+ // %103 = OpConstantNull %9
+ TransformationAddConstantNull(103, 9),
+
+ // %104 = OpConstantNull %10
+ TransformationAddConstantNull(104, 10),
+
+ // %105 = OpConstantNull %11
+ TransformationAddConstantNull(105, 11)};
+
+ for (auto& transformation : transformations) {
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
+ }
+ ASSERT_TRUE(IsValid(env, context.get()));
+
+ std::string after_transformation = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main"
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeFloat 32
+ %7 = OpTypeInt 32 1
+ %8 = OpTypeVector %6 2
+ %9 = OpTypeVector %6 3
+ %10 = OpTypeVector %6 4
+ %11 = OpTypeVector %7 2
+ %20 = OpTypeSampler
+ %21 = OpTypeImage %6 2D 0 0 0 0 Rgba32f
+ %22 = OpTypeSampledImage %21
+ %100 = OpConstantNull %6
+ %101 = OpConstantNull %7
+ %102 = OpConstantNull %8
+ %103 = OpConstantNull %9
+ %104 = OpConstantNull %10
+ %105 = OpConstantNull %11
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
+}
+
+} // namespace
+} // namespace fuzz
+} // namespace spvtools
diff --git a/test/fuzz/transformation_add_constant_scalar_test.cpp b/test/fuzz/transformation_add_constant_scalar_test.cpp
index b156111..5124b7d 100644
--- a/test/fuzz/transformation_add_constant_scalar_test.cpp
+++ b/test/fuzz/transformation_add_constant_scalar_test.cpp
@@ -62,6 +62,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
const float float_values[2] = {3.0, 30.0};
uint32_t uint_for_float[2];
@@ -87,55 +90,62 @@
auto bad_type_id_is_pointer = TransformationAddConstantScalar(111, 11, {0});
// Id is already in use.
- ASSERT_FALSE(bad_id_already_used.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ bad_id_already_used.IsApplicable(context.get(), transformation_context));
// At least one word of data must be provided.
- ASSERT_FALSE(bad_no_data.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(bad_no_data.IsApplicable(context.get(), transformation_context));
// Cannot give two data words for a 32-bit type.
- ASSERT_FALSE(bad_too_much_data.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ bad_too_much_data.IsApplicable(context.get(), transformation_context));
// Type id does not exist
- ASSERT_FALSE(
- bad_type_id_does_not_exist.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(bad_type_id_does_not_exist.IsApplicable(context.get(),
+ transformation_context));
// Type id is not a type
- ASSERT_FALSE(
- bad_type_id_is_not_a_type.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(bad_type_id_is_not_a_type.IsApplicable(context.get(),
+ transformation_context));
// Type id is void
- ASSERT_FALSE(bad_type_id_is_void.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ bad_type_id_is_void.IsApplicable(context.get(), transformation_context));
// Type id is pointer
- ASSERT_FALSE(
- bad_type_id_is_pointer.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(bad_type_id_is_pointer.IsApplicable(context.get(),
+ transformation_context));
- ASSERT_TRUE(add_signed_int_1.IsApplicable(context.get(), fact_manager));
- add_signed_int_1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ add_signed_int_1.IsApplicable(context.get(), transformation_context));
+ add_signed_int_1.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(add_signed_int_10.IsApplicable(context.get(), fact_manager));
- add_signed_int_10.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ add_signed_int_10.IsApplicable(context.get(), transformation_context));
+ add_signed_int_10.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(add_unsigned_int_2.IsApplicable(context.get(), fact_manager));
- add_unsigned_int_2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ add_unsigned_int_2.IsApplicable(context.get(), transformation_context));
+ add_unsigned_int_2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(add_unsigned_int_20.IsApplicable(context.get(), fact_manager));
- add_unsigned_int_20.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ add_unsigned_int_20.IsApplicable(context.get(), transformation_context));
+ add_unsigned_int_20.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(add_float_3.IsApplicable(context.get(), fact_manager));
- add_float_3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(add_float_3.IsApplicable(context.get(), transformation_context));
+ add_float_3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(add_float_30.IsApplicable(context.get(), fact_manager));
- add_float_30.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(add_float_30.IsApplicable(context.get(), transformation_context));
+ add_float_30.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_FALSE(bad_add_float_30_id_already_used.IsApplicable(context.get(),
- fact_manager));
+ ASSERT_FALSE(bad_add_float_30_id_already_used.IsApplicable(
+ context.get(), transformation_context));
std::string after_transformation = R"(
OpCapability Shader
diff --git a/test/fuzz/transformation_add_dead_block_test.cpp b/test/fuzz/transformation_add_dead_block_test.cpp
index f89140f..c9be520 100644
--- a/test/fuzz/transformation_add_dead_block_test.cpp
+++ b/test/fuzz/transformation_add_dead_block_test.cpp
@@ -46,21 +46,25 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Id 4 is already in use
ASSERT_FALSE(TransformationAddDeadBlock(4, 5, true)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Id 7 is not a block
ASSERT_FALSE(TransformationAddDeadBlock(100, 7, true)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
TransformationAddDeadBlock transformation(100, 5, true);
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.BlockIsDead(100));
+ ASSERT_TRUE(transformation_context.GetFactManager()->BlockIsDead(100));
std::string after_transformation = R"(
OpCapability Shader
@@ -119,9 +123,12 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
ASSERT_FALSE(TransformationAddDeadBlock(100, 9, true)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
}
TEST(TransformationAddDeadBlockTest, TargetBlockMustNotBeLoopMergeOrContinue) {
@@ -160,13 +167,16 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Bad because 9's successor is the loop continue target.
ASSERT_FALSE(TransformationAddDeadBlock(100, 9, true)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad because 10's successor is the loop merge.
ASSERT_FALSE(TransformationAddDeadBlock(100, 10, true)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
}
TEST(TransformationAddDeadBlockTest, SourceBlockMustNotBeLoopHead) {
@@ -203,10 +213,13 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Bad because 8 is a loop head.
ASSERT_FALSE(TransformationAddDeadBlock(100, 8, true)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
}
TEST(TransformationAddDeadBlockTest, OpPhiInTarget) {
@@ -240,13 +253,17 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationAddDeadBlock transformation(100, 5, true);
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.BlockIsDead(100));
+ ASSERT_TRUE(transformation_context.GetFactManager()->BlockIsDead(100));
std::string after_transformation = R"(
OpCapability Shader
@@ -309,11 +326,14 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// 9 is a back edge block, so it would not be OK to add a dead block here,
// as then both 9 and the dead block would branch to the loop header, 8.
ASSERT_FALSE(TransformationAddDeadBlock(100, 9, true)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
}
} // namespace
diff --git a/test/fuzz/transformation_add_dead_break_test.cpp b/test/fuzz/transformation_add_dead_break_test.cpp
index d60fc1f..8400b0c 100644
--- a/test/fuzz/transformation_add_dead_break_test.cpp
+++ b/test/fuzz/transformation_add_dead_break_test.cpp
@@ -100,44 +100,47 @@
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
const uint32_t merge_block = 16;
// These are all possibilities.
ASSERT_TRUE(TransformationAddDeadBreak(15, merge_block, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadBreak(15, merge_block, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadBreak(21, merge_block, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadBreak(21, merge_block, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadBreak(22, merge_block, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadBreak(22, merge_block, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadBreak(19, merge_block, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadBreak(19, merge_block, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadBreak(23, merge_block, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadBreak(23, merge_block, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadBreak(24, merge_block, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadBreak(24, merge_block, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Inapplicable: 100 is not a block id.
ASSERT_FALSE(TransformationAddDeadBreak(100, merge_block, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationAddDeadBreak(15, 100, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Inapplicable: 24 is not a merge block.
ASSERT_FALSE(TransformationAddDeadBreak(15, 24, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// These are the transformations we will apply.
auto transformation1 = TransformationAddDeadBreak(15, merge_block, true, {});
@@ -147,28 +150,34 @@
auto transformation5 = TransformationAddDeadBreak(23, merge_block, true, {});
auto transformation6 = TransformationAddDeadBreak(24, merge_block, false, {});
- ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager));
- transformation1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation1.IsApplicable(context.get(), transformation_context));
+ transformation1.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager));
- transformation2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation2.IsApplicable(context.get(), transformation_context));
+ transformation2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager));
- transformation3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation3.IsApplicable(context.get(), transformation_context));
+ transformation3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation4.IsApplicable(context.get(), fact_manager));
- transformation4.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation4.IsApplicable(context.get(), transformation_context));
+ transformation4.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation5.IsApplicable(context.get(), fact_manager));
- transformation5.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation5.IsApplicable(context.get(), transformation_context));
+ transformation5.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation6.IsApplicable(context.get(), fact_manager));
- transformation6.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation6.IsApplicable(context.get(), transformation_context));
+ transformation6.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -333,6 +342,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// The header and merge blocks
const uint32_t header_inner = 34;
@@ -354,53 +366,53 @@
// Fine to break from a construct to its merge
ASSERT_TRUE(TransformationAddDeadBreak(inner_block_1, merge_inner, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadBreak(inner_block_2, merge_inner, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadBreak(outer_block_1, merge_outer, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadBreak(outer_block_2, merge_outer, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadBreak(outer_block_3, merge_outer, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadBreak(outer_block_4, merge_outer, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadBreak(after_block_1, merge_after, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadBreak(after_block_2, merge_after, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Not OK to break to the wrong merge (whether enclosing or not)
ASSERT_FALSE(TransformationAddDeadBreak(inner_block_1, merge_outer, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationAddDeadBreak(inner_block_2, merge_after, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationAddDeadBreak(outer_block_1, merge_inner, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationAddDeadBreak(outer_block_2, merge_after, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationAddDeadBreak(after_block_1, merge_inner, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationAddDeadBreak(after_block_2, merge_outer, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Not OK to break from header (as it does not branch unconditionally)
ASSERT_FALSE(TransformationAddDeadBreak(header_inner, merge_inner, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationAddDeadBreak(header_outer, merge_outer, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationAddDeadBreak(header_after, merge_after, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Not OK to break to non-merge
ASSERT_FALSE(
TransformationAddDeadBreak(inner_block_1, inner_block_2, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationAddDeadBreak(outer_block_2, after_block_1, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationAddDeadBreak(outer_block_1, header_after, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
auto transformation1 =
TransformationAddDeadBreak(inner_block_1, merge_inner, true, {});
@@ -419,36 +431,44 @@
auto transformation8 =
TransformationAddDeadBreak(after_block_2, merge_after, false, {});
- ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager));
- transformation1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation1.IsApplicable(context.get(), transformation_context));
+ transformation1.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager));
- transformation2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation2.IsApplicable(context.get(), transformation_context));
+ transformation2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager));
- transformation3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation3.IsApplicable(context.get(), transformation_context));
+ transformation3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation4.IsApplicable(context.get(), fact_manager));
- transformation4.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation4.IsApplicable(context.get(), transformation_context));
+ transformation4.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation5.IsApplicable(context.get(), fact_manager));
- transformation5.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation5.IsApplicable(context.get(), transformation_context));
+ transformation5.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation6.IsApplicable(context.get(), fact_manager));
- transformation6.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation6.IsApplicable(context.get(), transformation_context));
+ transformation6.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation7.IsApplicable(context.get(), fact_manager));
- transformation7.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation7.IsApplicable(context.get(), transformation_context));
+ transformation7.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation8.IsApplicable(context.get(), fact_manager));
- transformation8.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation8.IsApplicable(context.get(), transformation_context));
+ transformation8.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -685,6 +705,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// The header and merge blocks
const uint32_t header_outer_if = 5;
@@ -715,63 +738,63 @@
// Fine to branch straight to direct merge block for a construct
ASSERT_TRUE(TransformationAddDeadBreak(then_outer_switch_block_1,
merge_then_outer_switch, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadBreak(then_inner_switch_block_1,
merge_then_inner_switch, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadBreak(then_inner_switch_block_2,
merge_then_inner_switch, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadBreak(then_inner_switch_block_3,
merge_then_inner_switch, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadBreak(else_switch_block_1, merge_else_switch,
false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadBreak(else_switch_block_2, merge_else_switch,
true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadBreak(else_switch_block_3, merge_else_switch,
false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationAddDeadBreak(inner_if_1_block_1, merge_inner_if_1, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadBreak(inner_if_1_block_2, merge_inner_if_1,
false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationAddDeadBreak(inner_if_2_block_1, merge_inner_if_2, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Not OK to break out of a switch from a selection construct inside the
// switch.
ASSERT_FALSE(TransformationAddDeadBreak(inner_if_1_block_1,
merge_then_outer_switch, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationAddDeadBreak(inner_if_1_block_2,
merge_then_outer_switch, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationAddDeadBreak(inner_if_2_block_1,
merge_then_outer_switch, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Some miscellaneous inapplicable cases.
ASSERT_FALSE(
TransformationAddDeadBreak(header_outer_if, merge_outer_if, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationAddDeadBreak(header_inner_if_1, inner_if_1_block_2,
false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationAddDeadBreak(header_then_inner_switch,
header_then_outer_switch, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationAddDeadBreak(header_else_switch,
then_inner_switch_block_3, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationAddDeadBreak(header_inner_if_2, header_inner_if_2,
false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
auto transformation1 = TransformationAddDeadBreak(
then_outer_switch_block_1, merge_then_outer_switch, true, {});
@@ -794,44 +817,54 @@
auto transformation10 = TransformationAddDeadBreak(
inner_if_2_block_1, merge_inner_if_2, true, {});
- ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager));
- transformation1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation1.IsApplicable(context.get(), transformation_context));
+ transformation1.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager));
- transformation2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation2.IsApplicable(context.get(), transformation_context));
+ transformation2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager));
- transformation3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation3.IsApplicable(context.get(), transformation_context));
+ transformation3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation4.IsApplicable(context.get(), fact_manager));
- transformation4.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation4.IsApplicable(context.get(), transformation_context));
+ transformation4.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation5.IsApplicable(context.get(), fact_manager));
- transformation5.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation5.IsApplicable(context.get(), transformation_context));
+ transformation5.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation6.IsApplicable(context.get(), fact_manager));
- transformation6.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation6.IsApplicable(context.get(), transformation_context));
+ transformation6.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation7.IsApplicable(context.get(), fact_manager));
- transformation7.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation7.IsApplicable(context.get(), transformation_context));
+ transformation7.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation8.IsApplicable(context.get(), fact_manager));
- transformation8.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation8.IsApplicable(context.get(), transformation_context));
+ transformation8.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation9.IsApplicable(context.get(), fact_manager));
- transformation9.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation9.IsApplicable(context.get(), transformation_context));
+ transformation9.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation10.IsApplicable(context.get(), fact_manager));
- transformation10.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation10.IsApplicable(context.get(), transformation_context));
+ transformation10.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -1094,6 +1127,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// The header and merge blocks
const uint32_t header_do_while = 6;
@@ -1123,75 +1159,75 @@
// Fine to break from any loop header to its merge
ASSERT_TRUE(
TransformationAddDeadBreak(header_do_while, merge_do_while, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadBreak(header_for_i, merge_for_i, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadBreak(header_for_j, merge_for_j, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Fine to break from any of the blocks in constructs in the "for j" loop to
// that loop's merge
ASSERT_TRUE(
TransformationAddDeadBreak(block_in_inner_if, merge_for_j, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationAddDeadBreak(block_switch_case, merge_for_j, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationAddDeadBreak(block_switch_default, merge_for_j, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Fine to break from the body of the "for i" loop to that loop's merge
ASSERT_TRUE(
TransformationAddDeadBreak(block_in_for_i_loop, merge_for_i, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Not OK to break from multiple loops
ASSERT_FALSE(
TransformationAddDeadBreak(block_in_inner_if, merge_do_while, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationAddDeadBreak(block_switch_case, merge_do_while, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationAddDeadBreak(block_switch_default, merge_do_while,
false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationAddDeadBreak(header_for_j, merge_do_while, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Not OK to break loop from its continue construct
ASSERT_FALSE(
TransformationAddDeadBreak(continue_do_while, merge_do_while, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationAddDeadBreak(continue_for_j, merge_for_j, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationAddDeadBreak(continue_for_i, merge_for_i, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Not OK to break out of multiple non-loop constructs if not breaking to a
// loop merge
ASSERT_FALSE(
TransformationAddDeadBreak(block_in_inner_if, merge_if_x_eq_y, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationAddDeadBreak(block_switch_case, merge_if_x_eq_y, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationAddDeadBreak(block_switch_default, merge_if_x_eq_y,
false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Some miscellaneous inapplicable transformations
ASSERT_FALSE(
TransformationAddDeadBreak(header_if_x_eq_2, header_if_x_eq_y, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationAddDeadBreak(merge_if_x_eq_2, merge_switch, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationAddDeadBreak(header_switch, header_switch, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
auto transformation1 =
TransformationAddDeadBreak(header_do_while, merge_do_while, true, {});
@@ -1208,32 +1244,39 @@
auto transformation7 =
TransformationAddDeadBreak(block_in_for_i_loop, merge_for_i, true, {});
- ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager));
- transformation1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation1.IsApplicable(context.get(), transformation_context));
+ transformation1.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager));
- transformation2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation2.IsApplicable(context.get(), transformation_context));
+ transformation2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager));
- transformation3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation3.IsApplicable(context.get(), transformation_context));
+ transformation3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation4.IsApplicable(context.get(), fact_manager));
- transformation4.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation4.IsApplicable(context.get(), transformation_context));
+ transformation4.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation5.IsApplicable(context.get(), fact_manager));
- transformation5.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation5.IsApplicable(context.get(), transformation_context));
+ transformation5.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation6.IsApplicable(context.get(), fact_manager));
- transformation6.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation6.IsApplicable(context.get(), transformation_context));
+ transformation6.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation7.IsApplicable(context.get(), fact_manager));
- transformation7.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation7.IsApplicable(context.get(), transformation_context));
+ transformation7.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -1421,12 +1464,15 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Not OK to break loop from its continue construct
ASSERT_FALSE(TransformationAddDeadBreak(13, 12, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationAddDeadBreak(23, 12, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
}
TEST(TransformationAddDeadBreakTest, SelectionInContinueConstruct) {
@@ -1509,6 +1555,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
const uint32_t loop_merge = 12;
const uint32_t selection_merge = 24;
@@ -1520,13 +1569,13 @@
// Not OK to jump from the selection to the loop merge, as this would break
// from the loop's continue construct.
ASSERT_FALSE(TransformationAddDeadBreak(in_selection_1, loop_merge, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationAddDeadBreak(in_selection_2, loop_merge, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationAddDeadBreak(in_selection_3, loop_merge, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationAddDeadBreak(in_selection_4, loop_merge, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// But fine to jump from the selection to its merge.
@@ -1539,20 +1588,24 @@
auto transformation4 =
TransformationAddDeadBreak(in_selection_4, selection_merge, true, {});
- ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager));
- transformation1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation1.IsApplicable(context.get(), transformation_context));
+ transformation1.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager));
- transformation2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation2.IsApplicable(context.get(), transformation_context));
+ transformation2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager));
- transformation3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation3.IsApplicable(context.get(), transformation_context));
+ transformation3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation4.IsApplicable(context.get(), fact_manager));
- transformation4.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation4.IsApplicable(context.get(), transformation_context));
+ transformation4.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -1720,6 +1773,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
const uint32_t outer_loop_merge = 34;
const uint32_t outer_loop_block = 33;
@@ -1729,22 +1785,24 @@
// Some inapplicable cases
ASSERT_FALSE(
TransformationAddDeadBreak(inner_loop_block, outer_loop_merge, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationAddDeadBreak(outer_loop_block, inner_loop_merge, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
auto transformation1 =
TransformationAddDeadBreak(inner_loop_block, inner_loop_merge, true, {});
auto transformation2 =
TransformationAddDeadBreak(outer_loop_block, outer_loop_merge, true, {});
- ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager));
- transformation1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation1.IsApplicable(context.get(), transformation_context));
+ transformation1.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager));
- transformation2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation2.IsApplicable(context.get(), transformation_context));
+ transformation2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -1936,36 +1994,39 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Some inapplicable transformations
// Not applicable because there is already an edge 19->20, so the OpPhis at 20
// do not need to be updated
ASSERT_FALSE(TransformationAddDeadBreak(19, 20, true, {13, 21})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Not applicable because two OpPhis (not zero) need to be updated at 20
ASSERT_FALSE(TransformationAddDeadBreak(23, 20, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Not applicable because two OpPhis (not just one) need to be updated at 20
ASSERT_FALSE(TransformationAddDeadBreak(23, 20, true, {13})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Not applicable because the given ids do not have types that match the
// OpPhis at 20, in order
ASSERT_FALSE(TransformationAddDeadBreak(23, 20, true, {21, 13})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Not applicable because id 23 is a label
ASSERT_FALSE(TransformationAddDeadBreak(23, 20, true, {21, 23})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Not applicable because 101 is not an id
ASSERT_FALSE(TransformationAddDeadBreak(23, 20, true, {21, 101})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Not applicable because ids 51 and 47 are not available at the end of block
// 23
ASSERT_FALSE(TransformationAddDeadBreak(23, 20, true, {51, 47})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Not applicable because OpConstantFalse is not present in the module
ASSERT_FALSE(TransformationAddDeadBreak(19, 20, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
auto transformation1 = TransformationAddDeadBreak(19, 20, true, {});
auto transformation2 = TransformationAddDeadBreak(23, 20, true, {13, 21});
@@ -1973,24 +2034,29 @@
auto transformation4 = TransformationAddDeadBreak(30, 31, true, {21, 13});
auto transformation5 = TransformationAddDeadBreak(75, 31, true, {47, 51});
- ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager));
- transformation1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation1.IsApplicable(context.get(), transformation_context));
+ transformation1.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager));
- transformation2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation2.IsApplicable(context.get(), transformation_context));
+ transformation2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager));
- transformation3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation3.IsApplicable(context.get(), transformation_context));
+ transformation3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation4.IsApplicable(context.get(), fact_manager));
- transformation4.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation4.IsApplicable(context.get(), transformation_context));
+ transformation4.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation5.IsApplicable(context.get(), fact_manager));
- transformation5.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation5.IsApplicable(context.get(), transformation_context));
+ transformation5.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -2119,9 +2185,13 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
auto bad_transformation = TransformationAddDeadBreak(100, 101, false, {});
- ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ bad_transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationAddDeadBreakTest, RespectDominanceRules2) {
@@ -2172,9 +2242,13 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
auto bad_transformation = TransformationAddDeadBreak(102, 101, false, {});
- ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ bad_transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationAddDeadBreakTest, RespectDominanceRules3) {
@@ -2219,11 +2293,15 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
auto good_transformation = TransformationAddDeadBreak(100, 101, false, {11});
- ASSERT_TRUE(good_transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_TRUE(
+ good_transformation.IsApplicable(context.get(), transformation_context));
- good_transformation.Apply(context.get(), &fact_manager);
+ good_transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -2307,11 +2385,15 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
auto good_transformation = TransformationAddDeadBreak(102, 101, false, {11});
- ASSERT_TRUE(good_transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_TRUE(
+ good_transformation.IsApplicable(context.get(), transformation_context));
- good_transformation.Apply(context.get(), &fact_manager);
+ good_transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -2389,9 +2471,13 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
auto bad_transformation = TransformationAddDeadBreak(100, 101, false, {});
- ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ bad_transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationAddDeadBreakTest, RespectDominanceRules6) {
@@ -2446,9 +2532,13 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
auto bad_transformation = TransformationAddDeadBreak(102, 101, false, {});
- ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ bad_transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationAddDeadBreakTest, RespectDominanceRules7) {
@@ -2505,9 +2595,13 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
auto bad_transformation = TransformationAddDeadBreak(102, 101, false, {});
- ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ bad_transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationAddDeadBreakTest, RespectDominanceRules8) {
@@ -2551,9 +2645,13 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
auto bad_transformation = TransformationAddDeadBreak(102, 101, false, {});
- ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ bad_transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationAddDeadBreakTest,
@@ -2597,12 +2695,16 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Bad because 14 comes before 12 in the module, and 14 has no predecessors.
// This means that an edge from 12 to 14 will lead to 12 dominating 14, which
// is illegal if 12 appears after 14.
auto bad_transformation = TransformationAddDeadBreak(12, 14, true, {});
- ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ bad_transformation.IsApplicable(context.get(), transformation_context));
}
} // namespace
diff --git a/test/fuzz/transformation_add_dead_continue_test.cpp b/test/fuzz/transformation_add_dead_continue_test.cpp
index ff93da8..07ee3b1 100644
--- a/test/fuzz/transformation_add_dead_continue_test.cpp
+++ b/test/fuzz/transformation_add_dead_continue_test.cpp
@@ -97,57 +97,63 @@
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// These are all possibilities.
ASSERT_TRUE(TransformationAddDeadContinue(11, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadContinue(11, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadContinue(12, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadContinue(12, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadContinue(40, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationAddDeadContinue(40, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Inapplicable: 100 is not a block id.
ASSERT_FALSE(TransformationAddDeadContinue(100, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Inapplicable: 10 is not in a loop.
ASSERT_FALSE(TransformationAddDeadContinue(10, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Inapplicable: 15 does not branch unconditionally to a single successor.
ASSERT_FALSE(TransformationAddDeadContinue(15, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Inapplicable: 13 is not in a loop and has no successor.
ASSERT_FALSE(TransformationAddDeadContinue(13, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Inapplicable: 14 is the loop continue target, so it's not OK to jump to
// the loop continue from there.
ASSERT_FALSE(TransformationAddDeadContinue(14, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// These are the transformations we will apply.
auto transformation1 = TransformationAddDeadContinue(11, true, {});
auto transformation2 = TransformationAddDeadContinue(12, false, {});
auto transformation3 = TransformationAddDeadContinue(40, true, {});
- ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager));
- transformation1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation1.IsApplicable(context.get(), transformation_context));
+ transformation1.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager));
- transformation2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation2.IsApplicable(context.get(), transformation_context));
+ transformation2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager));
- transformation3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation3.IsApplicable(context.get(), transformation_context));
+ transformation3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -365,19 +371,24 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
std::vector<uint32_t> good = {6, 7, 18, 20, 34, 40, 45, 46, 47, 56, 57};
std::vector<uint32_t> bad = {5, 8, 9, 19, 21, 22, 33, 41, 58, 59, 60};
for (uint32_t from_block : bad) {
ASSERT_FALSE(TransformationAddDeadContinue(from_block, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
}
for (uint32_t from_block : good) {
const TransformationAddDeadContinue transformation(from_block, true, {});
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
}
std::string after_transformation = R"(
@@ -600,19 +611,24 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
std::vector<uint32_t> good = {32, 33, 46, 52, 101};
std::vector<uint32_t> bad = {5, 34, 36, 35, 47, 49, 48};
for (uint32_t from_block : bad) {
ASSERT_FALSE(TransformationAddDeadContinue(from_block, false, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
}
for (uint32_t from_block : good) {
const TransformationAddDeadContinue transformation(from_block, false, {});
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
}
std::string after_transformation = R"(
@@ -806,6 +822,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
std::vector<uint32_t> bad = {5, 19, 20, 23, 31, 32, 33, 70};
@@ -813,24 +832,28 @@
for (uint32_t from_block : bad) {
ASSERT_FALSE(TransformationAddDeadContinue(from_block, true, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
}
auto transformation1 = TransformationAddDeadContinue(29, true, {13, 21});
- ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager));
- transformation1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation1.IsApplicable(context.get(), transformation_context));
+ transformation1.Apply(context.get(), &transformation_context);
auto transformation2 = TransformationAddDeadContinue(30, true, {22, 46});
- ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager));
- transformation2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation2.IsApplicable(context.get(), transformation_context));
+ transformation2.Apply(context.get(), &transformation_context);
// 75 already has the continue block as a successor, so we should not provide
// phi ids.
auto transformationBad = TransformationAddDeadContinue(75, true, {27, 46});
- ASSERT_FALSE(transformationBad.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ transformationBad.IsApplicable(context.get(), transformation_context));
auto transformation3 = TransformationAddDeadContinue(75, true, {});
- ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager));
- transformation3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation3.IsApplicable(context.get(), transformation_context));
+ transformation3.Apply(context.get(), &transformation_context);
std::string after_transformation = R"(
OpCapability Shader
@@ -974,26 +997,33 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// This transformation is not applicable because the dead continue from the
// loop body prevents the definition of %23 later in the loop body from
// dominating its use in the loop's continue target.
auto bad_transformation = TransformationAddDeadContinue(13, false, {});
- ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ bad_transformation.IsApplicable(context.get(), transformation_context));
auto good_transformation_1 = TransformationAddDeadContinue(7, false, {});
- ASSERT_TRUE(good_transformation_1.IsApplicable(context.get(), fact_manager));
- good_transformation_1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(good_transformation_1.IsApplicable(context.get(),
+ transformation_context));
+ good_transformation_1.Apply(context.get(), &transformation_context);
auto good_transformation_2 = TransformationAddDeadContinue(22, false, {});
- ASSERT_TRUE(good_transformation_2.IsApplicable(context.get(), fact_manager));
- good_transformation_2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(good_transformation_2.IsApplicable(context.get(),
+ transformation_context));
+ good_transformation_2.Apply(context.get(), &transformation_context);
// This transformation is OK, because the definition of %21 in the loop body
// is only used in an OpPhi in the loop's continue target.
auto good_transformation_3 = TransformationAddDeadContinue(6, false, {11});
- ASSERT_TRUE(good_transformation_3.IsApplicable(context.get(), fact_manager));
- good_transformation_3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(good_transformation_3.IsApplicable(context.get(),
+ transformation_context));
+ good_transformation_3.Apply(context.get(), &transformation_context);
std::string after_transformations = R"(
OpCapability Shader
@@ -1083,11 +1113,15 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// This transformation would shortcut the part of the loop body that defines
// an id used after the loop.
auto bad_transformation = TransformationAddDeadContinue(100, false, {});
- ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ bad_transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationAddDeadContinueTest, RespectDominanceRules3) {
@@ -1131,11 +1165,15 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// This transformation would shortcut the part of the loop body that defines
// an id used after the loop.
auto bad_transformation = TransformationAddDeadContinue(100, false, {});
- ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ bad_transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationAddDeadContinueTest, Miscellaneous1) {
@@ -1270,11 +1308,15 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// This transformation would shortcut the part of the loop body that defines
// an id used in the continue target.
auto bad_transformation = TransformationAddDeadContinue(165, false, {});
- ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ bad_transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationAddDeadContinueTest, Miscellaneous2) {
@@ -1336,11 +1378,15 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// This transformation would introduce a branch from a continue target to
// itself.
auto bad_transformation = TransformationAddDeadContinue(1554, true, {});
- ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ bad_transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationAddDeadContinueTest, Miscellaneous3) {
@@ -1394,13 +1440,17 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
auto bad_transformation = TransformationAddDeadContinue(299, false, {});
// The continue edge would connect %299 to the previously-unreachable %236,
// making %299 dominate %236, and breaking the rule that block ordering must
// respect dominance.
- ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ bad_transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationAddDeadContinueTest, Miscellaneous4) {
@@ -1454,13 +1504,17 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
auto bad_transformation = TransformationAddDeadContinue(10, false, {});
// The continue edge would connect %10 to the previously-unreachable %13,
// making %10 dominate %13, and breaking the rule that block ordering must
// respect dominance.
- ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ bad_transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationAddDeadContinueTest, Miscellaneous5) {
@@ -1506,12 +1560,16 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
auto bad_transformation = TransformationAddDeadContinue(110, true, {});
// The continue edge would lead to the use of %200 in block %101 no longer
// being dominated by its definition in block %111.
- ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ bad_transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationAddDeadContinueTest, Miscellaneous6) {
@@ -1551,10 +1609,14 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
auto bad_transformation = TransformationAddDeadContinue(10, true, {});
- ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ bad_transformation.IsApplicable(context.get(), transformation_context));
}
} // namespace
diff --git a/test/fuzz/transformation_add_function_test.cpp b/test/fuzz/transformation_add_function_test.cpp
index aed12dc..bbd915b 100644
--- a/test/fuzz/transformation_add_function_test.cpp
+++ b/test/fuzz/transformation_add_function_test.cpp
@@ -59,13 +59,14 @@
}
// Returns true if and only if every pointer parameter and variable associated
-// with |function_id| in |context| is known by |fact_manager| to be irrelevant,
-// with the exception of |loop_limiter_id|, which must not be irrelevant. (It
-// can be 0 if no loop limiter is expected, and 0 should not be deemed
-// irrelevant).
+// with |function_id| in |context| is known by |transformation_context| to be
+// irrelevant, with the exception of |loop_limiter_id|, which must not be
+// irrelevant. (It can be 0 if no loop limiter is expected, and 0 should not be
+// deemed irrelevant).
bool AllVariablesAndParametersExceptLoopLimiterAreIrrelevant(
- opt::IRContext* context, const FactManager& fact_manager,
- uint32_t function_id, uint32_t loop_limiter_id) {
+ opt::IRContext* context,
+ const TransformationContext& transformation_context, uint32_t function_id,
+ uint32_t loop_limiter_id) {
// Look at all the functions until the function of interest is found.
for (auto& function : *context->module()) {
if (function.result_id() != function_id) {
@@ -73,15 +74,16 @@
}
// Check that the parameters are all irrelevant.
bool found_non_irrelevant_parameter = false;
- function.ForEachParam(
- [context, &fact_manager,
- &found_non_irrelevant_parameter](opt::Instruction* inst) {
- if (context->get_def_use_mgr()->GetDef(inst->type_id())->opcode() ==
- SpvOpTypePointer &&
- !fact_manager.PointeeValueIsIrrelevant(inst->result_id())) {
- found_non_irrelevant_parameter = true;
- }
- });
+ function.ForEachParam([context, &transformation_context,
+ &found_non_irrelevant_parameter](
+ opt::Instruction* inst) {
+ if (context->get_def_use_mgr()->GetDef(inst->type_id())->opcode() ==
+ SpvOpTypePointer &&
+ !transformation_context.GetFactManager()->PointeeValueIsIrrelevant(
+ inst->result_id())) {
+ found_non_irrelevant_parameter = true;
+ }
+ });
if (found_non_irrelevant_parameter) {
// A non-irrelevant parameter was found.
return false;
@@ -96,7 +98,8 @@
// The variable should be irrelevant if and only if it is not the loop
// limiter.
if ((inst.result_id() == loop_limiter_id) ==
- fact_manager.PointeeValueIsIrrelevant(inst.result_id())) {
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(
+ inst.result_id())) {
return false;
}
}
@@ -142,6 +145,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationAddFunction transformation1(std::vector<protobufs::Instruction>(
{MakeInstructionMessage(
@@ -212,8 +218,9 @@
{{SPV_OPERAND_TYPE_ID, {39}}}),
MakeInstructionMessage(SpvOpFunctionEnd, 0, 0, {})}));
- ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager));
- transformation1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation1.IsApplicable(context.get(), transformation_context));
+ transformation1.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation1 = R"(
@@ -278,12 +285,12 @@
OpFunctionEnd
)";
ASSERT_TRUE(IsEqual(env, after_transformation1, context.get()));
- ASSERT_TRUE(fact_manager.BlockIsDead(14));
- ASSERT_TRUE(fact_manager.BlockIsDead(21));
- ASSERT_TRUE(fact_manager.BlockIsDead(22));
- ASSERT_TRUE(fact_manager.BlockIsDead(23));
- ASSERT_TRUE(fact_manager.BlockIsDead(24));
- ASSERT_TRUE(fact_manager.BlockIsDead(25));
+ ASSERT_TRUE(transformation_context.GetFactManager()->BlockIsDead(14));
+ ASSERT_TRUE(transformation_context.GetFactManager()->BlockIsDead(21));
+ ASSERT_TRUE(transformation_context.GetFactManager()->BlockIsDead(22));
+ ASSERT_TRUE(transformation_context.GetFactManager()->BlockIsDead(23));
+ ASSERT_TRUE(transformation_context.GetFactManager()->BlockIsDead(24));
+ ASSERT_TRUE(transformation_context.GetFactManager()->BlockIsDead(25));
TransformationAddFunction transformation2(std::vector<protobufs::Instruction>(
{MakeInstructionMessage(
@@ -332,8 +339,9 @@
MakeInstructionMessage(SpvOpReturn, 0, 0, {}),
MakeInstructionMessage(SpvOpFunctionEnd, 0, 0, {})}));
- ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager));
- transformation2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation2.IsApplicable(context.get(), transformation_context));
+ transformation2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation2 = R"(
@@ -414,7 +422,7 @@
OpFunctionEnd
)";
ASSERT_TRUE(IsEqual(env, after_transformation2, context.get()));
- ASSERT_TRUE(fact_manager.BlockIsDead(16));
+ ASSERT_TRUE(transformation_context.GetFactManager()->BlockIsDead(16));
}
TEST(TransformationAddFunctionTest, InapplicableTransformations) {
@@ -486,11 +494,14 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// No instructions
ASSERT_FALSE(
TransformationAddFunction(std::vector<protobufs::Instruction>({}))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// No function begin
ASSERT_FALSE(
@@ -499,7 +510,7 @@
{MakeInstructionMessage(SpvOpFunctionParameter, 7, 11, {}),
MakeInstructionMessage(SpvOpFunctionParameter, 9, 12, {}),
MakeInstructionMessage(SpvOpLabel, 0, 14, {})}))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// No OpLabel
ASSERT_FALSE(
@@ -512,7 +523,7 @@
MakeInstructionMessage(SpvOpReturnValue, 0, 0,
{{SPV_OPERAND_TYPE_ID, {39}}}),
MakeInstructionMessage(SpvOpFunctionEnd, 0, 0, {})}))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Abrupt end of instructions
ASSERT_FALSE(TransformationAddFunction(
@@ -521,7 +532,7 @@
{{SPV_OPERAND_TYPE_FUNCTION_CONTROL,
{SpvFunctionControlMaskNone}},
{SPV_OPERAND_TYPE_ID, {10}}})}))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// No function end
ASSERT_FALSE(
@@ -534,7 +545,7 @@
MakeInstructionMessage(SpvOpLabel, 0, 14, {}),
MakeInstructionMessage(SpvOpReturnValue, 0, 0,
{{SPV_OPERAND_TYPE_ID, {39}}})}))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
}
TEST(TransformationAddFunctionTest, LoopLimiters) {
@@ -622,20 +633,27 @@
FactManager fact_manager1;
FactManager fact_manager2;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context1(&fact_manager1,
+ validator_options);
+ TransformationContext transformation_context2(&fact_manager2,
+ validator_options);
const auto context1 = BuildModule(env, consumer, shader, kFuzzAssembleOption);
const auto context2 = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context1.get()));
TransformationAddFunction add_dead_function(instructions);
- ASSERT_TRUE(add_dead_function.IsApplicable(context1.get(), fact_manager1));
- add_dead_function.Apply(context1.get(), &fact_manager1);
+ ASSERT_TRUE(
+ add_dead_function.IsApplicable(context1.get(), transformation_context1));
+ add_dead_function.Apply(context1.get(), &transformation_context1);
ASSERT_TRUE(IsValid(env, context1.get()));
// The added function should not be deemed livesafe.
- ASSERT_FALSE(fact_manager1.FunctionIsLivesafe(30));
+ ASSERT_FALSE(
+ transformation_context1.GetFactManager()->FunctionIsLivesafe(30));
// All variables/parameters in the function should be deemed irrelevant.
ASSERT_TRUE(AllVariablesAndParametersExceptLoopLimiterAreIrrelevant(
- context1.get(), fact_manager1, 30, 0));
+ context1.get(), transformation_context1, 30, 0));
std::string added_as_dead_code = R"(
OpCapability Shader
@@ -711,16 +729,16 @@
TransformationAddFunction add_livesafe_function(instructions, 100, 10,
loop_limiters, 0, {});
- ASSERT_TRUE(
- add_livesafe_function.IsApplicable(context2.get(), fact_manager2));
- add_livesafe_function.Apply(context2.get(), &fact_manager2);
+ ASSERT_TRUE(add_livesafe_function.IsApplicable(context2.get(),
+ transformation_context2));
+ add_livesafe_function.Apply(context2.get(), &transformation_context2);
ASSERT_TRUE(IsValid(env, context2.get()));
// The added function should indeed be deemed livesafe.
- ASSERT_TRUE(fact_manager2.FunctionIsLivesafe(30));
+ ASSERT_TRUE(transformation_context2.GetFactManager()->FunctionIsLivesafe(30));
// All variables/parameters in the function should be deemed irrelevant,
// except the loop limiter.
ASSERT_TRUE(AllVariablesAndParametersExceptLoopLimiterAreIrrelevant(
- context2.get(), fact_manager2, 30, 100));
+ context2.get(), transformation_context2, 30, 100));
std::string added_as_livesafe_code = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
@@ -837,20 +855,27 @@
FactManager fact_manager1;
FactManager fact_manager2;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context1(&fact_manager1,
+ validator_options);
+ TransformationContext transformation_context2(&fact_manager2,
+ validator_options);
const auto context1 = BuildModule(env, consumer, shader, kFuzzAssembleOption);
const auto context2 = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context1.get()));
TransformationAddFunction add_dead_function(instructions);
- ASSERT_TRUE(add_dead_function.IsApplicable(context1.get(), fact_manager1));
- add_dead_function.Apply(context1.get(), &fact_manager1);
+ ASSERT_TRUE(
+ add_dead_function.IsApplicable(context1.get(), transformation_context1));
+ add_dead_function.Apply(context1.get(), &transformation_context1);
ASSERT_TRUE(IsValid(env, context1.get()));
// The added function should not be deemed livesafe.
- ASSERT_FALSE(fact_manager1.FunctionIsLivesafe(10));
+ ASSERT_FALSE(
+ transformation_context1.GetFactManager()->FunctionIsLivesafe(10));
// All variables/parameters in the function should be deemed irrelevant.
ASSERT_TRUE(AllVariablesAndParametersExceptLoopLimiterAreIrrelevant(
- context1.get(), fact_manager1, 10, 0));
+ context1.get(), transformation_context1, 10, 0));
std::string added_as_dead_code = R"(
OpCapability Shader
@@ -887,15 +912,15 @@
TransformationAddFunction add_livesafe_function(instructions, 0, 0, {}, 0,
{});
- ASSERT_TRUE(
- add_livesafe_function.IsApplicable(context2.get(), fact_manager2));
- add_livesafe_function.Apply(context2.get(), &fact_manager2);
+ ASSERT_TRUE(add_livesafe_function.IsApplicable(context2.get(),
+ transformation_context2));
+ add_livesafe_function.Apply(context2.get(), &transformation_context2);
ASSERT_TRUE(IsValid(env, context2.get()));
// The added function should indeed be deemed livesafe.
- ASSERT_TRUE(fact_manager2.FunctionIsLivesafe(10));
+ ASSERT_TRUE(transformation_context2.GetFactManager()->FunctionIsLivesafe(10));
// All variables/parameters in the function should be deemed irrelevant.
ASSERT_TRUE(AllVariablesAndParametersExceptLoopLimiterAreIrrelevant(
- context2.get(), fact_manager2, 10, 0));
+ context2.get(), transformation_context2, 10, 0));
std::string added_as_livesafe_code = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
@@ -985,20 +1010,27 @@
FactManager fact_manager1;
FactManager fact_manager2;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context1(&fact_manager1,
+ validator_options);
+ TransformationContext transformation_context2(&fact_manager2,
+ validator_options);
const auto context1 = BuildModule(env, consumer, shader, kFuzzAssembleOption);
const auto context2 = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context1.get()));
TransformationAddFunction add_dead_function(instructions);
- ASSERT_TRUE(add_dead_function.IsApplicable(context1.get(), fact_manager1));
- add_dead_function.Apply(context1.get(), &fact_manager1);
+ ASSERT_TRUE(
+ add_dead_function.IsApplicable(context1.get(), transformation_context1));
+ add_dead_function.Apply(context1.get(), &transformation_context1);
ASSERT_TRUE(IsValid(env, context1.get()));
// The added function should not be deemed livesafe.
- ASSERT_FALSE(fact_manager1.FunctionIsLivesafe(10));
+ ASSERT_FALSE(
+ transformation_context1.GetFactManager()->FunctionIsLivesafe(10));
// All variables/parameters in the function should be deemed irrelevant.
ASSERT_TRUE(AllVariablesAndParametersExceptLoopLimiterAreIrrelevant(
- context1.get(), fact_manager1, 10, 0));
+ context1.get(), transformation_context1, 10, 0));
std::string added_as_dead_code = R"(
OpCapability Shader
@@ -1036,15 +1068,15 @@
TransformationAddFunction add_livesafe_function(instructions, 0, 0, {}, 13,
{});
- ASSERT_TRUE(
- add_livesafe_function.IsApplicable(context2.get(), fact_manager2));
- add_livesafe_function.Apply(context2.get(), &fact_manager2);
+ ASSERT_TRUE(add_livesafe_function.IsApplicable(context2.get(),
+ transformation_context2));
+ add_livesafe_function.Apply(context2.get(), &transformation_context2);
ASSERT_TRUE(IsValid(env, context2.get()));
// The added function should indeed be deemed livesafe.
- ASSERT_TRUE(fact_manager2.FunctionIsLivesafe(10));
+ ASSERT_TRUE(transformation_context2.GetFactManager()->FunctionIsLivesafe(10));
// All variables/parameters in the function should be deemed irrelevant.
ASSERT_TRUE(AllVariablesAndParametersExceptLoopLimiterAreIrrelevant(
- context2.get(), fact_manager2, 10, 0));
+ context2.get(), transformation_context2, 10, 0));
std::string added_as_livesafe_code = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
@@ -1265,20 +1297,27 @@
FactManager fact_manager1;
FactManager fact_manager2;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context1(&fact_manager1,
+ validator_options);
+ TransformationContext transformation_context2(&fact_manager2,
+ validator_options);
const auto context1 = BuildModule(env, consumer, shader, kFuzzAssembleOption);
const auto context2 = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context1.get()));
TransformationAddFunction add_dead_function(instructions);
- ASSERT_TRUE(add_dead_function.IsApplicable(context1.get(), fact_manager1));
- add_dead_function.Apply(context1.get(), &fact_manager1);
+ ASSERT_TRUE(
+ add_dead_function.IsApplicable(context1.get(), transformation_context1));
+ add_dead_function.Apply(context1.get(), &transformation_context1);
ASSERT_TRUE(IsValid(env, context1.get()));
// The function should not be deemed livesafe
- ASSERT_FALSE(fact_manager1.FunctionIsLivesafe(12));
+ ASSERT_FALSE(
+ transformation_context1.GetFactManager()->FunctionIsLivesafe(12));
// All variables/parameters in the function should be deemed irrelevant.
ASSERT_TRUE(AllVariablesAndParametersExceptLoopLimiterAreIrrelevant(
- context1.get(), fact_manager1, 12, 0));
+ context1.get(), transformation_context1, 12, 0));
std::string added_as_dead_code = R"(
OpCapability Shader
@@ -1409,15 +1448,15 @@
TransformationAddFunction add_livesafe_function(instructions, 0, 0, {}, 13,
access_chain_clamping_info);
- ASSERT_TRUE(
- add_livesafe_function.IsApplicable(context2.get(), fact_manager2));
- add_livesafe_function.Apply(context2.get(), &fact_manager2);
+ ASSERT_TRUE(add_livesafe_function.IsApplicable(context2.get(),
+ transformation_context2));
+ add_livesafe_function.Apply(context2.get(), &transformation_context2);
ASSERT_TRUE(IsValid(env, context2.get()));
// The function should be deemed livesafe
- ASSERT_TRUE(fact_manager2.FunctionIsLivesafe(12));
+ ASSERT_TRUE(transformation_context2.GetFactManager()->FunctionIsLivesafe(12));
// All variables/parameters in the function should be deemed irrelevant.
ASSERT_TRUE(AllVariablesAndParametersExceptLoopLimiterAreIrrelevant(
- context2.get(), fact_manager2, 12, 0));
+ context2.get(), transformation_context2, 12, 0));
std::string added_as_livesafe_code = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
@@ -1585,23 +1624,29 @@
FactManager fact_manager1;
FactManager fact_manager2;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context1(&fact_manager1,
+ validator_options);
+ TransformationContext transformation_context2(&fact_manager2,
+ validator_options);
// Mark function 6 as livesafe.
- fact_manager2.AddFactFunctionIsLivesafe(6);
+ transformation_context2.GetFactManager()->AddFactFunctionIsLivesafe(6);
const auto context1 = BuildModule(env, consumer, shader, kFuzzAssembleOption);
const auto context2 = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context1.get()));
TransformationAddFunction add_dead_function(instructions);
- ASSERT_TRUE(add_dead_function.IsApplicable(context1.get(), fact_manager1));
- add_dead_function.Apply(context1.get(), &fact_manager1);
+ ASSERT_TRUE(
+ add_dead_function.IsApplicable(context1.get(), transformation_context1));
+ add_dead_function.Apply(context1.get(), &transformation_context1);
ASSERT_TRUE(IsValid(env, context1.get()));
// The function should not be deemed livesafe
- ASSERT_FALSE(fact_manager1.FunctionIsLivesafe(8));
+ ASSERT_FALSE(transformation_context1.GetFactManager()->FunctionIsLivesafe(8));
// All variables/parameters in the function should be deemed irrelevant.
ASSERT_TRUE(AllVariablesAndParametersExceptLoopLimiterAreIrrelevant(
- context1.get(), fact_manager1, 8, 0));
+ context1.get(), transformation_context1, 8, 0));
std::string added_as_live_or_dead_code = R"(
OpCapability Shader
@@ -1630,15 +1675,15 @@
TransformationAddFunction add_livesafe_function(instructions, 0, 0, {}, 0,
{});
- ASSERT_TRUE(
- add_livesafe_function.IsApplicable(context2.get(), fact_manager2));
- add_livesafe_function.Apply(context2.get(), &fact_manager2);
+ ASSERT_TRUE(add_livesafe_function.IsApplicable(context2.get(),
+ transformation_context2));
+ add_livesafe_function.Apply(context2.get(), &transformation_context2);
ASSERT_TRUE(IsValid(env, context2.get()));
// The function should be deemed livesafe
- ASSERT_TRUE(fact_manager2.FunctionIsLivesafe(8));
+ ASSERT_TRUE(transformation_context2.GetFactManager()->FunctionIsLivesafe(8));
// All variables/parameters in the function should be deemed irrelevant.
ASSERT_TRUE(AllVariablesAndParametersExceptLoopLimiterAreIrrelevant(
- context2.get(), fact_manager2, 8, 0));
+ context2.get(), transformation_context2, 8, 0));
ASSERT_TRUE(IsEqual(env, added_as_live_or_dead_code, context2.get()));
}
@@ -1679,20 +1724,26 @@
FactManager fact_manager1;
FactManager fact_manager2;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context1(&fact_manager1,
+ validator_options);
+ TransformationContext transformation_context2(&fact_manager2,
+ validator_options);
const auto context1 = BuildModule(env, consumer, shader, kFuzzAssembleOption);
const auto context2 = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context1.get()));
TransformationAddFunction add_dead_function(instructions);
- ASSERT_TRUE(add_dead_function.IsApplicable(context1.get(), fact_manager1));
- add_dead_function.Apply(context1.get(), &fact_manager1);
+ ASSERT_TRUE(
+ add_dead_function.IsApplicable(context1.get(), transformation_context1));
+ add_dead_function.Apply(context1.get(), &transformation_context1);
ASSERT_TRUE(IsValid(env, context1.get()));
// The function should not be deemed livesafe
- ASSERT_FALSE(fact_manager1.FunctionIsLivesafe(8));
+ ASSERT_FALSE(transformation_context1.GetFactManager()->FunctionIsLivesafe(8));
// All variables/parameters in the function should be deemed irrelevant.
ASSERT_TRUE(AllVariablesAndParametersExceptLoopLimiterAreIrrelevant(
- context1.get(), fact_manager1, 8, 0));
+ context1.get(), transformation_context1, 8, 0));
std::string added_as_dead_code = R"(
OpCapability Shader
@@ -1721,8 +1772,8 @@
TransformationAddFunction add_livesafe_function(instructions, 0, 0, {}, 0,
{});
- ASSERT_FALSE(
- add_livesafe_function.IsApplicable(context2.get(), fact_manager2));
+ ASSERT_FALSE(add_livesafe_function.IsApplicable(context2.get(),
+ transformation_context2));
}
TEST(TransformationAddFunctionTest,
@@ -1804,11 +1855,14 @@
const auto consumer = nullptr;
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context.get()));
- // Make a sequence of instruction messages corresponding to function %8 in
+ // Make a sequence of instruction messages corresponding to function %6 in
// |donor|.
std::vector<protobufs::Instruction> instructions =
GetInstructionsForFunction(env, consumer, donor, 6);
@@ -1821,8 +1875,9 @@
loop_limiter_info.set_logical_op_id(105);
TransformationAddFunction add_livesafe_function(instructions, 100, 32,
{loop_limiter_info}, 0, {});
- ASSERT_TRUE(add_livesafe_function.IsApplicable(context.get(), fact_manager));
- add_livesafe_function.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(add_livesafe_function.IsApplicable(context.get(),
+ transformation_context));
+ add_livesafe_function.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string expected = R"(
OpCapability Shader
@@ -1958,11 +2013,14 @@
const auto consumer = nullptr;
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context.get()));
- // Make a sequence of instruction messages corresponding to function %8 in
+ // Make a sequence of instruction messages corresponding to function %6 in
// |donor|.
std::vector<protobufs::Instruction> instructions =
GetInstructionsForFunction(env, consumer, donor, 6);
@@ -1975,8 +2033,9 @@
loop_limiter_info.set_logical_op_id(105);
TransformationAddFunction add_livesafe_function(instructions, 100, 32,
{loop_limiter_info}, 0, {});
- ASSERT_TRUE(add_livesafe_function.IsApplicable(context.get(), fact_manager));
- add_livesafe_function.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(add_livesafe_function.IsApplicable(context.get(),
+ transformation_context));
+ add_livesafe_function.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string expected = R"(
OpCapability Shader
@@ -2110,11 +2169,14 @@
const auto consumer = nullptr;
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context.get()));
- // Make a sequence of instruction messages corresponding to function %8 in
+ // Make a sequence of instruction messages corresponding to function %6 in
// |donor|.
std::vector<protobufs::Instruction> instructions =
GetInstructionsForFunction(env, consumer, donor, 6);
@@ -2127,8 +2189,9 @@
loop_limiter_info.set_logical_op_id(105);
TransformationAddFunction add_livesafe_function(instructions, 100, 32,
{loop_limiter_info}, 0, {});
- ASSERT_TRUE(add_livesafe_function.IsApplicable(context.get(), fact_manager));
- add_livesafe_function.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(add_livesafe_function.IsApplicable(context.get(),
+ transformation_context));
+ add_livesafe_function.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string expected = R"(
OpCapability Shader
@@ -2254,11 +2317,14 @@
const auto consumer = nullptr;
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context.get()));
- // Make a sequence of instruction messages corresponding to function %8 in
+ // Make a sequence of instruction messages corresponding to function %6 in
// |donor|.
std::vector<protobufs::Instruction> instructions =
GetInstructionsForFunction(env, consumer, donor, 6);
@@ -2271,8 +2337,9 @@
loop_limiter_info.set_logical_op_id(105);
TransformationAddFunction add_livesafe_function(instructions, 100, 32,
{loop_limiter_info}, 0, {});
- ASSERT_TRUE(add_livesafe_function.IsApplicable(context.get(), fact_manager));
- add_livesafe_function.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(add_livesafe_function.IsApplicable(context.get(),
+ transformation_context));
+ add_livesafe_function.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string expected = R"(
OpCapability Shader
@@ -2408,11 +2475,14 @@
const auto consumer = nullptr;
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context.get()));
- // Make a sequence of instruction messages corresponding to function %8 in
+ // Make a sequence of instruction messages corresponding to function %6 in
// |donor|.
std::vector<protobufs::Instruction> instructions =
GetInstructionsForFunction(env, consumer, donor, 6);
@@ -2425,8 +2495,9 @@
loop_limiter_info.set_logical_op_id(105);
TransformationAddFunction add_livesafe_function(instructions, 100, 32,
{loop_limiter_info}, 0, {});
- ASSERT_TRUE(add_livesafe_function.IsApplicable(context.get(), fact_manager));
- add_livesafe_function.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(add_livesafe_function.IsApplicable(context.get(),
+ transformation_context));
+ add_livesafe_function.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string expected = R"(
OpCapability Shader
@@ -2570,6 +2641,9 @@
const auto consumer = nullptr;
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context.get()));
@@ -2590,15 +2664,17 @@
{loop_limiter_info}, 0, {});
// The loop limiter info is not good enough; it does not include ids to patch
// up the OpPhi at the loop merge.
- ASSERT_FALSE(no_op_phi_data.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ no_op_phi_data.IsApplicable(context.get(), transformation_context));
// Add a phi id for the new edge from the loop back edge block to the loop
// merge.
loop_limiter_info.add_phi_id(28);
TransformationAddFunction with_op_phi_data(instructions, 100, 28,
{loop_limiter_info}, 0, {});
- ASSERT_TRUE(with_op_phi_data.IsApplicable(context.get(), fact_manager));
- with_op_phi_data.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ with_op_phi_data.IsApplicable(context.get(), transformation_context));
+ with_op_phi_data.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string expected = R"(
OpCapability Shader
@@ -2758,6 +2834,9 @@
const auto consumer = nullptr;
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context.get()));
@@ -2776,8 +2855,9 @@
TransformationAddFunction transformation(instructions, 100, 28,
{loop_limiter_info}, 0, {});
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string expected = R"(
OpCapability Shader
@@ -2845,6 +2925,120 @@
ASSERT_TRUE(IsEqual(env, expected, context.get()));
}
+TEST(TransformationAddFunctionTest, StaticallyOutOfBoundsArrayAccess) {
+ std::string shader = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main"
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %8 = OpTypeInt 32 1
+ %9 = OpTypeInt 32 0
+ %10 = OpConstant %9 3
+ %11 = OpTypeArray %8 %10
+ %12 = OpTypePointer Private %11
+ %13 = OpVariable %12 Private
+ %14 = OpConstant %8 3
+ %20 = OpConstant %8 2
+ %15 = OpConstant %8 1
+ %21 = OpTypeBool
+ %16 = OpTypePointer Private %8
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ std::string donor = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main"
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %8 = OpTypeInt 32 1
+ %9 = OpTypeInt 32 0
+ %10 = OpConstant %9 3
+ %11 = OpTypeArray %8 %10
+ %12 = OpTypePointer Private %11
+ %13 = OpVariable %12 Private
+ %14 = OpConstant %8 3
+ %15 = OpConstant %8 1
+ %16 = OpTypePointer Private %8
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ %6 = OpFunction %2 None %3
+ %7 = OpLabel
+ %17 = OpAccessChain %16 %13 %14
+ OpStore %17 %15
+ OpReturn
+ OpFunctionEnd
+ )";
+ const auto env = SPV_ENV_UNIVERSAL_1_4;
+ const auto consumer = nullptr;
+
+ FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, context.get()));
+
+ // Make a sequence of instruction messages corresponding to function %6 in
+ // |donor|.
+ std::vector<protobufs::Instruction> instructions =
+ GetInstructionsForFunction(env, consumer, donor, 6);
+
+ TransformationAddFunction add_livesafe_function(
+ instructions, 0, 0, {}, 0, {MakeAccessClampingInfo(17, {{100, 101}})});
+ ASSERT_TRUE(add_livesafe_function.IsApplicable(context.get(),
+ transformation_context));
+ add_livesafe_function.Apply(context.get(), &transformation_context);
+ ASSERT_TRUE(IsValid(env, context.get()));
+ std::string expected = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main"
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %8 = OpTypeInt 32 1
+ %9 = OpTypeInt 32 0
+ %10 = OpConstant %9 3
+ %11 = OpTypeArray %8 %10
+ %12 = OpTypePointer Private %11
+ %13 = OpVariable %12 Private
+ %14 = OpConstant %8 3
+ %20 = OpConstant %8 2
+ %15 = OpConstant %8 1
+ %21 = OpTypeBool
+ %16 = OpTypePointer Private %8
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ %6 = OpFunction %2 None %3
+ %7 = OpLabel
+ %100 = OpULessThanEqual %21 %14 %20
+ %101 = OpSelect %8 %100 %14 %20
+ %17 = OpAccessChain %16 %13 %101
+ OpStore %17 %15
+ OpReturn
+ OpFunctionEnd
+ )";
+ ASSERT_TRUE(IsEqual(env, expected, context.get()));
+}
+
} // namespace
} // namespace fuzz
} // namespace spvtools
diff --git a/test/fuzz/transformation_add_global_undef_test.cpp b/test/fuzz/transformation_add_global_undef_test.cpp
index c14f7e9..8c06db0 100644
--- a/test/fuzz/transformation_add_global_undef_test.cpp
+++ b/test/fuzz/transformation_add_global_undef_test.cpp
@@ -47,17 +47,20 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Id already in use
- ASSERT_FALSE(TransformationAddGlobalUndef(4, 11).IsApplicable(context.get(),
- fact_manager));
+ ASSERT_FALSE(TransformationAddGlobalUndef(4, 11).IsApplicable(
+ context.get(), transformation_context));
// %1 is not a type
- ASSERT_FALSE(TransformationAddGlobalUndef(100, 1).IsApplicable(context.get(),
- fact_manager));
+ ASSERT_FALSE(TransformationAddGlobalUndef(100, 1).IsApplicable(
+ context.get(), transformation_context));
// %3 is a function type
- ASSERT_FALSE(TransformationAddGlobalUndef(100, 3).IsApplicable(context.get(),
- fact_manager));
+ ASSERT_FALSE(TransformationAddGlobalUndef(100, 3).IsApplicable(
+ context.get(), transformation_context));
TransformationAddGlobalUndef transformations[] = {
// %100 = OpUndef %6
@@ -79,8 +82,9 @@
TransformationAddGlobalUndef(105, 11)};
for (auto& transformation : transformations) {
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
}
ASSERT_TRUE(IsValid(env, context.get()));
diff --git a/test/fuzz/transformation_add_global_variable_test.cpp b/test/fuzz/transformation_add_global_variable_test.cpp
index 619f068..5c74ca0 100644
--- a/test/fuzz/transformation_add_global_variable_test.cpp
+++ b/test/fuzz/transformation_add_global_variable_test.cpp
@@ -60,79 +60,105 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Id already in use
- ASSERT_FALSE(TransformationAddGlobalVariable(4, 10, 0, true)
- .IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ TransformationAddGlobalVariable(4, 10, SpvStorageClassPrivate, 0, true)
+ .IsApplicable(context.get(), transformation_context));
// %1 is not a type
- ASSERT_FALSE(TransformationAddGlobalVariable(100, 1, 0, false)
- .IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ TransformationAddGlobalVariable(100, 1, SpvStorageClassPrivate, 0, false)
+ .IsApplicable(context.get(), transformation_context));
// %7 is not a pointer type
- ASSERT_FALSE(TransformationAddGlobalVariable(100, 7, 0, true)
- .IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ TransformationAddGlobalVariable(100, 7, SpvStorageClassPrivate, 0, true)
+ .IsApplicable(context.get(), transformation_context));
// %9 does not have Private storage class
- ASSERT_FALSE(TransformationAddGlobalVariable(100, 9, 0, false)
- .IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ TransformationAddGlobalVariable(100, 9, SpvStorageClassPrivate, 0, false)
+ .IsApplicable(context.get(), transformation_context));
// %15 does not have Private storage class
- ASSERT_FALSE(TransformationAddGlobalVariable(100, 15, 0, true)
- .IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ TransformationAddGlobalVariable(100, 15, SpvStorageClassPrivate, 0, true)
+ .IsApplicable(context.get(), transformation_context));
// %10 is a pointer to float, while %16 is an int constant
- ASSERT_FALSE(TransformationAddGlobalVariable(100, 10, 16, false)
- .IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(TransformationAddGlobalVariable(100, 10, SpvStorageClassPrivate,
+ 16, false)
+ .IsApplicable(context.get(), transformation_context));
// %10 is a Private pointer to float, while %15 is a variable with type
// Uniform float pointer
- ASSERT_FALSE(TransformationAddGlobalVariable(100, 10, 15, true)
- .IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ TransformationAddGlobalVariable(100, 10, SpvStorageClassPrivate, 15, true)
+ .IsApplicable(context.get(), transformation_context));
// %12 is a Private pointer to int, while %10 is a variable with type
// Private float pointer
- ASSERT_FALSE(TransformationAddGlobalVariable(100, 12, 10, false)
- .IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(TransformationAddGlobalVariable(100, 12, SpvStorageClassPrivate,
+ 10, false)
+ .IsApplicable(context.get(), transformation_context));
// %10 is pointer-to-float, and %14 has type pointer-to-float; that's not OK
// since the initializer's type should be the *pointee* type.
- ASSERT_FALSE(TransformationAddGlobalVariable(104, 10, 14, true)
- .IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ TransformationAddGlobalVariable(104, 10, SpvStorageClassPrivate, 14, true)
+ .IsApplicable(context.get(), transformation_context));
// This would work in principle, but logical addressing does not allow
// a pointer to a pointer.
- ASSERT_FALSE(TransformationAddGlobalVariable(104, 17, 14, false)
- .IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(TransformationAddGlobalVariable(104, 17, SpvStorageClassPrivate,
+ 14, false)
+ .IsApplicable(context.get(), transformation_context));
TransformationAddGlobalVariable transformations[] = {
// %100 = OpVariable %12 Private
- TransformationAddGlobalVariable(100, 12, 16, true),
+ TransformationAddGlobalVariable(100, 12, SpvStorageClassPrivate, 16,
+ true),
// %101 = OpVariable %10 Private
- TransformationAddGlobalVariable(101, 10, 40, false),
+ TransformationAddGlobalVariable(101, 10, SpvStorageClassPrivate, 40,
+ false),
// %102 = OpVariable %13 Private
- TransformationAddGlobalVariable(102, 13, 41, true),
+ TransformationAddGlobalVariable(102, 13, SpvStorageClassPrivate, 41,
+ true),
// %103 = OpVariable %12 Private %16
- TransformationAddGlobalVariable(103, 12, 16, false),
+ TransformationAddGlobalVariable(103, 12, SpvStorageClassPrivate, 16,
+ false),
// %104 = OpVariable %19 Private %21
- TransformationAddGlobalVariable(104, 19, 21, true),
+ TransformationAddGlobalVariable(104, 19, SpvStorageClassPrivate, 21,
+ true),
// %105 = OpVariable %19 Private %22
- TransformationAddGlobalVariable(105, 19, 22, false)};
+ TransformationAddGlobalVariable(105, 19, SpvStorageClassPrivate, 22,
+ false)};
for (auto& transformation : transformations) {
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
}
- ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(100));
- ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(102));
- ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(104));
- ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(101));
- ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(103));
- ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(105));
+ ASSERT_TRUE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(100));
+ ASSERT_TRUE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(102));
+ ASSERT_TRUE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(104));
+ ASSERT_FALSE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(101));
+ ASSERT_FALSE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(103));
+ ASSERT_FALSE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(105));
ASSERT_TRUE(IsValid(env, context.get()));
@@ -223,24 +249,34 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationAddGlobalVariable transformations[] = {
// %100 = OpVariable %12 Private
- TransformationAddGlobalVariable(100, 12, 16, true),
+ TransformationAddGlobalVariable(100, 12, SpvStorageClassPrivate, 16,
+ true),
// %101 = OpVariable %12 Private %16
- TransformationAddGlobalVariable(101, 12, 16, false),
+ TransformationAddGlobalVariable(101, 12, SpvStorageClassPrivate, 16,
+ false),
// %102 = OpVariable %19 Private %21
- TransformationAddGlobalVariable(102, 19, 21, true)};
+ TransformationAddGlobalVariable(102, 19, SpvStorageClassPrivate, 21,
+ true)};
for (auto& transformation : transformations) {
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
}
- ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(100));
- ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(102));
- ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(101));
+ ASSERT_TRUE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(100));
+ ASSERT_TRUE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(102));
+ ASSERT_FALSE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(101));
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -284,6 +320,85 @@
ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
}
+TEST(TransformationAddGlobalVariableTest, TestAddingWorkgroupGlobals) {
+ // This checks that workgroup globals can be added to a compute shader.
+ std::string shader = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %4 "main"
+ OpExecutionMode %4 LocalSize 1 1 1
+ OpSource ESSL 310
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeInt 32 1
+ %7 = OpTypePointer Workgroup %6
+ %50 = OpConstant %6 2
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ const auto env = SPV_ENV_UNIVERSAL_1_4;
+ const auto consumer = nullptr;
+ const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, context.get()));
+
+ FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+#ifndef NDEBUG
+ ASSERT_DEATH(
+ TransformationAddGlobalVariable(8, 7, SpvStorageClassWorkgroup, 50, true)
+ .IsApplicable(context.get(), transformation_context),
+ "By construction this transformation should not have an.*initializer "
+ "when Workgroup storage class is used");
+#endif
+
+ TransformationAddGlobalVariable transformations[] = {
+ // %8 = OpVariable %7 Workgroup
+ TransformationAddGlobalVariable(8, 7, SpvStorageClassWorkgroup, 0, true),
+
+ // %10 = OpVariable %7 Workgroup
+ TransformationAddGlobalVariable(10, 7, SpvStorageClassWorkgroup, 0,
+ false)};
+
+ for (auto& transformation : transformations) {
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
+ }
+ ASSERT_TRUE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(8));
+ ASSERT_FALSE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(10));
+ ASSERT_TRUE(IsValid(env, context.get()));
+
+ std::string after_transformation = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %4 "main" %8 %10
+ OpExecutionMode %4 LocalSize 1 1 1
+ OpSource ESSL 310
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeInt 32 1
+ %7 = OpTypePointer Workgroup %6
+ %50 = OpConstant %6 2
+ %8 = OpVariable %7 Workgroup
+ %10 = OpVariable %7 Workgroup
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
+}
+
} // namespace
} // namespace fuzz
} // namespace spvtools
diff --git a/test/fuzz/transformation_add_local_variable_test.cpp b/test/fuzz/transformation_add_local_variable_test.cpp
index fd7047f..e989b33 100644
--- a/test/fuzz/transformation_add_local_variable_test.cpp
+++ b/test/fuzz/transformation_add_local_variable_test.cpp
@@ -79,66 +79,81 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// A few cases of inapplicable transformations:
// Id 4 is already in use
ASSERT_FALSE(TransformationAddLocalVariable(4, 50, 4, 51, true)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Type mismatch between initializer and pointer
ASSERT_FALSE(TransformationAddLocalVariable(105, 46, 4, 51, true)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Id 5 is not a function
ASSERT_FALSE(TransformationAddLocalVariable(105, 50, 5, 51, true)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// %105 = OpVariable %50 Function %51
{
TransformationAddLocalVariable transformation(105, 50, 4, 51, true);
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
}
// %104 = OpVariable %41 Function %46
{
TransformationAddLocalVariable transformation(104, 41, 4, 46, false);
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
}
// %103 = OpVariable %35 Function %38
{
TransformationAddLocalVariable transformation(103, 35, 4, 38, true);
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
}
// %102 = OpVariable %31 Function %33
{
TransformationAddLocalVariable transformation(102, 31, 4, 33, false);
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
}
// %101 = OpVariable %19 Function %29
{
TransformationAddLocalVariable transformation(101, 19, 4, 29, true);
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
}
// %100 = OpVariable %8 Function %12
{
TransformationAddLocalVariable transformation(100, 8, 4, 12, false);
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
}
- ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(100));
- ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(101));
- ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(102));
- ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(103));
- ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(104));
- ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(105));
+ ASSERT_FALSE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(100));
+ ASSERT_TRUE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(101));
+ ASSERT_FALSE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(102));
+ ASSERT_TRUE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(103));
+ ASSERT_FALSE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(104));
+ ASSERT_TRUE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(105));
std::string after_transformation = R"(
OpCapability Shader
diff --git a/test/fuzz/transformation_add_no_contraction_decoration_test.cpp b/test/fuzz/transformation_add_no_contraction_decoration_test.cpp
index b1a87ea..46841a5 100644
--- a/test/fuzz/transformation_add_no_contraction_decoration_test.cpp
+++ b/test/fuzz/transformation_add_no_contraction_decoration_test.cpp
@@ -94,23 +94,27 @@
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Invalid: 200 is not an id
ASSERT_FALSE(TransformationAddNoContractionDecoration(200).IsApplicable(
- context.get(), fact_manager));
+ context.get(), transformation_context));
// Invalid: 17 is a block id
ASSERT_FALSE(TransformationAddNoContractionDecoration(17).IsApplicable(
- context.get(), fact_manager));
+ context.get(), transformation_context));
// Invalid: 24 is not arithmetic
ASSERT_FALSE(TransformationAddNoContractionDecoration(24).IsApplicable(
- context.get(), fact_manager));
+ context.get(), transformation_context));
// It is valid to add NoContraction to each of these ids (and it's fine to
// have duplicates of the decoration, in the case of 32).
for (uint32_t result_id : {32u, 32u, 27u, 29u, 39u}) {
TransformationAddNoContractionDecoration transformation(result_id);
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
}
diff --git a/test/fuzz/transformation_add_type_array_test.cpp b/test/fuzz/transformation_add_type_array_test.cpp
index 2bcbe73..4392f99 100644
--- a/test/fuzz/transformation_add_type_array_test.cpp
+++ b/test/fuzz/transformation_add_type_array_test.cpp
@@ -54,37 +54,40 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Id already in use
ASSERT_FALSE(TransformationAddTypeArray(4, 10, 16).IsApplicable(
- context.get(), fact_manager));
+ context.get(), transformation_context));
// %1 is not a type
ASSERT_FALSE(TransformationAddTypeArray(100, 1, 16)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// %3 is a function type
ASSERT_FALSE(TransformationAddTypeArray(100, 3, 16)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// %2 is not a constant
ASSERT_FALSE(TransformationAddTypeArray(100, 11, 2)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// %18 is not an integer
ASSERT_FALSE(TransformationAddTypeArray(100, 11, 18)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// %13 is signed 0
ASSERT_FALSE(TransformationAddTypeArray(100, 11, 13)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// %14 is negative
ASSERT_FALSE(TransformationAddTypeArray(100, 11, 14)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// %17 is unsigned 0
ASSERT_FALSE(TransformationAddTypeArray(100, 11, 17)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
TransformationAddTypeArray transformations[] = {
// %100 = OpTypeArray %10 %16
@@ -94,8 +97,9 @@
TransformationAddTypeArray(101, 7, 12)};
for (auto& transformation : transformations) {
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
}
ASSERT_TRUE(IsValid(env, context.get()));
diff --git a/test/fuzz/transformation_add_type_boolean_test.cpp b/test/fuzz/transformation_add_type_boolean_test.cpp
index 9975953..60eabd9 100644
--- a/test/fuzz/transformation_add_type_boolean_test.cpp
+++ b/test/fuzz/transformation_add_type_boolean_test.cpp
@@ -42,19 +42,23 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Not applicable because id 1 is already in use.
- ASSERT_FALSE(TransformationAddTypeBoolean(1).IsApplicable(context.get(),
- fact_manager));
+ ASSERT_FALSE(TransformationAddTypeBoolean(1).IsApplicable(
+ context.get(), transformation_context));
auto add_type_bool = TransformationAddTypeBoolean(100);
- ASSERT_TRUE(add_type_bool.IsApplicable(context.get(), fact_manager));
- add_type_bool.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ add_type_bool.IsApplicable(context.get(), transformation_context));
+ add_type_bool.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Not applicable as we already have this type now.
- ASSERT_FALSE(TransformationAddTypeBoolean(101).IsApplicable(context.get(),
- fact_manager));
+ ASSERT_FALSE(TransformationAddTypeBoolean(101).IsApplicable(
+ context.get(), transformation_context));
std::string after_transformation = R"(
OpCapability Shader
diff --git a/test/fuzz/transformation_add_type_float_test.cpp b/test/fuzz/transformation_add_type_float_test.cpp
index 67408da..7d17266 100644
--- a/test/fuzz/transformation_add_type_float_test.cpp
+++ b/test/fuzz/transformation_add_type_float_test.cpp
@@ -42,19 +42,23 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Not applicable because id 1 is already in use.
- ASSERT_FALSE(TransformationAddTypeFloat(1, 32).IsApplicable(context.get(),
- fact_manager));
+ ASSERT_FALSE(TransformationAddTypeFloat(1, 32).IsApplicable(
+ context.get(), transformation_context));
auto add_type_float_32 = TransformationAddTypeFloat(100, 32);
- ASSERT_TRUE(add_type_float_32.IsApplicable(context.get(), fact_manager));
- add_type_float_32.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ add_type_float_32.IsApplicable(context.get(), transformation_context));
+ add_type_float_32.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Not applicable as we already have this type now.
- ASSERT_FALSE(TransformationAddTypeFloat(101, 32).IsApplicable(context.get(),
- fact_manager));
+ ASSERT_FALSE(TransformationAddTypeFloat(101, 32).IsApplicable(
+ context.get(), transformation_context));
std::string after_transformation = R"(
OpCapability Shader
diff --git a/test/fuzz/transformation_add_type_function_test.cpp b/test/fuzz/transformation_add_type_function_test.cpp
index 46bd436..1557bb8 100644
--- a/test/fuzz/transformation_add_type_function_test.cpp
+++ b/test/fuzz/transformation_add_type_function_test.cpp
@@ -59,21 +59,24 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Id already in use
ASSERT_FALSE(TransformationAddTypeFunction(4, 12, {12, 16, 14})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// %1 is not a type
ASSERT_FALSE(TransformationAddTypeFunction(100, 1, {12, 16, 14})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// %18 is a function type
ASSERT_FALSE(TransformationAddTypeFunction(100, 12, {18})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// A function of this signature already exists
ASSERT_FALSE(TransformationAddTypeFunction(100, 17, {14, 16})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
TransformationAddTypeFunction transformations[] = {
// %100 = OpTypeFunction %12 %12 %16 %14
@@ -86,8 +89,9 @@
TransformationAddTypeFunction(102, 17, {200, 16})};
for (auto& transformation : transformations) {
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
}
ASSERT_TRUE(IsValid(env, context.get()));
diff --git a/test/fuzz/transformation_add_type_int_test.cpp b/test/fuzz/transformation_add_type_int_test.cpp
index c6f884c..63b17c2 100644
--- a/test/fuzz/transformation_add_type_int_test.cpp
+++ b/test/fuzz/transformation_add_type_int_test.cpp
@@ -42,10 +42,13 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Not applicable because id 1 is already in use.
ASSERT_FALSE(TransformationAddTypeInt(1, 32, false)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
auto add_type_signed_int_32 = TransformationAddTypeInt(100, 32, true);
auto add_type_unsigned_int_32 = TransformationAddTypeInt(101, 32, false);
@@ -53,20 +56,21 @@
auto add_type_unsigned_int_32_again =
TransformationAddTypeInt(103, 32, false);
- ASSERT_TRUE(add_type_signed_int_32.IsApplicable(context.get(), fact_manager));
- add_type_signed_int_32.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(add_type_signed_int_32.IsApplicable(context.get(),
+ transformation_context));
+ add_type_signed_int_32.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(
- add_type_unsigned_int_32.IsApplicable(context.get(), fact_manager));
- add_type_unsigned_int_32.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(add_type_unsigned_int_32.IsApplicable(context.get(),
+ transformation_context));
+ add_type_unsigned_int_32.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Not applicable as we already have these types now.
- ASSERT_FALSE(
- add_type_signed_int_32_again.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(
- add_type_unsigned_int_32_again.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(add_type_signed_int_32_again.IsApplicable(
+ context.get(), transformation_context));
+ ASSERT_FALSE(add_type_unsigned_int_32_again.IsApplicable(
+ context.get(), transformation_context));
std::string after_transformation = R"(
OpCapability Shader
diff --git a/test/fuzz/transformation_add_type_matrix_test.cpp b/test/fuzz/transformation_add_type_matrix_test.cpp
index 84f27e9..e925012 100644
--- a/test/fuzz/transformation_add_type_matrix_test.cpp
+++ b/test/fuzz/transformation_add_type_matrix_test.cpp
@@ -47,17 +47,20 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Id already in use
- ASSERT_FALSE(TransformationAddTypeMatrix(4, 9, 2).IsApplicable(context.get(),
- fact_manager));
+ ASSERT_FALSE(TransformationAddTypeMatrix(4, 9, 2).IsApplicable(
+ context.get(), transformation_context));
// %1 is not a type
ASSERT_FALSE(TransformationAddTypeMatrix(100, 1, 2).IsApplicable(
- context.get(), fact_manager));
+ context.get(), transformation_context));
// %11 is not a floating-point vector
ASSERT_FALSE(TransformationAddTypeMatrix(100, 11, 2)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
TransformationAddTypeMatrix transformations[] = {
// %100 = OpTypeMatrix %8 2
@@ -88,8 +91,9 @@
TransformationAddTypeMatrix(108, 10, 4)};
for (auto& transformation : transformations) {
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
}
ASSERT_TRUE(IsValid(env, context.get()));
diff --git a/test/fuzz/transformation_add_type_pointer_test.cpp b/test/fuzz/transformation_add_type_pointer_test.cpp
index e36707f..35303e4 100644
--- a/test/fuzz/transformation_add_type_pointer_test.cpp
+++ b/test/fuzz/transformation_add_type_pointer_test.cpp
@@ -97,6 +97,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
auto bad_type_id_does_not_exist =
TransformationAddTypePointer(100, SpvStorageClassFunction, 101);
@@ -122,12 +125,12 @@
auto good_new_private_pointer_to_uniform_pointer_to_vec2 =
TransformationAddTypePointer(108, SpvStorageClassPrivate, 107);
- ASSERT_FALSE(
- bad_type_id_does_not_exist.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(
- bad_type_id_is_not_type.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(
- bad_result_id_is_not_fresh.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(bad_type_id_does_not_exist.IsApplicable(context.get(),
+ transformation_context));
+ ASSERT_FALSE(bad_type_id_is_not_type.IsApplicable(context.get(),
+ transformation_context));
+ ASSERT_FALSE(bad_result_id_is_not_fresh.IsApplicable(context.get(),
+ transformation_context));
for (auto& transformation :
{good_new_private_pointer_to_t, good_new_uniform_pointer_to_t,
@@ -136,8 +139,9 @@
good_new_private_pointer_to_private_pointer_to_float,
good_new_uniform_pointer_to_vec2,
good_new_private_pointer_to_uniform_pointer_to_vec2}) {
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
}
diff --git a/test/fuzz/transformation_add_type_struct_test.cpp b/test/fuzz/transformation_add_type_struct_test.cpp
index ae68c9a..06f78cd 100644
--- a/test/fuzz/transformation_add_type_struct_test.cpp
+++ b/test/fuzz/transformation_add_type_struct_test.cpp
@@ -47,17 +47,20 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Id already in use
- ASSERT_FALSE(TransformationAddTypeStruct(4, {}).IsApplicable(context.get(),
- fact_manager));
+ ASSERT_FALSE(TransformationAddTypeStruct(4, {}).IsApplicable(
+ context.get(), transformation_context));
// %1 is not a type
ASSERT_FALSE(TransformationAddTypeStruct(100, {1}).IsApplicable(
- context.get(), fact_manager));
+ context.get(), transformation_context));
// %3 is a function type
ASSERT_FALSE(TransformationAddTypeStruct(100, {3}).IsApplicable(
- context.get(), fact_manager));
+ context.get(), transformation_context));
TransformationAddTypeStruct transformations[] = {
// %100 = OpTypeStruct %6 %7 %8 %9 %10 %11
@@ -73,8 +76,9 @@
TransformationAddTypeStruct(103, {6, 6})};
for (auto& transformation : transformations) {
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
}
ASSERT_TRUE(IsValid(env, context.get()));
diff --git a/test/fuzz/transformation_add_type_vector_test.cpp b/test/fuzz/transformation_add_type_vector_test.cpp
index 6ac4498..f1252a3 100644
--- a/test/fuzz/transformation_add_type_vector_test.cpp
+++ b/test/fuzz/transformation_add_type_vector_test.cpp
@@ -45,13 +45,16 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Id already in use
- ASSERT_FALSE(TransformationAddTypeVector(4, 6, 2).IsApplicable(context.get(),
- fact_manager));
+ ASSERT_FALSE(TransformationAddTypeVector(4, 6, 2).IsApplicable(
+ context.get(), transformation_context));
// %1 is not a type
ASSERT_FALSE(TransformationAddTypeVector(100, 1, 2).IsApplicable(
- context.get(), fact_manager));
+ context.get(), transformation_context));
TransformationAddTypeVector transformations[] = {
// %100 = OpTypeVector %6 2
@@ -67,8 +70,9 @@
TransformationAddTypeVector(103, 9, 2)};
for (auto& transformation : transformations) {
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
}
ASSERT_TRUE(IsValid(env, context.get()));
diff --git a/test/fuzz/transformation_adjust_branch_weights_test.cpp b/test/fuzz/transformation_adjust_branch_weights_test.cpp
new file mode 100644
index 0000000..7f8ba31
--- /dev/null
+++ b/test/fuzz/transformation_adjust_branch_weights_test.cpp
@@ -0,0 +1,349 @@
+// Copyright (c) 2020 André Perez Maselco
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "source/fuzz/transformation_adjust_branch_weights.h"
+#include "source/fuzz/instruction_descriptor.h"
+#include "test/fuzz/fuzz_test_util.h"
+
+namespace spvtools {
+namespace fuzz {
+namespace {
+
+TEST(TransformationAdjustBranchWeightsTest, IsApplicableTest) {
+ std::string shader = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main" %51 %27
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ OpName %4 "main"
+ OpName %25 "buf"
+ OpMemberName %25 0 "value"
+ OpName %27 ""
+ OpName %51 "color"
+ OpMemberDecorate %25 0 Offset 0
+ OpDecorate %25 Block
+ OpDecorate %27 DescriptorSet 0
+ OpDecorate %27 Binding 0
+ OpDecorate %51 Location 0
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeFloat 32
+ %7 = OpTypeVector %6 4
+ %150 = OpTypeVector %6 2
+ %10 = OpConstant %6 0.300000012
+ %11 = OpConstant %6 0.400000006
+ %12 = OpConstant %6 0.5
+ %13 = OpConstant %6 1
+ %14 = OpConstantComposite %7 %10 %11 %12 %13
+ %15 = OpTypeInt 32 1
+ %18 = OpConstant %15 0
+ %25 = OpTypeStruct %6
+ %26 = OpTypePointer Uniform %25
+ %27 = OpVariable %26 Uniform
+ %28 = OpTypePointer Uniform %6
+ %32 = OpTypeBool
+ %103 = OpConstantTrue %32
+ %34 = OpConstant %6 0.100000001
+ %48 = OpConstant %15 1
+ %50 = OpTypePointer Output %7
+ %51 = OpVariable %50 Output
+ %100 = OpTypePointer Function %6
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ %101 = OpVariable %100 Function
+ %102 = OpVariable %100 Function
+ OpBranch %19
+ %19 = OpLabel
+ %60 = OpPhi %7 %14 %5 %58 %20
+ %59 = OpPhi %15 %18 %5 %49 %20
+ %29 = OpAccessChain %28 %27 %18
+ %30 = OpLoad %6 %29
+ %31 = OpConvertFToS %15 %30
+ %33 = OpSLessThan %32 %59 %31
+ OpLoopMerge %21 %20 None
+ OpBranchConditional %33 %20 %21 1 2
+ %20 = OpLabel
+ %39 = OpCompositeExtract %6 %60 0
+ %40 = OpFAdd %6 %39 %34
+ %55 = OpCompositeInsert %7 %40 %60 0
+ %44 = OpCompositeExtract %6 %60 1
+ %45 = OpFSub %6 %44 %34
+ %58 = OpCompositeInsert %7 %45 %55 1
+ %49 = OpIAdd %15 %59 %48
+ OpBranch %19
+ %21 = OpLabel
+ OpStore %51 %60
+ OpSelectionMerge %105 None
+ OpBranchConditional %103 %104 %105
+ %104 = OpLabel
+ OpBranch %105
+ %105 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ const auto env = SPV_ENV_UNIVERSAL_1_5;
+ const auto consumer = nullptr;
+ const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, context.get()));
+
+ FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ // Tests OpBranchConditional instruction with weigths.
+ auto instruction_descriptor =
+ MakeInstructionDescriptor(33, SpvOpBranchConditional, 0);
+ auto transformation =
+ TransformationAdjustBranchWeights(instruction_descriptor, {0, 1});
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+
+ // Tests the two branch weights equal to 0.
+ instruction_descriptor =
+ MakeInstructionDescriptor(33, SpvOpBranchConditional, 0);
+ transformation =
+ TransformationAdjustBranchWeights(instruction_descriptor, {0, 0});
+#ifndef NDEBUG
+ ASSERT_DEATH(
+ transformation.IsApplicable(context.get(), transformation_context),
+ "At least one weight must be non-zero");
+#endif
+
+ // Tests 32-bit unsigned integer overflow.
+ instruction_descriptor =
+ MakeInstructionDescriptor(33, SpvOpBranchConditional, 0);
+ transformation = TransformationAdjustBranchWeights(instruction_descriptor,
+ {UINT32_MAX, 0});
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+
+ instruction_descriptor =
+ MakeInstructionDescriptor(33, SpvOpBranchConditional, 0);
+ transformation = TransformationAdjustBranchWeights(instruction_descriptor,
+ {1, UINT32_MAX});
+#ifndef NDEBUG
+ ASSERT_DEATH(
+ transformation.IsApplicable(context.get(), transformation_context),
+ "The sum of the two weights must not be greater than UINT32_MAX");
+#endif
+
+ // Tests OpBranchConditional instruction with no weights.
+ instruction_descriptor =
+ MakeInstructionDescriptor(21, SpvOpBranchConditional, 0);
+ transformation =
+ TransformationAdjustBranchWeights(instruction_descriptor, {0, 1});
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+
+ // Tests non-OpBranchConditional instructions.
+ instruction_descriptor = MakeInstructionDescriptor(2, SpvOpTypeVoid, 0);
+ transformation =
+ TransformationAdjustBranchWeights(instruction_descriptor, {5, 6});
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
+
+ instruction_descriptor = MakeInstructionDescriptor(20, SpvOpLabel, 0);
+ transformation =
+ TransformationAdjustBranchWeights(instruction_descriptor, {1, 2});
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
+
+ instruction_descriptor = MakeInstructionDescriptor(49, SpvOpIAdd, 0);
+ transformation =
+ TransformationAdjustBranchWeights(instruction_descriptor, {1, 2});
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
+}
+
+TEST(TransformationAdjustBranchWeightsTest, ApplyTest) {
+ std::string shader = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main" %51 %27
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ OpName %4 "main"
+ OpName %25 "buf"
+ OpMemberName %25 0 "value"
+ OpName %27 ""
+ OpName %51 "color"
+ OpMemberDecorate %25 0 Offset 0
+ OpDecorate %25 Block
+ OpDecorate %27 DescriptorSet 0
+ OpDecorate %27 Binding 0
+ OpDecorate %51 Location 0
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeFloat 32
+ %7 = OpTypeVector %6 4
+ %150 = OpTypeVector %6 2
+ %10 = OpConstant %6 0.300000012
+ %11 = OpConstant %6 0.400000006
+ %12 = OpConstant %6 0.5
+ %13 = OpConstant %6 1
+ %14 = OpConstantComposite %7 %10 %11 %12 %13
+ %15 = OpTypeInt 32 1
+ %18 = OpConstant %15 0
+ %25 = OpTypeStruct %6
+ %26 = OpTypePointer Uniform %25
+ %27 = OpVariable %26 Uniform
+ %28 = OpTypePointer Uniform %6
+ %32 = OpTypeBool
+ %103 = OpConstantTrue %32
+ %34 = OpConstant %6 0.100000001
+ %48 = OpConstant %15 1
+ %50 = OpTypePointer Output %7
+ %51 = OpVariable %50 Output
+ %100 = OpTypePointer Function %6
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ %101 = OpVariable %100 Function
+ %102 = OpVariable %100 Function
+ OpBranch %19
+ %19 = OpLabel
+ %60 = OpPhi %7 %14 %5 %58 %20
+ %59 = OpPhi %15 %18 %5 %49 %20
+ %29 = OpAccessChain %28 %27 %18
+ %30 = OpLoad %6 %29
+ %31 = OpConvertFToS %15 %30
+ %33 = OpSLessThan %32 %59 %31
+ OpLoopMerge %21 %20 None
+ OpBranchConditional %33 %20 %21 1 2
+ %20 = OpLabel
+ %39 = OpCompositeExtract %6 %60 0
+ %40 = OpFAdd %6 %39 %34
+ %55 = OpCompositeInsert %7 %40 %60 0
+ %44 = OpCompositeExtract %6 %60 1
+ %45 = OpFSub %6 %44 %34
+ %58 = OpCompositeInsert %7 %45 %55 1
+ %49 = OpIAdd %15 %59 %48
+ OpBranch %19
+ %21 = OpLabel
+ OpStore %51 %60
+ OpSelectionMerge %105 None
+ OpBranchConditional %103 %104 %105
+ %104 = OpLabel
+ OpBranch %105
+ %105 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ const auto env = SPV_ENV_UNIVERSAL_1_5;
+ const auto consumer = nullptr;
+ const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, context.get()));
+
+ FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ auto instruction_descriptor =
+ MakeInstructionDescriptor(33, SpvOpBranchConditional, 0);
+ auto transformation =
+ TransformationAdjustBranchWeights(instruction_descriptor, {5, 6});
+ transformation.Apply(context.get(), &transformation_context);
+
+ instruction_descriptor =
+ MakeInstructionDescriptor(21, SpvOpBranchConditional, 0);
+ transformation =
+ TransformationAdjustBranchWeights(instruction_descriptor, {7, 8});
+ transformation.Apply(context.get(), &transformation_context);
+
+ std::string variant_shader = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main" %51 %27
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ OpName %4 "main"
+ OpName %25 "buf"
+ OpMemberName %25 0 "value"
+ OpName %27 ""
+ OpName %51 "color"
+ OpMemberDecorate %25 0 Offset 0
+ OpDecorate %25 Block
+ OpDecorate %27 DescriptorSet 0
+ OpDecorate %27 Binding 0
+ OpDecorate %51 Location 0
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeFloat 32
+ %7 = OpTypeVector %6 4
+ %150 = OpTypeVector %6 2
+ %10 = OpConstant %6 0.300000012
+ %11 = OpConstant %6 0.400000006
+ %12 = OpConstant %6 0.5
+ %13 = OpConstant %6 1
+ %14 = OpConstantComposite %7 %10 %11 %12 %13
+ %15 = OpTypeInt 32 1
+ %18 = OpConstant %15 0
+ %25 = OpTypeStruct %6
+ %26 = OpTypePointer Uniform %25
+ %27 = OpVariable %26 Uniform
+ %28 = OpTypePointer Uniform %6
+ %32 = OpTypeBool
+ %103 = OpConstantTrue %32
+ %34 = OpConstant %6 0.100000001
+ %48 = OpConstant %15 1
+ %50 = OpTypePointer Output %7
+ %51 = OpVariable %50 Output
+ %100 = OpTypePointer Function %6
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ %101 = OpVariable %100 Function
+ %102 = OpVariable %100 Function
+ OpBranch %19
+ %19 = OpLabel
+ %60 = OpPhi %7 %14 %5 %58 %20
+ %59 = OpPhi %15 %18 %5 %49 %20
+ %29 = OpAccessChain %28 %27 %18
+ %30 = OpLoad %6 %29
+ %31 = OpConvertFToS %15 %30
+ %33 = OpSLessThan %32 %59 %31
+ OpLoopMerge %21 %20 None
+ OpBranchConditional %33 %20 %21 5 6
+ %20 = OpLabel
+ %39 = OpCompositeExtract %6 %60 0
+ %40 = OpFAdd %6 %39 %34
+ %55 = OpCompositeInsert %7 %40 %60 0
+ %44 = OpCompositeExtract %6 %60 1
+ %45 = OpFSub %6 %44 %34
+ %58 = OpCompositeInsert %7 %45 %55 1
+ %49 = OpIAdd %15 %59 %48
+ OpBranch %19
+ %21 = OpLabel
+ OpStore %51 %60
+ OpSelectionMerge %105 None
+ OpBranchConditional %103 %104 %105 7 8
+ %104 = OpLabel
+ OpBranch %105
+ %105 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ ASSERT_TRUE(IsEqual(env, variant_shader, context.get()));
+}
+
+} // namespace
+} // namespace fuzz
+} // namespace spvtools
diff --git a/test/fuzz/transformation_composite_construct_test.cpp b/test/fuzz/transformation_composite_construct_test.cpp
index d303368..b663866 100644
--- a/test/fuzz/transformation_composite_construct_test.cpp
+++ b/test/fuzz/transformation_composite_construct_test.cpp
@@ -129,6 +129,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Make a vec2[3]
TransformationCompositeConstruct make_vec2_array_length_3(
@@ -138,18 +141,18 @@
TransformationCompositeConstruct make_vec2_array_length_3_bad(
37, {41, 45, 27, 27}, MakeInstructionDescriptor(46, SpvOpAccessChain, 0),
200);
- ASSERT_TRUE(
- make_vec2_array_length_3.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(
- make_vec2_array_length_3_bad.IsApplicable(context.get(), fact_manager));
- make_vec2_array_length_3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(make_vec2_array_length_3.IsApplicable(context.get(),
+ transformation_context));
+ ASSERT_FALSE(make_vec2_array_length_3_bad.IsApplicable(
+ context.get(), transformation_context));
+ make_vec2_array_length_3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(41, {}), MakeDataDescriptor(200, {0}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(45, {}), MakeDataDescriptor(200, {1}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(27, {}), MakeDataDescriptor(200, {2}), context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(41, {}), MakeDataDescriptor(200, {0})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(45, {}), MakeDataDescriptor(200, {1})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(27, {}), MakeDataDescriptor(200, {2})));
// Make a float[2]
TransformationCompositeConstruct make_float_array_length_2(
@@ -157,16 +160,16 @@
// Bad: %41 does not have type float
TransformationCompositeConstruct make_float_array_length_2_bad(
9, {41, 40}, MakeInstructionDescriptor(71, SpvOpStore, 0), 201);
- ASSERT_TRUE(
- make_float_array_length_2.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(
- make_float_array_length_2_bad.IsApplicable(context.get(), fact_manager));
- make_float_array_length_2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(make_float_array_length_2.IsApplicable(context.get(),
+ transformation_context));
+ ASSERT_FALSE(make_float_array_length_2_bad.IsApplicable(
+ context.get(), transformation_context));
+ make_float_array_length_2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(24, {}), MakeDataDescriptor(201, {0}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(40, {}), MakeDataDescriptor(201, {1}), context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(24, {}), MakeDataDescriptor(201, {0})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(40, {}), MakeDataDescriptor(201, {1})));
// Make a bool[3]
TransformationCompositeConstruct make_bool_array_length_3(
@@ -176,18 +179,18 @@
TransformationCompositeConstruct make_bool_array_length_3_bad(
47, {33, 54, 50}, MakeInstructionDescriptor(33, SpvOpSelectionMerge, 0),
202);
- ASSERT_TRUE(
- make_bool_array_length_3.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(
- make_bool_array_length_3_bad.IsApplicable(context.get(), fact_manager));
- make_bool_array_length_3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(make_bool_array_length_3.IsApplicable(context.get(),
+ transformation_context));
+ ASSERT_FALSE(make_bool_array_length_3_bad.IsApplicable(
+ context.get(), transformation_context));
+ make_bool_array_length_3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(33, {}), MakeDataDescriptor(202, {0}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(50, {}), MakeDataDescriptor(202, {1}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(50, {}), MakeDataDescriptor(202, {2}), context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(33, {}), MakeDataDescriptor(202, {0})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(50, {}), MakeDataDescriptor(202, {1})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(50, {}), MakeDataDescriptor(202, {2})));
// make a uvec3[2][2]
TransformationCompositeConstruct make_uvec3_array_length_2_2(
@@ -195,17 +198,16 @@
// Bad: Skip count 100 is too large.
TransformationCompositeConstruct make_uvec3_array_length_2_2_bad(
58, {33, 54}, MakeInstructionDescriptor(64, SpvOpStore, 100), 203);
- ASSERT_TRUE(
- make_uvec3_array_length_2_2.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(make_uvec3_array_length_2_2_bad.IsApplicable(context.get(),
- fact_manager));
- make_uvec3_array_length_2_2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(make_uvec3_array_length_2_2.IsApplicable(context.get(),
+ transformation_context));
+ ASSERT_FALSE(make_uvec3_array_length_2_2_bad.IsApplicable(
+ context.get(), transformation_context));
+ make_uvec3_array_length_2_2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(69, {}), MakeDataDescriptor(203, {0}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(100, {}),
- MakeDataDescriptor(203, {1}),
- context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(69, {}), MakeDataDescriptor(203, {0})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(100, {}), MakeDataDescriptor(203, {1})));
std::string after_transformation = R"(
OpCapability Shader
@@ -393,6 +395,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// make a mat3x4
TransformationCompositeConstruct make_mat34(
@@ -400,16 +405,17 @@
// Bad: %35 is mat4x3, not mat3x4.
TransformationCompositeConstruct make_mat34_bad(
35, {25, 28, 31}, MakeInstructionDescriptor(31, SpvOpReturn, 0), 200);
- ASSERT_TRUE(make_mat34.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(make_mat34_bad.IsApplicable(context.get(), fact_manager));
- make_mat34.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(make_mat34.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ make_mat34_bad.IsApplicable(context.get(), transformation_context));
+ make_mat34.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(25, {}), MakeDataDescriptor(200, {0}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(28, {}), MakeDataDescriptor(200, {1}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(31, {}), MakeDataDescriptor(200, {2}), context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(25, {}), MakeDataDescriptor(200, {0})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(28, {}), MakeDataDescriptor(200, {1})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(31, {}), MakeDataDescriptor(200, {2})));
// make a mat4x3
TransformationCompositeConstruct make_mat43(
@@ -417,19 +423,19 @@
// Bad: %25 does not match the matrix's column type.
TransformationCompositeConstruct make_mat43_bad(
35, {25, 13, 16, 100}, MakeInstructionDescriptor(31, SpvOpStore, 0), 201);
- ASSERT_TRUE(make_mat43.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(make_mat43_bad.IsApplicable(context.get(), fact_manager));
- make_mat43.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(make_mat43.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ make_mat43_bad.IsApplicable(context.get(), transformation_context));
+ make_mat43.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(11, {}), MakeDataDescriptor(201, {0}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(13, {}), MakeDataDescriptor(201, {1}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(16, {}), MakeDataDescriptor(201, {2}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(100, {}),
- MakeDataDescriptor(201, {3}),
- context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(11, {}), MakeDataDescriptor(201, {0})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(13, {}), MakeDataDescriptor(201, {1})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(16, {}), MakeDataDescriptor(201, {2})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(100, {}), MakeDataDescriptor(201, {3})));
std::string after_transformation = R"(
OpCapability Shader
@@ -602,6 +608,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// make an Inner
TransformationCompositeConstruct make_inner(
@@ -609,14 +618,15 @@
// Bad: Too few fields to make the struct.
TransformationCompositeConstruct make_inner_bad(
9, {25}, MakeInstructionDescriptor(57, SpvOpAccessChain, 0), 200);
- ASSERT_TRUE(make_inner.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(make_inner_bad.IsApplicable(context.get(), fact_manager));
- make_inner.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(make_inner.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ make_inner_bad.IsApplicable(context.get(), transformation_context));
+ make_inner.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(25, {}), MakeDataDescriptor(200, {0}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(19, {}), MakeDataDescriptor(200, {1}), context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(25, {}), MakeDataDescriptor(200, {0})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(19, {}), MakeDataDescriptor(200, {1})));
// make an Outer
TransformationCompositeConstruct make_outer(
@@ -626,17 +636,17 @@
TransformationCompositeConstruct make_outer_bad(
33, {46, 200, 56},
MakeInstructionDescriptor(200, SpvOpCompositeConstruct, 0), 201);
- ASSERT_TRUE(make_outer.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(make_outer_bad.IsApplicable(context.get(), fact_manager));
- make_outer.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(make_outer.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ make_outer_bad.IsApplicable(context.get(), transformation_context));
+ make_outer.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(46, {}), MakeDataDescriptor(201, {0}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(200, {}),
- MakeDataDescriptor(201, {1}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(56, {}), MakeDataDescriptor(201, {2}), context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(46, {}), MakeDataDescriptor(201, {0})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(200, {}), MakeDataDescriptor(201, {1})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(56, {}), MakeDataDescriptor(201, {2})));
std::string after_transformation = R"(
OpCapability Shader
@@ -922,20 +932,24 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationCompositeConstruct make_vec2(
7, {17, 11}, MakeInstructionDescriptor(100, SpvOpStore, 0), 200);
// Bad: not enough data for a vec2
TransformationCompositeConstruct make_vec2_bad(
7, {11}, MakeInstructionDescriptor(100, SpvOpStore, 0), 200);
- ASSERT_TRUE(make_vec2.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(make_vec2_bad.IsApplicable(context.get(), fact_manager));
- make_vec2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(make_vec2.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ make_vec2_bad.IsApplicable(context.get(), transformation_context));
+ make_vec2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(17, {}), MakeDataDescriptor(200, {0}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(11, {}), MakeDataDescriptor(200, {1}), context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(17, {}), MakeDataDescriptor(200, {0})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(11, {}), MakeDataDescriptor(200, {1})));
TransformationCompositeConstruct make_vec3(
25, {12, 32}, MakeInstructionDescriptor(35, SpvOpCompositeConstruct, 0),
@@ -944,18 +958,17 @@
TransformationCompositeConstruct make_vec3_bad(
25, {12, 32, 32},
MakeInstructionDescriptor(35, SpvOpCompositeConstruct, 0), 201);
- ASSERT_TRUE(make_vec3.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(make_vec3_bad.IsApplicable(context.get(), fact_manager));
- make_vec3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(make_vec3.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ make_vec3_bad.IsApplicable(context.get(), transformation_context));
+ make_vec3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(12, {0}),
- MakeDataDescriptor(201, {0}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(12, {1}),
- MakeDataDescriptor(201, {1}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(32, {}), MakeDataDescriptor(201, {2}), context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(12, {0}), MakeDataDescriptor(201, {0})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(12, {1}), MakeDataDescriptor(201, {1})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(32, {}), MakeDataDescriptor(201, {2})));
TransformationCompositeConstruct make_vec4(
44, {32, 32, 10, 11}, MakeInstructionDescriptor(75, SpvOpAccessChain, 0),
@@ -964,34 +977,34 @@
TransformationCompositeConstruct make_vec4_bad(
44, {48, 32, 10, 11}, MakeInstructionDescriptor(75, SpvOpAccessChain, 0),
202);
- ASSERT_TRUE(make_vec4.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(make_vec4_bad.IsApplicable(context.get(), fact_manager));
- make_vec4.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(make_vec4.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ make_vec4_bad.IsApplicable(context.get(), transformation_context));
+ make_vec4.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(32, {}), MakeDataDescriptor(202, {0}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(32, {}), MakeDataDescriptor(202, {1}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(10, {}), MakeDataDescriptor(202, {2}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(11, {}), MakeDataDescriptor(202, {3}), context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(32, {}), MakeDataDescriptor(202, {0})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(32, {}), MakeDataDescriptor(202, {1})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(10, {}), MakeDataDescriptor(202, {2})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(11, {}), MakeDataDescriptor(202, {3})));
TransformationCompositeConstruct make_ivec2(
51, {126, 120}, MakeInstructionDescriptor(128, SpvOpLoad, 0), 203);
// Bad: if 128 is not available at the instruction that defines 128
TransformationCompositeConstruct make_ivec2_bad(
51, {128, 120}, MakeInstructionDescriptor(128, SpvOpLoad, 0), 203);
- ASSERT_TRUE(make_ivec2.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(make_ivec2_bad.IsApplicable(context.get(), fact_manager));
- make_ivec2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(make_ivec2.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ make_ivec2_bad.IsApplicable(context.get(), transformation_context));
+ make_ivec2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(126, {}),
- MakeDataDescriptor(203, {0}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(120, {}),
- MakeDataDescriptor(203, {1}),
- context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(126, {}), MakeDataDescriptor(203, {0})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(120, {}), MakeDataDescriptor(203, {1})));
TransformationCompositeConstruct make_ivec3(
114, {56, 117, 56}, MakeInstructionDescriptor(66, SpvOpAccessChain, 0),
@@ -1000,17 +1013,17 @@
TransformationCompositeConstruct make_ivec3_bad(
114, {56, 117, 1300}, MakeInstructionDescriptor(66, SpvOpAccessChain, 0),
204);
- ASSERT_TRUE(make_ivec3.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(make_ivec3_bad.IsApplicable(context.get(), fact_manager));
- make_ivec3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(make_ivec3.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ make_ivec3_bad.IsApplicable(context.get(), transformation_context));
+ make_ivec3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(56, {}), MakeDataDescriptor(204, {0}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(117, {}),
- MakeDataDescriptor(204, {1}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(56, {}), MakeDataDescriptor(204, {2}), context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(56, {}), MakeDataDescriptor(204, {0})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(117, {}), MakeDataDescriptor(204, {1})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(56, {}), MakeDataDescriptor(204, {2})));
TransformationCompositeConstruct make_ivec4(
122, {56, 117, 117, 117}, MakeInstructionDescriptor(66, SpvOpIAdd, 0),
@@ -1019,51 +1032,50 @@
TransformationCompositeConstruct make_ivec4_bad(
86, {56, 117, 117, 117}, MakeInstructionDescriptor(66, SpvOpIAdd, 0),
205);
- ASSERT_TRUE(make_ivec4.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(make_ivec4_bad.IsApplicable(context.get(), fact_manager));
- make_ivec4.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(make_ivec4.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ make_ivec4_bad.IsApplicable(context.get(), transformation_context));
+ make_ivec4.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(56, {}), MakeDataDescriptor(205, {0}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(117, {}),
- MakeDataDescriptor(205, {1}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(117, {}),
- MakeDataDescriptor(205, {2}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(117, {}),
- MakeDataDescriptor(205, {3}),
- context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(56, {}), MakeDataDescriptor(205, {0})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(117, {}), MakeDataDescriptor(205, {1})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(117, {}), MakeDataDescriptor(205, {2})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(117, {}), MakeDataDescriptor(205, {3})));
TransformationCompositeConstruct make_uvec2(
86, {18, 38}, MakeInstructionDescriptor(133, SpvOpAccessChain, 0), 206);
TransformationCompositeConstruct make_uvec2_bad(
86, {18, 38}, MakeInstructionDescriptor(133, SpvOpAccessChain, 200), 206);
- ASSERT_TRUE(make_uvec2.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(make_uvec2_bad.IsApplicable(context.get(), fact_manager));
- make_uvec2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(make_uvec2.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ make_uvec2_bad.IsApplicable(context.get(), transformation_context));
+ make_uvec2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(18, {}), MakeDataDescriptor(206, {0}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(38, {}), MakeDataDescriptor(206, {1}), context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(18, {}), MakeDataDescriptor(206, {0})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(38, {}), MakeDataDescriptor(206, {1})));
TransformationCompositeConstruct make_uvec3(
59, {14, 18, 136}, MakeInstructionDescriptor(137, SpvOpReturn, 0), 207);
// Bad because 1300 is not an id
TransformationCompositeConstruct make_uvec3_bad(
59, {14, 18, 1300}, MakeInstructionDescriptor(137, SpvOpReturn, 0), 207);
- ASSERT_TRUE(make_uvec3.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(make_uvec3_bad.IsApplicable(context.get(), fact_manager));
- make_uvec3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(make_uvec3.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ make_uvec3_bad.IsApplicable(context.get(), transformation_context));
+ make_uvec3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(14, {}), MakeDataDescriptor(207, {0}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(18, {}), MakeDataDescriptor(207, {1}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(136, {}),
- MakeDataDescriptor(207, {2}),
- context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(14, {}), MakeDataDescriptor(207, {0})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(18, {}), MakeDataDescriptor(207, {1})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(136, {}), MakeDataDescriptor(207, {2})));
TransformationCompositeConstruct make_uvec4(
131, {14, 18, 136, 136},
@@ -1072,20 +1084,19 @@
TransformationCompositeConstruct make_uvec4_bad(
86, {14, 18, 136, 136},
MakeInstructionDescriptor(137, SpvOpAccessChain, 0), 208);
- ASSERT_TRUE(make_uvec4.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(make_uvec4_bad.IsApplicable(context.get(), fact_manager));
- make_uvec4.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(make_uvec4.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ make_uvec4_bad.IsApplicable(context.get(), transformation_context));
+ make_uvec4.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(14, {}), MakeDataDescriptor(208, {0}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(18, {}), MakeDataDescriptor(208, {1}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(136, {}),
- MakeDataDescriptor(208, {2}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(136, {}),
- MakeDataDescriptor(208, {3}),
- context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(14, {}), MakeDataDescriptor(208, {0})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(18, {}), MakeDataDescriptor(208, {1})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(136, {}), MakeDataDescriptor(208, {2})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(136, {}), MakeDataDescriptor(208, {3})));
TransformationCompositeConstruct make_bvec2(
102,
@@ -1102,55 +1113,51 @@
41,
},
MakeInstructionDescriptor(0, SpvOpExtInstImport, 0), 209);
- ASSERT_TRUE(make_bvec2.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(make_bvec2_bad.IsApplicable(context.get(), fact_manager));
- make_bvec2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(make_bvec2.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ make_bvec2_bad.IsApplicable(context.get(), transformation_context));
+ make_bvec2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(111, {}),
- MakeDataDescriptor(209, {0}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(41, {}), MakeDataDescriptor(209, {1}), context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(111, {}), MakeDataDescriptor(209, {0})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(41, {}), MakeDataDescriptor(209, {1})));
TransformationCompositeConstruct make_bvec3(
93, {108, 73}, MakeInstructionDescriptor(108, SpvOpStore, 0), 210);
// Bad because there are too many components for a bvec3
TransformationCompositeConstruct make_bvec3_bad(
93, {108, 108}, MakeInstructionDescriptor(108, SpvOpStore, 0), 210);
- ASSERT_TRUE(make_bvec3.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(make_bvec3_bad.IsApplicable(context.get(), fact_manager));
- make_bvec3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(make_bvec3.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ make_bvec3_bad.IsApplicable(context.get(), transformation_context));
+ make_bvec3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(108, {0}),
- MakeDataDescriptor(210, {0}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(108, {1}),
- MakeDataDescriptor(210, {1}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(73, {}), MakeDataDescriptor(210, {2}), context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(108, {0}), MakeDataDescriptor(210, {0})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(108, {1}), MakeDataDescriptor(210, {1})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(73, {}), MakeDataDescriptor(210, {2})));
TransformationCompositeConstruct make_bvec4(
70, {108, 108}, MakeInstructionDescriptor(108, SpvOpBranch, 0), 211);
// Bad because 21 is a type, not a result id
TransformationCompositeConstruct make_bvec4_bad(
70, {21, 108}, MakeInstructionDescriptor(108, SpvOpBranch, 0), 211);
- ASSERT_TRUE(make_bvec4.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(make_bvec4_bad.IsApplicable(context.get(), fact_manager));
- make_bvec4.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(make_bvec4.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ make_bvec4_bad.IsApplicable(context.get(), transformation_context));
+ make_bvec4.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(108, {0}),
- MakeDataDescriptor(211, {0}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(108, {1}),
- MakeDataDescriptor(211, {1}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(108, {0}),
- MakeDataDescriptor(211, {2}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(108, {1}),
- MakeDataDescriptor(211, {3}),
- context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(108, {0}), MakeDataDescriptor(211, {0})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(108, {1}), MakeDataDescriptor(211, {1})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(108, {0}), MakeDataDescriptor(211, {2})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(108, {1}), MakeDataDescriptor(211, {3})));
std::string after_transformation = R"(
OpCapability Shader
diff --git a/test/fuzz/transformation_composite_extract_test.cpp b/test/fuzz/transformation_composite_extract_test.cpp
index 5cc2115..a7674a6 100644
--- a/test/fuzz/transformation_composite_extract_test.cpp
+++ b/test/fuzz/transformation_composite_extract_test.cpp
@@ -96,100 +96,103 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Instruction does not exist.
ASSERT_FALSE(TransformationCompositeExtract(
MakeInstructionDescriptor(36, SpvOpIAdd, 0), 200, 101, {0})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Id for composite is not a composite.
ASSERT_FALSE(TransformationCompositeExtract(
MakeInstructionDescriptor(36, SpvOpIAdd, 0), 200, 27, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Composite does not dominate instruction being inserted before.
ASSERT_FALSE(
TransformationCompositeExtract(
MakeInstructionDescriptor(37, SpvOpAccessChain, 0), 200, 101, {0})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Too many indices for extraction from struct composite.
ASSERT_FALSE(
TransformationCompositeExtract(
MakeInstructionDescriptor(24, SpvOpAccessChain, 0), 200, 101, {0, 0})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Too many indices for extraction from struct composite.
ASSERT_FALSE(
TransformationCompositeExtract(
MakeInstructionDescriptor(13, SpvOpIEqual, 0), 200, 104, {0, 0, 0})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Out of bounds index for extraction from struct composite.
ASSERT_FALSE(
TransformationCompositeExtract(
MakeInstructionDescriptor(13, SpvOpIEqual, 0), 200, 104, {0, 3})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Result id already used.
ASSERT_FALSE(TransformationCompositeExtract(
MakeInstructionDescriptor(35, SpvOpFAdd, 0), 80, 103, {0})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
TransformationCompositeExtract transformation_1(
MakeInstructionDescriptor(36, SpvOpConvertFToS, 0), 201, 100, {2});
- ASSERT_TRUE(transformation_1.IsApplicable(context.get(), fact_manager));
- transformation_1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation_1.IsApplicable(context.get(), transformation_context));
+ transformation_1.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
TransformationCompositeExtract transformation_2(
MakeInstructionDescriptor(37, SpvOpAccessChain, 0), 202, 104, {0, 2});
- ASSERT_TRUE(transformation_2.IsApplicable(context.get(), fact_manager));
- transformation_2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation_2.IsApplicable(context.get(), transformation_context));
+ transformation_2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
TransformationCompositeExtract transformation_3(
MakeInstructionDescriptor(29, SpvOpAccessChain, 0), 203, 104, {0});
- ASSERT_TRUE(transformation_3.IsApplicable(context.get(), fact_manager));
- transformation_3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation_3.IsApplicable(context.get(), transformation_context));
+ transformation_3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
TransformationCompositeExtract transformation_4(
MakeInstructionDescriptor(24, SpvOpStore, 0), 204, 101, {0});
- ASSERT_TRUE(transformation_4.IsApplicable(context.get(), fact_manager));
- transformation_4.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation_4.IsApplicable(context.get(), transformation_context));
+ transformation_4.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
TransformationCompositeExtract transformation_5(
MakeInstructionDescriptor(29, SpvOpBranch, 0), 205, 102, {2});
- ASSERT_TRUE(transformation_5.IsApplicable(context.get(), fact_manager));
- transformation_5.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation_5.IsApplicable(context.get(), transformation_context));
+ transformation_5.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
TransformationCompositeExtract transformation_6(
MakeInstructionDescriptor(37, SpvOpReturn, 0), 206, 103, {1});
- ASSERT_TRUE(transformation_6.IsApplicable(context.get(), fact_manager));
- transformation_6.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation_6.IsApplicable(context.get(), transformation_context));
+ transformation_6.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(201, {}),
- MakeDataDescriptor(100, {2}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(202, {}),
- MakeDataDescriptor(104, {0, 2}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(203, {}),
- MakeDataDescriptor(104, {0}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(204, {}),
- MakeDataDescriptor(101, {0}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(205, {}),
- MakeDataDescriptor(102, {2}),
- context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(206, {}),
- MakeDataDescriptor(103, {1}),
- context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(201, {}), MakeDataDescriptor(100, {2})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(202, {}), MakeDataDescriptor(104, {0, 2})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(203, {}), MakeDataDescriptor(104, {0})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(204, {}), MakeDataDescriptor(101, {0})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(205, {}), MakeDataDescriptor(102, {2})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(206, {}), MakeDataDescriptor(103, {1})));
std::string after_transformation = R"(
OpCapability Shader
@@ -348,49 +351,52 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Cannot insert before the OpVariables of a function.
ASSERT_FALSE(
TransformationCompositeExtract(
MakeInstructionDescriptor(101, SpvOpVariable, 0), 200, 14, {0})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationCompositeExtract(
MakeInstructionDescriptor(101, SpvOpVariable, 1), 200, 14, {1})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationCompositeExtract(
MakeInstructionDescriptor(102, SpvOpVariable, 0), 200, 14, {1})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// OK to insert right after the OpVariables.
ASSERT_FALSE(TransformationCompositeExtract(
MakeInstructionDescriptor(102, SpvOpBranch, 1), 200, 14, {1})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Cannot insert before the OpPhis of a block.
ASSERT_FALSE(TransformationCompositeExtract(
MakeInstructionDescriptor(60, SpvOpPhi, 0), 200, 14, {2})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationCompositeExtract(
MakeInstructionDescriptor(59, SpvOpPhi, 0), 200, 14, {3})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// OK to insert after the OpPhis.
ASSERT_TRUE(
TransformationCompositeExtract(
MakeInstructionDescriptor(59, SpvOpAccessChain, 0), 200, 14, {3})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Cannot insert before OpLoopMerge
ASSERT_FALSE(TransformationCompositeExtract(
MakeInstructionDescriptor(33, SpvOpBranchConditional, 0),
200, 14, {3})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Cannot insert before OpSelectionMerge
ASSERT_FALSE(TransformationCompositeExtract(
MakeInstructionDescriptor(21, SpvOpBranchConditional, 0),
200, 14, {2})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
}
} // namespace
diff --git a/test/fuzz/transformation_compute_data_synonym_fact_closure_test.cpp b/test/fuzz/transformation_compute_data_synonym_fact_closure_test.cpp
new file mode 100644
index 0000000..5fa74b7
--- /dev/null
+++ b/test/fuzz/transformation_compute_data_synonym_fact_closure_test.cpp
@@ -0,0 +1,377 @@
+// Copyright (c) 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "source/fuzz/transformation_compute_data_synonym_fact_closure.h"
+#include "test/fuzz/fuzz_test_util.h"
+
+namespace spvtools {
+namespace fuzz {
+namespace {
+
+TEST(TransformationComputeDataSynonymFactClosureTest, DataSynonymFacts) {
+ // The SPIR-V types and constants come from the following code. The body of
+ // the SPIR-V function then constructs a composite that is synonymous with
+ // myT.
+ //
+ // #version 310 es
+ //
+ // precision highp float;
+ //
+ // struct S {
+ // int a;
+ // uvec2 b;
+ // };
+ //
+ // struct T {
+ // bool c[5];
+ // mat4x2 d;
+ // S e;
+ // };
+ //
+ // void main() {
+ // T myT = T(bool[5](true, false, true, false, true),
+ // mat4x2(vec2(1.0, 2.0), vec2(3.0, 4.0),
+ // vec2(5.0, 6.0), vec2(7.0, 8.0)),
+ // S(10, uvec2(100u, 200u)));
+ // }
+
+ std::string shader = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main"
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ OpName %4 "main"
+ OpName %15 "S"
+ OpMemberName %15 0 "a"
+ OpMemberName %15 1 "b"
+ OpName %16 "T"
+ OpMemberName %16 0 "c"
+ OpMemberName %16 1 "d"
+ OpMemberName %16 2 "e"
+ OpName %18 "myT"
+ OpMemberDecorate %15 0 RelaxedPrecision
+ OpMemberDecorate %15 1 RelaxedPrecision
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeBool
+ %7 = OpTypeInt 32 0
+ %8 = OpConstant %7 5
+ %9 = OpTypeArray %6 %8
+ %10 = OpTypeFloat 32
+ %11 = OpTypeVector %10 2
+ %12 = OpTypeMatrix %11 4
+ %13 = OpTypeInt 32 1
+ %14 = OpTypeVector %7 2
+ %15 = OpTypeStruct %13 %14
+ %16 = OpTypeStruct %9 %12 %15
+ %17 = OpTypePointer Function %16
+ %19 = OpConstantTrue %6
+ %20 = OpConstantFalse %6
+ %21 = OpConstantComposite %9 %19 %20 %19 %20 %19
+ %22 = OpConstant %10 1
+ %23 = OpConstant %10 2
+ %24 = OpConstantComposite %11 %22 %23
+ %25 = OpConstant %10 3
+ %26 = OpConstant %10 4
+ %27 = OpConstantComposite %11 %25 %26
+ %28 = OpConstant %10 5
+ %29 = OpConstant %10 6
+ %30 = OpConstantComposite %11 %28 %29
+ %31 = OpConstant %10 7
+ %32 = OpConstant %10 8
+ %33 = OpConstantComposite %11 %31 %32
+ %34 = OpConstantComposite %12 %24 %27 %30 %33
+ %35 = OpConstant %13 10
+ %36 = OpConstant %7 100
+ %37 = OpConstant %7 200
+ %38 = OpConstantComposite %14 %36 %37
+ %39 = OpConstantComposite %15 %35 %38
+ %40 = OpConstantComposite %16 %21 %34 %39
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ %18 = OpVariable %17 Function
+ OpStore %18 %40
+ %100 = OpCompositeConstruct %9 %19 %20 %19 %20 %19
+ %101 = OpCompositeConstruct %11 %22 %23
+ %102 = OpCompositeConstruct %11 %25 %26
+ %103 = OpCompositeConstruct %11 %28 %29
+ %104 = OpCompositeConstruct %11 %31 %32
+ %105 = OpCompositeConstruct %12 %101 %102 %103 %104
+ %106 = OpCompositeConstruct %14 %36 %37
+ %107 = OpCompositeConstruct %15 %35 %106
+ %108 = OpCompositeConstruct %16 %100 %105 %107
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ const auto env = SPV_ENV_UNIVERSAL_1_3;
+ const auto consumer = nullptr;
+ const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, context.get()));
+
+ FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ ASSERT_TRUE(TransformationComputeDataSynonymFactClosure(100).IsApplicable(
+ context.get(), transformation_context));
+
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {}),
+ MakeDataDescriptor(101, {})));
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {0}),
+ MakeDataDescriptor(101, {0})));
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {1}),
+ MakeDataDescriptor(101, {1})));
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {0}),
+ MakeDataDescriptor(101, {1})));
+
+ fact_manager.AddFactDataSynonym(MakeDataDescriptor(24, {}),
+ MakeDataDescriptor(101, {}), context.get());
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {}),
+ MakeDataDescriptor(101, {})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {0}),
+ MakeDataDescriptor(101, {0})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {1}),
+ MakeDataDescriptor(101, {1})));
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {0}),
+ MakeDataDescriptor(101, {1})));
+
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {}),
+ MakeDataDescriptor(102, {})));
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {0}),
+ MakeDataDescriptor(102, {0})));
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {1}),
+ MakeDataDescriptor(102, {1})));
+ fact_manager.AddFactDataSynonym(MakeDataDescriptor(27, {0}),
+ MakeDataDescriptor(102, {0}), context.get());
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {}),
+ MakeDataDescriptor(102, {})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {0}),
+ MakeDataDescriptor(102, {0})));
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {1}),
+ MakeDataDescriptor(102, {1})));
+ fact_manager.AddFactDataSynonym(MakeDataDescriptor(27, {1}),
+ MakeDataDescriptor(102, {1}), context.get());
+
+ TransformationComputeDataSynonymFactClosure(100).Apply(
+ context.get(), &transformation_context);
+
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {}),
+ MakeDataDescriptor(102, {})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {0}),
+ MakeDataDescriptor(102, {0})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {1}),
+ MakeDataDescriptor(102, {1})));
+
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(30, {}),
+ MakeDataDescriptor(103, {})));
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(30, {0}),
+ MakeDataDescriptor(103, {0})));
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(30, {1}),
+ MakeDataDescriptor(103, {1})));
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {}),
+ MakeDataDescriptor(104, {})));
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {0}),
+ MakeDataDescriptor(104, {0})));
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {1}),
+ MakeDataDescriptor(104, {1})));
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {}),
+ MakeDataDescriptor(105, {})));
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {0}),
+ MakeDataDescriptor(105, {0})));
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {1}),
+ MakeDataDescriptor(105, {1})));
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {2}),
+ MakeDataDescriptor(105, {2})));
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {3}),
+ MakeDataDescriptor(105, {3})));
+ fact_manager.AddFactDataSynonym(MakeDataDescriptor(30, {}),
+ MakeDataDescriptor(103, {}), context.get());
+ fact_manager.AddFactDataSynonym(MakeDataDescriptor(33, {}),
+ MakeDataDescriptor(104, {}), context.get());
+ fact_manager.AddFactDataSynonym(MakeDataDescriptor(34, {0}),
+ MakeDataDescriptor(105, {0}), context.get());
+ fact_manager.AddFactDataSynonym(MakeDataDescriptor(34, {1}),
+ MakeDataDescriptor(105, {1}), context.get());
+ fact_manager.AddFactDataSynonym(MakeDataDescriptor(34, {2}),
+ MakeDataDescriptor(105, {2}), context.get());
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(30, {}),
+ MakeDataDescriptor(103, {})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(30, {0}),
+ MakeDataDescriptor(103, {0})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(30, {1}),
+ MakeDataDescriptor(103, {1})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {}),
+ MakeDataDescriptor(104, {})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {0}),
+ MakeDataDescriptor(104, {0})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {1}),
+ MakeDataDescriptor(104, {1})));
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {}),
+ MakeDataDescriptor(105, {})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {0}),
+ MakeDataDescriptor(105, {0})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {1}),
+ MakeDataDescriptor(105, {1})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {2}),
+ MakeDataDescriptor(105, {2})));
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {3}),
+ MakeDataDescriptor(105, {3})));
+
+ fact_manager.AddFactDataSynonym(MakeDataDescriptor(34, {3}),
+ MakeDataDescriptor(105, {3}), context.get());
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {0}),
+ MakeDataDescriptor(104, {0})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {3}),
+ MakeDataDescriptor(105, {3})));
+
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(21, {}),
+ MakeDataDescriptor(100, {})));
+ fact_manager.AddFactDataSynonym(MakeDataDescriptor(21, {0}),
+ MakeDataDescriptor(100, {0}), context.get());
+ fact_manager.AddFactDataSynonym(MakeDataDescriptor(21, {1}),
+ MakeDataDescriptor(100, {1}), context.get());
+ fact_manager.AddFactDataSynonym(MakeDataDescriptor(21, {2}),
+ MakeDataDescriptor(100, {2}), context.get());
+ fact_manager.AddFactDataSynonym(MakeDataDescriptor(21, {3}),
+ MakeDataDescriptor(100, {3}), context.get());
+ fact_manager.AddFactDataSynonym(MakeDataDescriptor(21, {4}),
+ MakeDataDescriptor(100, {4}), context.get());
+
+ TransformationComputeDataSynonymFactClosure(100).Apply(
+ context.get(), &transformation_context);
+
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(21, {}),
+ MakeDataDescriptor(100, {})));
+
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(39, {0}),
+ MakeDataDescriptor(107, {0})));
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(35, {}),
+ MakeDataDescriptor(39, {0})));
+ fact_manager.AddFactDataSynonym(MakeDataDescriptor(39, {0}),
+ MakeDataDescriptor(35, {}), context.get());
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(39, {0}),
+ MakeDataDescriptor(107, {0})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(35, {}),
+ MakeDataDescriptor(39, {0})));
+
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(38, {0}),
+ MakeDataDescriptor(36, {})));
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(38, {1}),
+ MakeDataDescriptor(37, {})));
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(106, {0}),
+ MakeDataDescriptor(36, {})));
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(106, {1}),
+ MakeDataDescriptor(37, {})));
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(38, {}),
+ MakeDataDescriptor(106, {})));
+ fact_manager.AddFactDataSynonym(MakeDataDescriptor(38, {0}),
+ MakeDataDescriptor(36, {}), context.get());
+ fact_manager.AddFactDataSynonym(MakeDataDescriptor(106, {0}),
+ MakeDataDescriptor(36, {}), context.get());
+ fact_manager.AddFactDataSynonym(MakeDataDescriptor(38, {1}),
+ MakeDataDescriptor(37, {}), context.get());
+ fact_manager.AddFactDataSynonym(MakeDataDescriptor(106, {1}),
+ MakeDataDescriptor(37, {}), context.get());
+
+ TransformationComputeDataSynonymFactClosure(100).Apply(
+ context.get(), &transformation_context);
+
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(38, {0}),
+ MakeDataDescriptor(36, {})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(38, {1}),
+ MakeDataDescriptor(37, {})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(106, {0}),
+ MakeDataDescriptor(36, {})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(106, {1}),
+ MakeDataDescriptor(37, {})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(38, {}),
+ MakeDataDescriptor(106, {})));
+
+ ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {}),
+ MakeDataDescriptor(108, {})));
+ fact_manager.AddFactDataSynonym(MakeDataDescriptor(107, {0}),
+ MakeDataDescriptor(35, {}), context.get());
+ fact_manager.AddFactDataSynonym(MakeDataDescriptor(40, {0}),
+ MakeDataDescriptor(108, {0}), context.get());
+ fact_manager.AddFactDataSynonym(MakeDataDescriptor(40, {1}),
+ MakeDataDescriptor(108, {1}), context.get());
+ fact_manager.AddFactDataSynonym(MakeDataDescriptor(40, {2}),
+ MakeDataDescriptor(108, {2}), context.get());
+
+ TransformationComputeDataSynonymFactClosure(100).Apply(
+ context.get(), &transformation_context);
+
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {}),
+ MakeDataDescriptor(108, {})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0}),
+ MakeDataDescriptor(108, {0})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1}),
+ MakeDataDescriptor(108, {1})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {2}),
+ MakeDataDescriptor(108, {2})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0, 0}),
+ MakeDataDescriptor(108, {0, 0})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0, 1}),
+ MakeDataDescriptor(108, {0, 1})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0, 2}),
+ MakeDataDescriptor(108, {0, 2})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0, 3}),
+ MakeDataDescriptor(108, {0, 3})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0, 4}),
+ MakeDataDescriptor(108, {0, 4})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 0}),
+ MakeDataDescriptor(108, {1, 0})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 1}),
+ MakeDataDescriptor(108, {1, 1})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 2}),
+ MakeDataDescriptor(108, {1, 2})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 3}),
+ MakeDataDescriptor(108, {1, 3})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 0, 0}),
+ MakeDataDescriptor(108, {1, 0, 0})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 1, 0}),
+ MakeDataDescriptor(108, {1, 1, 0})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 2, 0}),
+ MakeDataDescriptor(108, {1, 2, 0})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 3, 0}),
+ MakeDataDescriptor(108, {1, 3, 0})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 0, 1}),
+ MakeDataDescriptor(108, {1, 0, 1})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 1, 1}),
+ MakeDataDescriptor(108, {1, 1, 1})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 2, 1}),
+ MakeDataDescriptor(108, {1, 2, 1})));
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 3, 1}),
+ MakeDataDescriptor(108, {1, 3, 1})));
+
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {2, 0}),
+ MakeDataDescriptor(108, {2, 0})));
+
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {2, 1}),
+ MakeDataDescriptor(108, {2, 1})));
+
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {2, 1, 0}),
+ MakeDataDescriptor(108, {2, 1, 0})));
+
+ ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {2, 1, 1}),
+ MakeDataDescriptor(108, {2, 1, 1})));
+}
+
+} // namespace
+} // namespace fuzz
+} // namespace spvtools
diff --git a/test/fuzz/transformation_copy_object_test.cpp b/test/fuzz/transformation_copy_object_test.cpp
index b85f75b..cf9d135 100644
--- a/test/fuzz/transformation_copy_object_test.cpp
+++ b/test/fuzz/transformation_copy_object_test.cpp
@@ -51,77 +51,92 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
- ASSERT_EQ(0,
- fact_manager.GetIdsForWhichSynonymsAreKnown(context.get()).size());
+ ASSERT_EQ(0, transformation_context.GetFactManager()
+ ->GetIdsForWhichSynonymsAreKnown()
+ .size());
{
TransformationCopyObject copy_true(
7, MakeInstructionDescriptor(5, SpvOpReturn, 0), 100);
- ASSERT_TRUE(copy_true.IsApplicable(context.get(), fact_manager));
- copy_true.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(copy_true.IsApplicable(context.get(), transformation_context));
+ copy_true.Apply(context.get(), &transformation_context);
std::vector<uint32_t> ids_for_which_synonyms_are_known =
- fact_manager.GetIdsForWhichSynonymsAreKnown(context.get());
+ transformation_context.GetFactManager()
+ ->GetIdsForWhichSynonymsAreKnown();
ASSERT_EQ(2, ids_for_which_synonyms_are_known.size());
ASSERT_TRUE(std::find(ids_for_which_synonyms_are_known.begin(),
ids_for_which_synonyms_are_known.end(),
7) != ids_for_which_synonyms_are_known.end());
- ASSERT_EQ(2, fact_manager.GetSynonymsForId(7, context.get()).size());
+ ASSERT_EQ(
+ 2, transformation_context.GetFactManager()->GetSynonymsForId(7).size());
protobufs::DataDescriptor descriptor_100 = MakeDataDescriptor(100, {});
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(7, {}),
- descriptor_100, context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(7, {}), descriptor_100));
}
{
TransformationCopyObject copy_false(
8, MakeInstructionDescriptor(100, SpvOpReturn, 0), 101);
- ASSERT_TRUE(copy_false.IsApplicable(context.get(), fact_manager));
- copy_false.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(copy_false.IsApplicable(context.get(), transformation_context));
+ copy_false.Apply(context.get(), &transformation_context);
std::vector<uint32_t> ids_for_which_synonyms_are_known =
- fact_manager.GetIdsForWhichSynonymsAreKnown(context.get());
+ transformation_context.GetFactManager()
+ ->GetIdsForWhichSynonymsAreKnown();
ASSERT_EQ(4, ids_for_which_synonyms_are_known.size());
ASSERT_TRUE(std::find(ids_for_which_synonyms_are_known.begin(),
ids_for_which_synonyms_are_known.end(),
8) != ids_for_which_synonyms_are_known.end());
- ASSERT_EQ(2, fact_manager.GetSynonymsForId(8, context.get()).size());
+ ASSERT_EQ(
+ 2, transformation_context.GetFactManager()->GetSynonymsForId(8).size());
protobufs::DataDescriptor descriptor_101 = MakeDataDescriptor(101, {});
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(8, {}),
- descriptor_101, context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(8, {}), descriptor_101));
}
{
TransformationCopyObject copy_false_again(
101, MakeInstructionDescriptor(5, SpvOpReturn, 0), 102);
- ASSERT_TRUE(copy_false_again.IsApplicable(context.get(), fact_manager));
- copy_false_again.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ copy_false_again.IsApplicable(context.get(), transformation_context));
+ copy_false_again.Apply(context.get(), &transformation_context);
std::vector<uint32_t> ids_for_which_synonyms_are_known =
- fact_manager.GetIdsForWhichSynonymsAreKnown(context.get());
+ transformation_context.GetFactManager()
+ ->GetIdsForWhichSynonymsAreKnown();
ASSERT_EQ(5, ids_for_which_synonyms_are_known.size());
ASSERT_TRUE(std::find(ids_for_which_synonyms_are_known.begin(),
ids_for_which_synonyms_are_known.end(),
101) != ids_for_which_synonyms_are_known.end());
- ASSERT_EQ(3, fact_manager.GetSynonymsForId(101, context.get()).size());
+ ASSERT_EQ(
+ 3,
+ transformation_context.GetFactManager()->GetSynonymsForId(101).size());
protobufs::DataDescriptor descriptor_102 = MakeDataDescriptor(102, {});
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(101, {}),
- descriptor_102, context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(101, {}), descriptor_102));
}
{
TransformationCopyObject copy_true_again(
7, MakeInstructionDescriptor(102, SpvOpReturn, 0), 103);
- ASSERT_TRUE(copy_true_again.IsApplicable(context.get(), fact_manager));
- copy_true_again.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ copy_true_again.IsApplicable(context.get(), transformation_context));
+ copy_true_again.Apply(context.get(), &transformation_context);
std::vector<uint32_t> ids_for_which_synonyms_are_known =
- fact_manager.GetIdsForWhichSynonymsAreKnown(context.get());
+ transformation_context.GetFactManager()
+ ->GetIdsForWhichSynonymsAreKnown();
ASSERT_EQ(6, ids_for_which_synonyms_are_known.size());
ASSERT_TRUE(std::find(ids_for_which_synonyms_are_known.begin(),
ids_for_which_synonyms_are_known.end(),
7) != ids_for_which_synonyms_are_known.end());
- ASSERT_EQ(3, fact_manager.GetSynonymsForId(7, context.get()).size());
+ ASSERT_EQ(
+ 3, transformation_context.GetFactManager()->GetSynonymsForId(7).size());
protobufs::DataDescriptor descriptor_103 = MakeDataDescriptor(103, {});
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(7, {}),
- descriptor_103, context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(7, {}), descriptor_103));
}
std::string after_transformation = R"(
@@ -340,116 +355,119 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Inapplicable because %18 is decorated.
ASSERT_FALSE(TransformationCopyObject(
18, MakeInstructionDescriptor(21, SpvOpAccessChain, 0), 200)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Inapplicable because %77 is decorated.
ASSERT_FALSE(TransformationCopyObject(
77, MakeInstructionDescriptor(77, SpvOpBranch, 0), 200)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Inapplicable because %80 is decorated.
ASSERT_FALSE(TransformationCopyObject(
80, MakeInstructionDescriptor(77, SpvOpIAdd, 0), 200)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Inapplicable because %84 is not available at the requested point
ASSERT_FALSE(
TransformationCopyObject(
84, MakeInstructionDescriptor(32, SpvOpCompositeExtract, 0), 200)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Fine because %84 is available at the requested point
ASSERT_TRUE(
TransformationCopyObject(
84, MakeInstructionDescriptor(32, SpvOpCompositeConstruct, 0), 200)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Inapplicable because id %9 is already in use
ASSERT_FALSE(
TransformationCopyObject(
84, MakeInstructionDescriptor(32, SpvOpCompositeConstruct, 0), 9)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Inapplicable because the requested point does not exist
ASSERT_FALSE(TransformationCopyObject(
84, MakeInstructionDescriptor(86, SpvOpReturn, 2), 200)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Inapplicable because %9 is not in a function
ASSERT_FALSE(TransformationCopyObject(
9, MakeInstructionDescriptor(9, SpvOpTypeInt, 0), 200)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Inapplicable because the insert point is right before, or inside, a chunk
// of OpPhis
ASSERT_FALSE(TransformationCopyObject(
9, MakeInstructionDescriptor(30, SpvOpPhi, 0), 200)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationCopyObject(
9, MakeInstructionDescriptor(99, SpvOpPhi, 1), 200)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// OK, because the insert point is just after a chunk of OpPhis.
ASSERT_TRUE(TransformationCopyObject(
9, MakeInstructionDescriptor(96, SpvOpAccessChain, 0), 200)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Inapplicable because the insert point is right after an OpSelectionMerge
ASSERT_FALSE(
TransformationCopyObject(
9, MakeInstructionDescriptor(58, SpvOpBranchConditional, 0), 200)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// OK, because the insert point is right before the OpSelectionMerge
ASSERT_TRUE(TransformationCopyObject(
9, MakeInstructionDescriptor(58, SpvOpSelectionMerge, 0), 200)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Inapplicable because the insert point is right after an OpSelectionMerge
ASSERT_FALSE(TransformationCopyObject(
9, MakeInstructionDescriptor(43, SpvOpSwitch, 0), 200)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// OK, because the insert point is right before the OpSelectionMerge
ASSERT_TRUE(TransformationCopyObject(
9, MakeInstructionDescriptor(43, SpvOpSelectionMerge, 0), 200)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Inapplicable because the insert point is right after an OpLoopMerge
ASSERT_FALSE(
TransformationCopyObject(
9, MakeInstructionDescriptor(40, SpvOpBranchConditional, 0), 200)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// OK, because the insert point is right before the OpLoopMerge
ASSERT_TRUE(TransformationCopyObject(
9, MakeInstructionDescriptor(40, SpvOpLoopMerge, 0), 200)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Inapplicable because id %300 does not exist
ASSERT_FALSE(TransformationCopyObject(
300, MakeInstructionDescriptor(40, SpvOpLoopMerge, 0), 200)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Inapplicable because the following instruction is OpVariable
ASSERT_FALSE(TransformationCopyObject(
9, MakeInstructionDescriptor(180, SpvOpVariable, 0), 200)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationCopyObject(
9, MakeInstructionDescriptor(181, SpvOpVariable, 0), 200)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationCopyObject(
9, MakeInstructionDescriptor(182, SpvOpVariable, 0), 200)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// OK, because this is just past the group of OpVariable instructions.
ASSERT_TRUE(TransformationCopyObject(
9, MakeInstructionDescriptor(182, SpvOpAccessChain, 0), 200)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
}
TEST(TransformationCopyObjectTest, MiscellaneousCopies) {
@@ -515,6 +533,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
std::vector<TransformationCopyObject> transformations = {
TransformationCopyObject(19, MakeInstructionDescriptor(22, SpvOpStore, 0),
@@ -533,8 +554,9 @@
17, MakeInstructionDescriptor(22, SpvOpCopyObject, 0), 106)};
for (auto& transformation : transformations) {
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
}
ASSERT_TRUE(IsValid(env, context.get()));
@@ -614,16 +636,19 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Illegal to copy null.
ASSERT_FALSE(TransformationCopyObject(
8, MakeInstructionDescriptor(5, SpvOpReturn, 0), 100)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Illegal to copy an OpUndef of pointer type.
ASSERT_FALSE(TransformationCopyObject(
9, MakeInstructionDescriptor(5, SpvOpReturn, 0), 100)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
}
TEST(TransformationCopyObjectTest, PropagateIrrelevantPointeeFact) {
@@ -655,7 +680,11 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
- fact_manager.AddFactValueOfPointeeIsIrrelevant(8);
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(8);
TransformationCopyObject transformation1(
8, MakeInstructionDescriptor(9, SpvOpReturn, 0), 100);
@@ -664,18 +693,84 @@
TransformationCopyObject transformation3(
100, MakeInstructionDescriptor(9, SpvOpReturn, 0), 102);
- ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager));
- transformation1.Apply(context.get(), &fact_manager);
- ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager));
- transformation2.Apply(context.get(), &fact_manager);
- ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager));
- transformation3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation1.IsApplicable(context.get(), transformation_context));
+ transformation1.Apply(context.get(), &transformation_context);
+ ASSERT_TRUE(
+ transformation2.IsApplicable(context.get(), transformation_context));
+ transformation2.Apply(context.get(), &transformation_context);
+ ASSERT_TRUE(
+ transformation3.IsApplicable(context.get(), transformation_context));
+ transformation3.Apply(context.get(), &transformation_context);
- ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(8));
- ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(100));
- ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(102));
- ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(9));
- ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(101));
+ ASSERT_TRUE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(8));
+ ASSERT_TRUE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(100));
+ ASSERT_TRUE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(102));
+ ASSERT_FALSE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(9));
+ ASSERT_FALSE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(101));
+}
+
+TEST(TransformationCopyObject, DoNotCopyOpSampledImage) {
+ // This checks that we do not try to copy the result id of an OpSampledImage
+ // instruction.
+ std::string shader = R"(
+ OpCapability Shader
+ OpCapability SampledBuffer
+ OpCapability ImageBuffer
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %40 %41
+ OpExecutionMode %2 OriginUpperLeft
+ OpSource GLSL 450
+ OpDecorate %40 DescriptorSet 0
+ OpDecorate %40 Binding 69
+ OpDecorate %41 DescriptorSet 0
+ OpDecorate %41 Binding 1
+ %54 = OpTypeFloat 32
+ %76 = OpTypeVector %54 4
+ %55 = OpConstant %54 0
+ %56 = OpTypeVector %54 3
+ %94 = OpTypeVector %54 2
+ %112 = OpConstantComposite %94 %55 %55
+ %57 = OpConstantComposite %56 %55 %55 %55
+ %15 = OpTypeImage %54 2D 2 0 0 1 Unknown
+ %114 = OpTypePointer UniformConstant %15
+ %38 = OpTypeSampler
+ %125 = OpTypePointer UniformConstant %38
+ %132 = OpTypeVoid
+ %133 = OpTypeFunction %132
+ %45 = OpTypeSampledImage %15
+ %40 = OpVariable %114 UniformConstant
+ %41 = OpVariable %125 UniformConstant
+ %2 = OpFunction %132 None %133
+ %164 = OpLabel
+ %184 = OpLoad %15 %40
+ %213 = OpLoad %38 %41
+ %216 = OpSampledImage %45 %184 %213
+ %217 = OpImageSampleImplicitLod %76 %216 %112 Bias %55
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ const auto env = SPV_ENV_UNIVERSAL_1_3;
+ const auto consumer = nullptr;
+ const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
+
+ FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ ASSERT_FALSE(
+ TransformationCopyObject(
+ 216, MakeInstructionDescriptor(217, SpvOpImageSampleImplicitLod, 0),
+ 500)
+ .IsApplicable(context.get(), transformation_context));
}
} // namespace
diff --git a/test/fuzz/transformation_equation_instruction_test.cpp b/test/fuzz/transformation_equation_instruction_test.cpp
index 81d849b..1e8aa7e 100644
--- a/test/fuzz/transformation_equation_instruction_test.cpp
+++ b/test/fuzz/transformation_equation_instruction_test.cpp
@@ -48,6 +48,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
protobufs::InstructionDescriptor return_instruction =
MakeInstructionDescriptor(13, SpvOpReturn, 0);
@@ -55,59 +58,61 @@
// Bad: id already in use.
ASSERT_FALSE(TransformationEquationInstruction(7, SpvOpSNegate, {7},
return_instruction)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: identified instruction does not exist.
ASSERT_FALSE(
TransformationEquationInstruction(
14, SpvOpSNegate, {7}, MakeInstructionDescriptor(13, SpvOpLoad, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: id 100 does not exist
ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpSNegate, {100},
return_instruction)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: id 20 is an OpUndef
ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpSNegate, {20},
return_instruction)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: id 30 is not available right before its definition
ASSERT_FALSE(TransformationEquationInstruction(
14, SpvOpSNegate, {30},
MakeInstructionDescriptor(30, SpvOpCopyObject, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: too many arguments to OpSNegate.
ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpSNegate, {7, 7},
return_instruction)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: 40 is a type id.
ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpSNegate, {40},
return_instruction)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: wrong type of argument to OpSNegate.
ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpSNegate, {41},
return_instruction)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
auto transformation1 = TransformationEquationInstruction(
14, SpvOpSNegate, {7}, return_instruction);
- ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager));
- transformation1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation1.IsApplicable(context.get(), transformation_context));
+ transformation1.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
auto transformation2 = TransformationEquationInstruction(
15, SpvOpSNegate, {14}, return_instruction);
- ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager));
- transformation2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation2.IsApplicable(context.get(), transformation_context));
+ transformation2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(15, {}), MakeDataDescriptor(7, {}), context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(15, {}), MakeDataDescriptor(7, {})));
std::string after_transformation = R"(
OpCapability Shader
@@ -161,6 +166,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
protobufs::InstructionDescriptor return_instruction =
MakeInstructionDescriptor(13, SpvOpReturn, 0);
@@ -168,32 +176,34 @@
// Bad: too few arguments to OpLogicalNot.
ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpLogicalNot, {},
return_instruction)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: 6 is a type id.
ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpLogicalNot, {6},
return_instruction)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: wrong type of argument to OpLogicalNot.
ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpLogicalNot, {21},
return_instruction)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
auto transformation1 = TransformationEquationInstruction(
14, SpvOpLogicalNot, {7}, return_instruction);
- ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager));
- transformation1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation1.IsApplicable(context.get(), transformation_context));
+ transformation1.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
auto transformation2 = TransformationEquationInstruction(
15, SpvOpLogicalNot, {14}, return_instruction);
- ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager));
- transformation2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation2.IsApplicable(context.get(), transformation_context));
+ transformation2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(15, {}), MakeDataDescriptor(7, {}), context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(15, {}), MakeDataDescriptor(7, {})));
std::string after_transformation = R"(
OpCapability Shader
@@ -248,6 +258,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
protobufs::InstructionDescriptor return_instruction =
MakeInstructionDescriptor(13, SpvOpReturn, 0);
@@ -255,59 +268,64 @@
// Bad: too many arguments to OpIAdd.
ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpIAdd, {15, 16, 16},
return_instruction)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: boolean argument to OpIAdd.
ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpIAdd, {15, 32},
return_instruction)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: type as argument to OpIAdd.
ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpIAdd, {33, 16},
return_instruction)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: arguments of mismatched widths
ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpIAdd, {15, 31},
return_instruction)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: arguments of mismatched widths
ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpIAdd, {31, 15},
return_instruction)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
auto transformation1 = TransformationEquationInstruction(
14, SpvOpIAdd, {15, 16}, return_instruction);
- ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager));
- transformation1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation1.IsApplicable(context.get(), transformation_context));
+ transformation1.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
auto transformation2 = TransformationEquationInstruction(
19, SpvOpISub, {14, 16}, return_instruction);
- ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager));
- transformation2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation2.IsApplicable(context.get(), transformation_context));
+ transformation2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(15, {}), MakeDataDescriptor(19, {}), context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(15, {}), MakeDataDescriptor(19, {})));
auto transformation3 = TransformationEquationInstruction(
20, SpvOpISub, {14, 15}, return_instruction);
- ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager));
- transformation3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation3.IsApplicable(context.get(), transformation_context));
+ transformation3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(20, {}), MakeDataDescriptor(16, {}), context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(20, {}), MakeDataDescriptor(16, {})));
auto transformation4 = TransformationEquationInstruction(
22, SpvOpISub, {16, 14}, return_instruction);
- ASSERT_TRUE(transformation4.IsApplicable(context.get(), fact_manager));
- transformation4.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation4.IsApplicable(context.get(), transformation_context));
+ transformation4.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
auto transformation5 = TransformationEquationInstruction(
24, SpvOpSNegate, {22}, return_instruction);
- ASSERT_TRUE(transformation5.IsApplicable(context.get(), fact_manager));
- transformation5.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation5.IsApplicable(context.get(), transformation_context));
+ transformation5.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(24, {}), MakeDataDescriptor(15, {}), context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(24, {}), MakeDataDescriptor(15, {})));
std::string after_transformation = R"(
OpCapability Shader
@@ -364,69 +382,80 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
protobufs::InstructionDescriptor return_instruction =
MakeInstructionDescriptor(13, SpvOpReturn, 0);
auto transformation1 = TransformationEquationInstruction(
14, SpvOpISub, {15, 16}, return_instruction);
- ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager));
- transformation1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation1.IsApplicable(context.get(), transformation_context));
+ transformation1.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
auto transformation2 = TransformationEquationInstruction(
17, SpvOpIAdd, {14, 16}, return_instruction);
- ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager));
- transformation2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation2.IsApplicable(context.get(), transformation_context));
+ transformation2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(17, {}), MakeDataDescriptor(15, {}), context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(17, {}), MakeDataDescriptor(15, {})));
auto transformation3 = TransformationEquationInstruction(
18, SpvOpIAdd, {16, 14}, return_instruction);
- ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager));
- transformation3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation3.IsApplicable(context.get(), transformation_context));
+ transformation3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(17, {}), MakeDataDescriptor(18, {}), context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(18, {}), MakeDataDescriptor(15, {}), context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(17, {}), MakeDataDescriptor(18, {})));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(18, {}), MakeDataDescriptor(15, {})));
auto transformation4 = TransformationEquationInstruction(
19, SpvOpISub, {14, 15}, return_instruction);
- ASSERT_TRUE(transformation4.IsApplicable(context.get(), fact_manager));
- transformation4.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation4.IsApplicable(context.get(), transformation_context));
+ transformation4.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
auto transformation5 = TransformationEquationInstruction(
20, SpvOpSNegate, {19}, return_instruction);
- ASSERT_TRUE(transformation5.IsApplicable(context.get(), fact_manager));
- transformation5.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation5.IsApplicable(context.get(), transformation_context));
+ transformation5.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(20, {}), MakeDataDescriptor(16, {}), context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(20, {}), MakeDataDescriptor(16, {})));
auto transformation6 = TransformationEquationInstruction(
21, SpvOpISub, {14, 19}, return_instruction);
- ASSERT_TRUE(transformation6.IsApplicable(context.get(), fact_manager));
- transformation6.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation6.IsApplicable(context.get(), transformation_context));
+ transformation6.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(21, {}), MakeDataDescriptor(15, {}), context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(21, {}), MakeDataDescriptor(15, {})));
auto transformation7 = TransformationEquationInstruction(
22, SpvOpISub, {14, 18}, return_instruction);
- ASSERT_TRUE(transformation7.IsApplicable(context.get(), fact_manager));
- transformation7.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation7.IsApplicable(context.get(), transformation_context));
+ transformation7.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
auto transformation8 = TransformationEquationInstruction(
23, SpvOpSNegate, {22}, return_instruction);
- ASSERT_TRUE(transformation8.IsApplicable(context.get(), fact_manager));
- transformation8.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation8.IsApplicable(context.get(), transformation_context));
+ transformation8.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.IsSynonymous(
- MakeDataDescriptor(23, {}), MakeDataDescriptor(16, {}), context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(23, {}), MakeDataDescriptor(16, {})));
std::string after_transformation = R"(
OpCapability Shader
@@ -457,6 +486,146 @@
ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
}
+TEST(TransformationEquationInstructionTest, Miscellaneous1) {
+ std::string shader = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %12 "main"
+ OpExecutionMode %12 OriginUpperLeft
+ OpSource ESSL 310
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeInt 32 1
+ %113 = OpConstant %6 24
+ %12 = OpFunction %2 None %3
+ %13 = 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;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ protobufs::InstructionDescriptor return_instruction =
+ MakeInstructionDescriptor(13, SpvOpReturn, 0);
+
+ auto transformation1 = TransformationEquationInstruction(
+ 522, SpvOpISub, {113, 113}, return_instruction);
+ ASSERT_TRUE(
+ transformation1.IsApplicable(context.get(), transformation_context));
+ transformation1.Apply(context.get(), &transformation_context);
+ ASSERT_TRUE(IsValid(env, context.get()));
+
+ auto transformation2 = TransformationEquationInstruction(
+ 570, SpvOpIAdd, {522, 113}, return_instruction);
+ ASSERT_TRUE(
+ transformation2.IsApplicable(context.get(), transformation_context));
+ transformation2.Apply(context.get(), &transformation_context);
+ ASSERT_TRUE(IsValid(env, context.get()));
+
+ std::string after_transformation = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %12 "main"
+ OpExecutionMode %12 OriginUpperLeft
+ OpSource ESSL 310
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeInt 32 1
+ %113 = OpConstant %6 24
+ %12 = OpFunction %2 None %3
+ %13 = OpLabel
+ %522 = OpISub %6 %113 %113
+ %570 = OpIAdd %6 %522 %113
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(570, {}), MakeDataDescriptor(113, {})));
+
+ ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
+}
+
+TEST(TransformationEquationInstructionTest, Miscellaneous2) {
+ std::string shader = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %12 "main"
+ OpExecutionMode %12 OriginUpperLeft
+ OpSource ESSL 310
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeInt 32 1
+ %113 = OpConstant %6 24
+ %12 = OpFunction %2 None %3
+ %13 = 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;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ protobufs::InstructionDescriptor return_instruction =
+ MakeInstructionDescriptor(13, SpvOpReturn, 0);
+
+ auto transformation1 = TransformationEquationInstruction(
+ 522, SpvOpISub, {113, 113}, return_instruction);
+ ASSERT_TRUE(
+ transformation1.IsApplicable(context.get(), transformation_context));
+ transformation1.Apply(context.get(), &transformation_context);
+ ASSERT_TRUE(IsValid(env, context.get()));
+
+ auto transformation2 = TransformationEquationInstruction(
+ 570, SpvOpIAdd, {522, 113}, return_instruction);
+ ASSERT_TRUE(
+ transformation2.IsApplicable(context.get(), transformation_context));
+ transformation2.Apply(context.get(), &transformation_context);
+ ASSERT_TRUE(IsValid(env, context.get()));
+
+ std::string after_transformation = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %12 "main"
+ OpExecutionMode %12 OriginUpperLeft
+ OpSource ESSL 310
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeInt 32 1
+ %113 = OpConstant %6 24
+ %12 = OpFunction %2 None %3
+ %13 = OpLabel
+ %522 = OpISub %6 %113 %113
+ %570 = OpIAdd %6 %522 %113
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(570, {}), MakeDataDescriptor(113, {})));
+
+ ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
+}
+
} // namespace
} // namespace fuzz
} // namespace spvtools
diff --git a/test/fuzz/transformation_function_call_test.cpp b/test/fuzz/transformation_function_call_test.cpp
index 9bd971e..d7305f8 100644
--- a/test/fuzz/transformation_function_call_test.cpp
+++ b/test/fuzz/transformation_function_call_test.cpp
@@ -134,24 +134,36 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
- fact_manager.AddFactBlockIsDead(59);
- fact_manager.AddFactBlockIsDead(11);
- fact_manager.AddFactBlockIsDead(18);
- fact_manager.AddFactBlockIsDead(25);
- fact_manager.AddFactBlockIsDead(96);
- fact_manager.AddFactBlockIsDead(205);
- fact_manager.AddFactFunctionIsLivesafe(21);
- fact_manager.AddFactFunctionIsLivesafe(200);
- fact_manager.AddFactValueOfPointeeIsIrrelevant(71);
- fact_manager.AddFactValueOfPointeeIsIrrelevant(72);
- fact_manager.AddFactValueOfPointeeIsIrrelevant(19);
- fact_manager.AddFactValueOfPointeeIsIrrelevant(20);
- fact_manager.AddFactValueOfPointeeIsIrrelevant(23);
- fact_manager.AddFactValueOfPointeeIsIrrelevant(44);
- fact_manager.AddFactValueOfPointeeIsIrrelevant(46);
- fact_manager.AddFactValueOfPointeeIsIrrelevant(51);
- fact_manager.AddFactValueOfPointeeIsIrrelevant(52);
+ transformation_context.GetFactManager()->AddFactBlockIsDead(59);
+ transformation_context.GetFactManager()->AddFactBlockIsDead(11);
+ transformation_context.GetFactManager()->AddFactBlockIsDead(18);
+ transformation_context.GetFactManager()->AddFactBlockIsDead(25);
+ transformation_context.GetFactManager()->AddFactBlockIsDead(96);
+ transformation_context.GetFactManager()->AddFactBlockIsDead(205);
+ transformation_context.GetFactManager()->AddFactFunctionIsLivesafe(21);
+ transformation_context.GetFactManager()->AddFactFunctionIsLivesafe(200);
+ transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
+ 71);
+ transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
+ 72);
+ transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
+ 19);
+ transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
+ 20);
+ transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
+ 23);
+ transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
+ 44);
+ transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
+ 46);
+ transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
+ 51);
+ transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
+ 52);
// 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)
@@ -164,127 +176,133 @@
ASSERT_FALSE(
TransformationFunctionCall(100, 21, {71, 72, 71},
MakeInstructionDescriptor(59, SpvOpBranch, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Too few arguments
ASSERT_FALSE(TransformationFunctionCall(
100, 21, {71}, MakeInstructionDescriptor(59, SpvOpBranch, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Arguments are the wrong way around (types do not match)
ASSERT_FALSE(
TransformationFunctionCall(100, 21, {72, 71},
MakeInstructionDescriptor(59, SpvOpBranch, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// 21 is not an appropriate argument
ASSERT_FALSE(
TransformationFunctionCall(100, 21, {21, 72},
MakeInstructionDescriptor(59, SpvOpBranch, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// 300 does not exist
ASSERT_FALSE(
TransformationFunctionCall(100, 21, {300, 72},
MakeInstructionDescriptor(59, SpvOpBranch, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// 71 is not a function
ASSERT_FALSE(
TransformationFunctionCall(100, 71, {71, 72},
MakeInstructionDescriptor(59, SpvOpBranch, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// 500 does not exist
ASSERT_FALSE(
TransformationFunctionCall(100, 500, {71, 72},
MakeInstructionDescriptor(59, SpvOpBranch, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Id is not fresh
ASSERT_FALSE(
TransformationFunctionCall(21, 21, {71, 72},
MakeInstructionDescriptor(59, SpvOpBranch, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Access chain as pointer parameter
ASSERT_FALSE(
TransformationFunctionCall(100, 21, {98, 72},
MakeInstructionDescriptor(59, SpvOpBranch, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Copied object as pointer parameter
ASSERT_FALSE(
TransformationFunctionCall(100, 21, {99, 72},
MakeInstructionDescriptor(59, SpvOpBranch, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Non-livesafe called from original live block
ASSERT_FALSE(
TransformationFunctionCall(
100, 10, {71}, MakeInstructionDescriptor(99, SpvOpSelectionMerge, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Non-livesafe called from livesafe function
ASSERT_FALSE(
TransformationFunctionCall(
100, 10, {19}, MakeInstructionDescriptor(38, SpvOpConvertFToS, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Livesafe function called with pointer to non-arbitrary local variable
ASSERT_FALSE(
TransformationFunctionCall(
100, 21, {61, 72}, MakeInstructionDescriptor(38, SpvOpConvertFToS, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Direct recursion
ASSERT_FALSE(TransformationFunctionCall(
100, 4, {}, MakeInstructionDescriptor(59, SpvOpBranch, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Indirect recursion
ASSERT_FALSE(TransformationFunctionCall(
100, 24, {9}, MakeInstructionDescriptor(96, SpvOpBranch, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Parameter 23 is not available at the call site
ASSERT_FALSE(
TransformationFunctionCall(104, 10, {23},
MakeInstructionDescriptor(205, SpvOpBranch, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Good transformations
{
// Livesafe called from dead block: fine
TransformationFunctionCall transformation(
100, 21, {71, 72}, MakeInstructionDescriptor(59, SpvOpBranch, 0));
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
}
{
// Livesafe called from original live block: fine
TransformationFunctionCall transformation(
101, 21, {71, 72}, MakeInstructionDescriptor(98, SpvOpAccessChain, 0));
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
}
{
// Livesafe called from livesafe function: fine
TransformationFunctionCall transformation(
102, 200, {19, 20}, MakeInstructionDescriptor(36, SpvOpLoad, 0));
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
}
{
// Dead called from dead block in injected function: fine
TransformationFunctionCall transformation(
103, 10, {23}, MakeInstructionDescriptor(45, SpvOpLoad, 0));
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
}
{
// Non-livesafe called from dead block in livesafe function: OK
TransformationFunctionCall transformation(
104, 10, {201}, MakeInstructionDescriptor(205, SpvOpBranch, 0));
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
}
{
// Livesafe called from dead block with non-arbitrary parameter
TransformationFunctionCall transformation(
105, 21, {62, 65}, MakeInstructionDescriptor(59, SpvOpBranch, 0));
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
}
@@ -429,13 +447,16 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
- fact_manager.AddFactBlockIsDead(11);
+ transformation_context.GetFactManager()->AddFactBlockIsDead(11);
// 4 is an entry point, so it is not legal for it to be the target of a call.
ASSERT_FALSE(TransformationFunctionCall(
100, 4, {}, MakeInstructionDescriptor(11, SpvOpReturn, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
}
} // namespace
diff --git a/test/fuzz/transformation_load_test.cpp b/test/fuzz/transformation_load_test.cpp
index 1f728ff..18ca195 100644
--- a/test/fuzz/transformation_load_test.cpp
+++ b/test/fuzz/transformation_load_test.cpp
@@ -85,14 +85,22 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
- fact_manager.AddFactValueOfPointeeIsIrrelevant(27);
- fact_manager.AddFactValueOfPointeeIsIrrelevant(11);
- fact_manager.AddFactValueOfPointeeIsIrrelevant(46);
- fact_manager.AddFactValueOfPointeeIsIrrelevant(16);
- fact_manager.AddFactValueOfPointeeIsIrrelevant(52);
+ transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
+ 27);
+ transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
+ 11);
+ transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
+ 46);
+ transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
+ 16);
+ transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
+ 52);
- fact_manager.AddFactBlockIsDead(36);
+ transformation_context.GetFactManager()->AddFactBlockIsDead(36);
// Variables with pointee types:
// 52 - ptr_to(7)
@@ -125,86 +133,90 @@
// Bad: id is not fresh
ASSERT_FALSE(TransformationLoad(
33, 33, MakeInstructionDescriptor(38, SpvOpAccessChain, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: attempt to load from 11 from outside its function
ASSERT_FALSE(TransformationLoad(
100, 11, MakeInstructionDescriptor(38, SpvOpAccessChain, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: pointer is not available
ASSERT_FALSE(TransformationLoad(
100, 33, MakeInstructionDescriptor(45, SpvOpCopyObject, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: attempt to insert before OpVariable
ASSERT_FALSE(TransformationLoad(
100, 27, MakeInstructionDescriptor(27, SpvOpVariable, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: pointer id does not exist
ASSERT_FALSE(
TransformationLoad(100, 1000,
MakeInstructionDescriptor(38, SpvOpAccessChain, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: pointer id exists but does not have a type
ASSERT_FALSE(TransformationLoad(
100, 5, MakeInstructionDescriptor(38, SpvOpAccessChain, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: pointer id exists and has a type, but is not a pointer
ASSERT_FALSE(TransformationLoad(
100, 24, MakeInstructionDescriptor(38, SpvOpAccessChain, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: attempt to load from null pointer
ASSERT_FALSE(TransformationLoad(
100, 60, MakeInstructionDescriptor(38, SpvOpAccessChain, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: attempt to load from undefined pointer
ASSERT_FALSE(TransformationLoad(
100, 61, MakeInstructionDescriptor(38, SpvOpAccessChain, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: %40 is not available at the program point
ASSERT_FALSE(
TransformationLoad(100, 40, MakeInstructionDescriptor(37, SpvOpReturn, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: The described instruction does not exist
ASSERT_FALSE(TransformationLoad(
100, 33, MakeInstructionDescriptor(1000, SpvOpReturn, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
{
TransformationLoad transformation(
100, 33, MakeInstructionDescriptor(38, SpvOpAccessChain, 0));
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
}
{
TransformationLoad transformation(
101, 46, MakeInstructionDescriptor(16, SpvOpReturnValue, 0));
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
}
{
TransformationLoad transformation(
102, 16, MakeInstructionDescriptor(16, SpvOpReturnValue, 0));
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
}
{
TransformationLoad transformation(
103, 40, MakeInstructionDescriptor(43, SpvOpAccessChain, 0));
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
}
diff --git a/test/fuzz/transformation_merge_blocks_test.cpp b/test/fuzz/transformation_merge_blocks_test.cpp
index e2b4aa6..4500445 100644
--- a/test/fuzz/transformation_merge_blocks_test.cpp
+++ b/test/fuzz/transformation_merge_blocks_test.cpp
@@ -45,11 +45,14 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
- ASSERT_FALSE(
- TransformationMergeBlocks(3).IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(
- TransformationMergeBlocks(7).IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(TransformationMergeBlocks(3).IsApplicable(
+ context.get(), transformation_context));
+ ASSERT_FALSE(TransformationMergeBlocks(7).IsApplicable(
+ context.get(), transformation_context));
}
TEST(TransformationMergeBlocksTest, DoNotMergeFirstBlockHasMultipleSuccessors) {
@@ -84,9 +87,12 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
- ASSERT_FALSE(
- TransformationMergeBlocks(6).IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(TransformationMergeBlocks(6).IsApplicable(
+ context.get(), transformation_context));
}
TEST(TransformationMergeBlocksTest,
@@ -122,9 +128,12 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
- ASSERT_FALSE(
- TransformationMergeBlocks(10).IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(TransformationMergeBlocks(10).IsApplicable(
+ context.get(), transformation_context));
}
TEST(TransformationMergeBlocksTest, MergeWhenSecondBlockIsSelectionMerge) {
@@ -161,10 +170,14 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationMergeBlocks transformation(10);
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -231,10 +244,14 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationMergeBlocks transformation(10);
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -306,10 +323,14 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationMergeBlocks transformation(11);
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -377,10 +398,14 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationMergeBlocks transformation(6);
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -454,12 +479,16 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
for (auto& transformation :
{TransformationMergeBlocks(100), TransformationMergeBlocks(101),
TransformationMergeBlocks(102), TransformationMergeBlocks(103)}) {
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
}
@@ -542,11 +571,15 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
for (auto& transformation :
{TransformationMergeBlocks(101), TransformationMergeBlocks(100)}) {
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
}
@@ -629,10 +662,14 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationMergeBlocks transformation(101);
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
diff --git a/test/fuzz/transformation_move_block_down_test.cpp b/test/fuzz/transformation_move_block_down_test.cpp
index 02761a2..662e88c 100644
--- a/test/fuzz/transformation_move_block_down_test.cpp
+++ b/test/fuzz/transformation_move_block_down_test.cpp
@@ -53,9 +53,13 @@
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
auto transformation = TransformationMoveBlockDown(11);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationMoveBlockDownTest, NoMovePossible2) {
@@ -90,9 +94,13 @@
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
auto transformation = TransformationMoveBlockDown(5);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationMoveBlockDownTest, NoMovePossible3) {
@@ -129,9 +137,13 @@
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
auto transformation = TransformationMoveBlockDown(100);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationMoveBlockDownTest, NoMovePossible4) {
@@ -172,9 +184,13 @@
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
auto transformation = TransformationMoveBlockDown(12);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationMoveBlockDownTest, ManyMovesPossible) {
@@ -277,6 +293,9 @@
BuildModule(env, consumer, before_transformation, kFuzzAssembleOption);
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// The block ids are: 5 14 20 23 21 25 29 32 30 15
// We make a transformation to move each of them down, plus a transformation
@@ -306,110 +325,130 @@
// 15 dominates nothing
// Current ordering: 5 14 20 23 21 25 29 32 30 15
- ASSERT_FALSE(move_down_5.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_14.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_20.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_23.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_21.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_25.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_29.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_32.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_30.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_15.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(move_down_5.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_14.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_20.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_23.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_21.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_25.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_29.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_32.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_30.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_15.IsApplicable(context.get(), transformation_context));
// Let's bubble 20 all the way down.
- move_down_20.Apply(context.get(), &fact_manager);
+ move_down_20.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Current ordering: 5 14 23 20 21 25 29 32 30 15
- ASSERT_FALSE(move_down_5.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_14.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_23.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_20.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_21.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_25.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_29.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_32.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_30.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_15.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(move_down_5.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_14.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_23.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_20.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_21.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_25.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_29.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_32.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_30.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_15.IsApplicable(context.get(), transformation_context));
- move_down_20.Apply(context.get(), &fact_manager);
+ move_down_20.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Current ordering: 5 14 23 21 20 25 29 32 30 15
- ASSERT_FALSE(move_down_5.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_14.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_23.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_21.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_20.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_25.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_29.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_32.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_30.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_15.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(move_down_5.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_14.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_23.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_21.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_20.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_25.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_29.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_32.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_30.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_15.IsApplicable(context.get(), transformation_context));
- move_down_20.Apply(context.get(), &fact_manager);
+ move_down_20.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Current ordering: 5 14 23 21 25 20 29 32 30 15
- ASSERT_FALSE(move_down_5.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_14.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_23.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_21.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_25.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_20.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_29.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_32.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_30.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_15.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(move_down_5.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_14.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_23.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_21.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_25.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_20.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_29.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_32.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_30.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_15.IsApplicable(context.get(), transformation_context));
- move_down_20.Apply(context.get(), &fact_manager);
+ move_down_20.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Current ordering: 5 14 23 21 25 29 20 32 30 15
- ASSERT_FALSE(move_down_5.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_14.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_23.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_21.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_25.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_29.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_20.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_32.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_30.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_15.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(move_down_5.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_14.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_23.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_21.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_25.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_29.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_20.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_32.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_30.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_15.IsApplicable(context.get(), transformation_context));
- move_down_20.Apply(context.get(), &fact_manager);
+ move_down_20.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Current ordering: 5 14 23 21 25 29 32 20 30 15
- ASSERT_FALSE(move_down_5.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_14.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_23.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_21.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_25.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_29.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_32.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_20.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_30.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_15.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(move_down_5.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_14.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_23.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_21.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_25.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_29.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_32.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_20.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_30.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_15.IsApplicable(context.get(), transformation_context));
- move_down_20.Apply(context.get(), &fact_manager);
+ move_down_20.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Current ordering: 5 14 23 21 25 29 32 30 20 15
- ASSERT_FALSE(move_down_5.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_14.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_23.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_21.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_25.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_29.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_32.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_30.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_20.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_15.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(move_down_5.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_14.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_23.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_21.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_25.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_29.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_32.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_30.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_20.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_15.IsApplicable(context.get(), transformation_context));
- move_down_20.Apply(context.get(), &fact_manager);
+ move_down_20.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_bubbling_20_down = R"(
@@ -485,63 +524,72 @@
ASSERT_TRUE(IsEqual(env, after_bubbling_20_down, context.get()));
// Current ordering: 5 14 23 21 25 29 32 30 15 20
- ASSERT_FALSE(move_down_5.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_14.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_23.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_21.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_25.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_29.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_32.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_30.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_15.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_20.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(move_down_5.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_14.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_23.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_21.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_25.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_29.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_32.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_30.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_15.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_20.IsApplicable(context.get(), transformation_context));
- move_down_23.Apply(context.get(), &fact_manager);
+ move_down_23.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Current ordering: 5 14 21 23 25 29 32 30 15 20
- ASSERT_FALSE(move_down_5.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_14.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_21.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_23.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_25.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_29.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_32.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_30.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_15.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_20.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(move_down_5.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_14.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_21.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_23.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_25.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_29.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_32.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_30.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_15.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_20.IsApplicable(context.get(), transformation_context));
- move_down_23.Apply(context.get(), &fact_manager);
+ move_down_23.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Current ordering: 5 14 21 25 23 29 32 30 15 20
- ASSERT_FALSE(move_down_5.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_14.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_21.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_25.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_23.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_29.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_32.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_30.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_15.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_20.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(move_down_5.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_14.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_21.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_25.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_23.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_29.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_32.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_30.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_15.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_20.IsApplicable(context.get(), transformation_context));
- move_down_21.Apply(context.get(), &fact_manager);
+ move_down_21.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Current ordering: 5 14 25 21 23 29 32 30 15 20
- ASSERT_FALSE(move_down_5.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_14.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_21.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_25.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_23.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_29.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_32.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_30.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_15.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_20.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(move_down_5.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_14.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_21.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_25.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_23.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_29.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_32.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_30.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_15.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_20.IsApplicable(context.get(), transformation_context));
- move_down_14.Apply(context.get(), &fact_manager);
+ move_down_14.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_more_shuffling = R"(
@@ -617,16 +665,18 @@
ASSERT_TRUE(IsEqual(env, after_more_shuffling, context.get()));
// Final ordering: 5 25 14 21 23 29 32 30 15 20
- ASSERT_FALSE(move_down_5.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_25.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_14.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_21.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_23.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_29.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_32.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_30.IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(move_down_15.IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(move_down_20.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(move_down_5.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_25.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_14.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_21.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_23.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_29.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_32.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_30.IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(move_down_15.IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ move_down_20.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationMoveBlockDownTest, DoNotMoveUnreachable) {
@@ -660,9 +710,13 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
auto transformation = TransformationMoveBlockDown(6);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
}
} // namespace
diff --git a/test/fuzz/transformation_outline_function_test.cpp b/test/fuzz/transformation_outline_function_test.cpp
index 40aaebc..ed4fd15 100644
--- a/test/fuzz/transformation_outline_function_test.cpp
+++ b/test/fuzz/transformation_outline_function_test.cpp
@@ -44,12 +44,16 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(5, 5, /* not relevant */ 200,
100, 101, 102, 103,
/* not relevant */ 201, {}, {});
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -105,11 +109,15 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(5, 5, /* not relevant */ 200,
100, 101, 102, 103,
/* not relevant */ 201, {}, {});
- ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationOutlineFunctionTest, OutlineInterestingControlFlowNoState) {
@@ -158,12 +166,16 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(6, 13, /* not relevant */
200, 100, 101, 102, 103,
/* not relevant */ 201, {}, {});
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -243,12 +255,16 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(6, 6, /* not relevant */ 200,
100, 101, 102, 103,
/* not relevant */ 201, {}, {});
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -317,11 +333,15 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(6, 6, 99, 100, 101, 102, 103,
105, {}, {{9, 104}});
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -412,12 +432,16 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(
6, 80, 100, 101, 102, 103, 104, 105, {},
{{15, 106}, {9, 107}, {7, 108}, {8, 109}});
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -508,11 +532,15 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(6, 6, 100, 101, 102, 103, 104,
105, {{7, 106}}, {});
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -582,11 +610,15 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(6, 6, 100, 101, 102, 103, 104,
105, {{13, 106}}, {});
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -666,11 +698,15 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(11, 11, 100, 101, 102, 103, 104,
105, {{9, 106}}, {{14, 107}});
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -752,10 +788,14 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(6, 8, 100, 101, 102, 103, 104,
105, {}, {});
- ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationOutlineFunctionTest, DoNotOutlineIfRegionInvolvesReturn) {
@@ -798,11 +838,15 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(6, 11, /* not relevant */ 200,
100, 101, 102, 103,
/* not relevant */ 201, {}, {});
- ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationOutlineFunctionTest, DoNotOutlineIfRegionInvolvesKill) {
@@ -845,11 +889,15 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(6, 11, /* not relevant */ 200,
100, 101, 102, 103,
/* not relevant */ 201, {}, {});
- ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationOutlineFunctionTest,
@@ -893,11 +941,15 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(6, 11, /* not relevant */ 200,
100, 101, 102, 103,
/* not relevant */ 201, {}, {});
- ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationOutlineFunctionTest,
@@ -933,10 +985,14 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(6, 8, 100, 101, 102, 103, 104,
105, {}, {});
- ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationOutlineFunctionTest, DoNotOutlineIfLoopHeadIsOutsideRegion) {
@@ -973,10 +1029,14 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(7, 8, 100, 101, 102, 103, 104,
105, {}, {});
- ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationOutlineFunctionTest,
@@ -1012,10 +1072,14 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(6, 7, 100, 101, 102, 103, 104,
105, {}, {});
- ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationOutlineFunctionTest,
@@ -1053,10 +1117,14 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(6, 7, 100, 101, 102, 103, 104,
105, {}, {});
- ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationOutlineFunctionTest,
@@ -1094,10 +1162,14 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(8, 11, 100, 101, 102, 103, 104,
105, {}, {});
- ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationOutlineFunctionTest, OutlineRegionEndingWithReturnVoid) {
@@ -1132,6 +1204,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(
/*entry_block*/ 54,
@@ -1145,8 +1220,9 @@
/*input_id_to_fresh_id*/ {{22, 206}},
/*output_id_to_fresh_id*/ {});
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -1219,6 +1295,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(
/*entry_block*/ 9,
@@ -1232,8 +1311,9 @@
/*input_id_to_fresh_id*/ {{31, 206}},
/*output_id_to_fresh_id*/ {{32, 207}});
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -1310,6 +1390,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(
/*entry_block*/ 54,
@@ -1323,8 +1406,9 @@
/*input_id_to_fresh_id*/ {{}},
/*output_id_to_fresh_id*/ {{6, 206}});
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -1396,6 +1480,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(
/*entry_block*/ 54,
@@ -1409,8 +1496,9 @@
/*input_id_to_fresh_id*/ {},
/*output_id_to_fresh_id*/ {});
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -1478,6 +1566,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(
/*entry_block*/ 21,
@@ -1491,7 +1582,8 @@
/*input_id_to_fresh_id*/ {{22, 207}},
/*output_id_to_fresh_id*/ {{23, 208}});
- ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationOutlineFunctionTest,
@@ -1531,6 +1623,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(
/*entry_block*/ 21,
@@ -1544,7 +1639,8 @@
/*input_id_to_fresh_id*/ {},
/*output_id_to_fresh_id*/ {});
- ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationOutlineFunctionTest,
@@ -1584,6 +1680,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(
/*entry_block*/ 5,
@@ -1597,7 +1696,8 @@
/*input_id_to_fresh_id*/ {},
/*output_id_to_fresh_id*/ {});
- ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationOutlineFunctionTest, DoNotOutlineRegionThatUsesAccessChain) {
@@ -1640,6 +1740,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(
/*entry_block*/ 13,
@@ -1653,7 +1756,8 @@
/*input_id_to_fresh_id*/ {{12, 207}},
/*output_id_to_fresh_id*/ {});
- ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationOutlineFunctionTest,
@@ -1698,6 +1802,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(
/*entry_block*/ 13,
@@ -1711,7 +1818,8 @@
/*input_id_to_fresh_id*/ {{20, 207}},
/*output_id_to_fresh_id*/ {});
- ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationOutlineFunctionTest,
@@ -1761,6 +1869,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(
/*entry_block*/ 11,
@@ -1774,8 +1885,9 @@
/*input_id_to_fresh_id*/ {{9, 207}},
/*output_id_to_fresh_id*/ {{14, 208}});
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -1913,9 +2025,15 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
- fact_manager.AddFactFunctionIsLivesafe(30);
- fact_manager.AddFactValueOfPointeeIsIrrelevant(200);
- fact_manager.AddFactValueOfPointeeIsIrrelevant(201);
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ transformation_context.GetFactManager()->AddFactFunctionIsLivesafe(30);
+ transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
+ 200);
+ transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
+ 201);
TransformationOutlineFunction transformation(
/*entry_block*/ 198,
@@ -1929,24 +2047,31 @@
/*input_id_to_fresh_id*/ {{100, 407}, {200, 408}, {201, 409}},
/*output_id_to_fresh_id*/ {});
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// The original function should still be livesafe.
- ASSERT_TRUE(fact_manager.FunctionIsLivesafe(30));
+ ASSERT_TRUE(transformation_context.GetFactManager()->FunctionIsLivesafe(30));
// The outlined function should be livesafe.
- ASSERT_TRUE(fact_manager.FunctionIsLivesafe(402));
+ ASSERT_TRUE(transformation_context.GetFactManager()->FunctionIsLivesafe(402));
// The variable and parameter that were originally irrelevant should still be.
- ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(200));
- ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(201));
+ ASSERT_TRUE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(200));
+ ASSERT_TRUE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(201));
// The loop limiter should still be non-irrelevant.
- ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(100));
+ ASSERT_FALSE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(100));
// The parameters for the original irrelevant variables should be irrelevant.
- ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(408));
- ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(409));
+ ASSERT_TRUE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(408));
+ ASSERT_TRUE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(409));
// The parameter for the loop limiter should not be irrelevant.
- ASSERT_FALSE(fact_manager.PointeeValueIsIrrelevant(407));
+ ASSERT_FALSE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(407));
std::string after_transformation = R"(
OpCapability Shader
@@ -2129,8 +2254,12 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
for (uint32_t block_id : {16u, 23u, 24u, 26u, 27u, 34u, 35u, 50u}) {
- fact_manager.AddFactBlockIsDead(block_id);
+ transformation_context.GetFactManager()->AddFactBlockIsDead(block_id);
}
TransformationOutlineFunction transformation(
@@ -2145,12 +2274,13 @@
/*input_id_to_fresh_id*/ {{9, 206}, {12, 207}, {21, 208}},
/*output_id_to_fresh_id*/ {});
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// All the original blocks, plus the new function entry block, should be dead.
for (uint32_t block_id : {16u, 23u, 24u, 26u, 27u, 34u, 35u, 50u, 203u}) {
- ASSERT_TRUE(fact_manager.BlockIsDead(block_id));
+ ASSERT_TRUE(transformation_context.GetFactManager()->BlockIsDead(block_id));
}
}
@@ -2208,8 +2338,12 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
for (uint32_t block_id : {32u, 34u, 35u}) {
- fact_manager.AddFactBlockIsDead(block_id);
+ transformation_context.GetFactManager()->AddFactBlockIsDead(block_id);
}
TransformationOutlineFunction transformation(
@@ -2224,15 +2358,17 @@
/*input_id_to_fresh_id*/ {{11, 206}},
/*output_id_to_fresh_id*/ {});
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// The blocks that were originally dead, but not others, should be dead.
for (uint32_t block_id : {32u, 34u, 35u}) {
- ASSERT_TRUE(fact_manager.BlockIsDead(block_id));
+ ASSERT_TRUE(transformation_context.GetFactManager()->BlockIsDead(block_id));
}
for (uint32_t block_id : {5u, 30u, 31u, 33u, 36u, 37u, 203u}) {
- ASSERT_FALSE(fact_manager.BlockIsDead(block_id));
+ ASSERT_FALSE(
+ transformation_context.GetFactManager()->BlockIsDead(block_id));
}
}
@@ -2287,8 +2423,13 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
- fact_manager.AddFactValueOfPointeeIsIrrelevant(9);
- fact_manager.AddFactValueOfPointeeIsIrrelevant(14);
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(9);
+ transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
+ 14);
TransformationOutlineFunction transformation(
/*entry_block*/ 50,
@@ -2302,19 +2443,141 @@
/*input_id_to_fresh_id*/ {{9, 206}, {10, 207}, {14, 208}, {20, 209}},
/*output_id_to_fresh_id*/ {});
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// The variables that were originally irrelevant, plus input parameters
// corresponding to them, should be irrelevant. The rest should not be.
for (uint32_t variable_id : {9u, 14u, 206u, 208u}) {
- ASSERT_TRUE(fact_manager.PointeeValueIsIrrelevant(variable_id));
+ ASSERT_TRUE(
+ transformation_context.GetFactManager()->PointeeValueIsIrrelevant(
+ variable_id));
}
for (uint32_t variable_id : {10u, 20u, 207u, 209u}) {
- ASSERT_FALSE(fact_manager.BlockIsDead(variable_id));
+ ASSERT_FALSE(
+ transformation_context.GetFactManager()->BlockIsDead(variable_id));
}
}
+TEST(TransformationOutlineFunctionTest,
+ DoNotOutlineCodeThatProducesUsedPointer) {
+ // This checks that we cannot outline a region of code if it produces a
+ // pointer result id that gets used outside the region. This avoids creating
+ // a struct with a pointer member.
+ std::string shader = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %6 "main"
+ OpExecutionMode %6 OriginUpperLeft
+ OpSource ESSL 310
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %21 = OpTypeBool
+ %100 = OpTypeInt 32 0
+ %99 = OpConstant %100 0
+ %101 = OpTypeVector %100 2
+ %102 = OpTypePointer Function %100
+ %103 = OpTypePointer Function %101
+ %6 = OpFunction %2 None %3
+ %7 = OpLabel
+ %104 = OpVariable %103 Function
+ OpBranch %80
+ %80 = OpLabel
+ %105 = OpAccessChain %102 %104 %99
+ OpBranch %106
+ %106 = OpLabel
+ OpStore %105 %99
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ const auto env = SPV_ENV_UNIVERSAL_1_5;
+ const auto consumer = nullptr;
+ const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, context.get()));
+
+ FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ TransformationOutlineFunction transformation(
+ /*entry_block*/ 80,
+ /*exit_block*/ 80,
+ /*new_function_struct_return_type_id*/ 300,
+ /*new_function_type_id*/ 301,
+ /*new_function_id*/ 302,
+ /*new_function_region_entry_block*/ 304,
+ /*new_caller_result_id*/ 305,
+ /*new_callee_result_id*/ 306,
+ /*input_id_to_fresh_id*/ {{104, 307}},
+ /*output_id_to_fresh_id*/ {{105, 308}});
+
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
+}
+
+TEST(TransformationOutlineFunctionTest, ExitBlockHeadsLoop) {
+ // This checks that it is not possible outline a region that ends in a loop
+ // head.
+ std::string shader = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main"
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %15 = OpTypeInt 32 1
+ %35 = OpTypeBool
+ %39 = OpConstant %15 1
+ %40 = OpConstantTrue %35
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ OpBranch %22
+ %22 = OpLabel
+ OpBranch %23
+ %23 = OpLabel
+ %24 = OpPhi %15 %39 %22 %39 %25
+ OpLoopMerge %26 %25 None
+ OpBranchConditional %40 %25 %26
+ %25 = OpLabel
+ OpBranch %23
+ %26 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ const auto env = SPV_ENV_UNIVERSAL_1_5;
+ const auto consumer = nullptr;
+ const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, context.get()));
+
+ FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ TransformationOutlineFunction transformation(
+ /*entry_block*/ 22,
+ /*exit_block*/ 23,
+ /*new_function_struct_return_type_id*/ 200,
+ /*new_function_type_id*/ 201,
+ /*new_function_id*/ 202,
+ /*new_function_region_entry_block*/ 203,
+ /*new_caller_result_id*/ 204,
+ /*new_callee_result_id*/ 205,
+ /*input_id_to_fresh_id*/ {},
+ /*output_id_to_fresh_id*/ {});
+
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
+}
+
TEST(TransformationOutlineFunctionTest, Miscellaneous1) {
// This tests outlining of some non-trivial code.
@@ -2423,6 +2686,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(
/*entry_block*/ 150,
@@ -2436,8 +2702,9 @@
/*input_id_to_fresh_id*/ {{102, 300}, {103, 301}, {40, 302}},
/*output_id_to_fresh_id*/ {{106, 400}, {107, 401}});
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -2588,6 +2855,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(
/*entry_block*/ 38,
@@ -2601,7 +2871,8 @@
/*input_id_to_fresh_id*/ {},
/*output_id_to_fresh_id*/ {});
- ASSERT_FALSE(transformation.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationOutlineFunctionTest, Miscellaneous3) {
@@ -2643,6 +2914,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(
/*entry_block*/ 80,
@@ -2656,8 +2930,9 @@
/*input_id_to_fresh_id*/ {},
/*output_id_to_fresh_id*/ {});
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
@@ -2732,6 +3007,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationOutlineFunction transformation(
/*entry_block*/ 80,
@@ -2745,8 +3023,9 @@
/*input_id_to_fresh_id*/ {{104, 307}},
/*output_id_to_fresh_id*/ {});
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
diff --git a/test/fuzz/transformation_permute_function_parameters_test.cpp b/test/fuzz/transformation_permute_function_parameters_test.cpp
index 1af4699..a4a7c00 100644
--- a/test/fuzz/transformation_permute_function_parameters_test.cpp
+++ b/test/fuzz/transformation_permute_function_parameters_test.cpp
@@ -200,52 +200,57 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Can't permute main function
ASSERT_FALSE(TransformationPermuteFunctionParameters(4, 0, {}).IsApplicable(
- context.get(), fact_manager));
+ context.get(), transformation_context));
// Can't permute invalid instruction
ASSERT_FALSE(TransformationPermuteFunctionParameters(101, 0, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Permutation has too many values
ASSERT_FALSE(TransformationPermuteFunctionParameters(22, 0, {2, 1, 0, 3})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Permutation has too few values
ASSERT_FALSE(TransformationPermuteFunctionParameters(22, 0, {0, 1})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Permutation has invalid values
ASSERT_FALSE(TransformationPermuteFunctionParameters(22, 0, {3, 1, 0})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Type id is not an OpTypeFunction instruction
ASSERT_FALSE(TransformationPermuteFunctionParameters(22, 42, {2, 1, 0})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Type id has incorrect number of operands
ASSERT_FALSE(TransformationPermuteFunctionParameters(22, 9, {2, 1, 0})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// OpTypeFunction has operands out of order
ASSERT_FALSE(TransformationPermuteFunctionParameters(22, 18, {2, 1, 0})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Successful transformations
{
// Function has two operands of the same type:
// initial OpTypeFunction should be enough
TransformationPermuteFunctionParameters transformation(12, 9, {1, 0});
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
}
{
TransformationPermuteFunctionParameters transformation(28, 105, {1, 0});
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
}
diff --git a/test/fuzz/transformation_replace_boolean_constant_with_constant_binary_test.cpp b/test/fuzz/transformation_replace_boolean_constant_with_constant_binary_test.cpp
index 527a7b7..b320308 100644
--- a/test/fuzz/transformation_replace_boolean_constant_with_constant_binary_test.cpp
+++ b/test/fuzz/transformation_replace_boolean_constant_with_constant_binary_test.cpp
@@ -163,6 +163,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
std::vector<protobufs::IdUseDescriptor> uses_of_true = {
MakeIdUseDescriptor(41, MakeInstructionDescriptor(44, SpvOpStore, 12), 1),
@@ -197,10 +200,10 @@
#define CHECK_OPERATOR(USE_DESCRIPTOR, LHS_ID, RHS_ID, OPCODE, FRESH_ID) \
ASSERT_TRUE(TransformationReplaceBooleanConstantWithConstantBinary( \
USE_DESCRIPTOR, LHS_ID, RHS_ID, OPCODE, FRESH_ID) \
- .IsApplicable(context.get(), fact_manager)); \
+ .IsApplicable(context.get(), transformation_context)); \
ASSERT_FALSE(TransformationReplaceBooleanConstantWithConstantBinary( \
USE_DESCRIPTOR, RHS_ID, LHS_ID, OPCODE, FRESH_ID) \
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
#define CHECK_TRANSFORMATION_APPLICABILITY(GT_OPCODES, LT_OPCODES, SMALL_ID, \
LARGE_ID) \
@@ -252,27 +255,27 @@
// Target id is not fresh
ASSERT_FALSE(TransformationReplaceBooleanConstantWithConstantBinary(
uses_of_true[0], 15, 17, SpvOpFOrdLessThan, 15)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// LHS id does not exist
ASSERT_FALSE(TransformationReplaceBooleanConstantWithConstantBinary(
uses_of_true[0], 300, 17, SpvOpFOrdLessThan, 200)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// RHS id does not exist
ASSERT_FALSE(TransformationReplaceBooleanConstantWithConstantBinary(
uses_of_true[0], 15, 300, SpvOpFOrdLessThan, 200)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// LHS and RHS ids do not match type
ASSERT_FALSE(TransformationReplaceBooleanConstantWithConstantBinary(
uses_of_true[0], 11, 17, SpvOpFOrdLessThan, 200)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Opcode not appropriate
ASSERT_FALSE(TransformationReplaceBooleanConstantWithConstantBinary(
uses_of_true[0], 15, 17, SpvOpFDiv, 200)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
auto replace_true_with_double_comparison =
TransformationReplaceBooleanConstantWithConstantBinary(
@@ -287,21 +290,25 @@
TransformationReplaceBooleanConstantWithConstantBinary(
uses_of_false[1], 33, 31, SpvOpSLessThan, 103);
- ASSERT_TRUE(replace_true_with_double_comparison.IsApplicable(context.get(),
- fact_manager));
- replace_true_with_double_comparison.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(replace_true_with_double_comparison.IsApplicable(
+ context.get(), transformation_context));
+ replace_true_with_double_comparison.Apply(context.get(),
+ &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(replace_true_with_uint32_comparison.IsApplicable(context.get(),
- fact_manager));
- replace_true_with_uint32_comparison.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(replace_true_with_uint32_comparison.IsApplicable(
+ context.get(), transformation_context));
+ replace_true_with_uint32_comparison.Apply(context.get(),
+ &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(replace_false_with_float_comparison.IsApplicable(context.get(),
- fact_manager));
- replace_false_with_float_comparison.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(replace_false_with_float_comparison.IsApplicable(
+ context.get(), transformation_context));
+ replace_false_with_float_comparison.Apply(context.get(),
+ &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(replace_false_with_sint64_comparison.IsApplicable(context.get(),
- fact_manager));
- replace_false_with_sint64_comparison.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(replace_false_with_sint64_comparison.IsApplicable(
+ context.get(), transformation_context));
+ replace_false_with_sint64_comparison.Apply(context.get(),
+ &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after = R"(
@@ -419,7 +426,7 @@
// The transformation is not applicable because %200 is NaN.
ASSERT_FALSE(TransformationReplaceBooleanConstantWithConstantBinary(
uses_of_true[0], 11, 200, SpvOpFOrdLessThan, 300)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
}
if (std::numeric_limits<double>::has_infinity) {
double positive_infinity_double = std::numeric_limits<double>::infinity();
@@ -436,7 +443,7 @@
// transformation is restricted to only apply to finite values.
ASSERT_FALSE(TransformationReplaceBooleanConstantWithConstantBinary(
uses_of_true[0], 11, 201, SpvOpFOrdLessThan, 300)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
}
if (std::numeric_limits<float>::has_infinity) {
float positive_infinity_float = std::numeric_limits<float>::infinity();
@@ -461,7 +468,7 @@
// values.
ASSERT_FALSE(TransformationReplaceBooleanConstantWithConstantBinary(
uses_of_true[0], 203, 202, SpvOpFOrdLessThan, 300)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
}
}
@@ -531,6 +538,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
auto use_of_true_in_if = MakeIdUseDescriptor(
13, MakeInstructionDescriptor(10, SpvOpBranchConditional, 0), 0);
@@ -542,12 +552,14 @@
auto replacement_2 = TransformationReplaceBooleanConstantWithConstantBinary(
use_of_false_in_while, 9, 11, SpvOpSGreaterThanEqual, 101);
- ASSERT_TRUE(replacement_1.IsApplicable(context.get(), fact_manager));
- replacement_1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement_1.IsApplicable(context.get(), transformation_context));
+ replacement_1.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(replacement_2.IsApplicable(context.get(), fact_manager));
- replacement_2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement_2.IsApplicable(context.get(), transformation_context));
+ replacement_2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after = R"(
@@ -642,12 +654,15 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
auto replacement = TransformationReplaceBooleanConstantWithConstantBinary(
MakeIdUseDescriptor(9, MakeInstructionDescriptor(23, SpvOpPhi, 0), 0), 13,
15, SpvOpSLessThan, 100);
- ASSERT_FALSE(replacement.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(replacement.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationReplaceBooleanConstantWithConstantBinaryTest,
@@ -681,12 +696,15 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
ASSERT_FALSE(TransformationReplaceBooleanConstantWithConstantBinary(
MakeIdUseDescriptor(
9, MakeInstructionDescriptor(50, SpvOpVariable, 0), 1),
13, 15, SpvOpSLessThan, 100)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
}
} // namespace
diff --git a/test/fuzz/transformation_replace_constant_with_uniform_test.cpp b/test/fuzz/transformation_replace_constant_with_uniform_test.cpp
index 58d4a89..8cbba46 100644
--- a/test/fuzz/transformation_replace_constant_with_uniform_test.cpp
+++ b/test/fuzz/transformation_replace_constant_with_uniform_test.cpp
@@ -22,7 +22,8 @@
namespace {
bool AddFactHelper(
- FactManager* fact_manager, opt::IRContext* context, uint32_t word,
+ TransformationContext* transformation_context, opt::IRContext* context,
+ uint32_t word,
const protobufs::UniformBufferElementDescriptor& descriptor) {
protobufs::FactConstantUniform constant_uniform_fact;
constant_uniform_fact.add_constant_word(word);
@@ -30,7 +31,7 @@
descriptor;
protobufs::Fact fact;
*fact.mutable_constant_uniform_fact() = constant_uniform_fact;
- return fact_manager->AddFact(fact, context);
+ return transformation_context->GetFactManager()->AddFact(fact, context);
}
TEST(TransformationReplaceConstantWithUniformTest, BasicReplacements) {
@@ -104,6 +105,10 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
protobufs::UniformBufferElementDescriptor blockname_a =
MakeUniformBufferElementDescriptor(0, 0, {0});
protobufs::UniformBufferElementDescriptor blockname_b =
@@ -111,9 +116,12 @@
protobufs::UniformBufferElementDescriptor blockname_c =
MakeUniformBufferElementDescriptor(0, 0, {2});
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 1, blockname_a));
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 2, blockname_b));
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 3, blockname_c));
+ ASSERT_TRUE(
+ AddFactHelper(&transformation_context, context.get(), 1, blockname_a));
+ ASSERT_TRUE(
+ AddFactHelper(&transformation_context, context.get(), 2, blockname_b));
+ ASSERT_TRUE(
+ AddFactHelper(&transformation_context, context.get(), 3, blockname_c));
// The constant ids are 9, 11 and 14, for 1, 2 and 3 respectively.
protobufs::IdUseDescriptor use_of_9_in_store =
@@ -127,30 +135,30 @@
auto transformation_use_of_9_in_store =
TransformationReplaceConstantWithUniform(use_of_9_in_store, blockname_a,
100, 101);
- ASSERT_TRUE(transformation_use_of_9_in_store.IsApplicable(context.get(),
- fact_manager));
+ ASSERT_TRUE(transformation_use_of_9_in_store.IsApplicable(
+ context.get(), transformation_context));
auto transformation_use_of_11_in_add =
TransformationReplaceConstantWithUniform(use_of_11_in_add, blockname_b,
102, 103);
- ASSERT_TRUE(transformation_use_of_11_in_add.IsApplicable(context.get(),
- fact_manager));
+ ASSERT_TRUE(transformation_use_of_11_in_add.IsApplicable(
+ context.get(), transformation_context));
auto transformation_use_of_14_in_add =
TransformationReplaceConstantWithUniform(use_of_14_in_add, blockname_c,
104, 105);
- ASSERT_TRUE(transformation_use_of_14_in_add.IsApplicable(context.get(),
- fact_manager));
+ ASSERT_TRUE(transformation_use_of_14_in_add.IsApplicable(
+ context.get(), transformation_context));
// The transformations are not applicable if we change which uniforms are
// applied to which constants.
ASSERT_FALSE(TransformationReplaceConstantWithUniform(use_of_9_in_store,
blockname_b, 101, 102)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationReplaceConstantWithUniform(use_of_11_in_add,
blockname_c, 101, 102)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationReplaceConstantWithUniform(use_of_14_in_add,
blockname_a, 101, 102)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// The following transformations do not apply because the uniform descriptors
// are not sensible.
@@ -160,10 +168,10 @@
MakeUniformBufferElementDescriptor(0, 0, {5});
ASSERT_FALSE(TransformationReplaceConstantWithUniform(
use_of_9_in_store, nonsense_uniform_descriptor1, 101, 102)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationReplaceConstantWithUniform(
use_of_9_in_store, nonsense_uniform_descriptor2, 101, 102)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// The following transformation does not apply because the id descriptor is
// not sensible.
@@ -171,18 +179,19 @@
MakeIdUseDescriptor(9, MakeInstructionDescriptor(15, SpvOpIAdd, 0), 0);
ASSERT_FALSE(TransformationReplaceConstantWithUniform(
nonsense_id_use_descriptor, blockname_a, 101, 102)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// The following transformations do not apply because the ids are not fresh.
ASSERT_FALSE(TransformationReplaceConstantWithUniform(use_of_11_in_add,
blockname_b, 15, 103)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationReplaceConstantWithUniform(use_of_11_in_add,
blockname_b, 102, 15)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Apply the use of 9 in a store.
- transformation_use_of_9_in_store.Apply(context.get(), &fact_manager);
+ transformation_use_of_9_in_store.Apply(context.get(),
+ &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_replacing_use_of_9_in_store = R"(
OpCapability Shader
@@ -233,10 +242,10 @@
)";
ASSERT_TRUE(IsEqual(env, after_replacing_use_of_9_in_store, context.get()));
- ASSERT_TRUE(transformation_use_of_11_in_add.IsApplicable(context.get(),
- fact_manager));
+ ASSERT_TRUE(transformation_use_of_11_in_add.IsApplicable(
+ context.get(), transformation_context));
// Apply the use of 11 in an add.
- transformation_use_of_11_in_add.Apply(context.get(), &fact_manager);
+ transformation_use_of_11_in_add.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_replacing_use_of_11_in_add = R"(
OpCapability Shader
@@ -289,10 +298,10 @@
)";
ASSERT_TRUE(IsEqual(env, after_replacing_use_of_11_in_add, context.get()));
- ASSERT_TRUE(transformation_use_of_14_in_add.IsApplicable(context.get(),
- fact_manager));
+ ASSERT_TRUE(transformation_use_of_14_in_add.IsApplicable(
+ context.get(), transformation_context));
// Apply the use of 15 in an add.
- transformation_use_of_14_in_add.Apply(context.get(), &fact_manager);
+ transformation_use_of_14_in_add.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_replacing_use_of_14_in_add = R"(
OpCapability Shader
@@ -462,6 +471,10 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
protobufs::UniformBufferElementDescriptor blockname_1 =
MakeUniformBufferElementDescriptor(0, 0, {0});
protobufs::UniformBufferElementDescriptor blockname_2 =
@@ -471,10 +484,14 @@
protobufs::UniformBufferElementDescriptor blockname_4 =
MakeUniformBufferElementDescriptor(0, 0, {1, 0, 1, 0});
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 1, blockname_1));
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 2, blockname_2));
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 3, blockname_3));
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 4, blockname_4));
+ ASSERT_TRUE(
+ AddFactHelper(&transformation_context, context.get(), 1, blockname_1));
+ ASSERT_TRUE(
+ AddFactHelper(&transformation_context, context.get(), 2, blockname_2));
+ ASSERT_TRUE(
+ AddFactHelper(&transformation_context, context.get(), 3, blockname_3));
+ ASSERT_TRUE(
+ AddFactHelper(&transformation_context, context.get(), 4, blockname_4));
// The constant ids are 13, 15, 17 and 20, for 1, 2, 3 and 4 respectively.
protobufs::IdUseDescriptor use_of_13_in_store =
@@ -490,76 +507,78 @@
auto transformation_use_of_13_in_store =
TransformationReplaceConstantWithUniform(use_of_13_in_store, blockname_1,
100, 101);
- ASSERT_TRUE(transformation_use_of_13_in_store.IsApplicable(context.get(),
- fact_manager));
+ ASSERT_TRUE(transformation_use_of_13_in_store.IsApplicable(
+ context.get(), transformation_context));
auto transformation_use_of_15_in_add =
TransformationReplaceConstantWithUniform(use_of_15_in_add, blockname_2,
102, 103);
- ASSERT_TRUE(transformation_use_of_15_in_add.IsApplicable(context.get(),
- fact_manager));
+ ASSERT_TRUE(transformation_use_of_15_in_add.IsApplicable(
+ context.get(), transformation_context));
auto transformation_use_of_17_in_add =
TransformationReplaceConstantWithUniform(use_of_17_in_add, blockname_3,
104, 105);
- ASSERT_TRUE(transformation_use_of_17_in_add.IsApplicable(context.get(),
- fact_manager));
+ ASSERT_TRUE(transformation_use_of_17_in_add.IsApplicable(
+ context.get(), transformation_context));
auto transformation_use_of_20_in_store =
TransformationReplaceConstantWithUniform(use_of_20_in_store, blockname_4,
106, 107);
- ASSERT_TRUE(transformation_use_of_20_in_store.IsApplicable(context.get(),
- fact_manager));
+ ASSERT_TRUE(transformation_use_of_20_in_store.IsApplicable(
+ context.get(), transformation_context));
- ASSERT_TRUE(transformation_use_of_13_in_store.IsApplicable(context.get(),
- fact_manager));
- ASSERT_TRUE(transformation_use_of_15_in_add.IsApplicable(context.get(),
- fact_manager));
- ASSERT_TRUE(transformation_use_of_17_in_add.IsApplicable(context.get(),
- fact_manager));
- ASSERT_TRUE(transformation_use_of_20_in_store.IsApplicable(context.get(),
- fact_manager));
+ ASSERT_TRUE(transformation_use_of_13_in_store.IsApplicable(
+ context.get(), transformation_context));
+ ASSERT_TRUE(transformation_use_of_15_in_add.IsApplicable(
+ context.get(), transformation_context));
+ ASSERT_TRUE(transformation_use_of_17_in_add.IsApplicable(
+ context.get(), transformation_context));
+ ASSERT_TRUE(transformation_use_of_20_in_store.IsApplicable(
+ context.get(), transformation_context));
- transformation_use_of_13_in_store.Apply(context.get(), &fact_manager);
+ transformation_use_of_13_in_store.Apply(context.get(),
+ &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_FALSE(transformation_use_of_13_in_store.IsApplicable(context.get(),
- fact_manager));
- ASSERT_TRUE(transformation_use_of_15_in_add.IsApplicable(context.get(),
- fact_manager));
- ASSERT_TRUE(transformation_use_of_17_in_add.IsApplicable(context.get(),
- fact_manager));
- ASSERT_TRUE(transformation_use_of_20_in_store.IsApplicable(context.get(),
- fact_manager));
+ ASSERT_FALSE(transformation_use_of_13_in_store.IsApplicable(
+ context.get(), transformation_context));
+ ASSERT_TRUE(transformation_use_of_15_in_add.IsApplicable(
+ context.get(), transformation_context));
+ ASSERT_TRUE(transformation_use_of_17_in_add.IsApplicable(
+ context.get(), transformation_context));
+ ASSERT_TRUE(transformation_use_of_20_in_store.IsApplicable(
+ context.get(), transformation_context));
- transformation_use_of_15_in_add.Apply(context.get(), &fact_manager);
+ transformation_use_of_15_in_add.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_FALSE(transformation_use_of_13_in_store.IsApplicable(context.get(),
- fact_manager));
- ASSERT_FALSE(transformation_use_of_15_in_add.IsApplicable(context.get(),
- fact_manager));
- ASSERT_TRUE(transformation_use_of_17_in_add.IsApplicable(context.get(),
- fact_manager));
- ASSERT_TRUE(transformation_use_of_20_in_store.IsApplicable(context.get(),
- fact_manager));
+ ASSERT_FALSE(transformation_use_of_13_in_store.IsApplicable(
+ context.get(), transformation_context));
+ ASSERT_FALSE(transformation_use_of_15_in_add.IsApplicable(
+ context.get(), transformation_context));
+ ASSERT_TRUE(transformation_use_of_17_in_add.IsApplicable(
+ context.get(), transformation_context));
+ ASSERT_TRUE(transformation_use_of_20_in_store.IsApplicable(
+ context.get(), transformation_context));
- transformation_use_of_17_in_add.Apply(context.get(), &fact_manager);
+ transformation_use_of_17_in_add.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_FALSE(transformation_use_of_13_in_store.IsApplicable(context.get(),
- fact_manager));
- ASSERT_FALSE(transformation_use_of_15_in_add.IsApplicable(context.get(),
- fact_manager));
- ASSERT_FALSE(transformation_use_of_17_in_add.IsApplicable(context.get(),
- fact_manager));
- ASSERT_TRUE(transformation_use_of_20_in_store.IsApplicable(context.get(),
- fact_manager));
+ ASSERT_FALSE(transformation_use_of_13_in_store.IsApplicable(
+ context.get(), transformation_context));
+ ASSERT_FALSE(transformation_use_of_15_in_add.IsApplicable(
+ context.get(), transformation_context));
+ ASSERT_FALSE(transformation_use_of_17_in_add.IsApplicable(
+ context.get(), transformation_context));
+ ASSERT_TRUE(transformation_use_of_20_in_store.IsApplicable(
+ context.get(), transformation_context));
- transformation_use_of_20_in_store.Apply(context.get(), &fact_manager);
+ transformation_use_of_20_in_store.Apply(context.get(),
+ &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_FALSE(transformation_use_of_13_in_store.IsApplicable(context.get(),
- fact_manager));
- ASSERT_FALSE(transformation_use_of_15_in_add.IsApplicable(context.get(),
- fact_manager));
- ASSERT_FALSE(transformation_use_of_17_in_add.IsApplicable(context.get(),
- fact_manager));
- ASSERT_FALSE(transformation_use_of_20_in_store.IsApplicable(context.get(),
- fact_manager));
+ ASSERT_FALSE(transformation_use_of_13_in_store.IsApplicable(
+ context.get(), transformation_context));
+ ASSERT_FALSE(transformation_use_of_15_in_add.IsApplicable(
+ context.get(), transformation_context));
+ ASSERT_FALSE(transformation_use_of_17_in_add.IsApplicable(
+ context.get(), transformation_context));
+ ASSERT_FALSE(transformation_use_of_20_in_store.IsApplicable(
+ context.get(), transformation_context));
std::string after = R"(
OpCapability Shader
@@ -697,10 +716,15 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
protobufs::UniformBufferElementDescriptor blockname_0 =
MakeUniformBufferElementDescriptor(0, 0, {0});
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 0, blockname_0));
+ ASSERT_TRUE(
+ AddFactHelper(&transformation_context, context.get(), 0, blockname_0));
// The constant id is 9 for 0.
protobufs::IdUseDescriptor use_of_9_in_store =
@@ -710,7 +734,7 @@
// type is present:
ASSERT_FALSE(TransformationReplaceConstantWithUniform(use_of_9_in_store,
blockname_0, 100, 101)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
}
TEST(TransformationReplaceConstantWithUniformTest, NoConstantPresentForIndex) {
@@ -770,12 +794,17 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
protobufs::UniformBufferElementDescriptor blockname_0 =
MakeUniformBufferElementDescriptor(0, 0, {0});
protobufs::UniformBufferElementDescriptor blockname_9 =
MakeUniformBufferElementDescriptor(0, 0, {1});
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 9, blockname_9));
+ ASSERT_TRUE(
+ AddFactHelper(&transformation_context, context.get(), 9, blockname_9));
// The constant id is 9 for 9.
protobufs::IdUseDescriptor use_of_9_in_store =
@@ -785,7 +814,7 @@
// index 1 required to index into the uniform buffer:
ASSERT_FALSE(TransformationReplaceConstantWithUniform(use_of_9_in_store,
blockname_9, 100, 101)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
}
TEST(TransformationReplaceConstantWithUniformTest,
@@ -842,14 +871,18 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
protobufs::UniformBufferElementDescriptor blockname_3 =
MakeUniformBufferElementDescriptor(0, 0, {0});
uint32_t float_data[1];
float temp = 3.0;
memcpy(&float_data[0], &temp, sizeof(float));
- ASSERT_TRUE(
- AddFactHelper(&fact_manager, context.get(), float_data[0], blockname_3));
+ ASSERT_TRUE(AddFactHelper(&transformation_context, context.get(),
+ float_data[0], blockname_3));
// The constant id is 9 for 3.0.
protobufs::IdUseDescriptor use_of_9_in_store =
@@ -859,7 +892,7 @@
// allow a constant index to be expressed:
ASSERT_FALSE(TransformationReplaceConstantWithUniform(use_of_9_in_store,
blockname_3, 100, 101)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
}
TEST(TransformationReplaceConstantWithUniformTest,
@@ -928,13 +961,19 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
protobufs::UniformBufferElementDescriptor blockname_9 =
MakeUniformBufferElementDescriptor(0, 0, {0});
protobufs::UniformBufferElementDescriptor blockname_10 =
MakeUniformBufferElementDescriptor(0, 0, {1});
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 9, blockname_9));
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 10, blockname_10));
+ ASSERT_TRUE(
+ AddFactHelper(&transformation_context, context.get(), 9, blockname_9));
+ ASSERT_TRUE(
+ AddFactHelper(&transformation_context, context.get(), 10, blockname_10));
// The constant ids for 9 and 10 are 9 and 11 respectively
protobufs::IdUseDescriptor use_of_9_in_store =
@@ -945,19 +984,19 @@
// These are right:
ASSERT_TRUE(TransformationReplaceConstantWithUniform(use_of_9_in_store,
blockname_9, 100, 101)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationReplaceConstantWithUniform(use_of_11_in_store,
blockname_10, 102, 103)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// These are wrong because the constants do not match the facts about
// uniforms.
ASSERT_FALSE(TransformationReplaceConstantWithUniform(use_of_11_in_store,
blockname_9, 100, 101)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationReplaceConstantWithUniform(use_of_9_in_store,
blockname_10, 102, 103)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
}
TEST(TransformationReplaceConstantWithUniformTest, ComplexReplacements) {
@@ -1141,6 +1180,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
const float float_array_values[5] = {1.0, 1.5, 1.75, 1.875, 1.9375};
uint32_t float_array_data[5];
@@ -1188,35 +1230,43 @@
protobufs::UniformBufferElementDescriptor uniform_h_y =
MakeUniformBufferElementDescriptor(0, 0, {2, 1});
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), float_array_data[0],
- uniform_f_a_0));
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), float_array_data[1],
- uniform_f_a_1));
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), float_array_data[2],
- uniform_f_a_2));
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), float_array_data[3],
- uniform_f_a_3));
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), float_array_data[4],
- uniform_f_a_4));
+ ASSERT_TRUE(AddFactHelper(&transformation_context, context.get(),
+ float_array_data[0], uniform_f_a_0));
+ ASSERT_TRUE(AddFactHelper(&transformation_context, context.get(),
+ float_array_data[1], uniform_f_a_1));
+ ASSERT_TRUE(AddFactHelper(&transformation_context, context.get(),
+ float_array_data[2], uniform_f_a_2));
+ ASSERT_TRUE(AddFactHelper(&transformation_context, context.get(),
+ float_array_data[3], uniform_f_a_3));
+ ASSERT_TRUE(AddFactHelper(&transformation_context, context.get(),
+ float_array_data[4], uniform_f_a_4));
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 1, uniform_f_b_x));
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 2, uniform_f_b_y));
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 3, uniform_f_b_z));
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 4, uniform_f_b_w));
+ ASSERT_TRUE(
+ AddFactHelper(&transformation_context, context.get(), 1, uniform_f_b_x));
+ ASSERT_TRUE(
+ AddFactHelper(&transformation_context, context.get(), 2, uniform_f_b_y));
+ ASSERT_TRUE(
+ AddFactHelper(&transformation_context, context.get(), 3, uniform_f_b_z));
+ ASSERT_TRUE(
+ AddFactHelper(&transformation_context, context.get(), 4, uniform_f_b_w));
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), float_vector_data[0],
- uniform_f_c_x));
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), float_vector_data[1],
- uniform_f_c_y));
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), float_vector_data[2],
- uniform_f_c_z));
+ ASSERT_TRUE(AddFactHelper(&transformation_context, context.get(),
+ float_vector_data[0], uniform_f_c_x));
+ ASSERT_TRUE(AddFactHelper(&transformation_context, context.get(),
+ float_vector_data[1], uniform_f_c_y));
+ ASSERT_TRUE(AddFactHelper(&transformation_context, context.get(),
+ float_vector_data[2], uniform_f_c_z));
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 42, uniform_f_d));
+ ASSERT_TRUE(
+ AddFactHelper(&transformation_context, context.get(), 42, uniform_f_d));
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 22, uniform_g));
+ ASSERT_TRUE(
+ AddFactHelper(&transformation_context, context.get(), 22, uniform_g));
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 100, uniform_h_x));
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 200, uniform_h_y));
+ ASSERT_TRUE(
+ AddFactHelper(&transformation_context, context.get(), 100, uniform_h_x));
+ ASSERT_TRUE(
+ AddFactHelper(&transformation_context, context.get(), 200, uniform_h_y));
std::vector<TransformationReplaceConstantWithUniform> transformations;
@@ -1275,8 +1325,9 @@
uniform_g, 218, 219));
for (auto& transformation : transformations) {
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
}
@@ -1480,16 +1531,21 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
protobufs::UniformBufferElementDescriptor blockname_a =
MakeUniformBufferElementDescriptor(0, 0, {0});
- ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 0, blockname_a));
+ ASSERT_TRUE(
+ AddFactHelper(&transformation_context, context.get(), 0, blockname_a));
ASSERT_FALSE(TransformationReplaceConstantWithUniform(
MakeIdUseDescriptor(
50, MakeInstructionDescriptor(8, SpvOpVariable, 0), 1),
blockname_a, 100, 101)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
}
} // namespace
diff --git a/test/fuzz/transformation_replace_id_with_synonym_test.cpp b/test/fuzz/transformation_replace_id_with_synonym_test.cpp
index 41b6116..37e9510 100644
--- a/test/fuzz/transformation_replace_id_with_synonym_test.cpp
+++ b/test/fuzz/transformation_replace_id_with_synonym_test.cpp
@@ -220,15 +220,19 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
- SetUpIdSynonyms(&fact_manager, context.get());
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ SetUpIdSynonyms(transformation_context.GetFactManager(), context.get());
// %202 cannot replace %15 as in-operand 0 of %300, since %202 does not
// dominate %300.
auto synonym_does_not_dominate_use = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(15, MakeInstructionDescriptor(300, SpvOpIAdd, 0), 0),
202);
- ASSERT_FALSE(
- synonym_does_not_dominate_use.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(synonym_does_not_dominate_use.IsApplicable(
+ context.get(), transformation_context));
// %202 cannot replace %15 as in-operand 2 of %301, since this is the OpPhi's
// incoming value for block %72, and %202 does not dominate %72.
@@ -237,22 +241,23 @@
MakeIdUseDescriptor(15, MakeInstructionDescriptor(301, SpvOpPhi, 0),
2),
202);
- ASSERT_FALSE(synonym_does_not_dominate_use_op_phi.IsApplicable(context.get(),
- fact_manager));
+ ASSERT_FALSE(synonym_does_not_dominate_use_op_phi.IsApplicable(
+ context.get(), transformation_context));
// %200 is not a synonym for %84
auto id_in_use_is_not_synonymous = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(
84, MakeInstructionDescriptor(67, SpvOpSGreaterThan, 0), 0),
200);
- ASSERT_FALSE(
- id_in_use_is_not_synonymous.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(id_in_use_is_not_synonymous.IsApplicable(
+ context.get(), transformation_context));
// %86 is not a synonym for anything (and in particular not for %74)
auto id_has_no_synonyms = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(86, MakeInstructionDescriptor(84, SpvOpPhi, 0), 2),
74);
- ASSERT_FALSE(id_has_no_synonyms.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ id_has_no_synonyms.IsApplicable(context.get(), transformation_context));
// This would lead to %207 = 'OpCopyObject %type %207' if it were allowed
auto synonym_use_is_in_synonym_definition =
@@ -260,8 +265,8 @@
MakeIdUseDescriptor(
84, MakeInstructionDescriptor(207, SpvOpCopyObject, 0), 0),
207);
- ASSERT_FALSE(synonym_use_is_in_synonym_definition.IsApplicable(context.get(),
- fact_manager));
+ ASSERT_FALSE(synonym_use_is_in_synonym_definition.IsApplicable(
+ context.get(), transformation_context));
// The id use descriptor does not lead to a use (%84 is not used in the
// definition of %207)
@@ -269,7 +274,8 @@
MakeIdUseDescriptor(
84, MakeInstructionDescriptor(200, SpvOpCopyObject, 0), 0),
207);
- ASSERT_FALSE(bad_id_use_descriptor.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(bad_id_use_descriptor.IsApplicable(context.get(),
+ transformation_context));
// This replacement would lead to an access chain into a struct using a
// non-constant index.
@@ -277,7 +283,8 @@
MakeIdUseDescriptor(
12, MakeInstructionDescriptor(14, SpvOpAccessChain, 0), 1),
209);
- ASSERT_FALSE(bad_access_chain.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ bad_access_chain.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationReplaceIdWithSynonymTest, LegalTransformations) {
@@ -288,23 +295,28 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
- SetUpIdSynonyms(&fact_manager, context.get());
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ SetUpIdSynonyms(transformation_context.GetFactManager(), context.get());
auto global_constant_synonym = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(19, MakeInstructionDescriptor(47, SpvOpStore, 0), 1),
210);
- ASSERT_TRUE(
- global_constant_synonym.IsApplicable(context.get(), fact_manager));
- global_constant_synonym.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(global_constant_synonym.IsApplicable(context.get(),
+ transformation_context));
+ global_constant_synonym.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
auto replace_vector_access_chain_index = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(
54, MakeInstructionDescriptor(55, SpvOpAccessChain, 0), 1),
204);
- ASSERT_TRUE(replace_vector_access_chain_index.IsApplicable(context.get(),
- fact_manager));
- replace_vector_access_chain_index.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(replace_vector_access_chain_index.IsApplicable(
+ context.get(), transformation_context));
+ replace_vector_access_chain_index.Apply(context.get(),
+ &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// This is an interesting case because it replaces something that is being
@@ -313,22 +325,24 @@
MakeIdUseDescriptor(
15, MakeInstructionDescriptor(202, SpvOpCopyObject, 0), 0),
201);
- ASSERT_TRUE(regular_replacement.IsApplicable(context.get(), fact_manager));
- regular_replacement.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ regular_replacement.IsApplicable(context.get(), transformation_context));
+ regular_replacement.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
auto regular_replacement2 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(55, MakeInstructionDescriptor(203, SpvOpStore, 0), 0),
203);
- ASSERT_TRUE(regular_replacement2.IsApplicable(context.get(), fact_manager));
- regular_replacement2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ regular_replacement2.IsApplicable(context.get(), transformation_context));
+ regular_replacement2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
auto good_op_phi = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(74, MakeInstructionDescriptor(86, SpvOpPhi, 0), 2),
205);
- ASSERT_TRUE(good_op_phi.IsApplicable(context.get(), fact_manager));
- good_op_phi.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(good_op_phi.IsApplicable(context.get(), transformation_context));
+ good_op_phi.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
const std::string after_transformation = R"(
@@ -504,17 +518,22 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
- fact_manager.AddFact(MakeSynonymFact(10, 100), context.get());
- fact_manager.AddFact(MakeSynonymFact(8, 101), context.get());
+ transformation_context.GetFactManager()->AddFact(MakeSynonymFact(10, 100),
+ context.get());
+ transformation_context.GetFactManager()->AddFact(MakeSynonymFact(8, 101),
+ context.get());
// Replace %10 with %100 in:
// %11 = OpLoad %6 %10
auto replacement1 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(10, MakeInstructionDescriptor(11, SpvOpLoad, 0), 0),
100);
- ASSERT_TRUE(replacement1.IsApplicable(context.get(), fact_manager));
- replacement1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(replacement1.IsApplicable(context.get(), transformation_context));
+ replacement1.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replace %8 with %101 in:
@@ -522,8 +541,8 @@
auto replacement2 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(8, MakeInstructionDescriptor(11, SpvOpStore, 0), 0),
101);
- ASSERT_TRUE(replacement2.IsApplicable(context.get(), fact_manager));
- replacement2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(replacement2.IsApplicable(context.get(), transformation_context));
+ replacement2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replace %8 with %101 in:
@@ -531,8 +550,8 @@
auto replacement3 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(8, MakeInstructionDescriptor(12, SpvOpLoad, 0), 0),
101);
- ASSERT_TRUE(replacement3.IsApplicable(context.get(), fact_manager));
- replacement3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(replacement3.IsApplicable(context.get(), transformation_context));
+ replacement3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replace %10 with %100 in:
@@ -540,8 +559,8 @@
auto replacement4 = TransformationReplaceIdWithSynonym(
MakeIdUseDescriptor(10, MakeInstructionDescriptor(12, SpvOpStore, 0), 0),
100);
- ASSERT_TRUE(replacement4.IsApplicable(context.get(), fact_manager));
- replacement4.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(replacement4.IsApplicable(context.get(), transformation_context));
+ replacement4.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
const std::string after_transformation = R"(
@@ -633,8 +652,12 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
- fact_manager.AddFact(MakeSynonymFact(14, 100), context.get());
+ transformation_context.GetFactManager()->AddFact(MakeSynonymFact(14, 100),
+ context.get());
// Replace %14 with %100 in:
// %16 = OpFunctionCall %2 %10 %14
@@ -642,7 +665,7 @@
MakeIdUseDescriptor(
14, MakeInstructionDescriptor(16, SpvOpFunctionCall, 0), 1),
100);
- ASSERT_FALSE(replacement.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(replacement.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) {
@@ -795,22 +818,38 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Add synonym facts corresponding to the OpCopyObject operations that have
// been applied to all constants in the module.
- fact_manager.AddFact(MakeSynonymFact(16, 100), context.get());
- fact_manager.AddFact(MakeSynonymFact(21, 101), context.get());
- fact_manager.AddFact(MakeSynonymFact(17, 102), context.get());
- fact_manager.AddFact(MakeSynonymFact(57, 103), context.get());
- fact_manager.AddFact(MakeSynonymFact(18, 104), context.get());
- fact_manager.AddFact(MakeSynonymFact(40, 105), context.get());
- fact_manager.AddFact(MakeSynonymFact(32, 106), context.get());
- fact_manager.AddFact(MakeSynonymFact(43, 107), context.get());
- fact_manager.AddFact(MakeSynonymFact(55, 108), context.get());
- fact_manager.AddFact(MakeSynonymFact(8, 109), context.get());
- fact_manager.AddFact(MakeSynonymFact(47, 110), context.get());
- fact_manager.AddFact(MakeSynonymFact(28, 111), context.get());
- fact_manager.AddFact(MakeSynonymFact(45, 112), context.get());
+ transformation_context.GetFactManager()->AddFact(MakeSynonymFact(16, 100),
+ context.get());
+ transformation_context.GetFactManager()->AddFact(MakeSynonymFact(21, 101),
+ context.get());
+ transformation_context.GetFactManager()->AddFact(MakeSynonymFact(17, 102),
+ context.get());
+ transformation_context.GetFactManager()->AddFact(MakeSynonymFact(57, 103),
+ context.get());
+ transformation_context.GetFactManager()->AddFact(MakeSynonymFact(18, 104),
+ context.get());
+ transformation_context.GetFactManager()->AddFact(MakeSynonymFact(40, 105),
+ context.get());
+ transformation_context.GetFactManager()->AddFact(MakeSynonymFact(32, 106),
+ context.get());
+ transformation_context.GetFactManager()->AddFact(MakeSynonymFact(43, 107),
+ context.get());
+ transformation_context.GetFactManager()->AddFact(MakeSynonymFact(55, 108),
+ context.get());
+ transformation_context.GetFactManager()->AddFact(MakeSynonymFact(8, 109),
+ context.get());
+ transformation_context.GetFactManager()->AddFact(MakeSynonymFact(47, 110),
+ context.get());
+ transformation_context.GetFactManager()->AddFact(MakeSynonymFact(28, 111),
+ context.get());
+ transformation_context.GetFactManager()->AddFact(MakeSynonymFact(45, 112),
+ context.get());
// Replacements of the form %16 -> %100
@@ -821,7 +860,8 @@
MakeIdUseDescriptor(
16, MakeInstructionDescriptor(20, SpvOpAccessChain, 0), 1),
100);
- ASSERT_FALSE(replacement1.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ replacement1.IsApplicable(context.get(), transformation_context));
// %39 = OpAccessChain %23 %37 *%16*
// Corresponds to h.*f*
@@ -830,7 +870,8 @@
MakeIdUseDescriptor(
16, MakeInstructionDescriptor(39, SpvOpAccessChain, 0), 1),
100);
- ASSERT_FALSE(replacement2.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ replacement2.IsApplicable(context.get(), transformation_context));
// %41 = OpAccessChain %19 %37 %21 *%16* %21
// Corresponds to h.g.*a*[1]
@@ -839,7 +880,8 @@
MakeIdUseDescriptor(
16, MakeInstructionDescriptor(41, SpvOpAccessChain, 0), 2),
100);
- ASSERT_FALSE(replacement3.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ replacement3.IsApplicable(context.get(), transformation_context));
// %52 = OpAccessChain %23 %50 *%16* %16
// Corresponds to i[*0*].f
@@ -848,8 +890,8 @@
MakeIdUseDescriptor(
16, MakeInstructionDescriptor(52, SpvOpAccessChain, 0), 1),
100);
- ASSERT_TRUE(replacement4.IsApplicable(context.get(), fact_manager));
- replacement4.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(replacement4.IsApplicable(context.get(), transformation_context));
+ replacement4.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// %52 = OpAccessChain %23 %50 %16 *%16*
@@ -859,7 +901,8 @@
MakeIdUseDescriptor(
16, MakeInstructionDescriptor(52, SpvOpAccessChain, 0), 2),
100);
- ASSERT_FALSE(replacement5.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ replacement5.IsApplicable(context.get(), transformation_context));
// %53 = OpAccessChain %19 %50 %21 %21 *%16* %16
// Corresponds to i[1].g.*a*[0]
@@ -868,7 +911,8 @@
MakeIdUseDescriptor(
16, MakeInstructionDescriptor(53, SpvOpAccessChain, 0), 3),
100);
- ASSERT_FALSE(replacement6.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ replacement6.IsApplicable(context.get(), transformation_context));
// %53 = OpAccessChain %19 %50 %21 %21 %16 *%16*
// Corresponds to i[1].g.a[*0*]
@@ -877,8 +921,8 @@
MakeIdUseDescriptor(
16, MakeInstructionDescriptor(53, SpvOpAccessChain, 0), 4),
100);
- ASSERT_TRUE(replacement7.IsApplicable(context.get(), fact_manager));
- replacement7.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(replacement7.IsApplicable(context.get(), transformation_context));
+ replacement7.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replacements of the form %21 -> %101
@@ -890,7 +934,8 @@
MakeIdUseDescriptor(
21, MakeInstructionDescriptor(24, SpvOpAccessChain, 0), 1),
101);
- ASSERT_FALSE(replacement8.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ replacement8.IsApplicable(context.get(), transformation_context));
// %41 = OpAccessChain %19 %37 *%21* %16 %21
// Corresponds to h.*g*.a[1]
@@ -899,7 +944,8 @@
MakeIdUseDescriptor(
21, MakeInstructionDescriptor(41, SpvOpAccessChain, 0), 1),
101);
- ASSERT_FALSE(replacement9.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ replacement9.IsApplicable(context.get(), transformation_context));
// %41 = OpAccessChain %19 %37 %21 %16 *%21*
// Corresponds to h.g.a[*1*]
@@ -908,8 +954,9 @@
MakeIdUseDescriptor(
21, MakeInstructionDescriptor(41, SpvOpAccessChain, 0), 3),
101);
- ASSERT_TRUE(replacement10.IsApplicable(context.get(), fact_manager));
- replacement10.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement10.IsApplicable(context.get(), transformation_context));
+ replacement10.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// %44 = OpAccessChain %23 %37 *%21* %21 %43
@@ -919,7 +966,8 @@
MakeIdUseDescriptor(
21, MakeInstructionDescriptor(44, SpvOpAccessChain, 0), 1),
101);
- ASSERT_FALSE(replacement11.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ replacement11.IsApplicable(context.get(), transformation_context));
// %44 = OpAccessChain %23 %37 %21 *%21* %43
// Corresponds to h.g.*b*[0]
@@ -928,7 +976,8 @@
MakeIdUseDescriptor(
21, MakeInstructionDescriptor(44, SpvOpAccessChain, 0), 2),
101);
- ASSERT_FALSE(replacement12.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ replacement12.IsApplicable(context.get(), transformation_context));
// %46 = OpAccessChain %26 %37 *%21* %17
// Corresponds to h.*g*.c
@@ -937,7 +986,8 @@
MakeIdUseDescriptor(
21, MakeInstructionDescriptor(46, SpvOpAccessChain, 0), 1),
101);
- ASSERT_FALSE(replacement13.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ replacement13.IsApplicable(context.get(), transformation_context));
// %53 = OpAccessChain %19 %50 *%21* %21 %16 %16
// Corresponds to i[*1*].g.a[0]
@@ -946,8 +996,9 @@
MakeIdUseDescriptor(
21, MakeInstructionDescriptor(53, SpvOpAccessChain, 0), 1),
101);
- ASSERT_TRUE(replacement14.IsApplicable(context.get(), fact_manager));
- replacement14.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement14.IsApplicable(context.get(), transformation_context));
+ replacement14.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// %53 = OpAccessChain %19 %50 %21 *%21* %16 %16
@@ -957,7 +1008,8 @@
MakeIdUseDescriptor(
21, MakeInstructionDescriptor(53, SpvOpAccessChain, 0), 2),
101);
- ASSERT_FALSE(replacement15.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ replacement15.IsApplicable(context.get(), transformation_context));
// %56 = OpAccessChain %23 %50 %17 *%21* %21 %55
// Corresponds to i[2].*g*.b[1]
@@ -966,7 +1018,8 @@
MakeIdUseDescriptor(
21, MakeInstructionDescriptor(56, SpvOpAccessChain, 0), 2),
101);
- ASSERT_FALSE(replacement16.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ replacement16.IsApplicable(context.get(), transformation_context));
// %56 = OpAccessChain %23 %50 %17 %21 *%21* %55
// Corresponds to i[2].g.*b*[1]
@@ -975,7 +1028,8 @@
MakeIdUseDescriptor(
21, MakeInstructionDescriptor(56, SpvOpAccessChain, 0), 3),
101);
- ASSERT_FALSE(replacement17.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ replacement17.IsApplicable(context.get(), transformation_context));
// %58 = OpAccessChain %26 %50 %57 *%21* %17
// Corresponds to i[3].*g*.c
@@ -984,7 +1038,8 @@
MakeIdUseDescriptor(
21, MakeInstructionDescriptor(58, SpvOpAccessChain, 0), 2),
101);
- ASSERT_FALSE(replacement18.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ replacement18.IsApplicable(context.get(), transformation_context));
// Replacements of the form %17 -> %102
@@ -995,8 +1050,9 @@
MakeIdUseDescriptor(
17, MakeInstructionDescriptor(20, SpvOpAccessChain, 0), 2),
102);
- ASSERT_TRUE(replacement19.IsApplicable(context.get(), fact_manager));
- replacement19.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement19.IsApplicable(context.get(), transformation_context));
+ replacement19.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// %27 = OpAccessChain %26 %15 %17
@@ -1006,7 +1062,8 @@
MakeIdUseDescriptor(
17, MakeInstructionDescriptor(27, SpvOpAccessChain, 0), 1),
102);
- ASSERT_FALSE(replacement20.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ replacement20.IsApplicable(context.get(), transformation_context));
// %46 = OpAccessChain %26 %37 %21 %17
// Corresponds to h.g.*c*
@@ -1015,7 +1072,8 @@
MakeIdUseDescriptor(
17, MakeInstructionDescriptor(46, SpvOpAccessChain, 0), 2),
102);
- ASSERT_FALSE(replacement21.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ replacement21.IsApplicable(context.get(), transformation_context));
// %56 = OpAccessChain %23 %50 %17 %21 %21 %55
// Corresponds to i[*2*].g.b[1]
@@ -1024,8 +1082,9 @@
MakeIdUseDescriptor(
17, MakeInstructionDescriptor(56, SpvOpAccessChain, 0), 1),
102);
- ASSERT_TRUE(replacement22.IsApplicable(context.get(), fact_manager));
- replacement22.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement22.IsApplicable(context.get(), transformation_context));
+ replacement22.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// %58 = OpAccessChain %26 %50 %57 %21 %17
@@ -1035,7 +1094,8 @@
MakeIdUseDescriptor(
17, MakeInstructionDescriptor(58, SpvOpAccessChain, 0), 3),
102);
- ASSERT_FALSE(replacement23.IsApplicable(context.get(), fact_manager));
+ ASSERT_FALSE(
+ replacement23.IsApplicable(context.get(), transformation_context));
// Replacements of the form %57 -> %103
@@ -1046,8 +1106,9 @@
MakeIdUseDescriptor(
57, MakeInstructionDescriptor(58, SpvOpAccessChain, 0), 1),
103);
- ASSERT_TRUE(replacement24.IsApplicable(context.get(), fact_manager));
- replacement24.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement24.IsApplicable(context.get(), transformation_context));
+ replacement24.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replacements of the form %32 -> %106
@@ -1059,8 +1120,9 @@
MakeIdUseDescriptor(
32, MakeInstructionDescriptor(34, SpvOpAccessChain, 0), 1),
106);
- ASSERT_TRUE(replacement25.IsApplicable(context.get(), fact_manager));
- replacement25.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement25.IsApplicable(context.get(), transformation_context));
+ replacement25.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replacements of the form %43 -> %107
@@ -1072,8 +1134,9 @@
MakeIdUseDescriptor(
43, MakeInstructionDescriptor(44, SpvOpAccessChain, 0), 3),
107);
- ASSERT_TRUE(replacement26.IsApplicable(context.get(), fact_manager));
- replacement26.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement26.IsApplicable(context.get(), transformation_context));
+ replacement26.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replacements of the form %55 -> %108
@@ -1085,8 +1148,9 @@
MakeIdUseDescriptor(
55, MakeInstructionDescriptor(56, SpvOpAccessChain, 0), 4),
108);
- ASSERT_TRUE(replacement27.IsApplicable(context.get(), fact_manager));
- replacement27.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement27.IsApplicable(context.get(), transformation_context));
+ replacement27.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
// Replacements of the form %8 -> %109
@@ -1098,8 +1162,9 @@
MakeIdUseDescriptor(8, MakeInstructionDescriptor(24, SpvOpAccessChain, 0),
2),
109);
- ASSERT_TRUE(replacement28.IsApplicable(context.get(), fact_manager));
- replacement28.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ replacement28.IsApplicable(context.get(), transformation_context));
+ replacement28.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
const std::string after_transformation = R"(
@@ -1212,6 +1277,179 @@
ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
}
+TEST(TransformationReplaceIdWithSynonymTest, RuntimeArrayTest) {
+ // This checks that OpRuntimeArray is correctly handled.
+ const std::string shader = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main"
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ OpDecorate %8 ArrayStride 8
+ OpMemberDecorate %9 0 Offset 0
+ OpDecorate %9 BufferBlock
+ OpDecorate %11 DescriptorSet 0
+ OpDecorate %11 Binding 0
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeInt 32 1
+ %7 = OpTypeVector %6 2
+ %8 = OpTypeRuntimeArray %7
+ %9 = OpTypeStruct %8
+ %10 = OpTypePointer Uniform %9
+ %11 = OpVariable %10 Uniform
+ %12 = OpConstant %6 0
+ %13 = OpTypeInt 32 0
+ %14 = OpConstant %13 0
+ %15 = OpTypePointer Uniform %6
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ %50 = OpCopyObject %6 %12
+ %51 = OpCopyObject %13 %14
+ %16 = OpAccessChain %15 %11 %12 %12 %14
+ OpStore %16 %12
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ const auto env = SPV_ENV_UNIVERSAL_1_3;
+ const auto consumer = nullptr;
+ const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, context.get()));
+
+ FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ // Add synonym fact relating %50 and %12.
+ transformation_context.GetFactManager()->AddFact(MakeSynonymFact(50, 12),
+ context.get());
+ // Add synonym fact relating %51 and %14.
+ transformation_context.GetFactManager()->AddFact(MakeSynonymFact(51, 14),
+ context.get());
+
+ // Not legal because the index being replaced is a struct index.
+ ASSERT_FALSE(
+ TransformationReplaceIdWithSynonym(
+ MakeIdUseDescriptor(
+ 12, MakeInstructionDescriptor(16, SpvOpAccessChain, 0), 1),
+ 50)
+ .IsApplicable(context.get(), transformation_context));
+
+ // Fine to replace an index into a runtime array.
+ auto replacement1 = TransformationReplaceIdWithSynonym(
+ MakeIdUseDescriptor(
+ 12, MakeInstructionDescriptor(16, SpvOpAccessChain, 0), 2),
+ 50);
+ ASSERT_TRUE(replacement1.IsApplicable(context.get(), transformation_context));
+ replacement1.Apply(context.get(), &transformation_context);
+
+ // Fine to replace an index into a vector inside the runtime array.
+ auto replacement2 = TransformationReplaceIdWithSynonym(
+ MakeIdUseDescriptor(
+ 14, MakeInstructionDescriptor(16, SpvOpAccessChain, 0), 3),
+ 51);
+ ASSERT_TRUE(replacement2.IsApplicable(context.get(), transformation_context));
+ replacement2.Apply(context.get(), &transformation_context);
+
+ ASSERT_TRUE(IsValid(env, context.get()));
+
+ const std::string after_transformation = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main"
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ OpDecorate %8 ArrayStride 8
+ OpMemberDecorate %9 0 Offset 0
+ OpDecorate %9 BufferBlock
+ OpDecorate %11 DescriptorSet 0
+ OpDecorate %11 Binding 0
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeInt 32 1
+ %7 = OpTypeVector %6 2
+ %8 = OpTypeRuntimeArray %7
+ %9 = OpTypeStruct %8
+ %10 = OpTypePointer Uniform %9
+ %11 = OpVariable %10 Uniform
+ %12 = OpConstant %6 0
+ %13 = OpTypeInt 32 0
+ %14 = OpConstant %13 0
+ %15 = OpTypePointer Uniform %6
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ %50 = OpCopyObject %6 %12
+ %51 = OpCopyObject %13 %14
+ %16 = OpAccessChain %15 %11 %12 %50 %51
+ OpStore %16 %12
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
+}
+
+TEST(TransformationReplaceIdWithSynonymTest,
+ DoNotReplaceSampleParameterOfOpImageTexelPointer) {
+ const std::string shader = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3
+ OpExecutionMode %2 OriginUpperLeft
+ OpSource ESSL 310
+ %4 = OpTypeVoid
+ %5 = OpTypeFunction %4
+ %6 = OpTypeInt 32 1
+ %7 = OpTypePointer Function %6
+ %8 = OpConstant %6 2
+ %9 = OpConstant %6 0
+ %10 = OpConstant %6 10
+ %11 = OpTypeBool
+ %12 = OpConstant %6 1
+ %13 = OpTypeFloat 32
+ %14 = OpTypePointer Image %13
+ %15 = OpTypeImage %13 2D 0 0 0 0 Rgba8
+ %16 = OpTypePointer Private %15
+ %3 = OpVariable %16 Private
+ %17 = OpTypeVector %6 2
+ %18 = OpConstantComposite %17 %9 %9
+ %2 = OpFunction %4 None %5
+ %19 = OpLabel
+ %100 = OpCopyObject %6 %9
+ %20 = OpImageTexelPointer %14 %3 %18 %9
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ const auto env = SPV_ENV_UNIVERSAL_1_5;
+ const auto consumer = nullptr;
+ const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, context.get()));
+
+ FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ // Add synonym fact relating %100 and %9.
+ transformation_context.GetFactManager()->AddFact(MakeSynonymFact(100, 9),
+ context.get());
+
+ // Not legal the Sample argument of OpImageTexelPointer needs to be a zero
+ // constant.
+ ASSERT_FALSE(
+ TransformationReplaceIdWithSynonym(
+ MakeIdUseDescriptor(
+ 9, MakeInstructionDescriptor(20, SpvOpImageTexelPointer, 0), 2),
+ 100)
+ .IsApplicable(context.get(), transformation_context));
+}
+
} // namespace
} // namespace fuzz
} // namespace spvtools
diff --git a/test/fuzz/transformation_set_function_control_test.cpp b/test/fuzz/transformation_set_function_control_test.cpp
index 536e965..be7f2be 100644
--- a/test/fuzz/transformation_set_function_control_test.cpp
+++ b/test/fuzz/transformation_set_function_control_test.cpp
@@ -118,41 +118,48 @@
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// %36 is not a function
ASSERT_FALSE(TransformationSetFunctionControl(36, SpvFunctionControlMaskNone)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Cannot add the Pure function control to %4 as it did not already have it
ASSERT_FALSE(TransformationSetFunctionControl(4, SpvFunctionControlPureMask)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Cannot add the Const function control to %21 as it did not already
// have it
ASSERT_FALSE(TransformationSetFunctionControl(21, SpvFunctionControlConstMask)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Set to None, removing Const
TransformationSetFunctionControl transformation1(11,
SpvFunctionControlMaskNone);
- ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager));
- transformation1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation1.IsApplicable(context.get(), transformation_context));
+ transformation1.Apply(context.get(), &transformation_context);
// Set to Inline; silly to do it on an entry point, but it is allowed
TransformationSetFunctionControl transformation2(
4, SpvFunctionControlInlineMask);
- ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager));
- transformation2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation2.IsApplicable(context.get(), transformation_context));
+ transformation2.Apply(context.get(), &transformation_context);
// Set to Pure, removing DontInline
TransformationSetFunctionControl transformation3(17,
SpvFunctionControlPureMask);
- ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager));
- transformation3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation3.IsApplicable(context.get(), transformation_context));
+ transformation3.Apply(context.get(), &transformation_context);
// Change from Inline to DontInline
TransformationSetFunctionControl transformation4(
13, SpvFunctionControlDontInlineMask);
- ASSERT_TRUE(transformation4.IsApplicable(context.get(), fact_manager));
- transformation4.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation4.IsApplicable(context.get(), transformation_context));
+ transformation4.Apply(context.get(), &transformation_context);
std::string after_transformation = R"(
OpCapability Shader
diff --git a/test/fuzz/transformation_set_loop_control_test.cpp b/test/fuzz/transformation_set_loop_control_test.cpp
index 83953ec..531aa7a 100644
--- a/test/fuzz/transformation_set_loop_control_test.cpp
+++ b/test/fuzz/transformation_set_loop_control_test.cpp
@@ -256,6 +256,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// These are the loop headers together with the selection controls of their
// merge instructions:
@@ -275,310 +278,310 @@
// 2 5 90 4 7 14
ASSERT_TRUE(TransformationSetLoopControl(10, SpvLoopControlMaskNone, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(10, SpvLoopControlUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationSetLoopControl(10, SpvLoopControlDontUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationSetLoopControl(
10, SpvLoopControlDependencyInfiniteMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationSetLoopControl(10, SpvLoopControlDependencyLengthMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationSetLoopControl(10, SpvLoopControlMinIterationsMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationSetLoopControl(10, SpvLoopControlMaxIterationsMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationSetLoopControl(
10, SpvLoopControlIterationMultipleMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationSetLoopControl(10, SpvLoopControlPeelCountMask, 3, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationSetLoopControl(10, SpvLoopControlPeelCountMask, 3, 3)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationSetLoopControl(10, SpvLoopControlPartialCountMask, 0, 3)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationSetLoopControl(10, SpvLoopControlPartialCountMask, 3, 3)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(
10,
SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask,
3, 3)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(10,
SpvLoopControlUnrollMask |
SpvLoopControlPeelCountMask |
SpvLoopControlPartialCountMask,
3, 3)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationSetLoopControl(10,
SpvLoopControlDontUnrollMask |
SpvLoopControlPeelCountMask |
SpvLoopControlPartialCountMask,
3, 3)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(23, SpvLoopControlMaskNone, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(23, SpvLoopControlUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationSetLoopControl(23, SpvLoopControlDontUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(
23,
SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask,
3, 3)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationSetLoopControl(23, SpvLoopControlMaxIterationsMask, 2, 3)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(33, SpvLoopControlMaskNone, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(33, SpvLoopControlUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationSetLoopControl(33, SpvLoopControlDontUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationSetLoopControl(33, SpvLoopControlMinIterationsMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationSetLoopControl(
33, SpvLoopControlUnrollMask | SpvLoopControlPeelCountMask, 5, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationSetLoopControl(33,
SpvLoopControlDontUnrollMask |
SpvLoopControlPartialCountMask,
0, 10)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(43, SpvLoopControlMaskNone, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(43, SpvLoopControlUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationSetLoopControl(43, SpvLoopControlDontUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(
43,
SpvLoopControlMaskNone | SpvLoopControlDependencyInfiniteMask,
0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationSetLoopControl(
43, SpvLoopControlUnrollMask | SpvLoopControlDependencyInfiniteMask,
0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationSetLoopControl(
43,
SpvLoopControlDontUnrollMask | SpvLoopControlDependencyInfiniteMask,
0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationSetLoopControl(43,
SpvLoopControlDependencyInfiniteMask |
SpvLoopControlDependencyLengthMask,
0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationSetLoopControl(
43, SpvLoopControlUnrollMask | SpvLoopControlPeelCountMask, 5, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(53, SpvLoopControlMaskNone, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(53, SpvLoopControlUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationSetLoopControl(53, SpvLoopControlDontUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationSetLoopControl(53, SpvLoopControlMaxIterationsMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationSetLoopControl(
53, SpvLoopControlMaskNone | SpvLoopControlDependencyLengthMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationSetLoopControl(
53, SpvLoopControlUnrollMask | SpvLoopControlDependencyInfiniteMask,
0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationSetLoopControl(
53, SpvLoopControlDontUnrollMask | SpvLoopControlDependencyLengthMask,
0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationSetLoopControl(53,
SpvLoopControlDependencyInfiniteMask |
SpvLoopControlDependencyLengthMask,
0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationSetLoopControl(
53,
SpvLoopControlUnrollMask | SpvLoopControlDependencyLengthMask |
SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask,
5, 3)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(63, SpvLoopControlMaskNone, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(63, SpvLoopControlUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationSetLoopControl(63, SpvLoopControlDontUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(63,
SpvLoopControlUnrollMask |
SpvLoopControlMinIterationsMask |
SpvLoopControlPeelCountMask |
SpvLoopControlPartialCountMask,
5, 3)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(63,
SpvLoopControlUnrollMask |
SpvLoopControlMinIterationsMask |
SpvLoopControlPeelCountMask,
23, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationSetLoopControl(
63,
SpvLoopControlUnrollMask | SpvLoopControlMinIterationsMask |
SpvLoopControlPeelCountMask,
2, 23)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(73, SpvLoopControlMaskNone, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(73, SpvLoopControlUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationSetLoopControl(73, SpvLoopControlDontUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationSetLoopControl(
73,
SpvLoopControlUnrollMask | SpvLoopControlMinIterationsMask |
SpvLoopControlPeelCountMask |
SpvLoopControlPartialCountMask,
5, 3)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(73,
SpvLoopControlUnrollMask |
SpvLoopControlMaxIterationsMask |
SpvLoopControlPeelCountMask,
23, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationSetLoopControl(
73,
SpvLoopControlUnrollMask | SpvLoopControlMaxIterationsMask |
SpvLoopControlPeelCountMask,
2, 23)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(83, SpvLoopControlMaskNone, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(83, SpvLoopControlUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationSetLoopControl(83, SpvLoopControlDontUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationSetLoopControl(
83,
SpvLoopControlUnrollMask | SpvLoopControlMinIterationsMask |
SpvLoopControlPeelCountMask |
SpvLoopControlPartialCountMask,
5, 3)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationSetLoopControl(83,
SpvLoopControlUnrollMask |
SpvLoopControlIterationMultipleMask |
SpvLoopControlPeelCountMask,
23, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationSetLoopControl(83,
SpvLoopControlUnrollMask |
SpvLoopControlIterationMultipleMask |
SpvLoopControlPeelCountMask,
2, 23)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(93, SpvLoopControlMaskNone, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(93, SpvLoopControlUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationSetLoopControl(93, SpvLoopControlDontUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationSetLoopControl(93, SpvLoopControlPeelCountMask, 8, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationSetLoopControl(93, SpvLoopControlPeelCountMask, 8, 8)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationSetLoopControl(93, SpvLoopControlPartialCountMask, 0, 8)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(
93,
SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask,
16, 8)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(103, SpvLoopControlMaskNone, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(103, SpvLoopControlUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationSetLoopControl(103, SpvLoopControlDontUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationSetLoopControl(103, SpvLoopControlPartialCountMask, 0, 60)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationSetLoopControl(103,
SpvLoopControlDontUnrollMask |
SpvLoopControlPartialCountMask,
0, 60)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(113, SpvLoopControlMaskNone, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(113, SpvLoopControlUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationSetLoopControl(113, SpvLoopControlDontUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationSetLoopControl(113, SpvLoopControlPeelCountMask, 12, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationSetLoopControl(
113,
SpvLoopControlIterationMultipleMask | SpvLoopControlPeelCountMask, 12,
0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(123, SpvLoopControlMaskNone, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(123, SpvLoopControlUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationSetLoopControl(123, SpvLoopControlDontUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(
TransformationSetLoopControl(
123,
@@ -586,72 +589,72 @@
SpvLoopControlIterationMultipleMask |
SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask,
7, 8)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_TRUE(TransformationSetLoopControl(123,
SpvLoopControlUnrollMask |
SpvLoopControlMinIterationsMask |
SpvLoopControlMaxIterationsMask |
SpvLoopControlPartialCountMask,
0, 9)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationSetLoopControl(
123,
SpvLoopControlUnrollMask | SpvLoopControlMinIterationsMask |
SpvLoopControlMaxIterationsMask |
SpvLoopControlPartialCountMask,
7, 9)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationSetLoopControl(
123,
SpvLoopControlDontUnrollMask | SpvLoopControlMinIterationsMask |
SpvLoopControlMaxIterationsMask | SpvLoopControlPartialCountMask,
7, 9)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
TransformationSetLoopControl(10,
SpvLoopControlUnrollMask |
SpvLoopControlPeelCountMask |
SpvLoopControlPartialCountMask,
3, 3)
- .Apply(context.get(), &fact_manager);
+ .Apply(context.get(), &transformation_context);
TransformationSetLoopControl(23, SpvLoopControlDontUnrollMask, 0, 0)
- .Apply(context.get(), &fact_manager);
+ .Apply(context.get(), &transformation_context);
TransformationSetLoopControl(33, SpvLoopControlUnrollMask, 0, 0)
- .Apply(context.get(), &fact_manager);
+ .Apply(context.get(), &transformation_context);
TransformationSetLoopControl(
43, SpvLoopControlDontUnrollMask | SpvLoopControlDependencyInfiniteMask,
0, 0)
- .Apply(context.get(), &fact_manager);
+ .Apply(context.get(), &transformation_context);
TransformationSetLoopControl(53, SpvLoopControlMaskNone, 0, 0)
- .Apply(context.get(), &fact_manager);
+ .Apply(context.get(), &transformation_context);
TransformationSetLoopControl(63,
SpvLoopControlUnrollMask |
SpvLoopControlMinIterationsMask |
SpvLoopControlPeelCountMask,
23, 0)
- .Apply(context.get(), &fact_manager);
+ .Apply(context.get(), &transformation_context);
TransformationSetLoopControl(73,
SpvLoopControlUnrollMask |
SpvLoopControlMaxIterationsMask |
SpvLoopControlPeelCountMask,
23, 0)
- .Apply(context.get(), &fact_manager);
+ .Apply(context.get(), &transformation_context);
TransformationSetLoopControl(83, SpvLoopControlDontUnrollMask, 0, 0)
- .Apply(context.get(), &fact_manager);
+ .Apply(context.get(), &transformation_context);
TransformationSetLoopControl(
93, SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask, 16, 8)
- .Apply(context.get(), &fact_manager);
+ .Apply(context.get(), &transformation_context);
TransformationSetLoopControl(103, SpvLoopControlPartialCountMask, 0, 60)
- .Apply(context.get(), &fact_manager);
+ .Apply(context.get(), &transformation_context);
TransformationSetLoopControl(113, SpvLoopControlPeelCountMask, 12, 0)
- .Apply(context.get(), &fact_manager);
+ .Apply(context.get(), &transformation_context);
TransformationSetLoopControl(
123,
SpvLoopControlUnrollMask | SpvLoopControlMinIterationsMask |
SpvLoopControlMaxIterationsMask | SpvLoopControlPartialCountMask,
0, 9)
- .Apply(context.get(), &fact_manager);
+ .Apply(context.get(), &transformation_context);
std::string after_transformation = R"(
OpCapability Shader
@@ -942,25 +945,28 @@
BuildModule(SPV_ENV_UNIVERSAL_1_5, consumer, shader, kFuzzAssembleOption);
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationSetLoopControl set_peel_and_partial(
10, SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask, 4, 4);
// PeelCount and PartialCount were introduced in SPIRV 1.4, so are not valid
// in the context of older versions.
- ASSERT_FALSE(
- set_peel_and_partial.IsApplicable(context_1_0.get(), fact_manager));
- ASSERT_FALSE(
- set_peel_and_partial.IsApplicable(context_1_1.get(), fact_manager));
- ASSERT_FALSE(
- set_peel_and_partial.IsApplicable(context_1_2.get(), fact_manager));
- ASSERT_FALSE(
- set_peel_and_partial.IsApplicable(context_1_3.get(), fact_manager));
+ ASSERT_FALSE(set_peel_and_partial.IsApplicable(context_1_0.get(),
+ transformation_context));
+ ASSERT_FALSE(set_peel_and_partial.IsApplicable(context_1_1.get(),
+ transformation_context));
+ ASSERT_FALSE(set_peel_and_partial.IsApplicable(context_1_2.get(),
+ transformation_context));
+ ASSERT_FALSE(set_peel_and_partial.IsApplicable(context_1_3.get(),
+ transformation_context));
- ASSERT_TRUE(
- set_peel_and_partial.IsApplicable(context_1_4.get(), fact_manager));
- ASSERT_TRUE(
- set_peel_and_partial.IsApplicable(context_1_5.get(), fact_manager));
+ ASSERT_TRUE(set_peel_and_partial.IsApplicable(context_1_4.get(),
+ transformation_context));
+ ASSERT_TRUE(set_peel_and_partial.IsApplicable(context_1_5.get(),
+ transformation_context));
}
} // namespace
diff --git a/test/fuzz/transformation_set_memory_operands_mask_test.cpp b/test/fuzz/transformation_set_memory_operands_mask_test.cpp
index ad4dc25..c02d8d4 100644
--- a/test/fuzz/transformation_set_memory_operands_mask_test.cpp
+++ b/test/fuzz/transformation_set_memory_operands_mask_test.cpp
@@ -92,37 +92,41 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Not OK: the instruction is not a memory access.
ASSERT_FALSE(TransformationSetMemoryOperandsMask(
MakeInstructionDescriptor(21, SpvOpAccessChain, 0),
SpvMemoryAccessMaskNone, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Not OK to remove Aligned
ASSERT_FALSE(TransformationSetMemoryOperandsMask(
MakeInstructionDescriptor(147, SpvOpLoad, 0),
SpvMemoryAccessVolatileMask | SpvMemoryAccessNontemporalMask,
0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
TransformationSetMemoryOperandsMask transformation1(
MakeInstructionDescriptor(147, SpvOpLoad, 0),
SpvMemoryAccessAlignedMask | SpvMemoryAccessVolatileMask, 0);
- ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager));
- transformation1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation1.IsApplicable(context.get(), transformation_context));
+ transformation1.Apply(context.get(), &transformation_context);
// Not OK to remove Aligned
ASSERT_FALSE(TransformationSetMemoryOperandsMask(
MakeInstructionDescriptor(21, SpvOpCopyMemory, 0),
SpvMemoryAccessMaskNone, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// OK: leaves the mask as is
ASSERT_TRUE(TransformationSetMemoryOperandsMask(
MakeInstructionDescriptor(21, SpvOpCopyMemory, 0),
SpvMemoryAccessAlignedMask, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// OK: adds Nontemporal and Volatile
TransformationSetMemoryOperandsMask transformation2(
@@ -130,41 +134,45 @@
SpvMemoryAccessAlignedMask | SpvMemoryAccessNontemporalMask |
SpvMemoryAccessVolatileMask,
0);
- ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager));
- transformation2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation2.IsApplicable(context.get(), transformation_context));
+ transformation2.Apply(context.get(), &transformation_context);
// Not OK to remove Volatile
ASSERT_FALSE(TransformationSetMemoryOperandsMask(
MakeInstructionDescriptor(21, SpvOpCopyMemory, 1),
SpvMemoryAccessNontemporalMask, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Not OK to add Aligned
ASSERT_FALSE(TransformationSetMemoryOperandsMask(
MakeInstructionDescriptor(21, SpvOpCopyMemory, 1),
SpvMemoryAccessAlignedMask | SpvMemoryAccessVolatileMask, 0)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// OK: adds Nontemporal
TransformationSetMemoryOperandsMask transformation3(
MakeInstructionDescriptor(21, SpvOpCopyMemory, 1),
SpvMemoryAccessNontemporalMask | SpvMemoryAccessVolatileMask, 0);
- ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager));
- transformation3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation3.IsApplicable(context.get(), transformation_context));
+ transformation3.Apply(context.get(), &transformation_context);
// OK: adds Nontemporal and Volatile
TransformationSetMemoryOperandsMask transformation4(
MakeInstructionDescriptor(138, SpvOpCopyMemory, 0),
SpvMemoryAccessNontemporalMask | SpvMemoryAccessVolatileMask, 0);
- ASSERT_TRUE(transformation4.IsApplicable(context.get(), fact_manager));
- transformation4.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation4.IsApplicable(context.get(), transformation_context));
+ transformation4.Apply(context.get(), &transformation_context);
// OK: removes Nontemporal, adds Volatile
TransformationSetMemoryOperandsMask transformation5(
MakeInstructionDescriptor(148, SpvOpStore, 0),
SpvMemoryAccessVolatileMask, 0);
- ASSERT_TRUE(transformation5.IsApplicable(context.get(), fact_manager));
- transformation5.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation5.IsApplicable(context.get(), transformation_context));
+ transformation5.Apply(context.get(), &transformation_context);
std::string after_transformation = R"(
OpCapability Shader
@@ -306,6 +314,9 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
TransformationSetMemoryOperandsMask transformation1(
MakeInstructionDescriptor(21, SpvOpCopyMemory, 0),
@@ -314,9 +325,10 @@
ASSERT_FALSE(TransformationSetMemoryOperandsMask(
MakeInstructionDescriptor(21, SpvOpCopyMemory, 0),
SpvMemoryAccessVolatileMask, 1)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager));
- transformation1.Apply(context.get(), &fact_manager);
+ .IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(
+ transformation1.IsApplicable(context.get(), transformation_context));
+ transformation1.Apply(context.get(), &transformation_context);
TransformationSetMemoryOperandsMask transformation2(
MakeInstructionDescriptor(21, SpvOpCopyMemory, 1),
@@ -325,9 +337,10 @@
ASSERT_FALSE(TransformationSetMemoryOperandsMask(
MakeInstructionDescriptor(21, SpvOpCopyMemory, 1),
SpvMemoryAccessNontemporalMask, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager));
- transformation2.Apply(context.get(), &fact_manager);
+ .IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(
+ transformation2.IsApplicable(context.get(), transformation_context));
+ transformation2.Apply(context.get(), &transformation_context);
TransformationSetMemoryOperandsMask transformation3(
MakeInstructionDescriptor(138, SpvOpCopyMemory, 0),
@@ -337,27 +350,31 @@
MakeInstructionDescriptor(138, SpvOpCopyMemory, 0),
SpvMemoryAccessAlignedMask | SpvMemoryAccessNontemporalMask,
0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager));
- transformation3.Apply(context.get(), &fact_manager);
+ .IsApplicable(context.get(), transformation_context));
+ ASSERT_TRUE(
+ transformation3.IsApplicable(context.get(), transformation_context));
+ transformation3.Apply(context.get(), &transformation_context);
TransformationSetMemoryOperandsMask transformation4(
MakeInstructionDescriptor(138, SpvOpCopyMemory, 1),
SpvMemoryAccessVolatileMask, 1);
- ASSERT_TRUE(transformation4.IsApplicable(context.get(), fact_manager));
- transformation4.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation4.IsApplicable(context.get(), transformation_context));
+ transformation4.Apply(context.get(), &transformation_context);
TransformationSetMemoryOperandsMask transformation5(
MakeInstructionDescriptor(147, SpvOpLoad, 0),
SpvMemoryAccessVolatileMask | SpvMemoryAccessAlignedMask, 0);
- ASSERT_TRUE(transformation5.IsApplicable(context.get(), fact_manager));
- transformation5.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation5.IsApplicable(context.get(), transformation_context));
+ transformation5.Apply(context.get(), &transformation_context);
TransformationSetMemoryOperandsMask transformation6(
MakeInstructionDescriptor(148, SpvOpStore, 0), SpvMemoryAccessMaskNone,
0);
- ASSERT_TRUE(transformation6.IsApplicable(context.get(), fact_manager));
- transformation6.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation6.IsApplicable(context.get(), transformation_context));
+ transformation6.Apply(context.get(), &transformation_context);
std::string after_transformation = R"(
OpCapability Shader
diff --git a/test/fuzz/transformation_set_selection_control_test.cpp b/test/fuzz/transformation_set_selection_control_test.cpp
index 9696417..9afb89d 100644
--- a/test/fuzz/transformation_set_selection_control_test.cpp
+++ b/test/fuzz/transformation_set_selection_control_test.cpp
@@ -103,39 +103,46 @@
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// %44 is not a block
ASSERT_FALSE(
TransformationSetSelectionControl(44, SpvSelectionControlFlattenMask)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// %13 does not end with OpSelectionMerge
ASSERT_FALSE(
TransformationSetSelectionControl(13, SpvSelectionControlMaskNone)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// %10 ends in OpLoopMerge, not OpSelectionMerge
ASSERT_FALSE(
TransformationSetSelectionControl(10, SpvSelectionControlMaskNone)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
TransformationSetSelectionControl transformation1(
11, SpvSelectionControlDontFlattenMask);
- ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager));
- transformation1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation1.IsApplicable(context.get(), transformation_context));
+ transformation1.Apply(context.get(), &transformation_context);
TransformationSetSelectionControl transformation2(
23, SpvSelectionControlFlattenMask);
- ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager));
- transformation2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation2.IsApplicable(context.get(), transformation_context));
+ transformation2.Apply(context.get(), &transformation_context);
TransformationSetSelectionControl transformation3(
31, SpvSelectionControlMaskNone);
- ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager));
- transformation3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation3.IsApplicable(context.get(), transformation_context));
+ transformation3.Apply(context.get(), &transformation_context);
TransformationSetSelectionControl transformation4(
31, SpvSelectionControlFlattenMask);
- ASSERT_TRUE(transformation4.IsApplicable(context.get(), fact_manager));
- transformation4.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation4.IsApplicable(context.get(), transformation_context));
+ transformation4.Apply(context.get(), &transformation_context);
std::string after_transformation = R"(
OpCapability Shader
diff --git a/test/fuzz/transformation_split_block_test.cpp b/test/fuzz/transformation_split_block_test.cpp
index 09007a5..30bac02 100644
--- a/test/fuzz/transformation_split_block_test.cpp
+++ b/test/fuzz/transformation_split_block_test.cpp
@@ -89,57 +89,60 @@
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// No split before OpVariable
ASSERT_FALSE(TransformationSplitBlock(
MakeInstructionDescriptor(8, SpvOpVariable, 0), 100)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationSplitBlock(
MakeInstructionDescriptor(8, SpvOpVariable, 1), 100)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// No split before OpLabel
ASSERT_FALSE(TransformationSplitBlock(
MakeInstructionDescriptor(14, SpvOpLabel, 0), 100)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// No split if base instruction is outside a function
ASSERT_FALSE(
TransformationSplitBlock(MakeInstructionDescriptor(1, SpvOpLabel, 0), 100)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationSplitBlock(
MakeInstructionDescriptor(1, SpvOpExecutionMode, 0), 100)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// No split if block is loop header
ASSERT_FALSE(
TransformationSplitBlock(MakeInstructionDescriptor(27, SpvOpPhi, 0), 100)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationSplitBlock(MakeInstructionDescriptor(27, SpvOpPhi, 1), 100)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// No split if base instruction does not exist
ASSERT_FALSE(
TransformationSplitBlock(MakeInstructionDescriptor(88, SpvOpIAdd, 0), 100)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationSplitBlock(
MakeInstructionDescriptor(88, SpvOpIMul, 22), 100)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// No split if too many instructions with the desired opcode are skipped
ASSERT_FALSE(
TransformationSplitBlock(
MakeInstructionDescriptor(18, SpvOpBranchConditional, 1), 100)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// No split if id in use
ASSERT_FALSE(TransformationSplitBlock(
MakeInstructionDescriptor(18, SpvOpSLessThan, 0), 27)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationSplitBlock(
MakeInstructionDescriptor(18, SpvOpSLessThan, 0), 14)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
}
TEST(TransformationSplitBlockTest, SplitBlockSeveralTimes) {
@@ -199,11 +202,14 @@
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
auto split_1 = TransformationSplitBlock(
MakeInstructionDescriptor(5, SpvOpStore, 0), 100);
- ASSERT_TRUE(split_1.IsApplicable(context.get(), fact_manager));
- split_1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(split_1.IsApplicable(context.get(), transformation_context));
+ split_1.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_split_1 = R"(
@@ -250,8 +256,8 @@
auto split_2 = TransformationSplitBlock(
MakeInstructionDescriptor(11, SpvOpStore, 0), 101);
- ASSERT_TRUE(split_2.IsApplicable(context.get(), fact_manager));
- split_2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(split_2.IsApplicable(context.get(), transformation_context));
+ split_2.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_split_2 = R"(
@@ -300,8 +306,8 @@
auto split_3 = TransformationSplitBlock(
MakeInstructionDescriptor(14, SpvOpLoad, 0), 102);
- ASSERT_TRUE(split_3.IsApplicable(context.get(), fact_manager));
- split_3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(split_3.IsApplicable(context.get(), transformation_context));
+ split_3.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_split_3 = R"(
@@ -412,21 +418,24 @@
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Illegal to split between the merge and the conditional branch.
ASSERT_FALSE(
TransformationSplitBlock(
MakeInstructionDescriptor(14, SpvOpBranchConditional, 0), 100)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationSplitBlock(
MakeInstructionDescriptor(12, SpvOpBranchConditional, 0), 100)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
auto split = TransformationSplitBlock(
MakeInstructionDescriptor(14, SpvOpSelectionMerge, 0), 100);
- ASSERT_TRUE(split.IsApplicable(context.get(), fact_manager));
- split.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(split.IsApplicable(context.get(), transformation_context));
+ split.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_split = R"(
@@ -541,19 +550,22 @@
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Illegal to split between the merge and the conditional branch.
ASSERT_FALSE(TransformationSplitBlock(
MakeInstructionDescriptor(9, SpvOpSwitch, 0), 100)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(TransformationSplitBlock(
MakeInstructionDescriptor(15, SpvOpSwitch, 0), 100)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
auto split = TransformationSplitBlock(
MakeInstructionDescriptor(9, SpvOpSelectionMerge, 0), 100);
- ASSERT_TRUE(split.IsApplicable(context.get(), fact_manager));
- split.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(split.IsApplicable(context.get(), transformation_context));
+ split.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_split = R"(
@@ -674,18 +686,21 @@
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// We cannot split before OpPhi instructions, since the number of incoming
// blocks may not appropriately match after splitting.
ASSERT_FALSE(
TransformationSplitBlock(MakeInstructionDescriptor(26, SpvOpPhi, 0), 100)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationSplitBlock(MakeInstructionDescriptor(27, SpvOpPhi, 0), 100)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationSplitBlock(MakeInstructionDescriptor(27, SpvOpPhi, 1), 100)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
}
TEST(TransformationSplitBlockTest, SplitOpPhiWithSinglePredecessor) {
@@ -726,16 +741,19 @@
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
ASSERT_TRUE(
TransformationSplitBlock(MakeInstructionDescriptor(21, SpvOpPhi, 0), 100)
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// An equivalent transformation to the above, just described with respect to a
// different base instruction.
auto split =
TransformationSplitBlock(MakeInstructionDescriptor(20, SpvOpPhi, 0), 100);
- ASSERT_TRUE(split.IsApplicable(context.get(), fact_manager));
- split.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(split.IsApplicable(context.get(), transformation_context));
+ split.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_split = R"(
@@ -805,18 +823,21 @@
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Record the fact that block 8 is dead.
- fact_manager.AddFactBlockIsDead(8);
+ transformation_context.GetFactManager()->AddFactBlockIsDead(8);
auto split = TransformationSplitBlock(
MakeInstructionDescriptor(8, SpvOpBranch, 0), 100);
- ASSERT_TRUE(split.IsApplicable(context.get(), fact_manager));
- split.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(split.IsApplicable(context.get(), transformation_context));
+ split.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
- ASSERT_TRUE(fact_manager.BlockIsDead(8));
- ASSERT_TRUE(fact_manager.BlockIsDead(100));
+ ASSERT_TRUE(transformation_context.GetFactManager()->BlockIsDead(8));
+ ASSERT_TRUE(transformation_context.GetFactManager()->BlockIsDead(100));
std::string after_split = R"(
OpCapability Shader
@@ -845,6 +866,62 @@
ASSERT_TRUE(IsEqual(env, after_split, context.get()));
}
+TEST(TransformationSplitBlockTest, DoNotSplitUseOfOpSampledImage) {
+ // This checks that we cannot split the definition of an OpSampledImage
+ // from its use.
+ std::string shader = R"(
+ OpCapability Shader
+ OpCapability SampledBuffer
+ OpCapability ImageBuffer
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %40 %41
+ OpExecutionMode %2 OriginUpperLeft
+ OpSource GLSL 450
+ OpDecorate %40 DescriptorSet 0
+ OpDecorate %40 Binding 69
+ OpDecorate %41 DescriptorSet 0
+ OpDecorate %41 Binding 1
+ %54 = OpTypeFloat 32
+ %76 = OpTypeVector %54 4
+ %55 = OpConstant %54 0
+ %56 = OpTypeVector %54 3
+ %94 = OpTypeVector %54 2
+ %112 = OpConstantComposite %94 %55 %55
+ %57 = OpConstantComposite %56 %55 %55 %55
+ %15 = OpTypeImage %54 2D 2 0 0 1 Unknown
+ %114 = OpTypePointer UniformConstant %15
+ %38 = OpTypeSampler
+ %125 = OpTypePointer UniformConstant %38
+ %132 = OpTypeVoid
+ %133 = OpTypeFunction %132
+ %45 = OpTypeSampledImage %15
+ %40 = OpVariable %114 UniformConstant
+ %41 = OpVariable %125 UniformConstant
+ %2 = OpFunction %132 None %133
+ %164 = OpLabel
+ %184 = OpLoad %15 %40
+ %213 = OpLoad %38 %41
+ %216 = OpSampledImage %45 %184 %213
+ %217 = OpImageSampleImplicitLod %76 %216 %112 Bias %55
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ const auto env = SPV_ENV_UNIVERSAL_1_3;
+ const auto consumer = nullptr;
+ const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
+
+ FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ auto split = TransformationSplitBlock(
+ MakeInstructionDescriptor(217, SpvOpImageSampleImplicitLod, 0), 500);
+ ASSERT_FALSE(split.IsApplicable(context.get(), transformation_context));
+}
+
} // namespace
} // namespace fuzz
} // namespace spvtools
diff --git a/test/fuzz/transformation_store_test.cpp b/test/fuzz/transformation_store_test.cpp
index 3fb9b61..07d222f 100644
--- a/test/fuzz/transformation_store_test.cpp
+++ b/test/fuzz/transformation_store_test.cpp
@@ -94,16 +94,26 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
- fact_manager.AddFactValueOfPointeeIsIrrelevant(27);
- fact_manager.AddFactValueOfPointeeIsIrrelevant(11);
- fact_manager.AddFactValueOfPointeeIsIrrelevant(46);
- fact_manager.AddFactValueOfPointeeIsIrrelevant(16);
- fact_manager.AddFactValueOfPointeeIsIrrelevant(52);
- fact_manager.AddFactValueOfPointeeIsIrrelevant(81);
- fact_manager.AddFactValueOfPointeeIsIrrelevant(82);
+ transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
+ 27);
+ transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
+ 11);
+ transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
+ 46);
+ transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
+ 16);
+ transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
+ 52);
+ transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
+ 81);
+ transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
+ 82);
- fact_manager.AddFactBlockIsDead(36);
+ transformation_context.GetFactManager()->AddFactBlockIsDead(36);
// Variables with pointee types:
// 52 - ptr_to(7)
@@ -139,90 +149,91 @@
// Bad: attempt to store to 11 from outside its function
ASSERT_FALSE(TransformationStore(
11, 80, MakeInstructionDescriptor(38, SpvOpAccessChain, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: pointer is not available
ASSERT_FALSE(TransformationStore(
81, 80, MakeInstructionDescriptor(45, SpvOpCopyObject, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: attempt to insert before OpVariable
ASSERT_FALSE(TransformationStore(
52, 24, MakeInstructionDescriptor(27, SpvOpVariable, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: pointer id does not exist
ASSERT_FALSE(TransformationStore(
1000, 24, MakeInstructionDescriptor(38, SpvOpAccessChain, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: pointer id exists but does not have a type
ASSERT_FALSE(TransformationStore(
5, 24, MakeInstructionDescriptor(38, SpvOpAccessChain, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: pointer id exists and has a type, but is not a pointer
ASSERT_FALSE(TransformationStore(
24, 24, MakeInstructionDescriptor(38, SpvOpAccessChain, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: attempt to store to a null pointer
ASSERT_FALSE(TransformationStore(
60, 24, MakeInstructionDescriptor(38, SpvOpAccessChain, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: attempt to store to an undefined pointer
ASSERT_FALSE(TransformationStore(
61, 21, MakeInstructionDescriptor(38, SpvOpAccessChain, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: %82 is not available at the program point
ASSERT_FALSE(
TransformationStore(82, 80, MakeInstructionDescriptor(37, SpvOpReturn, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: value id does not exist
ASSERT_FALSE(TransformationStore(
27, 1000, MakeInstructionDescriptor(38, SpvOpAccessChain, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: value id exists but does not have a type
ASSERT_FALSE(TransformationStore(
27, 15, MakeInstructionDescriptor(38, SpvOpAccessChain, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: value id exists but has the wrong type
ASSERT_FALSE(TransformationStore(
27, 14, MakeInstructionDescriptor(38, SpvOpAccessChain, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: attempt to store to read-only variable
ASSERT_FALSE(TransformationStore(
92, 93, MakeInstructionDescriptor(40, SpvOpAccessChain, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: value is not available
ASSERT_FALSE(TransformationStore(
27, 95, MakeInstructionDescriptor(40, SpvOpAccessChain, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Bad: variable being stored to does not have an irrelevant pointee value,
// and the store is not in a dead block.
ASSERT_FALSE(TransformationStore(
20, 95, MakeInstructionDescriptor(45, SpvOpCopyObject, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// The described instruction does not exist.
ASSERT_FALSE(TransformationStore(
27, 80, MakeInstructionDescriptor(1000, SpvOpAccessChain, 0))
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
{
// Store to irrelevant variable from dead block.
TransformationStore transformation(
27, 80, MakeInstructionDescriptor(38, SpvOpAccessChain, 0));
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
}
@@ -230,8 +241,9 @@
// Store to irrelevant variable from live block.
TransformationStore transformation(
11, 95, MakeInstructionDescriptor(95, SpvOpReturnValue, 0));
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
}
@@ -239,8 +251,9 @@
// Store to irrelevant variable from live block.
TransformationStore transformation(
46, 80, MakeInstructionDescriptor(95, SpvOpReturnValue, 0));
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
}
@@ -248,8 +261,9 @@
// Store to irrelevant variable from live block.
TransformationStore transformation(
16, 21, MakeInstructionDescriptor(95, SpvOpReturnValue, 0));
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
}
@@ -257,8 +271,9 @@
// Store to non-irrelevant variable from dead block.
TransformationStore transformation(
53, 21, MakeInstructionDescriptor(38, SpvOpAccessChain, 0));
- ASSERT_TRUE(transformation.IsApplicable(context.get(), fact_manager));
- transformation.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
+ transformation.Apply(context.get(), &transformation_context);
ASSERT_TRUE(IsValid(env, context.get()));
}
@@ -336,6 +351,70 @@
ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
}
+TEST(TransformationStoreTest, DoNotAllowStoresToReadOnlyMemory) {
+ std::string shader = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main"
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 320
+ OpMemberDecorate %10 0 Offset 0
+ OpMemberDecorate %10 1 Offset 4
+ OpDecorate %10 Block
+ OpMemberDecorate %23 0 Offset 0
+ OpDecorate %23 Block
+ OpDecorate %25 DescriptorSet 0
+ OpDecorate %25 Binding 0
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeInt 32 1
+ %7 = OpTypePointer Function %6
+ %9 = OpTypeFloat 32
+ %10 = OpTypeStruct %6 %9
+ %11 = OpTypePointer PushConstant %10
+ %12 = OpVariable %11 PushConstant
+ %13 = OpConstant %6 0
+ %14 = OpTypePointer PushConstant %6
+ %17 = OpConstant %6 1
+ %18 = OpTypePointer PushConstant %9
+ %23 = OpTypeStruct %9
+ %24 = OpTypePointer UniformConstant %23
+ %25 = OpVariable %24 UniformConstant
+ %26 = OpTypePointer UniformConstant %9
+ %50 = OpConstant %9 0
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ %15 = OpAccessChain %14 %12 %13
+ %19 = OpAccessChain %18 %12 %17
+ %27 = OpAccessChain %26 %25 %13
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ const auto env = SPV_ENV_UNIVERSAL_1_3;
+ const auto consumer = nullptr;
+ const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
+ ASSERT_TRUE(IsValid(env, context.get()));
+
+ FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
+
+ fact_manager.AddFactBlockIsDead(5);
+
+ ASSERT_FALSE(
+ TransformationStore(15, 13, MakeInstructionDescriptor(27, SpvOpReturn, 0))
+ .IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ TransformationStore(19, 50, MakeInstructionDescriptor(27, SpvOpReturn, 0))
+ .IsApplicable(context.get(), transformation_context));
+ ASSERT_FALSE(
+ TransformationStore(27, 50, MakeInstructionDescriptor(27, SpvOpReturn, 0))
+ .IsApplicable(context.get(), transformation_context));
+}
+
} // namespace
} // namespace fuzz
} // namespace spvtools
diff --git a/test/fuzz/transformation_swap_commutable_operands_test.cpp b/test/fuzz/transformation_swap_commutable_operands_test.cpp
index f0591cf..c213dfe 100644
--- a/test/fuzz/transformation_swap_commutable_operands_test.cpp
+++ b/test/fuzz/transformation_swap_commutable_operands_test.cpp
@@ -111,113 +111,140 @@
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context.get()));
- FactManager factManager;
+ FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Tests existing commutative instructions
auto instructionDescriptor = MakeInstructionDescriptor(22, SpvOpIAdd, 0);
auto transformation =
TransformationSwapCommutableOperands(instructionDescriptor);
- ASSERT_TRUE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
instructionDescriptor = MakeInstructionDescriptor(28, SpvOpIMul, 0);
transformation = TransformationSwapCommutableOperands(instructionDescriptor);
- ASSERT_TRUE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
instructionDescriptor = MakeInstructionDescriptor(42, SpvOpFAdd, 0);
transformation = TransformationSwapCommutableOperands(instructionDescriptor);
- ASSERT_TRUE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
instructionDescriptor = MakeInstructionDescriptor(48, SpvOpFMul, 0);
transformation = TransformationSwapCommutableOperands(instructionDescriptor);
- ASSERT_TRUE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
instructionDescriptor = MakeInstructionDescriptor(66, SpvOpDot, 0);
transformation = TransformationSwapCommutableOperands(instructionDescriptor);
- ASSERT_TRUE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
// Tests existing non-commutative instructions
instructionDescriptor = MakeInstructionDescriptor(1, SpvOpExtInstImport, 0);
transformation = TransformationSwapCommutableOperands(instructionDescriptor);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
instructionDescriptor = MakeInstructionDescriptor(5, SpvOpLabel, 0);
transformation = TransformationSwapCommutableOperands(instructionDescriptor);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
instructionDescriptor = MakeInstructionDescriptor(8, SpvOpConstant, 0);
transformation = TransformationSwapCommutableOperands(instructionDescriptor);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
instructionDescriptor = MakeInstructionDescriptor(11, SpvOpVariable, 0);
transformation = TransformationSwapCommutableOperands(instructionDescriptor);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
instructionDescriptor =
MakeInstructionDescriptor(14, SpvOpConstantComposite, 0);
transformation = TransformationSwapCommutableOperands(instructionDescriptor);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
// Tests the base instruction id not existing
instructionDescriptor = MakeInstructionDescriptor(67, SpvOpIAddCarry, 0);
transformation = TransformationSwapCommutableOperands(instructionDescriptor);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
instructionDescriptor = MakeInstructionDescriptor(68, SpvOpIEqual, 0);
transformation = TransformationSwapCommutableOperands(instructionDescriptor);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
instructionDescriptor = MakeInstructionDescriptor(69, SpvOpINotEqual, 0);
transformation = TransformationSwapCommutableOperands(instructionDescriptor);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
instructionDescriptor = MakeInstructionDescriptor(70, SpvOpFOrdEqual, 0);
transformation = TransformationSwapCommutableOperands(instructionDescriptor);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
instructionDescriptor = MakeInstructionDescriptor(71, SpvOpPtrEqual, 0);
transformation = TransformationSwapCommutableOperands(instructionDescriptor);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
// Tests there being no instruction with the desired opcode after the base
// instruction id
instructionDescriptor = MakeInstructionDescriptor(24, SpvOpIAdd, 0);
transformation = TransformationSwapCommutableOperands(instructionDescriptor);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
instructionDescriptor = MakeInstructionDescriptor(38, SpvOpIMul, 0);
transformation = TransformationSwapCommutableOperands(instructionDescriptor);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
instructionDescriptor = MakeInstructionDescriptor(45, SpvOpFAdd, 0);
transformation = TransformationSwapCommutableOperands(instructionDescriptor);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
instructionDescriptor = MakeInstructionDescriptor(66, SpvOpFMul, 0);
transformation = TransformationSwapCommutableOperands(instructionDescriptor);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
// Tests there being an instruction with the desired opcode after the base
// instruction id, but the skip count associated with the instruction
// descriptor being so high.
instructionDescriptor = MakeInstructionDescriptor(11, SpvOpIAdd, 100);
transformation = TransformationSwapCommutableOperands(instructionDescriptor);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
instructionDescriptor = MakeInstructionDescriptor(16, SpvOpIMul, 100);
transformation = TransformationSwapCommutableOperands(instructionDescriptor);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
instructionDescriptor = MakeInstructionDescriptor(23, SpvOpFAdd, 100);
transformation = TransformationSwapCommutableOperands(instructionDescriptor);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
instructionDescriptor = MakeInstructionDescriptor(32, SpvOpFMul, 100);
transformation = TransformationSwapCommutableOperands(instructionDescriptor);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
instructionDescriptor = MakeInstructionDescriptor(37, SpvOpDot, 100);
transformation = TransformationSwapCommutableOperands(instructionDescriptor);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationSwapCommutableOperandsTest, ApplyTest) {
@@ -311,28 +338,31 @@
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context.get()));
- FactManager factManager;
+ FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
auto instructionDescriptor = MakeInstructionDescriptor(22, SpvOpIAdd, 0);
auto transformation =
TransformationSwapCommutableOperands(instructionDescriptor);
- transformation.Apply(context.get(), &factManager);
+ transformation.Apply(context.get(), &transformation_context);
instructionDescriptor = MakeInstructionDescriptor(28, SpvOpIMul, 0);
transformation = TransformationSwapCommutableOperands(instructionDescriptor);
- transformation.Apply(context.get(), &factManager);
+ transformation.Apply(context.get(), &transformation_context);
instructionDescriptor = MakeInstructionDescriptor(42, SpvOpFAdd, 0);
transformation = TransformationSwapCommutableOperands(instructionDescriptor);
- transformation.Apply(context.get(), &factManager);
+ transformation.Apply(context.get(), &transformation_context);
instructionDescriptor = MakeInstructionDescriptor(48, SpvOpFMul, 0);
transformation = TransformationSwapCommutableOperands(instructionDescriptor);
- transformation.Apply(context.get(), &factManager);
+ transformation.Apply(context.get(), &transformation_context);
instructionDescriptor = MakeInstructionDescriptor(66, SpvOpDot, 0);
transformation = TransformationSwapCommutableOperands(instructionDescriptor);
- transformation.Apply(context.get(), &factManager);
+ transformation.Apply(context.get(), &transformation_context);
std::string variantShader = R"(
OpCapability Shader
diff --git a/test/fuzz/transformation_toggle_access_chain_instruction_test.cpp b/test/fuzz/transformation_toggle_access_chain_instruction_test.cpp
index 98e0a64..b20f59e 100644
--- a/test/fuzz/transformation_toggle_access_chain_instruction_test.cpp
+++ b/test/fuzz/transformation_toggle_access_chain_instruction_test.cpp
@@ -111,78 +111,93 @@
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context.get()));
- FactManager factManager;
+ FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Tests existing access chain instructions
auto instructionDescriptor =
MakeInstructionDescriptor(18, SpvOpAccessChain, 0);
auto transformation =
TransformationToggleAccessChainInstruction(instructionDescriptor);
- ASSERT_TRUE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
instructionDescriptor =
MakeInstructionDescriptor(20, SpvOpInBoundsAccessChain, 0);
transformation =
TransformationToggleAccessChainInstruction(instructionDescriptor);
- ASSERT_TRUE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
instructionDescriptor = MakeInstructionDescriptor(24, SpvOpAccessChain, 0);
transformation =
TransformationToggleAccessChainInstruction(instructionDescriptor);
- ASSERT_TRUE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
instructionDescriptor =
MakeInstructionDescriptor(26, SpvOpInBoundsAccessChain, 0);
transformation =
TransformationToggleAccessChainInstruction(instructionDescriptor);
- ASSERT_TRUE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_TRUE(
+ transformation.IsApplicable(context.get(), transformation_context));
// Tests existing non-access chain instructions
instructionDescriptor = MakeInstructionDescriptor(1, SpvOpExtInstImport, 0);
transformation =
TransformationToggleAccessChainInstruction(instructionDescriptor);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
instructionDescriptor = MakeInstructionDescriptor(5, SpvOpLabel, 0);
transformation =
TransformationToggleAccessChainInstruction(instructionDescriptor);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
instructionDescriptor =
MakeInstructionDescriptor(14, SpvOpConstantComposite, 0);
transformation =
TransformationToggleAccessChainInstruction(instructionDescriptor);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
// Tests the base instruction id not existing
instructionDescriptor = MakeInstructionDescriptor(67, SpvOpAccessChain, 0);
transformation =
TransformationToggleAccessChainInstruction(instructionDescriptor);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
instructionDescriptor = MakeInstructionDescriptor(68, SpvOpAccessChain, 0);
transformation =
TransformationToggleAccessChainInstruction(instructionDescriptor);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
instructionDescriptor =
MakeInstructionDescriptor(69, SpvOpInBoundsAccessChain, 0);
transformation =
TransformationToggleAccessChainInstruction(instructionDescriptor);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
// Tests there being no instruction with the desired opcode after the base
// instruction id
instructionDescriptor = MakeInstructionDescriptor(65, SpvOpAccessChain, 0);
transformation =
TransformationToggleAccessChainInstruction(instructionDescriptor);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
instructionDescriptor =
MakeInstructionDescriptor(66, SpvOpInBoundsAccessChain, 0);
transformation =
TransformationToggleAccessChainInstruction(instructionDescriptor);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
// Tests there being an instruction with the desired opcode after the base
// instruction id, but the skip count associated with the instruction
@@ -190,13 +205,15 @@
instructionDescriptor = MakeInstructionDescriptor(11, SpvOpAccessChain, 100);
transformation =
TransformationToggleAccessChainInstruction(instructionDescriptor);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
instructionDescriptor =
MakeInstructionDescriptor(16, SpvOpInBoundsAccessChain, 100);
transformation =
TransformationToggleAccessChainInstruction(instructionDescriptor);
- ASSERT_FALSE(transformation.IsApplicable(context.get(), factManager));
+ ASSERT_FALSE(
+ transformation.IsApplicable(context.get(), transformation_context));
}
TEST(TransformationToggleAccessChainInstructionTest, ApplyTest) {
@@ -290,35 +307,38 @@
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context.get()));
- FactManager factManager;
+ FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
auto instructionDescriptor =
MakeInstructionDescriptor(18, SpvOpAccessChain, 0);
auto transformation =
TransformationToggleAccessChainInstruction(instructionDescriptor);
- transformation.Apply(context.get(), &factManager);
+ transformation.Apply(context.get(), &transformation_context);
instructionDescriptor =
MakeInstructionDescriptor(20, SpvOpInBoundsAccessChain, 0);
transformation =
TransformationToggleAccessChainInstruction(instructionDescriptor);
- transformation.Apply(context.get(), &factManager);
+ transformation.Apply(context.get(), &transformation_context);
instructionDescriptor = MakeInstructionDescriptor(24, SpvOpAccessChain, 0);
transformation =
TransformationToggleAccessChainInstruction(instructionDescriptor);
- transformation.Apply(context.get(), &factManager);
+ transformation.Apply(context.get(), &transformation_context);
instructionDescriptor =
MakeInstructionDescriptor(26, SpvOpInBoundsAccessChain, 0);
transformation =
TransformationToggleAccessChainInstruction(instructionDescriptor);
- transformation.Apply(context.get(), &factManager);
+ transformation.Apply(context.get(), &transformation_context);
instructionDescriptor = MakeInstructionDescriptor(38, SpvOpAccessChain, 0);
transformation =
TransformationToggleAccessChainInstruction(instructionDescriptor);
- transformation.Apply(context.get(), &factManager);
+ transformation.Apply(context.get(), &transformation_context);
std::string variantShader = R"(
OpCapability Shader
diff --git a/test/fuzz/transformation_vector_shuffle_test.cpp b/test/fuzz/transformation_vector_shuffle_test.cpp
index 385c38b..a29c511 100644
--- a/test/fuzz/transformation_vector_shuffle_test.cpp
+++ b/test/fuzz/transformation_vector_shuffle_test.cpp
@@ -86,249 +86,259 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(10, {}),
- MakeDataDescriptor(12, {0}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(11, {}),
- MakeDataDescriptor(12, {1}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(10, {}), MakeDataDescriptor(12, {0}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(11, {}), MakeDataDescriptor(12, {1}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(10, {}),
- MakeDataDescriptor(16, {0}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(11, {}),
- MakeDataDescriptor(16, {1}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(10, {}),
- MakeDataDescriptor(16, {2}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(10, {}), MakeDataDescriptor(16, {0}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(11, {}), MakeDataDescriptor(16, {1}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(10, {}), MakeDataDescriptor(16, {2}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(10, {}),
- MakeDataDescriptor(20, {0}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(11, {}),
- MakeDataDescriptor(20, {1}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(10, {}),
- MakeDataDescriptor(20, {2}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(11, {}),
- MakeDataDescriptor(20, {3}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(10, {}), MakeDataDescriptor(20, {0}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(11, {}), MakeDataDescriptor(20, {1}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(10, {}), MakeDataDescriptor(20, {2}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(11, {}), MakeDataDescriptor(20, {3}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(25, {}),
- MakeDataDescriptor(27, {0}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(26, {}),
- MakeDataDescriptor(27, {1}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(25, {}), MakeDataDescriptor(27, {0}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(26, {}), MakeDataDescriptor(27, {1}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(25, {}),
- MakeDataDescriptor(31, {0}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(26, {}),
- MakeDataDescriptor(31, {1}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(25, {}),
- MakeDataDescriptor(31, {2}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(25, {}), MakeDataDescriptor(31, {0}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(26, {}), MakeDataDescriptor(31, {1}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(25, {}), MakeDataDescriptor(31, {2}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(25, {}),
- MakeDataDescriptor(35, {0}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(26, {}),
- MakeDataDescriptor(35, {1}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(25, {}),
- MakeDataDescriptor(35, {2}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(26, {}),
- MakeDataDescriptor(35, {3}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(25, {}), MakeDataDescriptor(35, {0}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(26, {}), MakeDataDescriptor(35, {1}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(25, {}), MakeDataDescriptor(35, {2}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(26, {}), MakeDataDescriptor(35, {3}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(40, {}),
- MakeDataDescriptor(42, {0}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(41, {}),
- MakeDataDescriptor(42, {1}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(40, {}), MakeDataDescriptor(42, {0}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(41, {}), MakeDataDescriptor(42, {1}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(40, {}),
- MakeDataDescriptor(46, {0}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(41, {}),
- MakeDataDescriptor(46, {1}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(40, {}),
- MakeDataDescriptor(46, {2}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(40, {}), MakeDataDescriptor(46, {0}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(41, {}), MakeDataDescriptor(46, {1}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(40, {}), MakeDataDescriptor(46, {2}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(40, {}),
- MakeDataDescriptor(50, {0}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(41, {}),
- MakeDataDescriptor(50, {1}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(40, {}),
- MakeDataDescriptor(50, {2}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(41, {}),
- MakeDataDescriptor(50, {3}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(40, {}), MakeDataDescriptor(50, {0}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(41, {}), MakeDataDescriptor(50, {1}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(40, {}), MakeDataDescriptor(50, {2}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(41, {}), MakeDataDescriptor(50, {3}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(55, {}),
- MakeDataDescriptor(61, {0}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(56, {}),
- MakeDataDescriptor(61, {1}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(55, {}),
- MakeDataDescriptor(61, {2}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(55, {}), MakeDataDescriptor(61, {0}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(56, {}), MakeDataDescriptor(61, {1}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(55, {}), MakeDataDescriptor(61, {2}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(55, {}),
- MakeDataDescriptor(65, {0}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(56, {}),
- MakeDataDescriptor(65, {1}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(55, {}),
- MakeDataDescriptor(65, {2}), context.get());
- fact_manager.AddFactDataSynonym(MakeDataDescriptor(56, {}),
- MakeDataDescriptor(65, {3}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(55, {}), MakeDataDescriptor(65, {0}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(56, {}), MakeDataDescriptor(65, {1}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(55, {}), MakeDataDescriptor(65, {2}), context.get());
+ transformation_context.GetFactManager()->AddFactDataSynonym(
+ MakeDataDescriptor(56, {}), MakeDataDescriptor(65, {3}), context.get());
// %103 does not dominate the return instruction.
ASSERT_FALSE(TransformationVectorShuffle(
MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 103, 65,
{3, 5, 7})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Illegal to shuffle a bvec2 and a vec3
ASSERT_FALSE(TransformationVectorShuffle(
MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 112, 61,
{0, 2, 4})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Illegal to shuffle an ivec2 and a uvec4
ASSERT_FALSE(TransformationVectorShuffle(
MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 27, 50,
{1, 3, 5})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Vector 1 does not exist
ASSERT_FALSE(TransformationVectorShuffle(
MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 300, 50,
{1, 3, 5})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Vector 2 does not exist
ASSERT_FALSE(TransformationVectorShuffle(
MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 27, 300,
{1, 3, 5})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Index out of range
ASSERT_FALSE(
TransformationVectorShuffle(
MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 12, 112, {0, 20})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Too many indices
ASSERT_FALSE(TransformationVectorShuffle(
MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 12, 112,
{0, 1, 0, 1, 0, 1, 0, 1})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Too few indices
ASSERT_FALSE(
TransformationVectorShuffle(
MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 12, 112, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Too few indices again
ASSERT_FALSE(
TransformationVectorShuffle(
MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 12, 112, {0})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Indices define unknown type: we do not have vec2
ASSERT_FALSE(
TransformationVectorShuffle(
MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 65, 65, {0, 1})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// The instruction to insert before does not exist
ASSERT_FALSE(TransformationVectorShuffle(
MakeInstructionDescriptor(100, SpvOpCompositeConstruct, 1),
201, 20, 12, {0xFFFFFFFF, 3, 5})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// The 'fresh' id is already in use
ASSERT_FALSE(
TransformationVectorShuffle(
MakeInstructionDescriptor(100, SpvOpReturn, 0), 12, 12, 112, {})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
protobufs::DataDescriptor temp_dd;
TransformationVectorShuffle transformation1(
MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 12, 112, {1, 0});
- ASSERT_TRUE(transformation1.IsApplicable(context.get(), fact_manager));
- transformation1.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation1.IsApplicable(context.get(), transformation_context));
+ transformation1.Apply(context.get(), &transformation_context);
temp_dd = MakeDataDescriptor(200, {0});
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(11, {}), temp_dd,
- context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(11, {}), temp_dd));
temp_dd = MakeDataDescriptor(200, {1});
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(10, {}), temp_dd,
- context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(10, {}), temp_dd));
TransformationVectorShuffle transformation2(
MakeInstructionDescriptor(100, SpvOpReturn, 0), 201, 20, 12,
{0xFFFFFFFF, 3, 5});
- ASSERT_TRUE(transformation2.IsApplicable(context.get(), fact_manager));
- transformation2.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation2.IsApplicable(context.get(), transformation_context));
+ transformation2.Apply(context.get(), &transformation_context);
temp_dd = MakeDataDescriptor(201, {1});
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(11, {}), temp_dd,
- context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(11, {}), temp_dd));
temp_dd = MakeDataDescriptor(201, {2});
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(11, {}), temp_dd,
- context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(11, {}), temp_dd));
TransformationVectorShuffle transformation3(
MakeInstructionDescriptor(100, SpvOpReturn, 0), 202, 27, 35, {5, 4, 1});
- ASSERT_TRUE(transformation3.IsApplicable(context.get(), fact_manager));
- transformation3.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation3.IsApplicable(context.get(), transformation_context));
+ transformation3.Apply(context.get(), &transformation_context);
temp_dd = MakeDataDescriptor(202, {0});
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(26, {}), temp_dd,
- context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(26, {}), temp_dd));
temp_dd = MakeDataDescriptor(202, {1});
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(25, {}), temp_dd,
- context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(25, {}), temp_dd));
temp_dd = MakeDataDescriptor(202, {2});
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(26, {}), temp_dd,
- context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(26, {}), temp_dd));
TransformationVectorShuffle transformation4(
MakeInstructionDescriptor(100, SpvOpReturn, 0), 203, 42, 46, {0, 1});
- ASSERT_TRUE(transformation4.IsApplicable(context.get(), fact_manager));
- transformation4.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation4.IsApplicable(context.get(), transformation_context));
+ transformation4.Apply(context.get(), &transformation_context);
temp_dd = MakeDataDescriptor(203, {0});
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {}), temp_dd,
- context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(40, {}), temp_dd));
temp_dd = MakeDataDescriptor(203, {1});
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(41, {}), temp_dd,
- context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(41, {}), temp_dd));
TransformationVectorShuffle transformation5(
MakeInstructionDescriptor(100, SpvOpReturn, 0), 204, 42, 46, {2, 3, 4});
- ASSERT_TRUE(transformation5.IsApplicable(context.get(), fact_manager));
- transformation5.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation5.IsApplicable(context.get(), transformation_context));
+ transformation5.Apply(context.get(), &transformation_context);
temp_dd = MakeDataDescriptor(204, {0});
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {}), temp_dd,
- context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(40, {}), temp_dd));
temp_dd = MakeDataDescriptor(204, {1});
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(41, {}), temp_dd,
- context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(41, {}), temp_dd));
temp_dd = MakeDataDescriptor(204, {2});
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {}), temp_dd,
- context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(40, {}), temp_dd));
TransformationVectorShuffle transformation6(
MakeInstructionDescriptor(100, SpvOpReturn, 0), 205, 42, 42,
{0, 1, 2, 3});
- ASSERT_TRUE(transformation6.IsApplicable(context.get(), fact_manager));
- transformation6.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation6.IsApplicable(context.get(), transformation_context));
+ transformation6.Apply(context.get(), &transformation_context);
temp_dd = MakeDataDescriptor(205, {0});
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {}), temp_dd,
- context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(40, {}), temp_dd));
temp_dd = MakeDataDescriptor(205, {1});
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(41, {}), temp_dd,
- context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(41, {}), temp_dd));
temp_dd = MakeDataDescriptor(205, {2});
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {}), temp_dd,
- context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(40, {}), temp_dd));
temp_dd = MakeDataDescriptor(205, {3});
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(41, {}), temp_dd,
- context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(41, {}), temp_dd));
// swizzle vec4 from vec4 and vec4 using some undefs
TransformationVectorShuffle transformation7(
MakeInstructionDescriptor(100, SpvOpReturn, 0), 206, 65, 65,
{0xFFFFFFFF, 3, 6, 0xFFFFFFFF});
- ASSERT_TRUE(transformation7.IsApplicable(context.get(), fact_manager));
- transformation7.Apply(context.get(), &fact_manager);
+ ASSERT_TRUE(
+ transformation7.IsApplicable(context.get(), transformation_context));
+ transformation7.Apply(context.get(), &transformation_context);
temp_dd = MakeDataDescriptor(206, {1});
- ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(56, {}), temp_dd,
- context.get()));
+ ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
+ MakeDataDescriptor(56, {}), temp_dd));
std::string after_transformation = R"(
OpCapability Shader
@@ -479,52 +489,55 @@
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
+ spvtools::ValidatorOptions validator_options;
+ TransformationContext transformation_context(&fact_manager,
+ validator_options);
// Cannot insert before the OpVariables of a function.
ASSERT_FALSE(
TransformationVectorShuffle(
MakeInstructionDescriptor(101, SpvOpVariable, 0), 200, 14, 14, {0, 1})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationVectorShuffle(
MakeInstructionDescriptor(101, SpvOpVariable, 1), 200, 14, 14, {1, 2})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationVectorShuffle(
MakeInstructionDescriptor(102, SpvOpVariable, 0), 200, 14, 14, {1, 2})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// OK to insert right after the OpVariables.
ASSERT_FALSE(
TransformationVectorShuffle(
MakeInstructionDescriptor(102, SpvOpBranch, 1), 200, 14, 14, {1, 1})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Cannot insert before the OpPhis of a block.
ASSERT_FALSE(
TransformationVectorShuffle(MakeInstructionDescriptor(60, SpvOpPhi, 0),
200, 14, 14, {2, 0})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
ASSERT_FALSE(
TransformationVectorShuffle(MakeInstructionDescriptor(59, SpvOpPhi, 0),
200, 14, 14, {3, 0})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// OK to insert after the OpPhis.
ASSERT_TRUE(TransformationVectorShuffle(
MakeInstructionDescriptor(59, SpvOpAccessChain, 0), 200, 14,
14, {3, 4})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Cannot insert before OpLoopMerge
ASSERT_FALSE(TransformationVectorShuffle(
MakeInstructionDescriptor(33, SpvOpBranchConditional, 0),
200, 14, 14, {3})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
// Cannot insert before OpSelectionMerge
ASSERT_FALSE(TransformationVectorShuffle(
MakeInstructionDescriptor(21, SpvOpBranchConditional, 0),
200, 14, 14, {2})
- .IsApplicable(context.get(), fact_manager));
+ .IsApplicable(context.get(), transformation_context));
}
} // namespace