Import Tint changes from Dawn
Changes:
- c96f8183280aa15e26e7fd9e197c818b7d219cf8 [tint][fuzz][ir] Add BindingRemapper fuzzer by Ben Clayton <bclayton@google.com>
- 3e18d6aead7a9bfce0a44e1cc224d8aad23a2563 [tint][fuzz][ir] Add BinaryPolyfill fuzzer by Ben Clayton <bclayton@google.com>
- b5045a6c9881bf4113313d534eaf8abdb235659b [tint][fuzz][ir] Add Bgra8UnormPolyfill fuzzer by Ben Clayton <bclayton@google.com>
- 8801bee379627f4a258d278a8a7a2f196d1cca9c [tint][fuzz][ir] Add AddEmptyEntryPoint fuzzer by Ben Clayton <bclayton@google.com>
- 6391acef4b6007a827546c5f226a384af4d008cb [tint][fuzz][ast] Add AddEmptyEntryPoint fuzzer by Ben Clayton <bclayton@google.com>
- c4d9ee724ea25288a5248ceb469514c0273eea7b [tint][fuzz][ast] Add AddBlockAttribute fuzzer by Ben Clayton <bclayton@google.com>
- ba06f4775aa0daeccd5af239f01fbdcd86a65e38 [tint][fuzz] Limit the first_index_offset value by Ben Clayton <bclayton@google.com>
- bc99356b1de0296043aebab79b9451d025c273c5 [Compat] Fix a bug when textureDimension with 1 arg is fi... by Shrek Shao <shrekshao@google.com>
- d011f42aeced8eb0ac7f3e999e8819baea66117d [tint][fuzz] Add fuzzer command line flags by Ben Clayton <bclayton@google.com>
- 988805ac8637dc9d93887fe521f5a5805600d02d [tint][spirv-ast] Fix emission of discard followed by sta... by Ben Clayton <bclayton@google.com>
GitOrigin-RevId: c96f8183280aa15e26e7fd9e197c818b7d219cf8
Change-Id: Ic3ab680cb92fe4c0427ddc35186ad4307e810f4e
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/185320
Commit-Queue: dan sinclair <dsinclair@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: dan sinclair <dsinclair@google.com>
diff --git a/src/tint/cmd/fuzz/wgsl/BUILD.cmake b/src/tint/cmd/fuzz/wgsl/BUILD.cmake
index 853fd5d..d51bd4d 100644
--- a/src/tint/cmd/fuzz/wgsl/BUILD.cmake
+++ b/src/tint/cmd/fuzz/wgsl/BUILD.cmake
@@ -48,6 +48,7 @@
tint_cmd_fuzz_ir_fuzz
tint_lang_core
tint_lang_core_constant
+ tint_lang_core_ir_transform_fuzz
tint_lang_core_type
tint_lang_wgsl
tint_lang_wgsl_ast
@@ -142,6 +143,7 @@
tint_lang_wgsl_features
tint_lang_wgsl_program
tint_lang_wgsl_sem
+ tint_lang_wgsl_writer_ir_to_program
tint_utils_bytes
tint_utils_containers
tint_utils_diagnostic
@@ -168,4 +170,10 @@
)
endif(TINT_BUILD_WGSL_READER)
+if(TINT_BUILD_WGSL_WRITER)
+ tint_target_add_dependencies(tint_cmd_fuzz_wgsl_fuzz fuzz
+ tint_lang_wgsl_writer
+ )
+endif(TINT_BUILD_WGSL_WRITER)
+
endif(TINT_BUILD_WGSL_READER)
\ No newline at end of file
diff --git a/src/tint/cmd/fuzz/wgsl/BUILD.gn b/src/tint/cmd/fuzz/wgsl/BUILD.gn
index 97cec04..389a98e 100644
--- a/src/tint/cmd/fuzz/wgsl/BUILD.gn
+++ b/src/tint/cmd/fuzz/wgsl/BUILD.gn
@@ -56,6 +56,7 @@
"${tint_src_dir}/lang/wgsl/features",
"${tint_src_dir}/lang/wgsl/program",
"${tint_src_dir}/lang/wgsl/sem",
+ "${tint_src_dir}/lang/wgsl/writer/ir_to_program",
"${tint_src_dir}/utils/bytes",
"${tint_src_dir}/utils/containers",
"${tint_src_dir}/utils/diagnostic",
@@ -75,6 +76,10 @@
if (tint_build_wgsl_reader) {
deps += [ "${tint_src_dir}/lang/wgsl/reader" ]
}
+
+ if (tint_build_wgsl_writer) {
+ deps += [ "${tint_src_dir}/lang/wgsl/writer" ]
+ }
}
}
if (tint_build_wgsl_reader) {
@@ -85,6 +90,7 @@
"${tint_src_dir}/cmd/fuzz/ir:fuzz",
"${tint_src_dir}/lang/core",
"${tint_src_dir}/lang/core/constant",
+ "${tint_src_dir}/lang/core/ir/transform:fuzz",
"${tint_src_dir}/lang/core/type",
"${tint_src_dir}/lang/wgsl",
"${tint_src_dir}/lang/wgsl:fuzz",
diff --git a/src/tint/cmd/fuzz/wgsl/fuzz.cc b/src/tint/cmd/fuzz/wgsl/fuzz.cc
index d6b90ec..6e4d9b8 100644
--- a/src/tint/cmd/fuzz/wgsl/fuzz.cc
+++ b/src/tint/cmd/fuzz/wgsl/fuzz.cc
@@ -35,6 +35,11 @@
#include "src/tint/utils/macros/defer.h"
#include "src/tint/utils/macros/static_init.h"
+#if TINT_BUILD_WGSL_WRITER
+#include "src/tint/lang/wgsl/program/program.h"
+#include "src/tint/lang/wgsl/writer/writer.h"
+#endif
+
namespace tint::fuzz::wgsl {
namespace {
@@ -63,6 +68,17 @@
void Run(std::string_view wgsl, Slice<const std::byte> data, const Options& options) {
tint::SetInternalCompilerErrorReporter(&TintInternalCompilerErrorReporter);
+#if TINT_BUILD_WGSL_WRITER
+ // Register the Program printer. This is used for debugging purposes.
+ tint::Program::printer = [](const tint::Program& program) {
+ auto result = tint::wgsl::writer::Generate(program, {});
+ if (result != Success) {
+ return result.Failure().reason.Str();
+ }
+ return result->wgsl;
+ };
+#endif
+
// Ensure that fuzzers are sorted. Without this, the fuzzers may be registered in any order,
// leading to non-determinism, which we must avoid.
TINT_STATIC_INIT(Fuzzers().Sort([](auto& a, auto& b) { return a.name < b.name; }));
@@ -80,13 +96,20 @@
if (options.run_concurrently) {
size_t n = Fuzzers().Length();
tint::Vector<std::thread, 32> threads;
- threads.Resize(n);
+ threads.Reserve(n);
for (size_t i = 0; i < n; i++) {
- threads[i] = std::thread([i, &program, &data] {
+ if (!options.filter.empty() &&
+ Fuzzers()[i].name.find(options.filter) == std::string::npos) {
+ continue;
+ }
+ threads.Push(std::thread([i, &program, &data, &options] {
auto& fuzzer = Fuzzers()[i];
currently_running = fuzzer.name;
+ if (options.verbose) {
+ std::cout << " • [" << i << "] Running: " << currently_running << std::endl;
+ }
fuzzer.fn(program, data);
- });
+ }));
}
for (auto& thread : threads) {
thread.join();
@@ -94,7 +117,14 @@
} else {
TINT_DEFER(currently_running = "");
for (auto& fuzzer : Fuzzers()) {
+ if (!options.filter.empty() && fuzzer.name.find(options.filter) == std::string::npos) {
+ continue;
+ }
+
currently_running = fuzzer.name;
+ if (options.verbose) {
+ std::cout << " • Running: " << currently_running << std::endl;
+ }
fuzzer.fn(program, data);
}
}
diff --git a/src/tint/cmd/fuzz/wgsl/fuzz.h b/src/tint/cmd/fuzz/wgsl/fuzz.h
index d54b3ec..c01455b 100644
--- a/src/tint/cmd/fuzz/wgsl/fuzz.h
+++ b/src/tint/cmd/fuzz/wgsl/fuzz.h
@@ -78,8 +78,12 @@
/// Options for Run()
struct Options {
+ /// If not empty, only run the fuzzers with the given substring.
+ std::string filter;
/// If true, the fuzzers will be run concurrently on separate threads.
bool run_concurrently = false;
+ /// If true, print the fuzzer name to stdout before running.
+ bool verbose = false;
};
/// Runs all the registered WGSL fuzzers with the supplied WGSL
diff --git a/src/tint/cmd/fuzz/wgsl/main_fuzz.cc b/src/tint/cmd/fuzz/wgsl/main_fuzz.cc
index 9762952..3420d40 100644
--- a/src/tint/cmd/fuzz/wgsl/main_fuzz.cc
+++ b/src/tint/cmd/fuzz/wgsl/main_fuzz.cc
@@ -70,8 +70,12 @@
};
auto& opt_help = opts.Add<tint::cli::BoolOption>("help", "shows the usage");
+ auto& opt_filter = opts.Add<tint::cli::StringOption>(
+ "filter", "runs only the fuzzers with the given substring");
auto& opt_concurrent =
opts.Add<tint::cli::BoolOption>("concurrent", "runs the fuzzers concurrently");
+ auto& opt_verbose =
+ opts.Add<tint::cli::BoolOption>("verbose", "prints the name of each fuzzer before running");
tint::cli::ParseOptions parse_opts;
parse_opts.ignore_unknown = true;
@@ -86,6 +90,8 @@
return 0;
}
+ options.filter = opt_filter.value.value_or("");
options.run_concurrently = opt_concurrent.value.value_or(false);
+ options.verbose = opt_verbose.value.value_or(false);
return 0;
}
diff --git a/src/tint/lang/core/ir/transform/BUILD.cmake b/src/tint/lang/core/ir/transform/BUILD.cmake
index 01120f4..223dbee 100644
--- a/src/tint/lang/core/ir/transform/BUILD.cmake
+++ b/src/tint/lang/core/ir/transform/BUILD.cmake
@@ -179,3 +179,33 @@
tint_lang_wgsl_writer
)
endif(TINT_BUILD_WGSL_WRITER)
+
+################################################################################
+# Target: tint_lang_core_ir_transform_fuzz
+# Kind: fuzz
+################################################################################
+tint_add_target(tint_lang_core_ir_transform_fuzz fuzz
+ lang/core/ir/transform/add_empty_entry_point_fuzz.cc
+ lang/core/ir/transform/bgra8unorm_polyfill_fuzz.cc
+ lang/core/ir/transform/binary_polyfill_fuzz.cc
+ lang/core/ir/transform/binding_remapper_fuzz.cc
+)
+
+tint_target_add_dependencies(tint_lang_core_ir_transform_fuzz fuzz
+ tint_api_common
+ tint_cmd_fuzz_ir_fuzz
+ tint_lang_core_ir
+ tint_lang_core_ir_transform
+ tint_utils_bytes
+ tint_utils_containers
+ tint_utils_diagnostic
+ tint_utils_ice
+ tint_utils_macros
+ tint_utils_math
+ tint_utils_memory
+ tint_utils_reflection
+ tint_utils_result
+ tint_utils_rtti
+ tint_utils_text
+ tint_utils_traits
+)
diff --git a/src/tint/lang/core/ir/transform/BUILD.gn b/src/tint/lang/core/ir/transform/BUILD.gn
index 56910e6..bd81416 100644
--- a/src/tint/lang/core/ir/transform/BUILD.gn
+++ b/src/tint/lang/core/ir/transform/BUILD.gn
@@ -175,3 +175,30 @@
}
}
}
+
+tint_fuzz_source_set("fuzz") {
+ sources = [
+ "add_empty_entry_point_fuzz.cc",
+ "bgra8unorm_polyfill_fuzz.cc",
+ "binary_polyfill_fuzz.cc",
+ "binding_remapper_fuzz.cc",
+ ]
+ deps = [
+ "${tint_src_dir}/api/common",
+ "${tint_src_dir}/cmd/fuzz/ir:fuzz",
+ "${tint_src_dir}/lang/core/ir",
+ "${tint_src_dir}/lang/core/ir/transform",
+ "${tint_src_dir}/utils/bytes",
+ "${tint_src_dir}/utils/containers",
+ "${tint_src_dir}/utils/diagnostic",
+ "${tint_src_dir}/utils/ice",
+ "${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/text",
+ "${tint_src_dir}/utils/traits",
+ ]
+}
diff --git a/src/tint/lang/core/ir/transform/add_empty_entry_point_fuzz.cc b/src/tint/lang/core/ir/transform/add_empty_entry_point_fuzz.cc
new file mode 100644
index 0000000..70056f6
--- /dev/null
+++ b/src/tint/lang/core/ir/transform/add_empty_entry_point_fuzz.cc
@@ -0,0 +1,50 @@
+// Copyright 2024 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/lang/core/ir/transform/add_empty_entry_point.h"
+
+#include "src/tint/cmd/fuzz/ir/fuzz.h"
+#include "src/tint/lang/core/ir/validator.h"
+
+namespace tint::core::ir::transform {
+namespace {
+
+void AddEmptyEntryPointFuzzer(Module& module) {
+ if (auto res = AddEmptyEntryPoint(module); res != Success) {
+ return;
+ }
+
+ Capabilities capabilities;
+ if (auto res = Validate(module, capabilities); res != Success) {
+ TINT_ICE() << "result of AddEmptyEntryPoint failed IR validation\n" << res.Failure();
+ }
+}
+
+} // namespace
+} // namespace tint::core::ir::transform
+
+TINT_IR_MODULE_FUZZER(tint::core::ir::transform::AddEmptyEntryPointFuzzer);
diff --git a/src/tint/lang/core/ir/transform/bgra8unorm_polyfill_fuzz.cc b/src/tint/lang/core/ir/transform/bgra8unorm_polyfill_fuzz.cc
new file mode 100644
index 0000000..cbb95fe
--- /dev/null
+++ b/src/tint/lang/core/ir/transform/bgra8unorm_polyfill_fuzz.cc
@@ -0,0 +1,50 @@
+// Copyright 2024 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/lang/core/ir/transform/bgra8unorm_polyfill.h"
+
+#include "src/tint/cmd/fuzz/ir/fuzz.h"
+#include "src/tint/lang/core/ir/validator.h"
+
+namespace tint::core::ir::transform {
+namespace {
+
+void Bgra8UnormPolyfillFuzzer(Module& module) {
+ if (auto res = Bgra8UnormPolyfill(module); res != Success) {
+ return;
+ }
+
+ Capabilities capabilities;
+ if (auto res = Validate(module, capabilities); res != Success) {
+ TINT_ICE() << "result of Bgra8UnormPolyfill failed IR validation\n" << res.Failure();
+ }
+}
+
+} // namespace
+} // namespace tint::core::ir::transform
+
+TINT_IR_MODULE_FUZZER(tint::core::ir::transform::Bgra8UnormPolyfillFuzzer);
diff --git a/src/tint/lang/core/ir/transform/binary_polyfill.h b/src/tint/lang/core/ir/transform/binary_polyfill.h
index 82fe8d5..1ff8efd 100644
--- a/src/tint/lang/core/ir/transform/binary_polyfill.h
+++ b/src/tint/lang/core/ir/transform/binary_polyfill.h
@@ -30,6 +30,7 @@
#include <string>
+#include "src/tint/utils/reflection/reflection.h"
#include "src/tint/utils/result/result.h"
// Forward declarations.
@@ -45,6 +46,9 @@
bool bitshift_modulo = false;
/// Should integer divide and modulo be polyfilled to avoid DBZ and integer overflow?
bool int_div_mod = false;
+
+ /// Reflection for this class
+ TINT_REFLECT(BinaryPolyfillConfig, bitshift_modulo, int_div_mod);
};
/// BinaryPolyfill is a transform that modifies binary instructions to prepare them for raising to
diff --git a/src/tint/lang/core/ir/transform/binary_polyfill_fuzz.cc b/src/tint/lang/core/ir/transform/binary_polyfill_fuzz.cc
new file mode 100644
index 0000000..13875ea
--- /dev/null
+++ b/src/tint/lang/core/ir/transform/binary_polyfill_fuzz.cc
@@ -0,0 +1,50 @@
+// Copyright 2024 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/lang/core/ir/transform/binary_polyfill.h"
+
+#include "src/tint/cmd/fuzz/ir/fuzz.h"
+#include "src/tint/lang/core/ir/validator.h"
+
+namespace tint::core::ir::transform {
+namespace {
+
+void BinaryPolyfillFuzzer(Module& module, BinaryPolyfillConfig config) {
+ if (auto res = BinaryPolyfill(module, config); res != Success) {
+ return;
+ }
+
+ Capabilities capabilities;
+ if (auto res = Validate(module, capabilities); res != Success) {
+ TINT_ICE() << "result of BinaryPolyfill failed IR validation\n" << res.Failure();
+ }
+}
+
+} // namespace
+} // namespace tint::core::ir::transform
+
+TINT_IR_MODULE_FUZZER(tint::core::ir::transform::BinaryPolyfillFuzzer);
diff --git a/src/tint/lang/core/ir/transform/binding_remapper_fuzz.cc b/src/tint/lang/core/ir/transform/binding_remapper_fuzz.cc
new file mode 100644
index 0000000..68ba651
--- /dev/null
+++ b/src/tint/lang/core/ir/transform/binding_remapper_fuzz.cc
@@ -0,0 +1,51 @@
+// Copyright 2024 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/lang/core/ir/transform/binding_remapper.h"
+
+#include "src/tint/cmd/fuzz/ir/fuzz.h"
+#include "src/tint/lang/core/ir/validator.h"
+
+namespace tint::core::ir::transform {
+namespace {
+
+void BindingRemapperFuzzer(Module& module,
+ const std::unordered_map<BindingPoint, BindingPoint>& binding_points) {
+ if (auto res = BindingRemapper(module, binding_points); res != Success) {
+ return;
+ }
+
+ Capabilities capabilities;
+ if (auto res = Validate(module, capabilities); res != Success) {
+ TINT_ICE() << "result of BindingRemapper failed IR validation\n" << res.Failure();
+ }
+}
+
+} // namespace
+} // namespace tint::core::ir::transform
+
+TINT_IR_MODULE_FUZZER(tint::core::ir::transform::BindingRemapperFuzzer);
diff --git a/src/tint/lang/glsl/writer/writer_ast_fuzz.cc b/src/tint/lang/glsl/writer/writer_ast_fuzz.cc
index 096c259..577f4f2 100644
--- a/src/tint/lang/glsl/writer/writer_ast_fuzz.cc
+++ b/src/tint/lang/glsl/writer/writer_ast_fuzz.cc
@@ -40,6 +40,10 @@
return;
}
+ if (options.first_instance_offset > 0x10000) {
+ return; // Excessive values can cause OOM.
+ }
+
auto inspector = tint::inspector::Inspector(program);
auto entrypoints = inspector.GetEntryPoints();
diff --git a/src/tint/lang/spirv/writer/ast_printer/builder.cc b/src/tint/lang/spirv/writer/ast_printer/builder.cc
index 9673668..4720efc 100644
--- a/src/tint/lang/spirv/writer/ast_printer/builder.cc
+++ b/src/tint/lang/spirv/writer/ast_printer/builder.cc
@@ -588,10 +588,8 @@
current_label_id_ = current_function_.label_id();
TINT_DEFER(current_function_ = Function());
- for (auto* stmt : func_ast->body->statements) {
- if (!GenerateStatement(stmt)) {
- return false;
- }
+ if (!GenerateBlockStatementWithoutScoping(func_ast->body)) {
+ return false;
}
if (InsideBasicBlock()) {
@@ -2198,6 +2196,9 @@
bool Builder::GenerateBlockStatementWithoutScoping(const ast::BlockStatement* stmt) {
for (auto* block_stmt : stmt->statements) {
+ if (!InsideBasicBlock()) {
+ break;
+ }
if (!GenerateStatement(block_stmt)) {
return false;
}
diff --git a/src/tint/lang/wgsl/ast/transform/BUILD.cmake b/src/tint/lang/wgsl/ast/transform/BUILD.cmake
index 4f2817f..05dae10 100644
--- a/src/tint/lang/wgsl/ast/transform/BUILD.cmake
+++ b/src/tint/lang/wgsl/ast/transform/BUILD.cmake
@@ -248,6 +248,8 @@
# Condition: TINT_BUILD_WGSL_READER
################################################################################
tint_add_target(tint_lang_wgsl_ast_transform_fuzz fuzz
+ lang/wgsl/ast/transform/add_block_attribute_fuzz.cc
+ lang/wgsl/ast/transform/add_empty_entry_point_fuzz.cc
lang/wgsl/ast/transform/zero_init_workgroup_memory_fuzz.cc
)
diff --git a/src/tint/lang/wgsl/ast/transform/BUILD.gn b/src/tint/lang/wgsl/ast/transform/BUILD.gn
index f0626b0..7b2d224 100644
--- a/src/tint/lang/wgsl/ast/transform/BUILD.gn
+++ b/src/tint/lang/wgsl/ast/transform/BUILD.gn
@@ -237,7 +237,11 @@
}
if (tint_build_wgsl_reader) {
tint_fuzz_source_set("fuzz") {
- sources = [ "zero_init_workgroup_memory_fuzz.cc" ]
+ sources = [
+ "add_block_attribute_fuzz.cc",
+ "add_empty_entry_point_fuzz.cc",
+ "zero_init_workgroup_memory_fuzz.cc",
+ ]
deps = [
"${tint_src_dir}/lang/core",
"${tint_src_dir}/lang/core/constant",
diff --git a/src/tint/lang/wgsl/ast/transform/add_block_attribute.h b/src/tint/lang/wgsl/ast/transform/add_block_attribute.h
index 544e1ee..5e9892b 100644
--- a/src/tint/lang/wgsl/ast/transform/add_block_attribute.h
+++ b/src/tint/lang/wgsl/ast/transform/add_block_attribute.h
@@ -40,7 +40,7 @@
class AddBlockAttribute final : public Castable<AddBlockAttribute, Transform> {
public:
/// BlockAttribute is an InternalAttribute that is used to decorate a
- // structure that is used as a buffer in SPIR-V or GLSL.
+ /// structure that is used as a buffer in SPIR-V or GLSL.
class BlockAttribute final : public Castable<BlockAttribute, InternalAttribute> {
public:
/// Constructor
diff --git a/src/tint/lang/wgsl/ast/transform/add_block_attribute_fuzz.cc b/src/tint/lang/wgsl/ast/transform/add_block_attribute_fuzz.cc
new file mode 100644
index 0000000..7898243
--- /dev/null
+++ b/src/tint/lang/wgsl/ast/transform/add_block_attribute_fuzz.cc
@@ -0,0 +1,46 @@
+// Copyright 2024 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/wgsl/fuzz.h"
+#include "src/tint/lang/wgsl/ast/transform/add_block_attribute.h"
+
+namespace tint::ast::transform {
+namespace {
+
+void AddBlockAttributeFuzzer(const Program& program) {
+ DataMap outputs;
+ if (auto result = AddBlockAttribute{}.Apply(program, DataMap{}, outputs)) {
+ if (!result->IsValid()) {
+ TINT_ICE() << "AddBlockAttribute returned invalid program:\n" << result->Diagnostics();
+ }
+ }
+}
+
+} // namespace
+} // namespace tint::ast::transform
+
+TINT_WGSL_PROGRAM_FUZZER(tint::ast::transform::AddBlockAttributeFuzzer);
diff --git a/src/tint/lang/wgsl/ast/transform/add_empty_entry_point_fuzz.cc b/src/tint/lang/wgsl/ast/transform/add_empty_entry_point_fuzz.cc
new file mode 100644
index 0000000..cee5702
--- /dev/null
+++ b/src/tint/lang/wgsl/ast/transform/add_empty_entry_point_fuzz.cc
@@ -0,0 +1,46 @@
+// Copyright 2024 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/wgsl/fuzz.h"
+#include "src/tint/lang/wgsl/ast/transform/add_empty_entry_point.h"
+
+namespace tint::ast::transform {
+namespace {
+
+void AddEmptyEntryPointFuzzer(const Program& program) {
+ DataMap outputs;
+ if (auto result = AddEmptyEntryPoint{}.Apply(program, DataMap{}, outputs)) {
+ if (!result->IsValid()) {
+ TINT_ICE() << "AddEmptyEntryPoint returned invalid program:\n" << result->Diagnostics();
+ }
+ }
+}
+
+} // namespace
+} // namespace tint::ast::transform
+
+TINT_WGSL_PROGRAM_FUZZER(tint::ast::transform::AddEmptyEntryPointFuzzer);
diff --git a/src/tint/lang/wgsl/ast/transform/zero_init_workgroup_memory_fuzz.cc b/src/tint/lang/wgsl/ast/transform/zero_init_workgroup_memory_fuzz.cc
index 7fe5685..2e3650d 100644
--- a/src/tint/lang/wgsl/ast/transform/zero_init_workgroup_memory_fuzz.cc
+++ b/src/tint/lang/wgsl/ast/transform/zero_init_workgroup_memory_fuzz.cc
@@ -32,7 +32,7 @@
namespace tint::ast::transform {
-void ZeroInitWorkgroupMemoryFuzzer(const tint::Program& program) {
+void ZeroInitWorkgroupMemoryFuzzer(const Program& program) {
if (program.AST().HasOverrides()) {
return;
}
diff --git a/src/tint/lang/wgsl/inspector/inspector.cc b/src/tint/lang/wgsl/inspector/inspector.cc
index f00ab13..1cdbcac 100644
--- a/src/tint/lang/wgsl/inspector/inspector.cc
+++ b/src/tint/lang/wgsl/inspector/inspector.cc
@@ -1029,24 +1029,14 @@
std::unordered_set<BindingPoint> seen = {};
- auto sample_type_for_call_and_type = [](wgsl::BuiltinFn builtin, const core::type::Type* ty,
- const Vector<const ast::Expression*, 8>& args) {
- if (builtin == wgsl::BuiltinFn::kTextureNumLevels) {
+ auto sample_type_for_call_and_type = [](wgsl::BuiltinFn builtin) {
+ if (builtin == wgsl::BuiltinFn::kTextureNumLevels ||
+ builtin == wgsl::BuiltinFn::kTextureDimensions ||
+ builtin == wgsl::BuiltinFn::kTextureLoad) {
return TextureQueryType::kTextureNumLevels;
}
- if (builtin == wgsl::BuiltinFn::kTextureDimensions && args.Length() > 1) {
- // When textureDimension takes level as the input,
- // it requires calls to textureNumLevels to clamp mip levels.
- return TextureQueryType::kTextureNumLevels;
- }
- if (builtin == wgsl::BuiltinFn::kTextureLoad) {
- if (!ty->UnwrapRef()
- ->IsAnyOf<core::type::MultisampledTexture,
- core::type::DepthMultisampledTexture>()) {
- return TextureQueryType::kTextureNumLevels;
- }
- }
+ TINT_ASSERT(builtin == wgsl::BuiltinFn::kTextureNumSamples);
return TextureQueryType::kTextureNumSamples;
};
@@ -1101,19 +1091,27 @@
call->Target(),
[&](const sem::BuiltinFn* builtin) {
if (builtin->Fn() != wgsl::BuiltinFn::kTextureNumLevels &&
- builtin->Fn() != wgsl::BuiltinFn::kTextureDimensions &&
builtin->Fn() != wgsl::BuiltinFn::kTextureNumSamples &&
- builtin->Fn() != wgsl::BuiltinFn::kTextureLoad) {
+ builtin->Fn() != wgsl::BuiltinFn::kTextureLoad &&
+ // When textureDimension takes level as the input,
+ // it requires calls to textureNumLevels to clamp mip levels.
+ !(builtin->Fn() == wgsl::BuiltinFn::kTextureDimensions &&
+ call->Declaration()->args.Length() > 1)) {
return;
}
auto* texture_expr = call->Declaration()->args[0];
auto* texture_sem = sem.GetVal(texture_expr)->RootIdentifier();
TINT_ASSERT(texture_sem);
+ if (builtin->Fn() == wgsl::BuiltinFn::kTextureLoad &&
+ texture_sem->Type()
+ ->UnwrapRef()
+ ->IsAnyOf<core::type::MultisampledTexture,
+ core::type::DepthMultisampledTexture>()) {
+ return;
+ }
- auto type = sample_type_for_call_and_type(builtin->Fn(), texture_sem->Type(),
- call->Declaration()->args);
-
+ auto type = sample_type_for_call_and_type(builtin->Fn());
tint::Switch(
texture_sem, //
[&](const sem::GlobalVariable* global) { save_if_needed(global, type); },
diff --git a/src/tint/lang/wgsl/inspector/inspector_test.cc b/src/tint/lang/wgsl/inspector/inspector_test.cc
index 8d1a4b3..7468ccc 100644
--- a/src/tint/lang/wgsl/inspector/inspector_test.cc
+++ b/src/tint/lang/wgsl/inspector/inspector_test.cc
@@ -3931,22 +3931,20 @@
Inspector& inspector = Initialize(shader);
auto info = inspector.GetTextureQueries("main");
- ASSERT_EQ(1u, info.size());
-
- EXPECT_EQ(Inspector::TextureQueryType::kTextureNumSamples, info[0].type);
- EXPECT_EQ(2u, info[0].group);
- EXPECT_EQ(3u, info[0].binding);
+ ASSERT_EQ(0u, info.size());
}
TEST_F(InspectorTextureTest, TextureLoadMultipleInEP) {
std::string shader = R"(
@group(2) @binding(3) var tex1: texture_2d<f32>;
@group(1) @binding(4) var tex2: texture_multisampled_2d<f32>;
+@group(0) @binding(1) var tex3: texture_2d<f32>;
@compute @workgroup_size(1)
fn main() {
let num1 = textureLoad(tex1, vec2(0, 0), 0);
let num2 = textureLoad(tex2, vec2(0, 0), 0);
+ let num3 = textureLoad(tex3, vec2(0, 0), 0);
})";
Inspector& inspector = Initialize(shader);
@@ -3957,9 +3955,9 @@
EXPECT_EQ(Inspector::TextureQueryType::kTextureNumLevels, info[0].type);
EXPECT_EQ(2u, info[0].group);
EXPECT_EQ(3u, info[0].binding);
- EXPECT_EQ(Inspector::TextureQueryType::kTextureNumSamples, info[1].type);
- EXPECT_EQ(1u, info[1].group);
- EXPECT_EQ(4u, info[1].binding);
+ EXPECT_EQ(Inspector::TextureQueryType::kTextureNumLevels, info[1].type);
+ EXPECT_EQ(0u, info[1].group);
+ EXPECT_EQ(1u, info[1].binding);
}
TEST_F(InspectorTextureTest, TextureInSubfunction) {