Skip to content

Commit

Permalink
opt: Mark InterpolateAt* argument as live for DCE (#5824)
Browse files Browse the repository at this point in the history
The GLSL 450 InterpolateAt* instructions should be treated as a load by dead code elimination. This is part of microsoft/DirectXShaderCompiler#3649.
  • Loading branch information
cassiebeckley authored Sep 26, 2024
1 parent 5b38abc commit b1ad37b
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 0 deletions.
16 changes: 16 additions & 0 deletions source/opt/aggressive_dead_code_elim_pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
Expand Down
127 changes: 127 additions & 0 deletions test/opt/aggressive_dead_code_elim_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8106,6 +8106,133 @@ OpFunctionEnd
SinglePassRunAndCheck<AggressiveDCEPass>(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<AggressiveDCEPass>(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<AggressiveDCEPass>(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<AggressiveDCEPass>(spirv, spirv, true, false);
}

} // namespace
} // namespace opt
} // namespace spvtools

0 comments on commit b1ad37b

Please sign in to comment.