spirv-fuzz: Add WGSL compatibility flag to context (#4193)

The new flags allows transformations and fuzzer passes to be enabled
and applied in a WGSL-compatible fashion.
diff --git a/source/fuzz/fuzzer.cpp b/source/fuzz/fuzzer.cpp
index f84e5be..f646069 100644
--- a/source/fuzz/fuzzer.cpp
+++ b/source/fuzz/fuzzer.cpp
@@ -228,8 +228,11 @@
   MaybeAddFinalPass<FuzzerPassAdjustMemoryOperandsMasks>(&final_passes_);
   MaybeAddFinalPass<FuzzerPassAdjustSelectionControls>(&final_passes_);
   MaybeAddFinalPass<FuzzerPassAddNoContractionDecorations>(&final_passes_);
-  MaybeAddFinalPass<FuzzerPassInterchangeSignednessOfIntegerOperands>(
-      &final_passes_);
+  if (!fuzzer_context_->IsWgslCompatible()) {
+    // Signedness is not as interchangeable in WGSL as in SPIR-V.
+    MaybeAddFinalPass<FuzzerPassInterchangeSignednessOfIntegerOperands>(
+        &final_passes_);
+  }
   MaybeAddFinalPass<FuzzerPassInterchangeZeroLikeConstants>(&final_passes_);
   MaybeAddFinalPass<FuzzerPassPermutePhiOperands>(&final_passes_);
   MaybeAddFinalPass<FuzzerPassSwapCommutableOperands>(&final_passes_);
diff --git a/source/fuzz/fuzzer_context.cpp b/source/fuzz/fuzzer_context.cpp
index 1ace8c2..ef93e71 100644
--- a/source/fuzz/fuzzer_context.cpp
+++ b/source/fuzz/fuzzer_context.cpp
@@ -184,9 +184,10 @@
 }  // namespace
 
 FuzzerContext::FuzzerContext(std::unique_ptr<RandomGenerator> 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 7db29c8..40fd878 100644
--- a/source/fuzz/fuzzer_context.h
+++ b/source/fuzz/fuzzer_context.h
@@ -34,7 +34,7 @@
   // Constructs a fuzzer context with a given random generator and the minimum
   // value that can be used for fresh ids.
   FuzzerContext(std::unique_ptr<RandomGenerator> random_generator,
-                uint32_t min_fresh_id);
+                uint32_t min_fresh_id, bool is_wgsl_compatible);
 
   ~FuzzerContext();
 
@@ -66,7 +66,7 @@
   }
 
   // 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 <typename T>
   void Shuffle(std::vector<T>* sequence, size_t lo, size_t hi) const {
     auto& array = *sequence;
@@ -91,7 +91,7 @@
     }
   }
 
-  // Ramdomly shuffles a |sequence|
+  // Randomly shuffles a |sequence|.
   template <typename T>
   void Shuffle(std::vector<T>* sequence) const {
     if (!sequence->empty()) {
@@ -104,7 +104,7 @@
   uint32_t GetFreshId();
 
   // Returns a vector of |count| fresh ids.
-  std::vector<uint32_t> GetFreshIds(const uint32_t count);
+  std::vector<uint32_t> 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 @@
   // 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 @@
   // 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 0e40b49..e04f5ec 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() = 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 ebc1002..734f47a 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 @@
                                                kConsoleMessageConsumer));
   TransformationContext transformation_context(
       MakeUnique<FactManager>(context.get()), validator_options);
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100);
+  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(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 8559ed9..a02176b 100644
--- a/test/fuzz/fuzzer_pass_construct_composites_test.cpp
+++ b/test/fuzz/fuzzer_pass_construct_composites_test.cpp
@@ -77,7 +77,8 @@
   const auto env = SPV_ENV_UNIVERSAL_1_3;
   const auto consumer = nullptr;
 
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100);
+  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100,
+                               false);
 
   for (uint32_t i = 0; i < 10; i++) {
     const auto context =
@@ -157,7 +158,8 @@
   const auto env = SPV_ENV_UNIVERSAL_1_3;
   const auto consumer = nullptr;
 
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100);
+  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(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 9902665..f11885d 100644
--- a/test/fuzz/fuzzer_pass_donate_modules_test.cpp
+++ b/test/fuzz/fuzzer_pass_donate_modules_test.cpp
@@ -204,7 +204,8 @@
   TransformationContext transformation_context(
       MakeUnique<FactManager>(recipient_context.get()), validator_options);
 
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100);
+  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100,
+                               false);
   protobufs::TransformationSequence transformation_sequence;
 
   FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
@@ -284,7 +285,8 @@
   TransformationContext transformation_context(
       MakeUnique<FactManager>(recipient_context.get()), validator_options);
 
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100);
+  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100,
+                               false);
   protobufs::TransformationSequence transformation_sequence;
 
   FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
@@ -414,7 +416,8 @@
   TransformationContext transformation_context(
       MakeUnique<FactManager>(recipient_context.get()), validator_options);
 
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100);
+  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100,
+                               false);
   protobufs::TransformationSequence transformation_sequence;
 
   FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
