spirv-reader: Ignore Restrict, RestrictPointer decorations
They have no effect in graphics APIs.
Fixes: tint:1440
Change-Id: I80a4b2f5875fbabbd53fd1ebd085ba146401ca71
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/80980
Auto-Submit: David Neto <dneto@google.com>
Kokoro: David Neto <dneto@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/reader/spirv/parser_impl.cc b/src/reader/spirv/parser_impl.cc
index c6b192e..d8c1a64 100644
--- a/src/reader/spirv/parser_impl.cc
+++ b/src/reader/spirv/parser_impl.cc
@@ -396,11 +396,19 @@
// Example: OpDecorate %struct_id Block
// Example: OpDecorate %array_ty ArrayStride 16
auto decoration_kind = inst->GetSingleWordInOperand(1);
- if (visited.emplace(decoration_kind).second) {
- std::vector<uint32_t> inst_as_words;
- inst->ToBinaryWithoutAttachedDebugInsts(&inst_as_words);
- Decoration d(inst_as_words.begin() + 2, inst_as_words.end());
- result.push_back(d);
+ switch (decoration_kind) {
+ // Restrict and RestrictPointer have no effect in graphics APIs.
+ case SpvDecorationRestrict:
+ case SpvDecorationRestrictPointer:
+ break;
+ default:
+ if (visited.emplace(decoration_kind).second) {
+ std::vector<uint32_t> inst_as_words;
+ inst->ToBinaryWithoutAttachedDebugInsts(&inst_as_words);
+ Decoration d(inst_as_words.begin() + 2, inst_as_words.end());
+ result.push_back(d);
+ }
+ break;
}
}
return result;
@@ -419,11 +427,18 @@
continue;
}
auto decoration_kind = inst->GetSingleWordInOperand(2);
- if (visited.emplace(decoration_kind).second) {
- std::vector<uint32_t> inst_as_words;
- inst->ToBinaryWithoutAttachedDebugInsts(&inst_as_words);
- Decoration d(inst_as_words.begin() + 3, inst_as_words.end());
- result.push_back(d);
+ switch (decoration_kind) {
+ // Restrict and RestrictPointer have no effect in graphics APIs.
+ case SpvDecorationRestrict:
+ case SpvDecorationRestrictPointer:
+ break;
+ default:
+ if (visited.emplace(decoration_kind).second) {
+ std::vector<uint32_t> inst_as_words;
+ inst->ToBinaryWithoutAttachedDebugInsts(&inst_as_words);
+ Decoration d(inst_as_words.begin() + 3, inst_as_words.end());
+ result.push_back(d);
+ }
}
}
return result;
diff --git a/src/reader/spirv/parser_impl.h b/src/reader/spirv/parser_impl.h
index ffa6251..f67d81a 100644
--- a/src/reader/spirv/parser_impl.h
+++ b/src/reader/spirv/parser_impl.h
@@ -221,6 +221,8 @@
/// Gets the list of unique decorations for a SPIR-V result ID. Returns an
/// empty vector if the ID is not a result ID, or if no decorations target
/// that ID. The internal representation must have already been built.
+ /// Ignores decorations that have no effect in graphics APIs, e.g. Restrict
+ /// and RestrictPointer.
/// @param id SPIR-V ID
/// @returns the list of decorations on the given ID
DecorationList GetDecorationsFor(uint32_t id) const;
@@ -228,6 +230,8 @@
/// an empty list if the `id` is not the ID of a struct, or if the member
/// index is out of range, or if the target member has no decorations. The
/// internal representation must have already been built.
+ /// Ignores decorations that have no effect in graphics APIs, e.g. Restrict
+ /// and RestrictPointer.
/// @param id SPIR-V ID of a struct
/// @param member_index the member within the struct
/// @returns the list of decorations on the member
diff --git a/src/reader/spirv/parser_impl_get_decorations_test.cc b/src/reader/spirv/parser_impl_get_decorations_test.cc
index fc41141..7b2818e 100644
--- a/src/reader/spirv/parser_impl_get_decorations_test.cc
+++ b/src/reader/spirv/parser_impl_get_decorations_test.cc
@@ -198,6 +198,68 @@
EXPECT_TRUE(p->error().empty());
}
+TEST_F(SpvParserGetDecorationsTest, GetDecorationsFor_Restrict) {
+ // RestrictPointer applies to a memory object declaration. Use a variable.
+ auto p = parser(test::Assemble(R"(
+ OpDecorate %10 Restrict
+ %float = OpTypeFloat 32
+ %ptr = OpTypePointer Workgroup %float
+ %10 = OpVariable %ptr Workgroup
+ )"));
+ EXPECT_TRUE(p->BuildAndParseInternalModule());
+ auto decorations = p->GetDecorationsFor(10);
+ EXPECT_TRUE(decorations.empty());
+ EXPECT_TRUE(p->error().empty());
+ p->SkipDumpingPending(kSkipReason);
+}
+
+TEST_F(SpvParserGetDecorationsTest, GetDecorationsForMember_Restrict) {
+ // Restrict applies to a memory object declaration.
+ // But OpMemberDecorate can only be applied to a structure type.
+ // Test the reader's ability to be resilient to more than what SPIR-V allows.
+ auto p = parser(test::Assemble(R"(
+ OpMemberDecorate %10 0 Restrict
+ %float = OpTypeFloat 32
+ %10 = OpTypeStruct %float
+ )"));
+ EXPECT_TRUE(p->BuildAndParseInternalModule());
+ auto decorations = p->GetDecorationsForMember(10, 0);
+ EXPECT_TRUE(decorations.empty());
+ EXPECT_TRUE(p->error().empty());
+ p->SkipDumpingPending(kSkipReason);
+}
+
+TEST_F(SpvParserGetDecorationsTest, GetDecorationsFor_RestrictPointer) {
+ // RestrictPointer applies to a memory object declaration. Use a variable.
+ auto p = parser(test::Assemble(R"(
+ OpDecorate %10 RestrictPointer
+ %float = OpTypeFloat 32
+ %ptr = OpTypePointer Workgroup %float
+ %10 = OpVariable %ptr Workgroup
+ )"));
+ EXPECT_TRUE(p->BuildAndParseInternalModule()) << p->error();
+ auto decorations = p->GetDecorationsFor(10);
+ EXPECT_TRUE(decorations.empty());
+ EXPECT_TRUE(p->error().empty());
+ p->SkipDumpingPending(kSkipReason);
+}
+
+TEST_F(SpvParserGetDecorationsTest, GetDecorationsForMember_RestrictPointer) {
+ // RestrictPointer applies to a memory object declaration.
+ // But OpMemberDecorate can only be applied to a structure type.
+ // Test the reader's ability to be resilient to more than what SPIR-V allows.
+ auto p = parser(test::Assemble(R"(
+ OpMemberDecorate %10 0 RestrictPointer
+ %float = OpTypeFloat 32
+ %10 = OpTypeStruct %float
+ )"));
+ EXPECT_TRUE(p->BuildAndParseInternalModule()) << p->error();
+ auto decorations = p->GetDecorationsFor(10);
+ EXPECT_TRUE(decorations.empty());
+ EXPECT_TRUE(p->error().empty());
+ p->SkipDumpingPending(kSkipReason);
+}
+
} // namespace
} // namespace spirv
} // namespace reader