From c07de73b0b56efcabc355c2a4df9211dcf1b0f30 Mon Sep 17 00:00:00 2001 From: Ben Clayton Date: Tue, 6 Dec 2022 19:41:22 +0000 Subject: [PATCH] tint/transform: Strip unused atomic builtins If a SPIR-V program declared spirv-atomic stubs, but didn't call them then the transform could be skipped, leaving stub functions behind. This could cause writers to vomit. Ensure that these are correctly stripped. Bug: oss-fuzz:54057 Change-Id: I27c89a621163b1a3cc5e2ef375f846a094434062 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/113023 Commit-Queue: Ben Clayton Auto-Submit: Ben Clayton Reviewed-by: James Price Kokoro: Kokoro --- src/tint/transform/spirv_atomic.cc | 5 ++++- src/tint/transform/spirv_atomic_test.cc | 13 +++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/tint/transform/spirv_atomic.cc b/src/tint/transform/spirv_atomic.cc index de3cdab0d3..72304e66b4 100644 --- a/src/tint/transform/spirv_atomic.cc +++ b/src/tint/transform/spirv_atomic.cc @@ -64,6 +64,8 @@ struct SpirvAtomic::State { /// Runs the transform /// @returns the new program or SkipTransform if the transform is not required ApplyResult Run() { + bool made_changes = false; + // Look for stub functions generated by the SPIR-V reader, which are used as placeholders // for atomic builtin calls. for (auto* fn : ctx.src->AST().Functions()) { @@ -104,10 +106,11 @@ struct SpirvAtomic::State { // Remove the stub from the output program ctx.Remove(ctx.src->AST().GlobalDeclarations(), fn); + made_changes = true; } } - if (atomic_expressions.IsEmpty()) { + if (!made_changes) { return SkipTransform; } diff --git a/src/tint/transform/spirv_atomic_test.cc b/src/tint/transform/spirv_atomic_test.cc index d9371bf67c..36312f790a 100644 --- a/src/tint/transform/spirv_atomic_test.cc +++ b/src/tint/transform/spirv_atomic_test.cc @@ -151,6 +151,19 @@ class SpirvAtomicTest : public TransformTest { std::vector> files_; }; +TEST_F(SpirvAtomicTest, StripUnusedBuiltins) { + auto* src = R"( +fn f() { +} +)"; + + auto* expect = src; + + auto got = Run(src); + + EXPECT_EQ(expect, str(got)); +} + TEST_F(SpirvAtomicTest, ArrayOfU32) { auto* src = R"( var wg : array;