Debug info preservation in if-conversion pass (#3861)

* Debug info preservation in if-conversion pass
diff --git a/source/opt/if_conversion.cpp b/source/opt/if_conversion.cpp
index 104182b..4284069 100644
--- a/source/opt/if_conversion.cpp
+++ b/source/opt/if_conversion.cpp
@@ -129,6 +129,7 @@
         Instruction* select = builder.AddSelect(phi->type_id(), condition,
                                                 true_value->result_id(),
                                                 false_value->result_id());
+        select->UpdateDebugInfoFrom(phi);
         context()->ReplaceAllUsesWith(phi->result_id(), select->result_id());
         to_kill.push_back(phi);
         modified = true;
diff --git a/test/opt/if_conversion_test.cpp b/test/opt/if_conversion_test.cpp
index aa5adea..dee15c3 100644
--- a/test/opt/if_conversion_test.cpp
+++ b/test/opt/if_conversion_test.cpp
@@ -504,6 +504,59 @@
   SinglePassRunAndCheck<IfConversion>(text, text, true, true);
 }
 
+TEST_F(IfConversionTest, DebugInfoSimpleIfThenElse) {
+  // When it replaces an OpPhi with OpSelect, the new OpSelect must have
+  // the same scope and line information with the OpPhi.
+  const std::string text = R"(
+; CHECK: OpSelectionMerge [[merge:%\w+]]
+; CHECK: [[merge]] = OpLabel
+; CHECK-NOT: OpPhi
+; CHECK: DebugScope
+; CHECK-NEXT: OpLine {{%\w+}} 3 7
+; CHECK-NEXT: [[sel:%\w+]] = OpSelect %uint %true %uint_0 %uint_1
+; CHECK-NEXT: DebugValue {{%\w+}} [[sel]]
+; CHECK: OpStore {{%\w+}} [[sel]]
+OpCapability Shader
+%ext = OpExtInstImport "OpenCL.DebugInfo.100"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %1 "func" %2
+%name = OpString "test"
+%void = OpTypeVoid
+%bool = OpTypeBool
+%true = OpConstantTrue %bool
+%uint = OpTypeInt 32 0
+%uint_0 = OpConstant %uint 0
+%uint_1 = OpConstant %uint 1
+%uint_32 = OpConstant %uint 32
+%_ptr_Output_uint = OpTypePointer Output %uint
+%2 = OpVariable %_ptr_Output_uint Output
+%11 = OpTypeFunction %void
+%null_expr = OpExtInst %void %ext DebugExpression
+%src = OpExtInst %void %ext DebugSource %name
+%cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL
+%dbg_tf = OpExtInst %void %ext DebugTypeBasic %name %uint_32 Float
+%dbg_f = OpExtInst %void %ext DebugLocalVariable %name %dbg_tf %src 0 0 %cu FlagIsLocal
+%1 = OpFunction %void None %11
+%12 = OpLabel
+OpSelectionMerge %14 None
+OpBranchConditional %true %15 %16
+%15 = OpLabel
+OpBranch %14
+%16 = OpLabel
+OpBranch %14
+%14 = OpLabel
+%scope = OpExtInst %void %ext DebugScope %cu
+OpLine %name 3 7
+%18 = OpPhi %uint %uint_0 %15 %uint_1 %16
+%value = OpExtInst %void %ext DebugValue %dbg_f %18 %null_expr
+OpStore %2 %18
+OpReturn
+OpFunctionEnd
+)";
+
+  SinglePassRunAndMatch<IfConversion>(text, true);
+}
+
 }  // namespace
 }  // namespace opt
 }  // namespace spvtools