From b1ad37b175940db03ee4e1fee9a14cc349281ec1 Mon Sep 17 00:00:00 2001 From: Cassandra Beckley Date: Thu, 26 Sep 2024 13:49:36 -0700 Subject: [PATCH] opt: Mark InterpolateAt* argument as live for DCE (#5824) The GLSL 450 InterpolateAt* instructions should be treated as a load by dead code elimination. This is part of https://github.com/microsoft/DirectXShaderCompiler/issues/3649. --- source/opt/aggressive_dead_code_elim_pass.cpp | 16 +++ test/opt/aggressive_dead_code_elim_test.cpp | 127 ++++++++++++++++++ 2 files changed, 143 insertions(+) diff --git a/source/opt/aggressive_dead_code_elim_pass.cpp b/source/opt/aggressive_dead_code_elim_pass.cpp index 953a7f5a3f..79654224ac 100644 --- a/source/opt/aggressive_dead_code_elim_pass.cpp +++ b/source/opt/aggressive_dead_code_elim_pass.cpp @@ -40,6 +40,9 @@ constexpr uint32_t kCopyMemorySourceAddrInIdx = 1; constexpr uint32_t kLoadSourceAddrInIdx = 0; constexpr uint32_t kDebugDeclareOperandVariableIndex = 5; constexpr uint32_t kGlobalVariableVariableIndex = 12; +constexpr uint32_t kExtInstSetInIdx = 0; +constexpr uint32_t kExtInstOpInIdx = 1; +constexpr uint32_t kInterpolantInIdx = 2; // Sorting functor to present annotation instructions in an easy-to-process // order. The functor orders by opcode first and falls back on unique id @@ -422,6 +425,19 @@ uint32_t AggressiveDCEPass::GetLoadedVariableFromNonFunctionCalls( case spv::Op::OpCopyMemorySized: return GetVariableId( inst->GetSingleWordInOperand(kCopyMemorySourceAddrInIdx)); + case spv::Op::OpExtInst: { + if (inst->GetSingleWordInOperand(kExtInstSetInIdx) == + context()->get_feature_mgr()->GetExtInstImportId_GLSLstd450()) { + auto ext_inst = inst->GetSingleWordInOperand(kExtInstOpInIdx); + switch (ext_inst) { + case GLSLstd450InterpolateAtCentroid: + case GLSLstd450InterpolateAtOffset: + case GLSLstd450InterpolateAtSample: + return inst->GetSingleWordInOperand(kInterpolantInIdx); + } + } + break; + } default: break; } diff --git a/test/opt/aggressive_dead_code_elim_test.cpp b/test/opt/aggressive_dead_code_elim_test.cpp index a4353b1b88..5b88117ee9 100644 --- a/test/opt/aggressive_dead_code_elim_test.cpp +++ b/test/opt/aggressive_dead_code_elim_test.cpp @@ -8106,6 +8106,133 @@ OpFunctionEnd SinglePassRunAndCheck(text, text, true, true); } +TEST_F(AggressiveDCETest, MarkCentroidInterpolantLive) { + const std::string spirv = + R"(OpCapability InterpolationFunction +OpCapability Shader +%1 = OpExtInstImport "GLSL.std.450" +OpMemoryModel Logical GLSL450 +OpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_Target +OpExecutionMode %main OriginUpperLeft +OpSource HLSL 680 +OpName %in_var_COLOR "in.var.COLOR" +OpName %out_var_SV_Target "out.var.SV_Target" +OpName %main "main" +OpName %param_var_p1 "param.var.p1" +OpDecorate %in_var_COLOR Location 0 +OpDecorate %out_var_SV_Target Location 0 +%float = OpTypeFloat 32 +%v4float = OpTypeVector %float 4 +%_ptr_Input_v4float = OpTypePointer Input %v4float +%_ptr_Output_v4float = OpTypePointer Output %v4float +%void = OpTypeVoid +%11 = OpTypeFunction %void +%_ptr_Function_v4float = OpTypePointer Function %v4float +%in_var_COLOR = OpVariable %_ptr_Input_v4float Input +%out_var_SV_Target = OpVariable %_ptr_Output_v4float Output +%main = OpFunction %void None %11 +%13 = OpLabel +%14 = OpVariable %_ptr_Function_v4float Function +%param_var_p1 = OpVariable %_ptr_Function_v4float Function +%15 = OpLoad %v4float %in_var_COLOR +OpStore %param_var_p1 %15 +%16 = OpExtInst %v4float %1 InterpolateAtCentroid %param_var_p1 +OpStore %14 %16 +%17 = OpLoad %v4float %14 +OpStore %out_var_SV_Target %17 +OpReturn +OpFunctionEnd +)"; + + SinglePassRunAndCheck(spirv, spirv, true, false); +} + +TEST_F(AggressiveDCETest, MarkSampleInterpolantLive) { + const std::string spirv = + R"(OpCapability InterpolationFunction +OpCapability Shader +%1 = OpExtInstImport "GLSL.std.450" +OpMemoryModel Logical GLSL450 +OpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_Target +OpExecutionMode %main OriginUpperLeft +OpSource HLSL 680 +OpName %in_var_COLOR "in.var.COLOR" +OpName %out_var_SV_Target "out.var.SV_Target" +OpName %main "main" +OpName %param_var_p1 "param.var.p1" +OpDecorate %in_var_COLOR Location 0 +OpDecorate %out_var_SV_Target Location 0 +%float = OpTypeFloat 32 +%int = OpTypeInt 32 1 +%v4float = OpTypeVector %float 4 +%_ptr_Input_v4float = OpTypePointer Input %v4float +%_ptr_Output_v4float = OpTypePointer Output %v4float +%void = OpTypeVoid +%12 = OpTypeFunction %void +%_ptr_Function_v4float = OpTypePointer Function %v4float +%in_var_COLOR = OpVariable %_ptr_Input_v4float Input +%out_var_SV_Target = OpVariable %_ptr_Output_v4float Output +%int_123 = OpConstant %int 123 +%main = OpFunction %void None %12 +%15 = OpLabel +%16 = OpVariable %_ptr_Function_v4float Function +%param_var_p1 = OpVariable %_ptr_Function_v4float Function +%17 = OpLoad %v4float %in_var_COLOR +OpStore %param_var_p1 %17 +%18 = OpExtInst %v4float %1 InterpolateAtSample %param_var_p1 %int_123 +OpStore %16 %18 +%19 = OpLoad %v4float %16 +OpStore %out_var_SV_Target %19 +OpReturn +OpFunctionEnd +)"; + + SinglePassRunAndCheck(spirv, spirv, true, false); +} + +TEST_F(AggressiveDCETest, MarkOffsetInterpolantLive) { + const std::string spirv = + R"(OpCapability InterpolationFunction +OpCapability Shader +%1 = OpExtInstImport "GLSL.std.450" +OpMemoryModel Logical GLSL450 +OpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_Target +OpExecutionMode %main OriginUpperLeft +OpSource HLSL 680 +OpName %in_var_COLOR "in.var.COLOR" +OpName %out_var_SV_Target "out.var.SV_Target" +OpName %main "main" +OpName %param_var_p1 "param.var.p1" +OpDecorate %in_var_COLOR Location 0 +OpDecorate %out_var_SV_Target Location 0 +%float = OpTypeFloat 32 +%int = OpTypeInt 32 1 +%v4float = OpTypeVector %float 4 +%_ptr_Input_v4float = OpTypePointer Input %v4float +%_ptr_Output_v4float = OpTypePointer Output %v4float +%void = OpTypeVoid +%12 = OpTypeFunction %void +%_ptr_Function_v4float = OpTypePointer Function %v4float +%in_var_COLOR = OpVariable %_ptr_Input_v4float Input +%out_var_SV_Target = OpVariable %_ptr_Output_v4float Output +%int_123 = OpConstant %int 123 +%main = OpFunction %void None %12 +%15 = OpLabel +%16 = OpVariable %_ptr_Function_v4float Function +%param_var_p1 = OpVariable %_ptr_Function_v4float Function +%17 = OpLoad %v4float %in_var_COLOR +OpStore %param_var_p1 %17 +%18 = OpExtInst %v4float %1 InterpolateAtOffset %param_var_p1 %int_123 +OpStore %16 %18 +%19 = OpLoad %v4float %16 +OpStore %out_var_SV_Target %19 +OpReturn +OpFunctionEnd +)"; + + SinglePassRunAndCheck(spirv, spirv, true, false); +} + } // namespace } // namespace opt } // namespace spvtools