[tint][fuzz] Make IRRoundTripFuzzer WGSL only

This also adds in a check to the fuzzers to error if --filter= does
not match against any fuzzers, since libfuzzer will happily generate
cases indefinitely, since no actual tests are being run.

Fixes: 355010829

Change-Id: I163ff0de6367c11f9d3292b6af82ac15a7d32423
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/200015
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
Auto-Submit: Ryan Harrison <rharrison@chromium.org>
diff --git a/src/tint/cmd/fuzz/ir/fuzz.cc b/src/tint/cmd/fuzz/ir/fuzz.cc
index d74467c..a917336 100644
--- a/src/tint/cmd/fuzz/ir/fuzz.cc
+++ b/src/tint/cmd/fuzz/ir/fuzz.cc
@@ -108,6 +108,8 @@
     // leading to non-determinism, which we must avoid.
     TINT_STATIC_INIT(Fuzzers().Sort([](auto& a, auto& b) { return a.name < b.name; }));
 
+    bool ran_atleast_once = false;
+
     // Run each of the program fuzzer functions
     if (options.run_concurrently) {
         const size_t n = Fuzzers().Length();
@@ -118,6 +120,8 @@
                 Fuzzers()[i].name.find(options.filter) == std::string::npos) {
                 continue;
             }
+            ran_atleast_once = true;
+
             threads.Push(std::thread([i, &acquire_module, &data, &options] {
                 auto& fuzzer = Fuzzers()[i];
                 currently_running = fuzzer.name;
@@ -137,6 +141,7 @@
             if (!options.filter.empty() && fuzzer.name.find(options.filter) == std::string::npos) {
                 continue;
             }
+            ran_atleast_once = true;
 
             currently_running = fuzzer.name;
             if (options.verbose) {
@@ -146,6 +151,11 @@
             fuzzer.fn(mod, data);
         }
     }
+
+    if (!options.filter.empty() && !ran_atleast_once) {
+        std::cerr << "ERROR: --filter=" << options.filter << " did not match any fuzzers\n";
+        exit(EXIT_FAILURE);
+    }
 }
 #endif  // TINT_BUILD_IR_BINARY
 
diff --git a/src/tint/cmd/fuzz/wgsl/fuzz.cc b/src/tint/cmd/fuzz/wgsl/fuzz.cc
index 43962b7..2f367bd 100644
--- a/src/tint/cmd/fuzz/wgsl/fuzz.cc
+++ b/src/tint/cmd/fuzz/wgsl/fuzz.cc
@@ -171,6 +171,8 @@
     context.options = options;
     context.program_properties = ScanProgramProperties(program);
 
+    bool ran_atleast_once = false;
+
     // Run each of the program fuzzer functions
     if (options.run_concurrently) {
         size_t n = Fuzzers().Length();
@@ -181,6 +183,8 @@
                 Fuzzers()[i].name.find(options.filter) == std::string::npos) {
                 continue;
             }
+            ran_atleast_once = true;
+
             threads.Push(std::thread([i, &program, &data, &context] {
                 auto& fuzzer = Fuzzers()[i];
                 currently_running = fuzzer.name;
@@ -199,6 +203,7 @@
             if (!options.filter.empty() && fuzzer.name.find(options.filter) == std::string::npos) {
                 continue;
             }
+            ran_atleast_once = true;
 
             currently_running = fuzzer.name;
             if (options.verbose) {
@@ -207,6 +212,11 @@
             fuzzer.fn(program, context, data);
         }
     }
+
+    if (!options.filter.empty() && !ran_atleast_once) {
+        std::cerr << "ERROR: --filter=" << options.filter << " did not match any fuzzers\n";
+        exit(EXIT_FAILURE);
+    }
 }
 
 }  // namespace tint::fuzz::wgsl
diff --git a/src/tint/lang/wgsl/BUILD.cmake b/src/tint/lang/wgsl/BUILD.cmake
index 704e42a..ae000ff 100644
--- a/src/tint/lang/wgsl/BUILD.cmake
+++ b/src/tint/lang/wgsl/BUILD.cmake
@@ -176,20 +176,22 @@
 
 tint_target_add_dependencies(tint_lang_wgsl_fuzz fuzz
   tint_api_common
-  tint_cmd_fuzz_ir_fuzz
   tint_lang_core
   tint_lang_core_constant
   tint_lang_core_ir
   tint_lang_core_type
   tint_lang_wgsl
   tint_lang_wgsl_ast
+  tint_lang_wgsl_ast_transform
   tint_lang_wgsl_common
   tint_lang_wgsl_features
+  tint_lang_wgsl_helpers
   tint_lang_wgsl_program
   tint_lang_wgsl_sem
   tint_lang_wgsl_writer_ir_to_program
   tint_lang_wgsl_writer_raise
   tint_utils_bytes
+  tint_utils_command
   tint_utils_containers
   tint_utils_diagnostic
   tint_utils_ice
@@ -207,6 +209,8 @@
 
 if(TINT_BUILD_WGSL_READER)
   tint_target_add_dependencies(tint_lang_wgsl_fuzz fuzz
+    tint_cmd_fuzz_wgsl_fuzz
+    tint_lang_wgsl_reader
     tint_lang_wgsl_reader_program_to_ir
   )
 endif(TINT_BUILD_WGSL_READER)
diff --git a/src/tint/lang/wgsl/BUILD.gn b/src/tint/lang/wgsl/BUILD.gn
index d46ee4c..f6c072a 100644
--- a/src/tint/lang/wgsl/BUILD.gn
+++ b/src/tint/lang/wgsl/BUILD.gn
@@ -148,20 +148,22 @@
   sources = []
   deps = [
     "${tint_src_dir}/api/common",
-    "${tint_src_dir}/cmd/fuzz/ir:fuzz",
     "${tint_src_dir}/lang/core",
     "${tint_src_dir}/lang/core/constant",
     "${tint_src_dir}/lang/core/ir",
     "${tint_src_dir}/lang/core/type",
     "${tint_src_dir}/lang/wgsl",
     "${tint_src_dir}/lang/wgsl/ast",
+    "${tint_src_dir}/lang/wgsl/ast/transform",
     "${tint_src_dir}/lang/wgsl/common",
     "${tint_src_dir}/lang/wgsl/features",
+    "${tint_src_dir}/lang/wgsl/helpers",
     "${tint_src_dir}/lang/wgsl/program",
     "${tint_src_dir}/lang/wgsl/sem",
     "${tint_src_dir}/lang/wgsl/writer/ir_to_program",
     "${tint_src_dir}/lang/wgsl/writer/raise",
     "${tint_src_dir}/utils/bytes",
+    "${tint_src_dir}/utils/command",
     "${tint_src_dir}/utils/containers",
     "${tint_src_dir}/utils/diagnostic",
     "${tint_src_dir}/utils/ice",
@@ -178,7 +180,11 @@
   ]
 
   if (tint_build_wgsl_reader) {
-    deps += [ "${tint_src_dir}/lang/wgsl/reader/program_to_ir" ]
+    deps += [
+      "${tint_src_dir}/cmd/fuzz/wgsl:fuzz",
+      "${tint_src_dir}/lang/wgsl/reader",
+      "${tint_src_dir}/lang/wgsl/reader/program_to_ir",
+    ]
   }
 
   if (tint_build_wgsl_reader && tint_build_wgsl_writer) {
diff --git a/src/tint/lang/wgsl/ir_roundtrip_fuzz.cc b/src/tint/lang/wgsl/ir_roundtrip_fuzz.cc
index 1222a2d..3e7e074 100644
--- a/src/tint/lang/wgsl/ir_roundtrip_fuzz.cc
+++ b/src/tint/lang/wgsl/ir_roundtrip_fuzz.cc
@@ -29,12 +29,18 @@
 
 #include <iostream>
 
-#include "src/tint/cmd/fuzz/ir/fuzz.h"
+#include "src/tint/cmd/fuzz/wgsl/fuzz.h"
 #include "src/tint/lang/core/ir/disassembler.h"
+#include "src/tint/lang/core/ir/validator.h"
+#include "src/tint/lang/wgsl/ast/module.h"
+#include "src/tint/lang/wgsl/ast/transform/renamer.h"
+#include "src/tint/lang/wgsl/helpers/apply_substitute_overrides.h"
 #include "src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.h"
+#include "src/tint/lang/wgsl/reader/reader.h"
 #include "src/tint/lang/wgsl/writer/ir_to_program/ir_to_program.h"
 #include "src/tint/lang/wgsl/writer/raise/raise.h"
 #include "src/tint/lang/wgsl/writer/writer.h"
+#include "src/tint/utils/command/command.h"
 #include "src/tint/utils/text/string.h"
 
 namespace tint::wgsl {
@@ -53,20 +59,36 @@
     return true;
 }
 
-void IRRoundtripFuzzer(core::ir::Module& ir) {
-    if (!CanRun(ir)) {
+void IRRoundtripFuzzer(const tint::Program& program, const fuzz::wgsl::Context& context) {
+    if (program.AST().Enables().Any(tint::wgsl::reader::IsUnsupportedByIR)) {
+        return;
+    }
+    auto transformed = tint::wgsl::ApplySubstituteOverrides(program);
+    auto& src = transformed ? transformed.value() : program;
+    if (!src.IsValid()) {
+        return;
+    }
+    auto ir = tint::wgsl::reader::ProgramToLoweredIR(src);
+    if (ir != Success) {
+        return;
+    }
+    if (auto val = core::ir::Validate(ir.Get()); val != Success) {
+        TINT_ICE() << val.Failure();
+    }
+
+    if (!CanRun(ir.Get())) {
         return;
     }
 
-    if (auto res = tint::wgsl::writer::Raise(ir); res != Success) {
+    if (auto res = tint::wgsl::writer::Raise(ir.Get()); res != Success) {
         TINT_ICE() << res.Failure();
     }
 
     writer::ProgramOptions program_options;
     program_options.allowed_features = AllowedFeatures::Everything();
-    auto dst = tint::wgsl::writer::IRToProgram(ir, program_options);
+    auto dst = tint::wgsl::writer::IRToProgram(ir.Get(), program_options);
     if (!dst.IsValid()) {
-        std::cerr << "IR:\n" << core::ir::Disassembler(ir).Plain() << "\n";
+        std::cerr << "IR:\n" << core::ir::Disassembler(ir.Get()).Plain() << "\n";
         if (auto result = tint::wgsl::writer::Generate(dst, {}); result == Success) {
             std::cerr << "WGSL:\n" << result->wgsl << "\n\n";
         }
@@ -78,4 +100,4 @@
 
 }  // namespace tint::wgsl
 
-TINT_IR_MODULE_FUZZER(tint::wgsl::IRRoundtripFuzzer);
+TINT_WGSL_PROGRAM_FUZZER(tint::wgsl::IRRoundtripFuzzer);