@@ -508,7 +511,8 @@
   TransformationContext transformation_context(
       MakeUnique<FactManager>(recipient_context.get()), validator_options);
 
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100);
+  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100,
+                               false);
   protobufs::TransformationSequence transformation_sequence;
 
   FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
@@ -577,7 +581,8 @@
   TransformationContext transformation_context(
       MakeUnique<FactManager>(recipient_context.get()), validator_options);
 
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100);
+  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100,
+                               false);
   protobufs::TransformationSequence transformation_sequence;
 
   FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
@@ -704,7 +709,8 @@
   TransformationContext transformation_context(
       MakeUnique<FactManager>(recipient_context.get()), validator_options);
 
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100);
+  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100,
+                               false);
   protobufs::TransformationSequence transformation_sequence;
 
   FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
@@ -799,7 +805,8 @@
   TransformationContext transformation_context(
       MakeUnique<FactManager>(recipient_context.get()), validator_options);
 
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100);
+  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100,
+                               false);
   protobufs::TransformationSequence transformation_sequence;
 
   FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
@@ -930,7 +937,8 @@
   TransformationContext transformation_context(
       MakeUnique<FactManager>(recipient_context.get()), validator_options);
 
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100);
+  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100,
+                               false);
   protobufs::TransformationSequence transformation_sequence;
 
   FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
@@ -1065,7 +1073,8 @@
   TransformationContext transformation_context(
       MakeUnique<FactManager>(recipient_context.get()), validator_options);
 
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100);
+  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100,
+                               false);
   protobufs::TransformationSequence transformation_sequence;
 
   FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
@@ -1146,7 +1155,8 @@
   TransformationContext transformation_context(
       MakeUnique<FactManager>(recipient_context.get()), validator_options);
 
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100);
+  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100,
+                               false);
   protobufs::TransformationSequence transformation_sequence;
 
   FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
@@ -1232,7 +1242,8 @@
   TransformationContext transformation_context(
       MakeUnique<FactManager>(recipient_context.get()), validator_options);
 
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100);
+  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100,
+                               false);
   protobufs::TransformationSequence transformation_sequence;
 
   FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
@@ -1335,7 +1346,8 @@
   TransformationContext transformation_context(
       MakeUnique<FactManager>(recipient_context.get()), validator_options);
 
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100);
+  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100,
+                               false);
   protobufs::TransformationSequence transformation_sequence;
 
   FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
@@ -1406,7 +1418,8 @@
   TransformationContext transformation_context(
       MakeUnique<FactManager>(recipient_context.get()), validator_options);
 
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100);
+  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100,
+                               false);
   protobufs::TransformationSequence transformation_sequence;
 
   FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
@@ -1515,7 +1528,8 @@
   TransformationContext transformation_context(
       MakeUnique<FactManager>(recipient_context.get()), validator_options);
 
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100);
+  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100,
+                               false);
   protobufs::TransformationSequence transformation_sequence;
 
   FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
@@ -1698,7 +1712,8 @@
   TransformationContext transformation_context(
       MakeUnique<FactManager>(recipient_context.get()), validator_options);
 
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100);
+  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100,
+                               false);
   protobufs::TransformationSequence transformation_sequence;
 
   FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
@@ -1769,7 +1784,8 @@
   TransformationContext transformation_context(
       MakeUnique<FactManager>(recipient_context.get()), validator_options);
 
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100);
+  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100,
+                               false);
   protobufs::TransformationSequence transformation_sequence;
 
   FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
@@ -1925,7 +1941,8 @@
   TransformationContext transformation_context(
       MakeUnique<FactManager>(recipient_context.get()), validator_options);
 
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100);
+  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100,
+                               false);
   protobufs::TransformationSequence transformation_sequence;
 
   FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
@@ -1997,7 +2014,8 @@
   TransformationContext transformation_context(
       MakeUnique<FactManager>(recipient_context.get()), validator_options);
 
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100);
+  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100,
+                               false);
   protobufs::TransformationSequence transformation_sequence;
 
   FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
