Keep DebugBuildIdentifier during dce (#6166)
It is expected that no other instructions should refer to the
DebugBuildIdentifier instruction, but this causes it to be removed
during dead code elimination. Instead keep the instruction if it is
found.
diff --git a/source/opt/aggressive_dead_code_elim_pass.cpp b/source/opt/aggressive_dead_code_elim_pass.cpp
index 3bb573c..490a487 100644
--- a/source/opt/aggressive_dead_code_elim_pass.cpp
+++ b/source/opt/aggressive_dead_code_elim_pass.cpp
@@ -914,6 +914,10 @@
context()->AnalyzeUses(&dbg);
continue;
}
+ // Save debug build identifier even if no other instructions refer to it.
+ if (dbg.GetShader100DebugOpcode() ==
+ NonSemanticShaderDebugInfo100DebugBuildIdentifier)
+ continue;
to_kill_.push_back(&dbg);
modified = true;
}
diff --git a/test/opt/optimizer_test.cpp b/test/opt/optimizer_test.cpp
index 49d4f8f..3e5fd5f 100644
--- a/test/opt/optimizer_test.cpp
+++ b/test/opt/optimizer_test.cpp
@@ -506,6 +506,72 @@
EXPECT_EQ(test_disassembly, default_disassembly);
}
+TEST(Optimizer, KeepDebugBuildIdentifierAfterDCE) {
+ // Test that DebugBuildIdentifier is not removed after DCE.
+ const std::string before = R"(
+OpCapability Shader
+OpExtension "SPV_KHR_non_semantic_info"
+%1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 8 8 1
+%4 = OpString "8937d8f571cf7b58d86d9d66196024f5d04e3186"
+%7 = OpString ""
+%9 = OpString ""
+OpSource Slang 1
+%19 = OpString ""
+%24 = OpString ""
+%25 = OpString ""
+OpName %main "main"
+%void = OpTypeVoid
+%uint = OpTypeInt 32 0
+%uint_0 = OpConstant %uint 0
+%uint_11 = OpConstant %uint 11
+%uint_5 = OpConstant %uint 5
+%uint_100 = OpConstant %uint 100
+%15 = OpTypeFunction %void
+%uint_6 = OpConstant %uint 6
+%uint_7 = OpConstant %uint 7
+%uint_1 = OpConstant %uint 1
+%uint_2 = OpConstant %uint 2
+%3 = OpExtInst %void %1 DebugBuildIdentifier %4 %uint_0
+%8 = OpExtInst %void %1 DebugSource %9 %7
+%13 = OpExtInst %void %1 DebugCompilationUnit %uint_100 %uint_5 %8 %uint_11
+%17 = OpExtInst %void %1 DebugTypeFunction %uint_0 %void
+%18 = OpExtInst %void %1 DebugFunction %19 %17 %8 %uint_5 %uint_6 %13 %19 %uint_0 %uint_5
+%23 = OpExtInst %void %1 DebugEntryPoint %18 %13 %24 %25
+%main = OpFunction %void None %15
+%16 = OpLabel
+%21 = OpExtInst %void %1 DebugFunctionDefinition %18 %main
+%32 = OpExtInst %void %1 DebugScope %18
+%26 = OpExtInst %void %1 DebugLine %8 %uint_7 %uint_7 %uint_1 %uint_2
+OpReturn
+%33 = OpExtInst %void %1 DebugNoScope
+OpFunctionEnd
+ )";
+
+ std::vector<uint32_t> binary;
+ SpirvTools tools(SPV_ENV_VULKAN_1_3);
+ tools.Assemble(before, &binary,
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+
+ Optimizer opt(SPV_ENV_VULKAN_1_3);
+ opt.RegisterPerformancePasses().RegisterPass(CreateAggressiveDCEPass());
+
+ std::vector<uint32_t> optimized;
+ ASSERT_TRUE(opt.Run(binary.data(), binary.size(), &optimized))
+ << before << "\n";
+
+ std::string after;
+ tools.Disassemble(optimized.data(), optimized.size(), &after,
+ SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+
+ // Test that the DebugBuildIdentifier is not removed after DCE.
+ bool found = after.find("DebugBuildIdentifier") != std::string::npos;
+ EXPECT_TRUE(found)
+ << "Was expecting the DebugBuildIdentifier to have been kept.";
+}
+
} // namespace
} // namespace opt
} // namespace spvtools