From f43c464d536360163b78a9cf08ef8dac5fdeb8b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= Date: Tue, 14 Nov 2023 18:49:04 +0100 Subject: [PATCH] opt: add PhysicalStorageBufferAddresses to trim (#5476) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PhysicalStorageBufferAddresses capability can now be trimmed. From the spec, it seems any instruction enabled by this required some operand to have the PhysicalStorageBuffer storage class. This means checking the storage class is enough. Now, because the pass uses the grammar, we don't need to add any new logic. Signed-off-by: Nathan Gauër --- source/opt/trim_capabilities_pass.h | 9 +- test/opt/trim_capabilities_pass_test.cpp | 120 +++++++++++++++++++++++ 2 files changed, 125 insertions(+), 4 deletions(-) diff --git a/source/opt/trim_capabilities_pass.h b/source/opt/trim_capabilities_pass.h index 84eff6ef7..73d5dc80d 100644 --- a/source/opt/trim_capabilities_pass.h +++ b/source/opt/trim_capabilities_pass.h @@ -74,14 +74,18 @@ class TrimCapabilitiesPass : public Pass { // contains unsupported instruction, the pass could yield bad results. static constexpr std::array kSupportedCapabilities{ // clang-format off + spv::Capability::ComputeDerivativeGroupLinearNV, + spv::Capability::ComputeDerivativeGroupQuadsNV, spv::Capability::Float64, spv::Capability::FragmentShaderPixelInterlockEXT, spv::Capability::FragmentShaderSampleInterlockEXT, spv::Capability::FragmentShaderShadingRateInterlockEXT, spv::Capability::Groups, + spv::Capability::ImageMSArray, spv::Capability::Int64, spv::Capability::Linkage, spv::Capability::MinLod, + spv::Capability::PhysicalStorageBufferAddresses, spv::Capability::RayQueryKHR, spv::Capability::RayTracingKHR, spv::Capability::RayTraversalPrimitiveCullingKHR, @@ -91,10 +95,7 @@ class TrimCapabilitiesPass : public Pass { spv::Capability::StorageInputOutput16, spv::Capability::StoragePushConstant16, spv::Capability::StorageUniform16, - spv::Capability::StorageUniformBufferBlock16, - spv::Capability::ImageMSArray, - spv::Capability::ComputeDerivativeGroupQuadsNV, - spv::Capability::ComputeDerivativeGroupLinearNV + spv::Capability::StorageUniformBufferBlock16 // clang-format on }; diff --git a/test/opt/trim_capabilities_pass_test.cpp b/test/opt/trim_capabilities_pass_test.cpp index 5636d5f93..14a8aa3a5 100644 --- a/test/opt/trim_capabilities_pass_test.cpp +++ b/test/opt/trim_capabilities_pass_test.cpp @@ -2366,6 +2366,126 @@ TEST_F(TrimCapabilitiesPassTest, EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); } +TEST_F(TrimCapabilitiesPassTest, PhysicalStorageBuffer_RemovedWhenUnused) { + const std::string kTest = R"( + OpCapability PhysicalStorageBufferAddresses +; CHECK-NOT: OpCapability PhysicalStorageBufferAddresses + OpCapability Shader + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %1 "main" + %void = OpTypeVoid + %3 = OpTypeFunction %void + %1 = OpFunction %void None %3 + %6 = OpLabel + OpReturn + OpFunctionEnd; + )"; + const auto result = + SinglePassRunAndMatch(kTest, /* skip_nop= */ false); + EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); +} + +TEST_F(TrimCapabilitiesPassTest, + PhysicalStorageBuffer_RemainsWithOpTypeForwardPointer) { + const std::string kTest = R"( + OpCapability PhysicalStorageBufferAddresses +; CHECK: OpCapability PhysicalStorageBufferAddresses + OpCapability Shader + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %main "main" + OpExecutionMode %main LocalSize 1 2 4 + %void = OpTypeVoid + %int = OpTypeInt 32 0 + %struct = OpTypeStruct %int + OpTypeForwardPointer %ptr PhysicalStorageBuffer + %ptr = OpTypePointer PhysicalStorageBuffer %struct + %3 = OpTypeFunction %void + %main = OpFunction %void None %3 + %6 = OpLabel + OpReturn + OpFunctionEnd + )"; + const auto result = + SinglePassRunAndMatch(kTest, /* skip_nop= */ false); + EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); +} + +TEST_F(TrimCapabilitiesPassTest, + PhysicalStorageBuffer_RemainsWithPhysicalStorageBufferStorage) { + const std::string kTest = R"( + OpCapability PhysicalStorageBufferAddresses +; CHECK: OpCapability PhysicalStorageBufferAddresses + OpCapability Shader + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %main "main" + OpExecutionMode %main LocalSize 1 2 4 + %void = OpTypeVoid + %int = OpTypeInt 32 0 + %struct = OpTypeStruct %int + %ptr = OpTypePointer PhysicalStorageBuffer %struct + %3 = OpTypeFunction %void + %main = OpFunction %void None %3 + %6 = OpLabel + OpReturn + OpFunctionEnd; + )"; + const auto result = + SinglePassRunAndMatch(kTest, /* skip_nop= */ false); + EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); +} + +TEST_F(TrimCapabilitiesPassTest, + PhysicalStorageBuffer_RemainsWithRestrictDecoration) { + const std::string kTest = R"( + OpCapability PhysicalStorageBufferAddresses +; CHECK: OpCapability PhysicalStorageBufferAddresses + OpCapability Shader + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %main "main" + OpExecutionMode %main LocalSize 1 2 4 + OpDecorate %var RestrictPointer + %void = OpTypeVoid + %int = OpTypeInt 32 0 + %struct = OpTypeStruct %int + %ptr = OpTypePointer Function %struct + %3 = OpTypeFunction %void + %main = OpFunction %void None %3 + %6 = OpLabel + %var = OpVariable %ptr Function + OpReturn + OpFunctionEnd; + )"; + const auto result = + SinglePassRunAndMatch(kTest, /* skip_nop= */ false); + EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); +} + +TEST_F(TrimCapabilitiesPassTest, + PhysicalStorageBuffer_RemainsWithAliasedDecoration) { + const std::string kTest = R"( + OpCapability PhysicalStorageBufferAddresses +; CHECK: OpCapability PhysicalStorageBufferAddresses + OpCapability Shader + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %main "main" + OpExecutionMode %main LocalSize 1 2 4 + OpDecorate %var AliasedPointer + %void = OpTypeVoid + %int = OpTypeInt 32 0 + %struct = OpTypeStruct %int + %ptr = OpTypePointer Function %struct + %3 = OpTypeFunction %void + %main = OpFunction %void None %3 + %6 = OpLabel + %var = OpVariable %ptr Function + OpReturn + OpFunctionEnd; + )"; + const auto result = + SinglePassRunAndMatch(kTest, /* skip_nop= */ false); + EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); +} + } // namespace } // namespace opt } // namespace spvtools