[tint][fuzz] Add an IR fuzzer framework
This currently registers the IR fuzzers with the WGSL fuzzer using a
ProgramToIR() translation stub.
Change-Id: I116a50dc809d6789ce8510171f91b98fde70d5e7
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/162307
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Reviewed-by: James Price <jrprice@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/cmd/fuzz/BUILD.cmake b/src/tint/cmd/fuzz/BUILD.cmake
index 65795ac..65ca459 100644
--- a/src/tint/cmd/fuzz/BUILD.cmake
+++ b/src/tint/cmd/fuzz/BUILD.cmake
@@ -34,4 +34,5 @@
# Do not modify this file directly
################################################################################
+include(cmd/fuzz/ir/BUILD.cmake)
include(cmd/fuzz/wgsl/BUILD.cmake)
diff --git a/src/tint/cmd/fuzz/ir/BUILD.bazel b/src/tint/cmd/fuzz/ir/BUILD.bazel
new file mode 100644
index 0000000..7c71462
--- /dev/null
+++ b/src/tint/cmd/fuzz/ir/BUILD.bazel
@@ -0,0 +1,44 @@
+# Copyright 2023 The Dawn & Tint Authors
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+################################################################################
+# File generated by 'tools/src/cmd/gen' using the template:
+# tools/src/cmd/gen/build/BUILD.bazel.tmpl
+#
+# To regenerate run: './tools/run gen'
+#
+# Do not modify this file directly
+################################################################################
+
+load("//src/tint:flags.bzl", "COPTS")
+load("@bazel_skylib//lib:selects.bzl", "selects")
+
+alias(
+ name = "tint_build_wgsl_reader",
+ actual = "//src/tint:tint_build_wgsl_reader_true",
+)
+
diff --git a/src/tint/cmd/fuzz/ir/BUILD.cmake b/src/tint/cmd/fuzz/ir/BUILD.cmake
new file mode 100644
index 0000000..87e9013
--- /dev/null
+++ b/src/tint/cmd/fuzz/ir/BUILD.cmake
@@ -0,0 +1,79 @@
+# Copyright 2023 The Dawn & Tint Authors
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+################################################################################
+# File generated by 'tools/src/cmd/gen' using the template:
+# tools/src/cmd/gen/build/BUILD.cmake.tmpl
+#
+# To regenerate run: './tools/run gen'
+#
+# Do not modify this file directly
+################################################################################
+
+################################################################################
+# Target: tint_cmd_fuzz_ir_fuzz
+# Kind: fuzz
+################################################################################
+tint_add_target(tint_cmd_fuzz_ir_fuzz fuzz
+ cmd/fuzz/ir/fuzz.cc
+ cmd/fuzz/ir/fuzz.h
+)
+
+tint_target_add_dependencies(tint_cmd_fuzz_ir_fuzz fuzz
+ tint_api_common
+ 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_common
+ tint_lang_wgsl_helpers
+ tint_lang_wgsl_program
+ tint_lang_wgsl_sem
+ tint_utils_bytes
+ tint_utils_containers
+ tint_utils_diagnostic
+ tint_utils_ice
+ tint_utils_id
+ tint_utils_macros
+ tint_utils_math
+ tint_utils_memory
+ tint_utils_reflection
+ tint_utils_result
+ tint_utils_rtti
+ tint_utils_symbol
+ tint_utils_text
+ tint_utils_traits
+)
+
+if(TINT_BUILD_WGSL_READER)
+ tint_target_add_dependencies(tint_cmd_fuzz_ir_fuzz fuzz
+ tint_cmd_fuzz_wgsl_fuzz
+ tint_lang_wgsl_reader
+ )
+endif(TINT_BUILD_WGSL_READER)
diff --git a/src/tint/cmd/fuzz/ir/BUILD.gn b/src/tint/cmd/fuzz/ir/BUILD.gn
new file mode 100644
index 0000000..e9c37c7
--- /dev/null
+++ b/src/tint/cmd/fuzz/ir/BUILD.gn
@@ -0,0 +1,80 @@
+# Copyright 2023 The Dawn & Tint Authors
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+################################################################################
+# File generated by 'tools/src/cmd/gen' using the template:
+# tools/src/cmd/gen/build/BUILD.gn.tmpl
+#
+# To regenerate run: './tools/run gen'
+#
+# Do not modify this file directly
+################################################################################
+
+import("../../../../../scripts/tint_overrides_with_defaults.gni")
+
+import("${tint_src_dir}/tint.gni")
+
+tint_fuzz_source_set("fuzz") {
+ sources = [
+ "fuzz.cc",
+ "fuzz.h",
+ ]
+ deps = [
+ "${tint_src_dir}/api/common",
+ "${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/common",
+ "${tint_src_dir}/lang/wgsl/helpers",
+ "${tint_src_dir}/lang/wgsl/program",
+ "${tint_src_dir}/lang/wgsl/sem",
+ "${tint_src_dir}/utils/bytes",
+ "${tint_src_dir}/utils/containers",
+ "${tint_src_dir}/utils/diagnostic",
+ "${tint_src_dir}/utils/ice",
+ "${tint_src_dir}/utils/id",
+ "${tint_src_dir}/utils/macros",
+ "${tint_src_dir}/utils/math",
+ "${tint_src_dir}/utils/memory",
+ "${tint_src_dir}/utils/reflection",
+ "${tint_src_dir}/utils/result",
+ "${tint_src_dir}/utils/rtti",
+ "${tint_src_dir}/utils/symbol",
+ "${tint_src_dir}/utils/text",
+ "${tint_src_dir}/utils/traits",
+ ]
+
+ if (tint_build_wgsl_reader) {
+ deps += [
+ "${tint_src_dir}/cmd/fuzz/wgsl:fuzz",
+ "${tint_src_dir}/lang/wgsl/reader",
+ ]
+ }
+}
diff --git a/src/tint/cmd/fuzz/ir/fuzz.cc b/src/tint/cmd/fuzz/ir/fuzz.cc
new file mode 100644
index 0000000..fc96dcc
--- /dev/null
+++ b/src/tint/cmd/fuzz/ir/fuzz.cc
@@ -0,0 +1,100 @@
+// Copyright 2023 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "src/tint/cmd/fuzz/ir/fuzz.h"
+
+#include "src/tint/utils/containers/vector.h"
+
+#if TINT_BUILD_WGSL_READER
+#include "src/tint/cmd/fuzz/wgsl/fuzz.h"
+#include "src/tint/lang/wgsl/ast/enable.h"
+#include "src/tint/lang/wgsl/ast/module.h"
+#include "src/tint/lang/wgsl/helpers/apply_substitute_overrides.h"
+#include "src/tint/lang/wgsl/reader/reader.h"
+#endif
+
+#include "src/tint/lang/core/ir/validator.h"
+
+#if TINT_BUILD_WGSL_READER
+namespace tint::fuzz::ir {
+namespace {
+
+bool IsUnsupported(const ast::Enable* enable) {
+ for (auto ext : enable->extensions) {
+ switch (ext->name) {
+ case tint::wgsl::Extension::kChromiumExperimentalDp4A:
+ case tint::wgsl::Extension::kChromiumExperimentalFullPtrParameters:
+ case tint::wgsl::Extension::kChromiumExperimentalPixelLocal:
+ case tint::wgsl::Extension::kChromiumExperimentalPushConstant:
+ case tint::wgsl::Extension::kChromiumInternalDualSourceBlending:
+ case tint::wgsl::Extension::kChromiumInternalRelaxedUniformLayout:
+ return true;
+ default:
+ break;
+ }
+ }
+ return false;
+}
+
+} // namespace
+
+void Register(const IRFuzzer& fuzzer) {
+ wgsl::Register({
+ fuzzer.name,
+ [fn = fuzzer.fn](const Program& program, Slice<const std::byte> data) {
+ if (program.AST().Enables().Any(IsUnsupported)) {
+ 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) {
+ return;
+ }
+
+ if (auto val = core::ir::Validate(ir.Get()); !val) {
+ TINT_ICE() << val.Failure();
+ return;
+ }
+
+ return fn(ir.Get(), data);
+ },
+ });
+}
+
+} // namespace tint::fuzz::ir
+
+#else
+
+void tint::fuzz::ir::Register([[maybe_unused]] const IRFuzzer&) {}
+
+#endif
diff --git a/src/tint/cmd/fuzz/ir/fuzz.h b/src/tint/cmd/fuzz/ir/fuzz.h
new file mode 100644
index 0000000..897f6e1
--- /dev/null
+++ b/src/tint/cmd/fuzz/ir/fuzz.h
@@ -0,0 +1,89 @@
+// Copyright 2023 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef SRC_TINT_CMD_FUZZ_IR_FUZZ_H_
+#define SRC_TINT_CMD_FUZZ_IR_FUZZ_H_
+
+#include <functional>
+#include <string>
+#include <tuple>
+#include <utility>
+
+#include "src/tint/utils/bytes/decoder.h"
+#include "src/tint/utils/containers/slice.h"
+#include "src/tint/utils/macros/static_init.h"
+
+namespace tint::core::ir {
+class Module;
+}
+
+namespace tint::fuzz::ir {
+
+/// IRFuzzer describes a fuzzer function that takes a IR module as input
+struct IRFuzzer {
+ /// @param name the name of the fuzzer
+ /// @param fn the fuzzer function
+ /// @returns an IRFuzzer that invokes the function @p fn with the IR module, along with any
+ /// additional arguments which are deserialized from the fuzzer input.
+ template <typename... ARGS>
+ static IRFuzzer Create(std::string_view name, void (*fn)(core::ir::Module&, ARGS...)) {
+ if constexpr (sizeof...(ARGS) > 0) {
+ auto fn_with_decode = [fn](core::ir::Module& module, Slice<const std::byte> data) {
+ bytes::Reader reader{data};
+ if (auto data_args = bytes::Decode<std::tuple<std::decay_t<ARGS>...>>(reader)) {
+ auto all_args =
+ std::tuple_cat(std::tuple<core::ir::Module&>{module}, data_args.Get());
+ std::apply(*fn, all_args);
+ }
+ };
+ return IRFuzzer{name, std::move(fn_with_decode)};
+ } else {
+ return IRFuzzer{
+ name,
+ [fn](core::ir::Module& module, Slice<const std::byte>) { fn(module); },
+ };
+ }
+ }
+
+ /// Name of the fuzzer function
+ std::string_view name;
+ /// The fuzzer function
+ std::function<void(core::ir::Module&, Slice<const std::byte> data)> fn;
+};
+
+/// Registers the fuzzer function with the IR fuzzer executable.
+/// @param fuzzer the fuzzer
+void Register(const IRFuzzer& fuzzer);
+
+/// TINT_IR_MODULE_FUZZER registers the fuzzer function.
+#define TINT_IR_MODULE_FUZZER(FUNCTION) \
+ TINT_STATIC_INIT( \
+ ::tint::fuzz::ir::Register(::tint::fuzz::ir::IRFuzzer::Create(#FUNCTION, FUNCTION)))
+
+} // namespace tint::fuzz::ir
+
+#endif // SRC_TINT_CMD_FUZZ_IR_FUZZ_H_
diff --git a/src/tint/cmd/fuzz/wgsl/BUILD.cmake b/src/tint/cmd/fuzz/wgsl/BUILD.cmake
index b3f6717..90ab52d 100644
--- a/src/tint/cmd/fuzz/wgsl/BUILD.cmake
+++ b/src/tint/cmd/fuzz/wgsl/BUILD.cmake
@@ -45,6 +45,7 @@
)
tint_target_add_dependencies(tint_cmd_fuzz_wgsl_fuzz_cmd fuzz_cmd
+ tint_cmd_fuzz_ir_fuzz
tint_lang_core
tint_lang_core_constant
tint_lang_core_type
diff --git a/src/tint/cmd/fuzz/wgsl/BUILD.gn b/src/tint/cmd/fuzz/wgsl/BUILD.gn
index f752d35..b853246 100644
--- a/src/tint/cmd/fuzz/wgsl/BUILD.gn
+++ b/src/tint/cmd/fuzz/wgsl/BUILD.gn
@@ -81,6 +81,7 @@
output_name = "tint_wgsl_fuzzer"
sources = [ "main_fuzz.cc" ]
deps = [
+ "${tint_src_dir}/cmd/fuzz/ir:fuzz",
"${tint_src_dir}/lang/core",
"${tint_src_dir}/lang/core/constant",
"${tint_src_dir}/lang/core/type",