Tests for preserving line debug insts even killing its affecting targets.
diff --git a/source/opt/module.cpp b/source/opt/module.cpp
index 0846012..c061ae1 100644
--- a/source/opt/module.cpp
+++ b/source/opt/module.cpp
@@ -116,7 +116,7 @@
   binary->push_back(header_.reserved);
 
   auto write_inst = [this, binary, skip_nop](const Instruction* i) {
-    if (!skip_nop || !i->IsNop()) i->ToBinaryWithoutAttachedDebugInsts(binary);
+    if (!(skip_nop && i->IsNop())) i->ToBinaryWithoutAttachedDebugInsts(binary);
   };
   ForEachInst(write_inst, true);
 }
diff --git a/test/opt/CMakeLists.txt b/test/opt/CMakeLists.txt
index 6fb9e27..d17f233 100644
--- a/test/opt/CMakeLists.txt
+++ b/test/opt/CMakeLists.txt
@@ -99,4 +99,9 @@
 add_spvtools_unittest(TARGET pass_unify_const
   SRCS test_unify_const.cpp
   LIBS SPIRV-Tools-opt ${SPIRV_TOOLS}
-)
\ No newline at end of file
+)
+
+add_spvtools_unittest(TARGET line_debug_info
+  SRCS test_line_debug_info.cpp pass_utils.cpp
+  LIBS SPIRV-Tools-opt ${SPIRV_TOOLS}
+)
diff --git a/test/opt/test_line_debug_info.cpp b/test/opt/test_line_debug_info.cpp
new file mode 100644
index 0000000..4f561a7
--- /dev/null
+++ b/test/opt/test_line_debug_info.cpp
@@ -0,0 +1,118 @@
+// Copyright (c) 2016 Google Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and/or associated documentation files (the
+// "Materials"), to deal in the Materials without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Materials, and to
+// permit persons to whom the Materials are furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Materials.
+//
+// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS
+// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS
+// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT
+//    https://www.khronos.org/registry/
+//
+// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+
+#include "pass_fixture.h"
+#include "pass_utils.h"
+
+namespace {
+
+using namespace spvtools;
+
+// A pass turning all none debug line instructions into Nop.
+class NopifyPass : public opt::Pass {
+ public:
+  const char* name() const override { return "NopifyPass"; }
+  bool Process(ir::Module* module) override {
+    module->ForEachInst([](ir::Instruction* inst) { inst->ToNop(); },
+                        /* run_on_debug_line_insts = */ false);
+    return true;
+  }
+};
+
+using PassTestForLineDebugInfo = PassTest<::testing::Test>;
+
+// This test's purpose to show our implementation choice: line debug info is
+// preserved even if the following instruction is killed. It serves as a guard
+// of potential behavior changes.
+TEST_F(PassTestForLineDebugInfo, KeepLineDebugInfo) {
+  // clang-format off
+  const char* text =
+               "OpCapability Shader "
+          "%1 = OpExtInstImport \"GLSL.std.450\" "
+               "OpMemoryModel Logical GLSL450 "
+               "OpEntryPoint Vertex %2 \"main\" "
+          "%3 = OpString \"minimal.vert\" "
+               "OpNoLine "
+               "OpLine %3 10 10 "
+       "%void = OpTypeVoid "
+               "OpLine %3 100 100 "
+          "%5 = OpTypeFunction %void "
+          "%2 = OpFunction %void None %5 "
+               "OpLine %3 1 1 "
+               "OpNoLine "
+               "OpLine %3 2 2 "
+               "OpLine %3 3 3 "
+          "%6 = OpLabel "
+               "OpLine %3 4 4 "
+               "OpNoLine "
+               "OpReturn "
+               "OpLine %3 4 4 "
+               "OpNoLine "
+               "OpFunctionEnd ";
+  // clang-format on
+
+  const char* result_keep_nop =
+      "OpNop\n"
+      "OpNop\n"
+      "OpNop\n"
+      "OpNop\n"
+      "OpNop\n"
+      "OpNoLine\n"
+      "OpLine %3 10 10\n"
+      "OpNop\n"
+      "OpLine %3 100 100\n"
+      "OpNop\n"
+      "OpNop\n"
+      "OpLine %3 1 1\n"
+      "OpNoLine\n"
+      "OpLine %3 2 2\n"
+      "OpLine %3 3 3\n"
+      "OpNop\n"
+      "OpLine %3 4 4\n"
+      "OpNoLine\n"
+      "OpNop\n"
+      "OpLine %3 4 4\n"
+      "OpNoLine\n"
+      "OpNop\n";
+  SinglePassRunAndCheck<NopifyPass>(text, result_keep_nop,
+                                    /* skip_nop = */ false);
+  const char* result_skip_nop =
+      "OpNoLine\n"
+      "OpLine %3 10 10\n"
+      "OpLine %3 100 100\n"
+      "OpLine %3 1 1\n"
+      "OpNoLine\n"
+      "OpLine %3 2 2\n"
+      "OpLine %3 3 3\n"
+      "OpLine %3 4 4\n"
+      "OpNoLine\n"
+      "OpLine %3 4 4\n"
+      "OpNoLine\n";
+  SinglePassRunAndCheck<NopifyPass>(text, result_skip_nop,
+                                    /* skip_nop = */ true);
+}
+
+}  // anonymous namespace