In LICM don't place code between merge instruction and branch. (#2252)

Fixes #2210.
diff --git a/source/opt/licm_pass.cpp b/source/opt/licm_pass.cpp
index c553221..82851fd 100644
--- a/source/opt/licm_pass.cpp
+++ b/source/opt/licm_pass.cpp
@@ -124,7 +124,14 @@
   if (!pre_header_bb) {
     return false;
   }
-  inst->InsertBefore(std::move(&(*pre_header_bb->tail())));
+  Instruction* insertion_point = &*pre_header_bb->tail();
+  Instruction* previous_node = insertion_point->PreviousNode();
+  if (previous_node && (previous_node->opcode() == SpvOpLoopMerge ||
+                        previous_node->opcode() == SpvOpSelectionMerge)) {
+    insertion_point = previous_node;
+  }
+
+  inst->InsertBefore(insertion_point);
   context()->set_instr_block(inst, pre_header_bb);
   return true;
 }
diff --git a/source/opt/licm_pass.h b/source/opt/licm_pass.h
index a94ae11..597fe92 100644
--- a/source/opt/licm_pass.h
+++ b/source/opt/licm_pass.h
@@ -61,7 +61,7 @@
   // Returns true if |bb| is immediately contained in |loop|
   bool IsImmediatelyContainedInLoop(Loop* loop, Function* f, BasicBlock* bb);
 
-  // Move the instruction to the given BasicBlock
+  // Move the instruction to the preheader of |loop|.
   // This method will update the instruction to block mapping for the context
   bool HoistInstruction(Loop* loop, Instruction* inst);
 };
diff --git a/test/opt/loop_optimizations/hoist_single_nested_loops.cpp b/test/opt/loop_optimizations/hoist_single_nested_loops.cpp
index 7fa1fb0..056f3f0 100644
--- a/test/opt/loop_optimizations/hoist_single_nested_loops.cpp
+++ b/test/opt/loop_optimizations/hoist_single_nested_loops.cpp
@@ -158,6 +158,52 @@
   SinglePassRunAndCheck<LICMPass>(before_hoist, after_hoist, true);
 }
 
+TEST_F(PassClassTest, PreHeaderIsAlsoHeader) {
+  // Move OpSLessThan out of the inner loop.  The preheader for the inner loop
+  // is the header of the outer loop.  The loop merge should not be separated
+  // from the branch in that block.
+  const std::string text = R"(
+  ; CHECK: OpFunction
+  ; CHECK-NEXT: OpLabel
+  ; CHECK-NEXT: OpBranch [[header:%\w+]]
+  ; CHECK: [[header]] = OpLabel
+  ; CHECK-NEXT: OpSLessThan %bool %int_1 %int_1
+  ; CHECK-NEXT: OpLoopMerge
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %2 "main"
+               OpExecutionMode %2 OriginUpperLeft
+               OpSource ESSL 310
+       %void = OpTypeVoid
+          %4 = OpTypeFunction %void
+        %int = OpTypeInt 32 1
+      %int_1 = OpConstant %int 1
+       %bool = OpTypeBool
+          %2 = OpFunction %void None %4
+         %18 = OpLabel
+               OpBranch %21
+         %21 = OpLabel
+               OpLoopMerge %22 %23 None
+               OpBranch %24
+         %24 = OpLabel
+         %25 = OpSLessThan %bool %int_1 %int_1
+               OpLoopMerge %26 %27 None
+               OpBranchConditional %25 %27 %26
+         %27 = OpLabel
+               OpBranch %24
+         %26 = OpLabel
+               OpBranch %22
+         %23 = OpLabel
+               OpBranch %21
+         %22 = OpLabel
+               OpReturn
+               OpFunctionEnd
+  )";
+
+  SinglePassRunAndMatch<LICMPass>(text, true);
+}
+
 }  // namespace
 }  // namespace opt
 }  // namespace spvtools