@@ -2229,7 +2247,8 @@
   TransformationContext transformation_context(
       MakeUnique<FactManager>(recipient_context.get()), validator_options);
 
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100);
+  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(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 3a29513..0d2c5bf 100644
--- a/test/fuzz/fuzzer_pass_outline_functions_test.cpp
+++ b/test/fuzz/fuzzer_pass_outline_functions_test.cpp
@@ -124,7 +124,8 @@
                                                kConsoleMessageConsumer));
   TransformationContext transformation_context(
       MakeUnique<FactManager>(context.get()), validator_options);
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100);
+  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100,
+                               false);
   protobufs::TransformationSequence transformation_sequence;
 
   FuzzerPassOutlineFunctions fuzzer_pass(context.get(), &transformation_context,
@@ -166,7 +167,8 @@
                                                kConsoleMessageConsumer));
   TransformationContext transformation_context(
       MakeUnique<FactManager>(context.get()), validator_options);
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100);
+  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100,
+                               false);
   protobufs::TransformationSequence transformation_sequence;
 
   FuzzerPassOutlineFunctions fuzzer_pass(context.get(), &transformation_context,
@@ -289,7 +291,8 @@
                                                kConsoleMessageConsumer));
   TransformationContext transformation_context(
       MakeUnique<FactManager>(context.get()), validator_options);
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100);
+  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100,
+                               false);
   protobufs::TransformationSequence transformation_sequence;
 
   FuzzerPassOutlineFunctions fuzzer_pass(context.get(), &transformation_context,
@@ -455,7 +458,8 @@
                                                kConsoleMessageConsumer));
   TransformationContext transformation_context(
       MakeUnique<FactManager>(context.get()), validator_options);
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100);
+  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(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 81f7bc4..b035de7 100644
--- a/test/fuzz/fuzzer_pass_test.cpp
+++ b/test/fuzz/fuzzer_pass_test.cpp
@@ -87,7 +87,8 @@
   ASSERT_TRUE(dominator_analysis->IsReachable(5));
   ASSERT_FALSE(dominator_analysis->IsReachable(8));
 
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100);
+  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(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 2baa4c6..6dc7ffb 100644
--- a/test/fuzz/fuzzer_replayer_test.cpp
+++ b/test/fuzz/fuzzer_replayer_test.cpp
@@ -1656,7 +1656,7 @@
 
     auto fuzzer_context = MakeUnique<FuzzerContext>(
         MakeUnique<PseudoRandomGenerator>(seed),
-        FuzzerContext::GetMinFreshId(ir_context.get()));
+        FuzzerContext::GetMinFreshId(ir_context.get()), false);
 
     auto transformation_context = MakeUnique<TransformationContext>(
         MakeUnique<FactManager>(ir_context.get()), validator_options);
diff --git a/test/fuzz/fuzzer_shrinker_test.cpp b/test/fuzz/fuzzer_shrinker_test.cpp
index 68329f6..e792116 100644
--- a/test/fuzz/fuzzer_shrinker_test.cpp
+++ b/test/fuzz/fuzzer_shrinker_test.cpp
@@ -1056,9 +1056,9 @@
   ASSERT_TRUE(fuzzerutil::BuildIRContext(
       env, kConsoleMessageConsumer, binary_in, validator_options, &ir_context));
 
-  auto fuzzer_context =
-      MakeUnique<FuzzerContext>(MakeUnique<PseudoRandomGenerator>(seed),
-                                FuzzerContext::GetMinFreshId(ir_context.get()));
+  auto fuzzer_context = MakeUnique<FuzzerContext>(
+      MakeUnique<PseudoRandomGenerator>(seed),
+      FuzzerContext::GetMinFreshId(ir_context.get()), false);
 
   auto transformation_context = MakeUnique<TransformationContext>(
       MakeUnique<FactManager>(ir_context.get()), validator_options);
diff --git a/test/fuzz/shrinker_test.cpp b/test/fuzz/shrinker_test.cpp
index 2071a50..447ebec 100644
--- a/test/fuzz/shrinker_test.cpp
+++ b/test/fuzz/shrinker_test.cpp
@@ -163,7 +163,8 @@
   ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(
       donor_ir_context.get(), validator_options, kConsoleMessageConsumer));
 
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100);
+  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100,
+                               false);
   TransformationContext transformation_context(
       MakeUnique<FactManager>(variant_ir_context.get()), validator_options);
 
@@ -340,7 +341,8 @@
   ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(
       donor_ir_context.get(), validator_options, kConsoleMessageConsumer));
 
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100);
+  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100,
+                               false);
   TransformationContext transformation_context(
       MakeUnique<FactManager>(variant_ir_context.get()), validator_options);
 
@@ -363,7 +365,6 @@
           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 4400e0c..422bea5 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 @@
                  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 @@
     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 @@
           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 @@
           const spvtools::fuzz::protobufs::FactSequence& initial_facts,
           const std::string& donors,
           spvtools::fuzz::RepeatedPassStrategy repeated_pass_strategy,
-          std::vector<uint32_t>* binary_out,
+          FuzzingTarget fuzzing_target, std::vector<uint32_t>* binary_out,
           spvtools::fuzz::protobufs::TransformationSequence*
               transformations_applied) {
   auto message_consumer = spvtools::utils::CLIMessageConsumer;
@@ -586,12 +608,16 @@
     return false;
   }
 
+  assert((fuzzing_target == FuzzingTarget::kWgsl ||
+          fuzzing_target == FuzzingTarget::kSpirv) &&
+         "Not all fuzzing targets are handled");
   auto fuzzer_context = spvtools::MakeUnique<spvtools::fuzz::FuzzerContext>(
       spvtools::MakeUnique<spvtools::fuzz::PseudoRandomGenerator>(
           fuzzer_options->has_random_seed
               ? fuzzer_options->random_seed
               : static_cast<uint32_t>(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<spvtools::fuzz::TransformationContext>(
@@ -675,6 +701,7 @@
   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 @@
       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 @@
       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;