diff --git a/source/fuzz/fuzzer.cpp b/source/fuzz/fuzzer.cpp index f84e5be9e..f6460693e 100644 --- a/source/fuzz/fuzzer.cpp +++ b/source/fuzz/fuzzer.cpp @@ -228,8 +228,11 @@ Fuzzer::Fuzzer(std::unique_ptr ir_context, MaybeAddFinalPass(&final_passes_); MaybeAddFinalPass(&final_passes_); MaybeAddFinalPass(&final_passes_); - MaybeAddFinalPass( - &final_passes_); + if (!fuzzer_context_->IsWgslCompatible()) { + // Signedness is not as interchangeable in WGSL as in SPIR-V. + MaybeAddFinalPass( + &final_passes_); + } MaybeAddFinalPass(&final_passes_); MaybeAddFinalPass(&final_passes_); MaybeAddFinalPass(&final_passes_); diff --git a/source/fuzz/fuzzer_context.cpp b/source/fuzz/fuzzer_context.cpp index 1ace8c25e..ef93e7197 100644 --- a/source/fuzz/fuzzer_context.cpp +++ b/source/fuzz/fuzzer_context.cpp @@ -184,9 +184,10 @@ const std::function } // namespace FuzzerContext::FuzzerContext(std::unique_ptr random_generator, - uint32_t min_fresh_id) + uint32_t min_fresh_id, bool is_wgsl_compatible) : random_generator_(std::move(random_generator)), next_fresh_id_(min_fresh_id), + is_wgsl_compatible_(is_wgsl_compatible), max_equivalence_class_size_for_data_synonym_fact_closure_( kDefaultMaxEquivalenceClassSizeForDataSynonymFactClosure), max_loop_control_partial_count_(kDefaultMaxLoopControlPartialCount), diff --git a/source/fuzz/fuzzer_context.h b/source/fuzz/fuzzer_context.h index 7db29c8db..40fd8783d 100644 --- a/source/fuzz/fuzzer_context.h +++ b/source/fuzz/fuzzer_context.h @@ -34,7 +34,7 @@ class FuzzerContext { // Constructs a fuzzer context with a given random generator and the minimum // value that can be used for fresh ids. FuzzerContext(std::unique_ptr random_generator, - uint32_t min_fresh_id); + uint32_t min_fresh_id, bool is_wgsl_compatible); ~FuzzerContext(); @@ -66,7 +66,7 @@ class FuzzerContext { } // Randomly shuffles a |sequence| between |lo| and |hi| indices inclusively. - // |lo| and |hi| must be valid indices to the |sequence| + // |lo| and |hi| must be valid indices to the |sequence|. template void Shuffle(std::vector* sequence, size_t lo, size_t hi) const { auto& array = *sequence; @@ -91,7 +91,7 @@ class FuzzerContext { } } - // Ramdomly shuffles a |sequence| + // Randomly shuffles a |sequence|. template void Shuffle(std::vector* sequence) const { if (!sequence->empty()) { @@ -104,7 +104,7 @@ class FuzzerContext { uint32_t GetFreshId(); // Returns a vector of |count| fresh ids. - std::vector GetFreshIds(const uint32_t count); + std::vector GetFreshIds(uint32_t count); // A suggested limit on the id bound for the module being fuzzed. This is // useful for deciding when to stop the overall fuzzing process. Furthermore, @@ -120,6 +120,11 @@ class FuzzerContext { // Returns the minimum fresh id that can be used given the |ir_context|. static uint32_t GetMinFreshId(opt::IRContext* ir_context); + // Returns true if all transformations should be compatible with WGSL. + bool IsWgslCompatible() const { + return is_wgsl_compatible_; + } + // Probabilities associated with applying various transformations. // Keep them in alphabetical order. uint32_t GetChanceOfAcceptingRepeatedPassRecommendation() const { @@ -456,6 +461,9 @@ class FuzzerContext { // The next fresh id to be issued. uint32_t next_fresh_id_; + // True if all transformations should be compatible with WGSL spec. + bool is_wgsl_compatible_; + // Probabilities associated with applying various transformations. // Keep them in alphabetical order. uint32_t chance_of_accepting_repeated_pass_recommendation_; diff --git a/source/fuzz/fuzzer_pass_interchange_signedness_of_integer_operands.cpp b/source/fuzz/fuzzer_pass_interchange_signedness_of_integer_operands.cpp index 0e40b4963..e04f5ec71 100644 --- a/source/fuzz/fuzzer_pass_interchange_signedness_of_integer_operands.cpp +++ b/source/fuzz/fuzzer_pass_interchange_signedness_of_integer_operands.cpp @@ -35,6 +35,9 @@ FuzzerPassInterchangeSignednessOfIntegerOperands:: ~FuzzerPassInterchangeSignednessOfIntegerOperands() = default; void FuzzerPassInterchangeSignednessOfIntegerOperands::Apply() { + assert(!GetFuzzerContext()->IsWgslCompatible() && + "Cannot interchange signedness in WGSL"); + // Make vector keeping track of all the uses we want to replace. // This is a vector of pairs, where the first element is an id use descriptor // identifying the use of a constant id and the second is the id that should diff --git a/test/fuzz/fuzzer_pass_add_opphi_synonyms_test.cpp b/test/fuzz/fuzzer_pass_add_opphi_synonyms_test.cpp index ebc100271..734f47afd 100644 --- a/test/fuzz/fuzzer_pass_add_opphi_synonyms_test.cpp +++ b/test/fuzz/fuzzer_pass_add_opphi_synonyms_test.cpp @@ -128,7 +128,8 @@ TEST(FuzzerPassAddOpPhiSynonymsTest, HelperFunctions) { kConsoleMessageConsumer)); TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - FuzzerContext fuzzer_context(MakeUnique(0), 100); + FuzzerContext fuzzer_context(MakeUnique(0), 100, + false); protobufs::TransformationSequence transformation_sequence; FuzzerPassAddOpPhiSynonyms fuzzer_pass(context.get(), &transformation_context, diff --git a/test/fuzz/fuzzer_pass_construct_composites_test.cpp b/test/fuzz/fuzzer_pass_construct_composites_test.cpp index 8559ed947..a02176b21 100644 --- a/test/fuzz/fuzzer_pass_construct_composites_test.cpp +++ b/test/fuzz/fuzzer_pass_construct_composites_test.cpp @@ -77,7 +77,8 @@ TEST(FuzzerPassConstructCompositesTest, IsomorphicStructs) { const auto env = SPV_ENV_UNIVERSAL_1_3; const auto consumer = nullptr; - FuzzerContext fuzzer_context(MakeUnique(0), 100); + FuzzerContext fuzzer_context(MakeUnique(0), 100, + false); for (uint32_t i = 0; i < 10; i++) { const auto context = @@ -157,7 +158,8 @@ TEST(FuzzerPassConstructCompositesTest, IsomorphicArrays) { const auto env = SPV_ENV_UNIVERSAL_1_3; const auto consumer = nullptr; - FuzzerContext fuzzer_context(MakeUnique(0), 100); + FuzzerContext fuzzer_context(MakeUnique(0), 100, + false); for (uint32_t i = 0; i < 10; i++) { const auto context = diff --git a/test/fuzz/fuzzer_pass_donate_modules_test.cpp b/test/fuzz/fuzzer_pass_donate_modules_test.cpp index 99026652b..f11885d4e 100644 --- a/test/fuzz/fuzzer_pass_donate_modules_test.cpp +++ b/test/fuzz/fuzzer_pass_donate_modules_test.cpp @@ -204,7 +204,8 @@ TEST(FuzzerPassDonateModulesTest, BasicDonation) { TransformationContext transformation_context( MakeUnique(recipient_context.get()), validator_options); - FuzzerContext fuzzer_context(MakeUnique(0), 100); + FuzzerContext fuzzer_context(MakeUnique(0), 100, + false); protobufs::TransformationSequence transformation_sequence; FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), @@ -284,7 +285,8 @@ TEST(FuzzerPassDonateModulesTest, DonationWithUniforms) { TransformationContext transformation_context( MakeUnique(recipient_context.get()), validator_options); - FuzzerContext fuzzer_context(MakeUnique(0), 100); + FuzzerContext fuzzer_context(MakeUnique(0), 100, + false); protobufs::TransformationSequence transformation_sequence; FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), @@ -414,7 +416,8 @@ TEST(FuzzerPassDonateModulesTest, DonationWithInputAndOutputVariables) { TransformationContext transformation_context( MakeUnique(recipient_context.get()), validator_options); - FuzzerContext fuzzer_context(MakeUnique(0), 100); + FuzzerContext fuzzer_context(MakeUnique(0), 100, + false); protobufs::TransformationSequence transformation_sequence; FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), @@ -508,7 +511,8 @@ TEST(FuzzerPassDonateModulesTest, DonateFunctionTypeWithDifferentPointers) { TransformationContext transformation_context( MakeUnique(recipient_context.get()), validator_options); - FuzzerContext fuzzer_context(MakeUnique(0), 100); + FuzzerContext fuzzer_context(MakeUnique(0), 100, + false); protobufs::TransformationSequence transformation_sequence; FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), @@ -577,7 +581,8 @@ TEST(FuzzerPassDonateModulesTest, DonateOpConstantNull) { TransformationContext transformation_context( MakeUnique(recipient_context.get()), validator_options); - FuzzerContext fuzzer_context(MakeUnique(0), 100); + FuzzerContext fuzzer_context(MakeUnique(0), 100, + false); protobufs::TransformationSequence transformation_sequence; FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), @@ -704,7 +709,8 @@ TEST(FuzzerPassDonateModulesTest, DonateCodeThatUsesImages) { TransformationContext transformation_context( MakeUnique(recipient_context.get()), validator_options); - FuzzerContext fuzzer_context(MakeUnique(0), 100); + FuzzerContext fuzzer_context(MakeUnique(0), 100, + false); protobufs::TransformationSequence transformation_sequence; FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), @@ -799,7 +805,8 @@ TEST(FuzzerPassDonateModulesTest, DonateCodeThatUsesSampler) { TransformationContext transformation_context( MakeUnique(recipient_context.get()), validator_options); - FuzzerContext fuzzer_context(MakeUnique(0), 100); + FuzzerContext fuzzer_context(MakeUnique(0), 100, + false); protobufs::TransformationSequence transformation_sequence; FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), @@ -930,7 +937,8 @@ TEST(FuzzerPassDonateModulesTest, DonateCodeThatUsesImageStructField) { TransformationContext transformation_context( MakeUnique(recipient_context.get()), validator_options); - FuzzerContext fuzzer_context(MakeUnique(0), 100); + FuzzerContext fuzzer_context(MakeUnique(0), 100, + false); protobufs::TransformationSequence transformation_sequence; FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), @@ -1065,7 +1073,8 @@ TEST(FuzzerPassDonateModulesTest, DonateCodeThatUsesImageFunctionParameter) { TransformationContext transformation_context( MakeUnique(recipient_context.get()), validator_options); - FuzzerContext fuzzer_context(MakeUnique(0), 100); + FuzzerContext fuzzer_context(MakeUnique(0), 100, + false); protobufs::TransformationSequence transformation_sequence; FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), @@ -1146,7 +1155,8 @@ TEST(FuzzerPassDonateModulesTest, DonateShaderWithImageStorageClass) { TransformationContext transformation_context( MakeUnique(recipient_context.get()), validator_options); - FuzzerContext fuzzer_context(MakeUnique(0), 100); + FuzzerContext fuzzer_context(MakeUnique(0), 100, + false); protobufs::TransformationSequence transformation_sequence; FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), @@ -1232,7 +1242,8 @@ TEST(FuzzerPassDonateModulesTest, DonateComputeShaderWithRuntimeArray) { TransformationContext transformation_context( MakeUnique(recipient_context.get()), validator_options); - FuzzerContext fuzzer_context(MakeUnique(0), 100); + FuzzerContext fuzzer_context(MakeUnique(0), 100, + false); protobufs::TransformationSequence transformation_sequence; FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), @@ -1335,7 +1346,8 @@ TEST(FuzzerPassDonateModulesTest, DonateComputeShaderWithRuntimeArrayLivesafe) { TransformationContext transformation_context( MakeUnique(recipient_context.get()), validator_options); - FuzzerContext fuzzer_context(MakeUnique(0), 100); + FuzzerContext fuzzer_context(MakeUnique(0), 100, + false); protobufs::TransformationSequence transformation_sequence; FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), @@ -1406,7 +1418,8 @@ TEST(FuzzerPassDonateModulesTest, DonateComputeShaderWithWorkgroupVariables) { TransformationContext transformation_context( MakeUnique(recipient_context.get()), validator_options); - FuzzerContext fuzzer_context(MakeUnique(0), 100); + FuzzerContext fuzzer_context(MakeUnique(0), 100, + false); protobufs::TransformationSequence transformation_sequence; FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), @@ -1515,7 +1528,8 @@ TEST(FuzzerPassDonateModulesTest, DonateComputeShaderWithAtomics) { TransformationContext transformation_context( MakeUnique(recipient_context.get()), validator_options); - FuzzerContext fuzzer_context(MakeUnique(0), 100); + FuzzerContext fuzzer_context(MakeUnique(0), 100, + false); protobufs::TransformationSequence transformation_sequence; FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), @@ -1698,7 +1712,8 @@ TEST(FuzzerPassDonateModulesTest, Miscellaneous1) { TransformationContext transformation_context( MakeUnique(recipient_context.get()), validator_options); - FuzzerContext fuzzer_context(MakeUnique(0), 100); + FuzzerContext fuzzer_context(MakeUnique(0), 100, + false); protobufs::TransformationSequence transformation_sequence; FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), @@ -1769,7 +1784,8 @@ TEST(FuzzerPassDonateModulesTest, OpSpecConstantInstructions) { TransformationContext transformation_context( MakeUnique(recipient_context.get()), validator_options); - FuzzerContext fuzzer_context(MakeUnique(0), 100); + FuzzerContext fuzzer_context(MakeUnique(0), 100, + false); protobufs::TransformationSequence transformation_sequence; FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), @@ -1925,7 +1941,8 @@ TEST(FuzzerPassDonateModulesTest, DonationSupportsOpTypeRuntimeArray) { TransformationContext transformation_context( MakeUnique(recipient_context.get()), validator_options); - FuzzerContext fuzzer_context(MakeUnique(0), 100); + FuzzerContext fuzzer_context(MakeUnique(0), 100, + false); protobufs::TransformationSequence transformation_sequence; FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), @@ -1997,7 +2014,8 @@ TEST(FuzzerPassDonateModulesTest, HandlesCapabilities) { TransformationContext transformation_context( MakeUnique(recipient_context.get()), validator_options); - FuzzerContext fuzzer_context(MakeUnique(0), 100); + FuzzerContext fuzzer_context(MakeUnique(0), 100, + false); protobufs::TransformationSequence transformation_sequence; FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), @@ -2229,7 +2247,8 @@ TEST(FuzzerPassDonateModulesTest, HandlesOpPhisInMergeBlock) { TransformationContext transformation_context( MakeUnique(recipient_context.get()), validator_options); - FuzzerContext fuzzer_context(MakeUnique(0), 100); + FuzzerContext fuzzer_context(MakeUnique(0), 100, + false); protobufs::TransformationSequence transformation_sequence; FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), diff --git a/test/fuzz/fuzzer_pass_outline_functions_test.cpp b/test/fuzz/fuzzer_pass_outline_functions_test.cpp index 3a29513c6..0d2c5bf74 100644 --- a/test/fuzz/fuzzer_pass_outline_functions_test.cpp +++ b/test/fuzz/fuzzer_pass_outline_functions_test.cpp @@ -124,7 +124,8 @@ TEST(FuzzerPassOutlineFunctionsTest, EntryIsAlreadySuitable) { kConsoleMessageConsumer)); TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - FuzzerContext fuzzer_context(MakeUnique(0), 100); + FuzzerContext fuzzer_context(MakeUnique(0), 100, + false); protobufs::TransformationSequence transformation_sequence; FuzzerPassOutlineFunctions fuzzer_pass(context.get(), &transformation_context, @@ -166,7 +167,8 @@ TEST(FuzzerPassOutlineFunctionsTest, EntryHasOpVariable) { kConsoleMessageConsumer)); TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - FuzzerContext fuzzer_context(MakeUnique(0), 100); + FuzzerContext fuzzer_context(MakeUnique(0), 100, + false); protobufs::TransformationSequence transformation_sequence; FuzzerPassOutlineFunctions fuzzer_pass(context.get(), &transformation_context, @@ -289,7 +291,8 @@ TEST(FuzzerPassOutlineFunctionsTest, EntryBlockIsHeader) { kConsoleMessageConsumer)); TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - FuzzerContext fuzzer_context(MakeUnique(0), 100); + FuzzerContext fuzzer_context(MakeUnique(0), 100, + false); protobufs::TransformationSequence transformation_sequence; FuzzerPassOutlineFunctions fuzzer_pass(context.get(), &transformation_context, @@ -455,7 +458,8 @@ TEST(FuzzerPassOutlineFunctionsTest, ExitBlock) { kConsoleMessageConsumer)); TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - FuzzerContext fuzzer_context(MakeUnique(0), 100); + FuzzerContext fuzzer_context(MakeUnique(0), 100, + false); protobufs::TransformationSequence transformation_sequence; FuzzerPassOutlineFunctions fuzzer_pass(context.get(), &transformation_context, diff --git a/test/fuzz/fuzzer_pass_test.cpp b/test/fuzz/fuzzer_pass_test.cpp index 81f7bc41f..b035de744 100644 --- a/test/fuzz/fuzzer_pass_test.cpp +++ b/test/fuzz/fuzzer_pass_test.cpp @@ -87,7 +87,8 @@ TEST(FuzzerPassTest, ForEachInstructionWithInstructionDescriptor) { ASSERT_TRUE(dominator_analysis->IsReachable(5)); ASSERT_FALSE(dominator_analysis->IsReachable(8)); - FuzzerContext fuzzer_context(MakeUnique(0), 100); + FuzzerContext fuzzer_context(MakeUnique(0), 100, + false); protobufs::TransformationSequence transformations; FuzzerPassMock fuzzer_pass_mock(context.get(), &transformation_context, &fuzzer_context, &transformations); diff --git a/test/fuzz/fuzzer_replayer_test.cpp b/test/fuzz/fuzzer_replayer_test.cpp index 2baa4c6e0..6dc7ffb11 100644 --- a/test/fuzz/fuzzer_replayer_test.cpp +++ b/test/fuzz/fuzzer_replayer_test.cpp @@ -1656,7 +1656,7 @@ void RunFuzzerAndReplayer(const std::string& shader, auto fuzzer_context = MakeUnique( MakeUnique(seed), - FuzzerContext::GetMinFreshId(ir_context.get())); + FuzzerContext::GetMinFreshId(ir_context.get()), false); auto transformation_context = MakeUnique( MakeUnique(ir_context.get()), validator_options); diff --git a/test/fuzz/fuzzer_shrinker_test.cpp b/test/fuzz/fuzzer_shrinker_test.cpp index 68329f6a6..e79211698 100644 --- a/test/fuzz/fuzzer_shrinker_test.cpp +++ b/test/fuzz/fuzzer_shrinker_test.cpp @@ -1056,9 +1056,9 @@ void RunFuzzerAndShrinker(const std::string& shader, ASSERT_TRUE(fuzzerutil::BuildIRContext( env, kConsoleMessageConsumer, binary_in, validator_options, &ir_context)); - auto fuzzer_context = - MakeUnique(MakeUnique(seed), - FuzzerContext::GetMinFreshId(ir_context.get())); + auto fuzzer_context = MakeUnique( + MakeUnique(seed), + FuzzerContext::GetMinFreshId(ir_context.get()), false); auto transformation_context = MakeUnique( MakeUnique(ir_context.get()), validator_options); diff --git a/test/fuzz/shrinker_test.cpp b/test/fuzz/shrinker_test.cpp index 2071a500a..447ebecd7 100644 --- a/test/fuzz/shrinker_test.cpp +++ b/test/fuzz/shrinker_test.cpp @@ -163,7 +163,8 @@ TEST(ShrinkerTest, ReduceAddedFunctions) { ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( donor_ir_context.get(), validator_options, kConsoleMessageConsumer)); - FuzzerContext fuzzer_context(MakeUnique(0), 100); + FuzzerContext fuzzer_context(MakeUnique(0), 100, + false); TransformationContext transformation_context( MakeUnique(variant_ir_context.get()), validator_options); @@ -340,7 +341,8 @@ TEST(ShrinkerTest, HitStepLimitWhenReducingAddedFunctions) { ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( donor_ir_context.get(), validator_options, kConsoleMessageConsumer)); - FuzzerContext fuzzer_context(MakeUnique(0), 100); + FuzzerContext fuzzer_context(MakeUnique(0), 100, + false); TransformationContext transformation_context( MakeUnique(variant_ir_context.get()), validator_options); @@ -363,7 +365,6 @@ TEST(ShrinkerTest, HitStepLimitWhenReducingAddedFunctions) { if (inst->opcode() == SpvOpCopyObject) { copy_object_count++; } - }); return copy_object_count >= 8; }; diff --git a/tools/fuzz/fuzz.cpp b/tools/fuzz/fuzz.cpp index 4400e0c01..422bea53b 100644 --- a/tools/fuzz/fuzz.cpp +++ b/tools/fuzz/fuzz.cpp @@ -39,6 +39,8 @@ namespace { +enum class FuzzingTarget { kSpirv, kWgsl }; + // Check that the std::system function can actually be used. bool CheckExecuteCommand() { int res = std::system(nullptr); @@ -141,6 +143,12 @@ Options (in lexicographical order): that was used previously. - simple: each time a fuzzer pass is requested, one is provided at random from the set of enabled passes. + --fuzzing-target= + This option will adjust probabilities of applying certain + transformations s.t. the module always remains valid according + to the semantics of some fuzzing target. Available targets: + - spir-v - module is valid according to the SPIR-V spec. + - wgsl - module is valid according to the WGSL spec. --replay File from which to read a sequence of transformations to replay (instead of fuzzing) @@ -205,7 +213,7 @@ FuzzStatus ParseFlags( std::string* shrink_transformations_file, std::string* shrink_temp_file_prefix, spvtools::fuzz::RepeatedPassStrategy* repeated_pass_strategy, - spvtools::FuzzerOptions* fuzzer_options, + FuzzingTarget* fuzzing_target, spvtools::FuzzerOptions* fuzzer_options, spvtools::ValidatorOptions* validator_options) { uint32_t positional_arg_index = 0; bool only_positional_arguments_remain = false; @@ -266,6 +274,20 @@ FuzzStatus ParseFlags( spvtools::Error(FuzzDiagnostic, nullptr, {}, ss.str().c_str()); return {FuzzActions::STOP, 1}; } + } else if (0 == strncmp(cur_arg, "--fuzzing-target=", + sizeof("--fuzzing-target=") - 1)) { + std::string target = spvtools::utils::SplitFlagArgs(cur_arg).second; + if (target == "spir-v") { + *fuzzing_target = FuzzingTarget::kSpirv; + } else if (target == "wgsl") { + *fuzzing_target = FuzzingTarget::kWgsl; + } else { + std::stringstream ss; + ss << "Unknown fuzzing target '" << target << "'" << std::endl; + ss << "Valid options are 'spir-v' and 'wgsl'."; + spvtools::Error(FuzzDiagnostic, nullptr, {}, ss.str().c_str()); + return {FuzzActions::STOP, 1}; + } } else if (0 == strncmp(cur_arg, "--replay-range=", sizeof("--replay-range=") - 1)) { const auto split_flag = spvtools::utils::SplitFlagArgs(cur_arg); @@ -550,7 +572,7 @@ bool Fuzz(const spv_target_env& target_env, const spvtools::fuzz::protobufs::FactSequence& initial_facts, const std::string& donors, spvtools::fuzz::RepeatedPassStrategy repeated_pass_strategy, - std::vector* binary_out, + FuzzingTarget fuzzing_target, std::vector* binary_out, spvtools::fuzz::protobufs::TransformationSequence* transformations_applied) { auto message_consumer = spvtools::utils::CLIMessageConsumer; @@ -586,12 +608,16 @@ bool Fuzz(const spv_target_env& target_env, return false; } + assert((fuzzing_target == FuzzingTarget::kWgsl || + fuzzing_target == FuzzingTarget::kSpirv) && + "Not all fuzzing targets are handled"); auto fuzzer_context = spvtools::MakeUnique( spvtools::MakeUnique( fuzzer_options->has_random_seed ? fuzzer_options->random_seed : static_cast(std::random_device()())), - spvtools::fuzz::FuzzerContext::GetMinFreshId(ir_context.get())); + spvtools::fuzz::FuzzerContext::GetMinFreshId(ir_context.get()), + fuzzing_target == FuzzingTarget::kWgsl); auto transformation_context = spvtools::MakeUnique( @@ -675,6 +701,7 @@ int main(int argc, const char** argv) { std::string shrink_transformations_file; std::string shrink_temp_file_prefix = "temp_"; spvtools::fuzz::RepeatedPassStrategy repeated_pass_strategy; + auto fuzzing_target = FuzzingTarget::kSpirv; spvtools::FuzzerOptions fuzzer_options; spvtools::ValidatorOptions validator_options; @@ -683,7 +710,8 @@ int main(int argc, const char** argv) { ParseFlags(argc, argv, &in_binary_file, &out_binary_file, &donors_file, &replay_transformations_file, &interestingness_test, &shrink_transformations_file, &shrink_temp_file_prefix, - &repeated_pass_strategy, &fuzzer_options, &validator_options); + &repeated_pass_strategy, &fuzzing_target, &fuzzer_options, + &validator_options); if (status.action == FuzzActions::STOP) { return status.code; @@ -729,8 +757,8 @@ int main(int argc, const char** argv) { break; case FuzzActions::FUZZ: if (!Fuzz(target_env, fuzzer_options, validator_options, binary_in, - initial_facts, donors_file, repeated_pass_strategy, &binary_out, - &transformations_applied)) { + initial_facts, donors_file, repeated_pass_strategy, + fuzzing_target, &binary_out, &transformations_applied)) { return 1; } break;