GraphicsRobustAccessPass: Set module_status_.modified (#4167)
When calling `replace_index`.
Fixes: #4166
diff --git a/source/opt/graphics_robust_access_pass.cpp b/source/opt/graphics_robust_access_pass.cpp
index 46483e4..1b28f9b 100644
--- a/source/opt/graphics_robust_access_pass.cpp
+++ b/source/opt/graphics_robust_access_pass.cpp
@@ -272,10 +272,11 @@
// Replaces one of the OpAccessChain index operands with a new value.
// Updates def-use analysis.
- auto replace_index = [&inst, def_use_mgr](uint32_t operand_index,
- Instruction* new_value) {
+ auto replace_index = [this, &inst, def_use_mgr](uint32_t operand_index,
+ Instruction* new_value) {
inst.SetOperand(operand_index, {new_value->result_id()});
def_use_mgr->AnalyzeInstUse(&inst);
+ module_status_.modified = true;
return SPV_SUCCESS;
};
diff --git a/test/opt/graphics_robust_access_test.cpp b/test/opt/graphics_robust_access_test.cpp
index 4b2cd44..3c23347 100644
--- a/test/opt/graphics_robust_access_test.cpp
+++ b/test/opt/graphics_robust_access_test.cpp
@@ -1548,6 +1548,105 @@
true);
}
+TEST_F(GraphicsRobustAccessTest, ReplaceIndexReportsChanged) {
+ // A ClusterFuzz generated shader that triggered a
+ // "Binary size unexpectedly changed despite the optimizer saying there was no
+ // change" assertion.
+ // See https://github.com/KhronosGroup/SPIRV-Tools/issues/4166.
+ std::string shader = R"(
+; SPIR-V
+; Version: 1.0
+; Generator: Google Shaderc over Glslang; 245
+; Bound: 41
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "else" %gl_GlobalInvocationID
+ OpExecutionMode %main LocalSize 1 1 3338665985
+ OpSource GLSL 450
+ OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
+ OpSourceExtension "GL_GOOGLE_include_directive"
+ OpName %main "main"
+ OpName %index "index"
+ OpName %gl_GlobalInvocationID "gl_GlobalInvocationID"
+ OpName %S "S"
+ OpMemberName %_struct_24 0 ""
+ OpMemberName %_struct_24 1 ""
+ OpName %Dst "Dst"
+ OpMemberName %Dst 0 "s"
+ OpName %dst "dst"
+ OpName %Src "Src"
+ OpMemberName %Src 0 "s"
+ OpName %src "src"
+ OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
+ OpMemberDecorate %_struct_24 0 Offset 64
+ OpMemberDecorate %_struct_24 1 Offset 8
+ OpDecorate %_arr__struct_24_uint_1 ArrayStride 16
+ OpMemberDecorate %Dst 0 Offset 0
+ OpDecorate %Dst BufferBlock
+ OpDecorate %dst DescriptorSet 0
+ OpDecorate %dst Binding 1
+ OpDecorate %_arr__struct_24_uint_1_0 ArrayStride 16
+ OpMemberDecorate %Src 0 Offset 0
+ OpDecorate %Src Block
+ OpDecorate %src DescriptorSet 0
+ OpDecorate %src Binding 0
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+ %v3uint = OpTypeVector %uint 3
+%_ptr_Input_v3uint = OpTypePointer Input %v3uint
+%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
+ %uint_4864 = OpConstant %uint 4864
+%_ptr_Input_uint = OpTypePointer Input %uint
+ %uint_1 = OpConstant %uint 1
+ %bool = OpTypeBool
+ %v2uint = OpTypeVector %uint 2
+ %_struct_24 = OpTypeStruct %_ptr_Input_uint %v2uint
+%_arr__struct_24_uint_1 = OpTypeArray %_struct_24 %uint_1
+ %Dst = OpTypeStruct %_arr__struct_24_uint_1
+%_ptr_Uniform_Dst = OpTypePointer Uniform %Dst
+ %dst = OpVariable %_ptr_Uniform_Dst Uniform
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+%_arr__struct_24_uint_1_0 = OpTypeArray %_struct_24 %uint_1
+ %Src = OpTypeStruct %_arr__struct_24_uint_1_0
+%_ptr_Uniform_Src = OpTypePointer Uniform %Src
+ %src = OpVariable %_ptr_Uniform_Src Uniform
+%_ptr_Uniform__struct_24 = OpTypePointer Uniform %_struct_24
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %index = OpVariable %_ptr_Function_uint Function
+ %14 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_4864
+ %15 = OpLoad %uint %14
+ OpStore %index %15
+ %16 = OpLoad %uint %index
+ %S = OpUGreaterThanEqual %bool %16 %uint_1
+ OpSelectionMerge %21 None
+ OpBranchConditional %S %20 %21
+ %20 = OpLabel
+ OpReturn
+ %21 = OpLabel
+ %31 = OpLoad %uint %index
+ %36 = OpLoad %uint %index
+ %38 = OpAccessChain %_ptr_Uniform__struct_24 %src %int_0 %36
+ %39 = OpLoad %_struct_24 %38
+ %40 = OpAccessChain %_ptr_Uniform__struct_24 %dst %int_0 %31
+ OpStore %40 %39
+ OpReturn
+ OpFunctionEnd
+)";
+
+ std::vector<uint32_t> optimized_bin;
+ auto status = spvtools::opt::Pass::Status::Failure;
+ std::tie(optimized_bin, status) =
+ SinglePassRunToBinary<GraphicsRobustAccessPass>(shader, false);
+ // Check whether the pass returns the correct modification indication.
+ EXPECT_EQ(status, spvtools::opt::Pass::Status::SuccessWithChange);
+}
+
// TODO(dneto): Test access chain index wider than 64 bits?
// TODO(dneto): Test struct access chain index wider than 64 bits?
// TODO(dneto): OpImageTexelPointer