Handle unreachable block when computing register pressure (#3070)
Fixes #3053
diff --git a/source/opt/register_pressure.cpp b/source/opt/register_pressure.cpp
index 34dac1d..cb24674 100644
--- a/source/opt/register_pressure.cpp
+++ b/source/opt/register_pressure.cpp
@@ -78,9 +78,16 @@
// - Second, walk loop forest to propagate registers crossing back-edges
// (add iterative values into the liveness set).
void Compute() {
- cfg_.ForEachBlockInPostOrder(&*function_->begin(), [this](BasicBlock* bb) {
- ComputePartialLiveness(bb);
- });
+ for (BasicBlock& start_bb : *function_) {
+ if (reg_pressure_->Get(start_bb.id()) != nullptr) {
+ continue;
+ }
+ cfg_.ForEachBlockInPostOrder(&start_bb, [this](BasicBlock* bb) {
+ if (reg_pressure_->Get(bb->id()) == nullptr) {
+ ComputePartialLiveness(bb);
+ }
+ });
+ }
DoLoopLivenessUnification();
EvaluateRegisterRequirements();
}
diff --git a/test/opt/register_liveness.cpp b/test/opt/register_liveness.cpp
index cb973d2..7cb210f 100644
--- a/test/opt/register_liveness.cpp
+++ b/test/opt/register_liveness.cpp
@@ -1277,6 +1277,46 @@
}
}
+// Test that register liveness does not fail when there is an unreachable block.
+// We are not testing if the liveness is computed correctly because the specific
+// results do not matter for unreachable blocks.
+TEST_F(PassClassTest, RegisterLivenessWithUnreachableBlock) {
+ const std::string text = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main"
+ OpExecutionMode %2 OriginLowerLeft
+ OpSource GLSL 330
+ OpSourceExtension "GL_ARB_shading_language_420pack"
+ %void = OpTypeVoid
+ %4 = OpTypeFunction %void
+ %2 = OpFunction %void None %4
+ %5 = OpLabel
+ OpBranch %6
+ %6 = OpLabel
+ OpLoopMerge %7 %8 None
+ OpBranch %9
+ %9 = OpLabel
+ OpBranch %7
+ %8 = OpLabel
+ OpBranch %6
+ %7 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ std::unique_ptr<IRContext> context =
+ BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ Module* module = context->module();
+ EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
+ << text << std::endl;
+ Function* f = &*module->begin();
+ LivenessAnalysis* liveness_analysis = context->GetLivenessAnalysis();
+ liveness_analysis->Get(f);
+}
+
} // namespace
} // namespace opt
} // namespace spvtools