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