Handle shaders without execution model in spread-volatile-semantics (#4766)
spread-volatile-semantics pass spreads Volatile semantics for builtin
variables used by certain execution models based on
VUID-StandaloneSpirv-VulkanMemoryModel-04678 and
VUID-StandaloneSpirv-VulkanMemoryModel-04679 (See "Standalone SPIR-V
Validation" section of Vulkan spec "Appendix A: Vulkan Environment for
SPIR-V"). Therefore, shaders without execution model (e.g., used only
for linkage) are not the target of the pass. This commit lets the pass
just return SuccessWithoutChange in that case.
diff --git a/source/opt/spread_volatile_semantics.cpp b/source/opt/spread_volatile_semantics.cpp
index 17a4c72..a1d3432 100644
--- a/source/opt/spread_volatile_semantics.cpp
+++ b/source/opt/spread_volatile_semantics.cpp
@@ -92,6 +92,10 @@
} // namespace
Pass::Status SpreadVolatileSemantics::Process() {
+ if (HasNoExecutionModel()) {
+ return Status::SuccessWithoutChange;
+ }
+
if (!HasOnlyEntryPointsAsFunctions(context(), get_module())) {
return Status::Failure;
}
diff --git a/source/opt/spread_volatile_semantics.h b/source/opt/spread_volatile_semantics.h
index 3d0a183..531a21d 100644
--- a/source/opt/spread_volatile_semantics.h
+++ b/source/opt/spread_volatile_semantics.h
@@ -35,6 +35,13 @@
}
private:
+ // Returns true if it does not have an execution model. Linkage shaders do not
+ // have an execution model.
+ bool HasNoExecutionModel() {
+ return get_module()->entry_points().empty() &&
+ context()->get_feature_mgr()->HasCapability(SpvCapabilityLinkage);
+ }
+
// Iterates interface variables and spreads the Volatile semantics if it has
// load instructions for the Volatile semantics.
Pass::Status SpreadVolatileSemanticsToVariables(
diff --git a/test/opt/spread_volatile_semantics_test.cpp b/test/opt/spread_volatile_semantics_test.cpp
index 83b2dcf..fdabd92 100644
--- a/test/opt/spread_volatile_semantics_test.cpp
+++ b/test/opt/spread_volatile_semantics_test.cpp
@@ -1113,6 +1113,26 @@
SinglePassRunAndMatch<SpreadVolatileSemantics>(text, true);
}
+TEST_F(VolatileSpreadTest, SkipIfItHasNoExecutionModel) {
+ const std::string text = R"(
+OpCapability Shader
+OpCapability Linkage
+OpMemoryModel Logical GLSL450
+%2 = OpTypeVoid
+%3 = OpTypeFunction %2
+%4 = OpFunction %2 None %3
+%5 = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ Pass::Status status;
+ std::tie(std::ignore, status) =
+ SinglePassRunToBinary<SpreadVolatileSemantics>(text,
+ /* skip_nop = */ false);
+ EXPECT_EQ(status, Pass::Status::SuccessWithoutChange);
+}
+
} // namespace
} // namespace opt
} // namespace spvtools