From 3a8a961cffb7699422a05dcbafdd721226b4547d Mon Sep 17 00:00:00 2001 From: Cassandra Beckley Date: Thu, 11 Aug 2022 09:59:37 -0700 Subject: [PATCH] Fix array copy propagation (#4890) Array copy propagation was interpreting OpEntryPoint as a store --- source/opt/copy_prop_arrays.cpp | 2 ++ source/opt/copy_prop_arrays.h | 2 +- test/opt/copy_prop_array_test.cpp | 45 +++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/source/opt/copy_prop_arrays.cpp b/source/opt/copy_prop_arrays.cpp index 321d4969..1c30138e 100644 --- a/source/opt/copy_prop_arrays.cpp +++ b/source/opt/copy_prop_arrays.cpp @@ -168,6 +168,8 @@ bool CopyPropagateArrays::HasNoStores(Instruction* ptr_inst) { return false; } else if (use->opcode() == SpvOpImageTexelPointer) { return true; + } else if (use->opcode() == SpvOpEntryPoint) { + return true; } // Some other instruction. Be conservative. return false; diff --git a/source/opt/copy_prop_arrays.h b/source/opt/copy_prop_arrays.h index 46a508cf..07747c10 100644 --- a/source/opt/copy_prop_arrays.h +++ b/source/opt/copy_prop_arrays.h @@ -195,7 +195,7 @@ class CopyPropagateArrays : public MemPass { // Return true if |type_id| is a pointer type whose pointee type is an array. bool IsPointerToArrayType(uint32_t type_id); - // Returns true of there are not stores using |ptr_inst| or something derived + // Returns true if there are not stores using |ptr_inst| or something derived // from it. bool HasNoStores(Instruction* ptr_inst); diff --git a/test/opt/copy_prop_array_test.cpp b/test/opt/copy_prop_array_test.cpp index a4599f0f..f322f4ad 100644 --- a/test/opt/copy_prop_array_test.cpp +++ b/test/opt/copy_prop_array_test.cpp @@ -1839,6 +1839,51 @@ OpFunctionEnd SinglePassRunAndCheck(text, text, false); } + +// Since Spir-V 1.4, resources that are used by a shader must be on the +// OpEntryPoint instruction with the inputs and outputs. This test ensures that +// this does not stop the pass from working. +TEST_F(CopyPropArrayPassTest, EntryPointUser) { + const std::string before = R"(OpCapability Shader +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %main "main" %g_rwTexture3d +OpExecutionMode %main LocalSize 256 1 1 +OpSource HLSL 660 +OpName %type_3d_image "type.3d.image" +OpName %g_rwTexture3d "g_rwTexture3d" +OpName %main "main" +OpDecorate %g_rwTexture3d DescriptorSet 0 +OpDecorate %g_rwTexture3d Binding 0 +%uint = OpTypeInt 32 0 +%uint_0 = OpConstant %uint 0 +%uint_1 = OpConstant %uint 1 +%uint_2 = OpConstant %uint 2 +%uint_3 = OpConstant %uint 3 +%v3uint = OpTypeVector %uint 3 +%10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 +%type_3d_image = OpTypeImage %uint 3D 2 0 0 2 R32ui +%_ptr_UniformConstant_type_3d_image = OpTypePointer UniformConstant %type_3d_image +%void = OpTypeVoid +%13 = OpTypeFunction %void +%_ptr_Function_type_3d_image = OpTypePointer Function %type_3d_image +%_ptr_Image_uint = OpTypePointer Image %uint +%g_rwTexture3d = OpVariable %_ptr_UniformConstant_type_3d_image UniformConstant +%main = OpFunction %void None %13 +%16 = OpLabel +%17 = OpVariable %_ptr_Function_type_3d_image Function +%18 = OpLoad %type_3d_image %g_rwTexture3d +OpStore %17 %18 +; CHECK: %19 = OpImageTexelPointer %_ptr_Image_uint %g_rwTexture3d %10 %uint_0 +%19 = OpImageTexelPointer %_ptr_Image_uint %17 %10 %uint_0 +%20 = OpAtomicIAdd %uint %19 %uint_1 %uint_0 %uint_1 +OpReturn +OpFunctionEnd +)"; + + SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); + SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); + SinglePassRunAndMatch(before, false); +} } // namespace } // namespace opt } // namespace spvtools -- 2.37.2