Fix OpLine bug of merge-blocks pass (#3130)

As explained in #3118, spirv-opt merge-blocks pass causes a
spirv-val error when an OpBranch has an OpLine in front of it.

OpLoopMerge
OpBranch ; Will be killed by merge-blocks pass
OpLabel  ; Will be killed by merge-blocks pass
OpLine   ; will be placed between OpLoopMerge and OpBranch - error!
OpBranch

To fix this issue, this commit moves line info of OpBranch to
OpLoopMerge.

Fixes #3118 
diff --git a/source/opt/block_merge_util.cpp b/source/opt/block_merge_util.cpp
index 263a069..14b5d36 100644
--- a/source/opt/block_merge_util.cpp
+++ b/source/opt/block_merge_util.cpp
@@ -171,8 +171,17 @@
       // flow declaration.
       context->KillInst(merge_inst);
     } else {
+      // Move OpLine/OpNoLine information to merge_inst. This solves
+      // the validation error that OpLine is placed between OpLoopMerge
+      // and OpBranchConditional.
+      auto terminator = bi->terminator();
+      auto& vec = terminator->dbg_line_insts();
+      auto& new_vec = merge_inst->dbg_line_insts();
+      new_vec.insert(new_vec.end(), vec.begin(), vec.end());
+      terminator->clear_dbg_line_insts();
+
       // Move the merge instruction to just before the terminator.
-      merge_inst->InsertBefore(bi->terminator());
+      merge_inst->InsertBefore(terminator);
     }
   }
   context->ReplaceAllUsesWith(lab_id, bi->id());
diff --git a/source/opt/instruction.h b/source/opt/instruction.h
index d1c4ce1..322e0aa 100644
--- a/source/opt/instruction.h
+++ b/source/opt/instruction.h
@@ -172,6 +172,9 @@
     return dbg_line_insts_;
   }
 
+  // Clear line-related debug instructions attached to this instruction.
+  void clear_dbg_line_insts() { dbg_line_insts_.clear(); }
+
   // Same semantics as in the base class except the list the InstructionList
   // containing |pos| will now assume ownership of |this|.
   // inline void MoveBefore(Instruction* pos);
diff --git a/test/opt/block_merge_test.cpp b/test/opt/block_merge_test.cpp
index 11fba73..f1460c5 100644
--- a/test/opt/block_merge_test.cpp
+++ b/test/opt/block_merge_test.cpp
@@ -423,6 +423,42 @@
   SinglePassRunAndMatch<BlockMergePass>(text, true);
 }
 
+TEST_F(BlockMergeTest, MergeContinueWithOpLine) {
+  const std::string text = R"(
+; CHECK: OpBranch [[header:%\w+]]
+; CHECK: [[header]] = OpLabel
+; CHECK-NEXT: OpLogicalAnd
+; CHECK-NEXT: OpLine {{%\w+}} 1 1
+; CHECK-NEXT: OpLoopMerge {{%\w+}} [[header]] None
+; CHECK-NEXT: OpBranch [[header]]
+OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %func "func"
+OpExecutionMode %func OriginUpperLeft
+%src = OpString "test.shader"
+%void = OpTypeVoid
+%bool = OpTypeBool
+%true = OpConstantTrue %bool
+%false = OpConstantFalse  %bool
+%functy = OpTypeFunction %void
+%func = OpFunction %void None %functy
+%entry = OpLabel
+OpBranch %header
+%header = OpLabel
+OpLoopMerge %merge %continue None
+OpBranch %continue
+%continue = OpLabel
+%op = OpLogicalAnd %bool %true %false
+OpLine %src 1 1
+OpBranch %header
+%merge = OpLabel
+OpUnreachable
+OpFunctionEnd
+)";
+
+  SinglePassRunAndMatch<BlockMergePass>(text, true);
+}
+
 TEST_F(BlockMergeTest, TwoHeadersCannotBeMerged) {
   const std::string text = R"(
 ; CHECK: OpBranch [[loop_header:%\w+]]