[spirv] Fail for functions with >255 parameters
Some IR transforms add new parameters to existing functions, which can
cause a valid input shader to exceed SPIR-V limit of 255
parameters. We can't easily fix this, so just fail gracefully and
class it as a spurious failure as per the WGSL spec.
Fixed: 354748060
Change-Id: I31b1d1eddc2b75e237e3f01f967f4bb3e3488cee
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/200014
Reviewed-by: David Neto <dneto@google.com>
Auto-Submit: James Price <jrprice@google.com>
Commit-Queue: David Neto <dneto@google.com>
diff --git a/src/tint/lang/spirv/writer/printer/printer.cc b/src/tint/lang/spirv/writer/printer/printer.cc
index aedc7d5..e403d0f 100644
--- a/src/tint/lang/spirv/writer/printer/printer.cc
+++ b/src/tint/lang/spirv/writer/printer/printer.cc
@@ -307,7 +307,10 @@
// Emit functions.
for (core::ir::Function* func : ir_.functions) {
- EmitFunction(func);
+ auto res = EmitFunction(func);
+ if (res != Success) {
+ return res;
+ }
}
return Success;
@@ -694,7 +697,17 @@
/// Emit a function.
/// @param func the function to emit
- void EmitFunction(core::ir::Function* func) {
+ Result<SuccessType> EmitFunction(core::ir::Function* func) {
+ if (func->Params().Length() > 255) {
+ // Tint transforms may add additional function parameters which can cause a valid input
+ // shader to exceed SPIR-V's function parameter limit. There isn't much we can do about
+ // this, so just fail gracefully instead of a generating invalid SPIR-V.
+ StringStream ss;
+ ss << "Function '" << ir_.NameOf(func).Name()
+ << "' has more than 255 parameters after running Tint transforms";
+ return Failure{ss.str()};
+ }
+
auto id = Value(func);
// Emit the function name.
@@ -748,6 +761,8 @@
// Add the function to the module.
module_.PushFunction(current_function_);
+
+ return Success;
}
/// Emit entry point declarations for a function.
diff --git a/src/tint/lang/spirv/writer/writer_test.cc b/src/tint/lang/spirv/writer/writer_test.cc
index b64c0ef..c00563f 100644
--- a/src/tint/lang/spirv/writer/writer_test.cc
+++ b/src/tint/lang/spirv/writer/writer_test.cc
@@ -86,5 +86,24 @@
)");
}
+// Test that we fail gracefully when a function has too many parameters.
+// See crbug.com/354748060.
+TEST_F(SpirvWriterTest, TooManyFunctionParameters) {
+ Vector<core::ir::FunctionParam*, 256> params;
+ for (uint32_t i = 0; i < 256; i++) {
+ params.Push(b.FunctionParam(ty.i32()));
+ }
+ auto* func = b.Function("foo", ty.void_());
+ func->SetParams(std::move(params));
+ b.Append(func->Block(), [&] { //
+ b.Return(func);
+ });
+
+ EXPECT_FALSE(Generate());
+ EXPECT_THAT(Error(),
+ testing::HasSubstr(
+ "Function 'foo' has more than 255 parameters after running Tint transforms"));
+}
+
} // namespace
} // namespace tint::spirv::writer