Browse Source

[spirv] use presumed loc for line info (#2344)

Fixes #2333
Jaebaek Seo 6 years ago
parent
commit
4f457e34fa
22 changed files with 493 additions and 322 deletions
  1. 26 15
      tools/clang/include/clang/SPIRV/SpirvBuilder.h
  2. 1 1
      tools/clang/include/clang/SPIRV/SpirvModule.h
  3. 54 20
      tools/clang/lib/SPIRV/EmitVisitor.cpp
  4. 14 9
      tools/clang/lib/SPIRV/EmitVisitor.h
  5. 7 5
      tools/clang/lib/SPIRV/SpirvEmitter.cpp
  6. 14 10
      tools/clang/lib/SPIRV/SpirvModule.cpp
  7. 19 22
      tools/clang/test/CodeGenSPIRV/spirv.debug.opline.branch.hlsl
  8. 17 17
      tools/clang/test/CodeGenSPIRV/spirv.debug.opline.composite.hlsl
  9. 13 18
      tools/clang/test/CodeGenSPIRV/spirv.debug.opline.entry.hlsl
  10. 38 38
      tools/clang/test/CodeGenSPIRV/spirv.debug.opline.function.hlsl
  11. 12 17
      tools/clang/test/CodeGenSPIRV/spirv.debug.opline.hlsl
  12. 3 0
      tools/clang/test/CodeGenSPIRV/spirv.debug.opline.include-file-1.hlsl
  13. 4 0
      tools/clang/test/CodeGenSPIRV/spirv.debug.opline.include-file-2.hlsl
  14. 8 0
      tools/clang/test/CodeGenSPIRV/spirv.debug.opline.include-file-3.hlsl
  15. 125 0
      tools/clang/test/CodeGenSPIRV/spirv.debug.opline.include.hlsl
  16. 3 7
      tools/clang/test/CodeGenSPIRV/spirv.debug.opline.intrinsic.control.barrier.hlsl
  17. 52 55
      tools/clang/test/CodeGenSPIRV/spirv.debug.opline.intrinsic.hlsl
  18. 13 15
      tools/clang/test/CodeGenSPIRV/spirv.debug.opline.intrinsic.vulkan1.1.hlsl
  19. 47 50
      tools/clang/test/CodeGenSPIRV/spirv.debug.opline.operators.hlsl
  20. 2 2
      tools/clang/test/CodeGenSPIRV/spirv.debug.opline.precedence.hlsl
  21. 18 21
      tools/clang/test/CodeGenSPIRV/spirv.debug.opline.variables.hlsl
  22. 3 0
      tools/clang/unittests/SPIRV/CodeGenSpirvTest.cpp

+ 26 - 15
tools/clang/include/clang/SPIRV/SpirvBuilder.h

@@ -423,7 +423,7 @@ public:
   /// \brief Sets the shader model version, source file name, and source file
   /// content. Returns the SpirvString instruction of the file name.
   inline SpirvString *setDebugSource(uint32_t major, uint32_t minor,
-                                     llvm::StringRef name,
+                                     const std::vector<llvm::StringRef> &name,
                                      llvm::StringRef content);
 
   /// \brief Adds an execution mode to the module under construction.
@@ -613,22 +613,33 @@ void SpirvBuilder::addEntryPoint(spv::ExecutionModel em, SpirvFunction *target,
       target->getSourceLocation(), em, target, targetName, interfaces));
 }
 
-SpirvString *SpirvBuilder::setDebugSource(uint32_t major, uint32_t minor,
-                                          llvm::StringRef name,
-                                          llvm::StringRef content) {
+SpirvString *
+SpirvBuilder::setDebugSource(uint32_t major, uint32_t minor,
+                             const std::vector<llvm::StringRef> &fileNames,
+                             llvm::StringRef content) {
   uint32_t version = 100 * major + 10 * minor;
+  SpirvSource *mainSource = nullptr;
+  for (const auto &name : fileNames) {
+    SpirvString *fileString =
+        name.empty() ? nullptr
+                     : new (context) SpirvString(/*SourceLocation*/ {}, name);
+    SpirvSource *debugSource = new (context)
+        SpirvSource(/*SourceLocation*/ {}, spv::SourceLanguage::HLSL, version,
+                    fileString, content);
+    module->addDebugSource(debugSource);
+    if (!mainSource)
+      mainSource = debugSource;
+  }
 
-  SpirvString *fileString =
-      name.empty() ? nullptr
-                   : new (context) SpirvString(/*SourceLocation*/ {}, name);
-
-  SpirvSource *debugSource = new (context)
-      SpirvSource(/*SourceLocation*/ {}, spv::SourceLanguage::HLSL, version,
-                  fileString, content);
-
-  module->addDebugSource(debugSource);
-
-  return fileString;
+  // If mainSource is nullptr, fileNames is empty and no input file is
+  // specified. We must create a SpirvSource for OpSource HLSL <version>.
+  if (!mainSource) {
+    mainSource = new (context)
+        SpirvSource(/*SourceLocation*/ {}, spv::SourceLanguage::HLSL, version,
+                    nullptr, content);
+    module->addDebugSource(mainSource);
+  }
+  return mainSource->getFile();
 }
 
 void SpirvBuilder::addExecutionMode(SpirvFunction *entryPoint,

+ 1 - 1
tools/clang/include/clang/SPIRV/SpirvModule.h

@@ -150,7 +150,7 @@ private:
   SpirvMemoryModel *memoryModel;
   llvm::SmallVector<SpirvEntryPoint *, 1> entryPoints;
   llvm::SmallVector<SpirvExecutionMode *, 4> executionModes;
-  SpirvSource *debugSource;
+  std::vector<SpirvSource *> debugSources;
   std::vector<SpirvModuleProcessed *> moduleProcesses;
 
   // Use a set for storing decoration. This will ensure that we don't apply the

+ 54 - 20
tools/clang/lib/SPIRV/EmitVisitor.cpp

@@ -116,7 +116,8 @@ void EmitVisitor::emitDebugNameForInstruction(uint32_t resultId,
   curInst.push_back(resultId);
   encodeString(debugName);
   curInst[0] |= static_cast<uint32_t>(curInst.size()) << 16;
-  debugBinary.insert(debugBinary.end(), curInst.begin(), curInst.end());
+  debugVariableBinary.insert(debugVariableBinary.end(), curInst.begin(),
+                             curInst.end());
 }
 
 void EmitVisitor::emitDebugLine(spv::Op op, const SourceLocation &loc) {
@@ -137,14 +138,28 @@ void EmitVisitor::emitDebugLine(spv::Op op, const SourceLocation &loc) {
   if (!spvOptions.debugInfoLine)
     return;
 
-  if (!debugFileId) {
-    emitError("spvOptions.debugInfoLine is true but no debugFileId was set");
+  auto fileId = debugMainFileId;
+  const auto &sm = astContext.getSourceManager();
+  const char *fileName = sm.getPresumedLoc(loc).getFilename();
+  if (fileName) {
+    auto it = debugFileIdMap.find(fileName);
+    if (it == debugFileIdMap.end()) {
+      // Emit the OpString for this new fileName.
+      SpirvString *inst =
+          new (context) SpirvString(/*SourceLocation*/ {}, fileName);
+      visit(inst);
+      it = debugFileIdMap.find(fileName);
+    }
+    fileId = it->second;
+  }
+
+  if (!fileId) {
+    emitError("spvOptions.debugInfoLine is true but no fileId was set");
     return;
   }
 
-  const auto &sm = astContext.getSourceManager();
-  uint32_t line = sm.getSpellingLineNumber(loc);
-  uint32_t column = sm.getSpellingColumnNumber(loc);
+  uint32_t line = sm.getPresumedLineNumber(loc);
+  uint32_t column = sm.getPresumedColumnNumber(loc);
 
   if (!line || !column)
     return;
@@ -158,7 +173,7 @@ void EmitVisitor::emitDebugLine(spv::Op op, const SourceLocation &loc) {
 
   curInst.clear();
   curInst.push_back(static_cast<uint32_t>(spv::Op::OpLine));
-  curInst.push_back(debugFileId);
+  curInst.push_back(fileId);
   curInst.push_back(line);
   curInst.push_back(column);
   curInst[0] |= static_cast<uint32_t>(curInst.size()) << 16;
@@ -220,9 +235,13 @@ void EmitVisitor::finalizeInstruction() {
   case spv::Op::OpSource:
   case spv::Op::OpSourceExtension:
   case spv::Op::OpSourceContinued:
+    debugFileBinary.insert(debugFileBinary.end(), curInst.begin(),
+                           curInst.end());
+    break;
   case spv::Op::OpName:
   case spv::Op::OpMemberName:
-    debugBinary.insert(debugBinary.end(), curInst.begin(), curInst.end());
+    debugVariableBinary.insert(debugVariableBinary.end(), curInst.begin(),
+                               curInst.end());
     break;
   case spv::Op::OpModuleProcessed:
   case spv::Op::OpDecorate:
@@ -260,7 +279,9 @@ std::vector<uint32_t> EmitVisitor::takeBinary() {
   auto headerBinary = header.takeBinary();
   result.insert(result.end(), headerBinary.begin(), headerBinary.end());
   result.insert(result.end(), preambleBinary.begin(), preambleBinary.end());
-  result.insert(result.end(), debugBinary.begin(), debugBinary.end());
+  result.insert(result.end(), debugFileBinary.begin(), debugFileBinary.end());
+  result.insert(result.end(), debugVariableBinary.begin(),
+                debugVariableBinary.end());
   result.insert(result.end(), annotationsBinary.begin(),
                 annotationsBinary.end());
   result.insert(result.end(), typeConstantBinary.begin(),
@@ -388,14 +409,25 @@ bool EmitVisitor::visit(SpirvString *inst) {
   curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
   encodeString(inst->getString());
   finalizeInstruction();
+
+  if (spvOptions.debugInfoLine) {
+    if (debugFileIdMap.find(inst->getString()) != debugFileIdMap.end())
+      return true;
+    debugFileIdMap[inst->getString()] =
+        getOrAssignResultId<SpirvInstruction>(inst);
+  }
   return true;
 }
 
 bool EmitVisitor::visit(SpirvSource *inst) {
   // Emit the OpString for the file name.
-  if (inst->hasFile())
+  if (inst->hasFile()) {
     visit(inst->getFile());
 
+    if (spvOptions.debugInfoLine && !debugMainFileId)
+      debugMainFileId = debugFileIdMap[inst->getFile()->getString()];
+  }
+
   // Chop up the source into multiple segments if it is too long.
   llvm::Optional<llvm::StringRef> firstSnippet = llvm::None;
   llvm::SmallVector<llvm::StringRef, 2> choppedSrcCode;
@@ -414,31 +446,32 @@ bool EmitVisitor::visit(SpirvSource *inst) {
   }
   if (firstSnippet.hasValue()) {
     // Note: in order to improve performance and avoid multiple copies, we
-    // encode this (potentially large) string directly into the debugBinary.
+    // encode this (potentially large) string directly into the debugFileBinary.
     const auto &words = string::encodeSPIRVString(firstSnippet.getValue());
     const auto numWordsInInstr = curInst.size() + words.size();
     curInst[0] |= static_cast<uint32_t>(numWordsInInstr) << 16;
-    debugBinary.insert(debugBinary.end(), curInst.begin(), curInst.end());
-    debugBinary.insert(debugBinary.end(), words.begin(), words.end());
+    debugFileBinary.insert(debugFileBinary.end(), curInst.begin(),
+                           curInst.end());
+    debugFileBinary.insert(debugFileBinary.end(), words.begin(), words.end());
   } else {
     curInst[0] |= static_cast<uint32_t>(curInst.size()) << 16;
-    debugBinary.insert(debugBinary.end(), curInst.begin(), curInst.end());
+    debugFileBinary.insert(debugFileBinary.end(), curInst.begin(),
+                           curInst.end());
   }
 
   // Now emit OpSourceContinued for the [second:last] snippet.
   for (uint32_t i = 1; i < choppedSrcCode.size(); ++i) {
     initInstruction(spv::Op::OpSourceContinued, /* SourceLocation */ {});
     // Note: in order to improve performance and avoid multiple copies, we
-    // encode this (potentially large) string directly into the debugBinary.
+    // encode this (potentially large) string directly into the debugFileBinary.
     const auto &words = string::encodeSPIRVString(choppedSrcCode[i]);
     const auto numWordsInInstr = curInst.size() + words.size();
     curInst[0] |= static_cast<uint32_t>(numWordsInInstr) << 16;
-    debugBinary.insert(debugBinary.end(), curInst.begin(), curInst.end());
-    debugBinary.insert(debugBinary.end(), words.begin(), words.end());
+    debugFileBinary.insert(debugFileBinary.end(), curInst.begin(),
+                           curInst.end());
+    debugFileBinary.insert(debugFileBinary.end(), words.begin(), words.end());
   }
 
-  if (spvOptions.debugInfoLine)
-    debugFileId = inst->getFile()->getResultId();
   return true;
 }
 
@@ -1642,7 +1675,8 @@ void EmitTypeHandler::emitNameForType(llvm::StringRef name,
   const auto &words = string::encodeSPIRVString(name);
   nameInstr.insert(nameInstr.end(), words.begin(), words.end());
   nameInstr[0] |= static_cast<uint32_t>(nameInstr.size()) << 16;
-  debugBinary->insert(debugBinary->end(), nameInstr.begin(), nameInstr.end());
+  debugVariableBinary->insert(debugVariableBinary->end(), nameInstr.begin(),
+                              nameInstr.end());
 }
 
 } // end namespace spirv

+ 14 - 9
tools/clang/lib/SPIRV/EmitVisitor.h

@@ -11,6 +11,7 @@
 #include "clang/SPIRV/SpirvContext.h"
 #include "clang/SPIRV/SpirvVisitor.h"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringMap.h"
 
 #include <functional>
 
@@ -48,7 +49,7 @@ public:
                   std::vector<uint32_t> *decVec,
                   std::vector<uint32_t> *typesVec,
                   const std::function<uint32_t()> &takeNextIdFn)
-      : astContext(astCtx), context(spvContext), debugBinary(debugVec),
+      : astContext(astCtx), context(spvContext), debugVariableBinary(debugVec),
         annotationsBinary(decVec), typeConstantBinary(typesVec),
         takeNextIdFunction(takeNextIdFn), emittedConstantInts({}),
         emittedConstantFloats({}), emittedConstantComposites({}),
@@ -144,7 +145,7 @@ private:
   SpirvContext &context;
   std::vector<uint32_t> curTypeInst;
   std::vector<uint32_t> curDecorationInst;
-  std::vector<uint32_t> *debugBinary;
+  std::vector<uint32_t> *debugVariableBinary;
   std::vector<uint32_t> *annotationsBinary;
   std::vector<uint32_t> *typeConstantBinary;
   std::function<uint32_t()> takeNextIdFunction;
@@ -188,10 +189,10 @@ public:
   EmitVisitor(ASTContext &astCtx, SpirvContext &spvCtx,
               const SpirvCodeGenOptions &opts)
       : Visitor(opts, spvCtx), astContext(astCtx), id(0),
-        typeHandler(astCtx, spvCtx, &debugBinary, &annotationsBinary,
+        typeHandler(astCtx, spvCtx, &debugVariableBinary, &annotationsBinary,
                     &typeConstantBinary,
                     [this]() -> uint32_t { return takeNextId(); }),
-        debugFileId(0), debugLine(0), debugColumn(0),
+        debugMainFileId(0), debugLine(0), debugColumn(0),
         lastOpWasMergeInst(false) {}
 
   // Visit different SPIR-V constructs for emitting.
@@ -319,10 +320,12 @@ private:
   // OpCapability, OpExtension, OpExtInstImport, OpMemoryModel, OpEntryPoint,
   // OpExecutionMode(Id)
   std::vector<uint32_t> preambleBinary;
-  // All debug instructions *except* OpLine. Includes:
-  // OpString, OpSourceExtension, OpSource, OpSourceContinued, OpName,
-  // OpMemberName, OpModuleProcessed
-  std::vector<uint32_t> debugBinary;
+  // Debug instructions related to file. Includes:
+  // OpString, OpSourceExtension, OpSource, OpSourceContinued
+  std::vector<uint32_t> debugFileBinary;
+  // All debug instructions related to variable name. Includes:
+  // OpName, OpMemberName, OpModuleProcessed
+  std::vector<uint32_t> debugVariableBinary;
   // All annotation instructions: OpDecorate, OpMemberDecorate, OpGroupDecorate,
   // OpGroupMemberDecorate, and OpDecorationGroup.
   std::vector<uint32_t> annotationsBinary;
@@ -331,7 +334,9 @@ private:
   // All other instructions
   std::vector<uint32_t> mainBinary;
   // File information for debugging that will be used by OpLine.
-  uint32_t debugFileId;
+  llvm::StringMap<uint32_t> debugFileIdMap;
+  // Main file information for debugging that will be used by OpLine.
+  uint32_t debugMainFileId;
   // One HLSL source line may result in several SPIR-V instructions. In order to
   // avoid emitting many OpLine instructions with identical line and column
   // numbers, we record the last line and column number that was used by OpLine,

+ 7 - 5
tools/clang/lib/SPIRV/SpirvEmitter.cpp

@@ -533,11 +533,13 @@ SpirvEmitter::SpirvEmitter(CompilerInstance &ci)
   // Set shader module version, source file name, and source file content (if
   // needed).
   llvm::StringRef source = "";
-  llvm::StringRef fileName = "";
+  std::vector<llvm::StringRef> fileNames;
   const auto &inputFiles = ci.getFrontendOpts().Inputs;
   // File name
   if (spirvOptions.debugInfoFile && !inputFiles.empty()) {
-    fileName = inputFiles.front().getFile();
+    for (const auto &inputFile : inputFiles) {
+      fileNames.push_back(inputFile.getFile());
+    }
   }
   // Source code
   if (spirvOptions.debugInfoSource) {
@@ -546,9 +548,9 @@ SpirvEmitter::SpirvEmitter(CompilerInstance &ci)
         sm.getBuffer(sm.getMainFileID(), SourceLocation());
     source = StringRef(mainFile->getBufferStart(), mainFile->getBufferSize());
   }
-  mainSourceFile =
-      spvBuilder.setDebugSource(spvContext.getMajorVersion(),
-                                spvContext.getMinorVersion(), fileName, source);
+  mainSourceFile = spvBuilder.setDebugSource(spvContext.getMajorVersion(),
+                                             spvContext.getMinorVersion(),
+                                             fileNames, source);
 
   if (spirvOptions.debugInfoTool && spirvOptions.targetEnv == "vulkan1.1") {
     // Emit OpModuleProcessed to indicate the commit information.

+ 14 - 10
tools/clang/lib/SPIRV/SpirvModule.cpp

@@ -16,9 +16,8 @@ namespace spirv {
 
 SpirvModule::SpirvModule()
     : capabilities({}), extensions({}), extInstSets({}), memoryModel(nullptr),
-      entryPoints({}), executionModes({}), debugSource(nullptr),
-      moduleProcesses({}), decorations({}), constants({}), variables({}),
-      functions({}) {}
+      entryPoints({}), executionModes({}), moduleProcesses({}), decorations({}),
+      constants({}), variables({}), functions({}) {}
 
 bool SpirvModule::invokeVisitor(Visitor *visitor, bool reverseOrder) {
   // Note: It is debatable whether reverse order of visiting the module should
@@ -68,9 +67,13 @@ bool SpirvModule::invokeVisitor(Visitor *visitor, bool reverseOrder) {
         return false;
     }
 
-    if (debugSource)
-      if (!debugSource->invokeVisitor(visitor))
-        return false;
+    if (!debugSources.empty())
+      for (auto iter = debugSources.rbegin(); iter != debugSources.rend();
+           ++iter) {
+        auto *source = *iter;
+        if (!source->invokeVisitor(visitor))
+          return false;
+      }
 
     for (auto iter = executionModes.rbegin(); iter != executionModes.rend();
          ++iter) {
@@ -135,9 +138,10 @@ bool SpirvModule::invokeVisitor(Visitor *visitor, bool reverseOrder) {
       if (!execMode->invokeVisitor(visitor))
         return false;
 
-    if (debugSource)
-      if (!debugSource->invokeVisitor(visitor))
-        return false;
+    if (!debugSources.empty())
+      for (auto *source : debugSources)
+        if (!source->invokeVisitor(visitor))
+          return false;
 
     for (auto moduleProcess : moduleProcesses)
       if (!moduleProcess->invokeVisitor(visitor))
@@ -233,7 +237,7 @@ void SpirvModule::addConstant(SpirvConstant *constant) {
 
 void SpirvModule::addDebugSource(SpirvSource *src) {
   assert(src);
-  debugSource = src;
+  debugSources.push_back(src);
 }
 
 void SpirvModule::addModuleProcessed(SpirvModuleProcessed *p) {

+ 19 - 22
tools/clang/test/CodeGenSPIRV/spirv.debug.opline.branch.hlsl

@@ -5,91 +5,88 @@
 
 static int a, b, c;
 
-// Note that preprocessor prepends a "#line 1 ..." line to the whole file and
-// the compliation sees line numbers incremented by 1.
-
 void main() {
-// CHECK:       OpLine [[file]] 15 3
+// CHECK:       OpLine [[file]] 11 3
 // CHECK-NEXT:  OpBranch %do_while_header
   do {
-// CHECK:       OpLine [[file]] 15 6
+// CHECK:       OpLine [[file]] 11 6
 // CHECK-NEXT:  OpLoopMerge %do_while_merge %do_while_continue None
 // CHECK-NEXT:  OpBranch %do_while_body
     if (a < 27) {
       ++a;
-// CHECK:       OpLine [[file]] 23 7
+// CHECK:       OpLine [[file]] 19 7
 // CHECK-NEXT:  OpBranch %do_while_continue
       continue;
     }
     b += a;
-// CHECK:       OpLine [[file]] 31 3
+// CHECK:       OpLine [[file]] 27 3
 // CHECK-NEXT:  OpBranch %do_while_continue
 
-// CHECK:       OpLine [[file]] 31 17
+// CHECK:       OpLine [[file]] 27 17
 // CHECK-NEXT:  OpBranchConditional {{%\d+}} %do_while_header %do_while_merge
   } while (c < b);
 
-// CHECK:       OpLine [[file]] 37 3
+// CHECK:       OpLine [[file]] 33 3
 // CHECK-NEXT:  OpBranch %while_check
-// CHECK:       OpLine [[file]] 37 3
+// CHECK:       OpLine [[file]] 33 3
 // CHECK-NEXT:  OpLoopMerge %while_merge %while_continue None
   while (a < c) {
-// CHECK:       OpLine [[file]] 41 17
+// CHECK:       OpLine [[file]] 37 17
 // CHECK-NEXT:  OpSelectionMerge %if_merge_1 None
 // CHECK-NEXT:  OpBranchConditional {{%\d+}} %if_true_0 %if_false
     if (b < 34) {
       a = 99;
-// CHECK:       OpLine [[file]] 46 25
+// CHECK:       OpLine [[file]] 42 25
 // CHECK-NEXT:  OpSelectionMerge %if_merge_0 None
 // CHECK-NEXT:  OpBranchConditional {{%\d+}} %if_true_1 %if_false_0
     } else if (a > 100) {
       a -= 20;
-// CHECK:       OpLine [[file]] 50 7
+// CHECK:       OpLine [[file]] 46 7
 // CHECK-NEXT:  OpBranch %while_merge
       break;
     } else {
       c = b;
-// CHECK:       OpLine [[file]] 55 5
+// CHECK:       OpLine [[file]] 51 5
 // CHECK-NEXT:  OpBranch %if_merge_0
     }
-// CHECK:                        OpLine [[file]] 61 3
+// CHECK:                        OpLine [[file]] 57 3
 // CHECK-NEXT:                   OpBranch %while_continue
 // CHECK-NEXT: %while_continue = OpLabel
 // CHECK-NEXT:                   OpBranch %while_check
 // CHECK-NEXT:    %while_merge = OpLabel
   }
 
-// CHECK:       OpLine [[file]] 65 19
+// CHECK:       OpLine [[file]] 61 19
 // CHECK-NEXT:  OpBranch %for_check
   for (int i = 0; i < 10 && float(a / b) < 2.7; ++i) {
-// CHECK:       OpLine [[file]] 65 44
+// CHECK:       OpLine [[file]] 61 44
 // CHECK-NEXT:  OpLoopMerge %for_merge %for_continue None
 // CHECK-NEXT:  OpBranchConditional {{%\d+}} %for_body %for_merge
     c = a + 2 * b + c;
-// CHECK:                      OpLine [[file]] 73 3
+// CHECK:                      OpLine [[file]] 69 3
 // CHECK-NEXT:                 OpBranch %for_continue
 // CHECK-NEXT: %for_continue = OpLabel
   }
-// CHECK:                      OpLine [[file]] 73 3
+// CHECK:                      OpLine [[file]] 69 3
 // CHECK-NEXT:                 OpBranch %for_check
 // CHECK-NEXT:    %for_merge = OpLabel
 
   switch (a) {
   case 1:
     b = c;
-// CHECK:      OpLine [[file]] 83 5
+// CHECK:      OpLine [[file]] 79 5
 // CHECK-NEXT: OpBranch %switch_merge
     break;
   case 2:
     b = 2 * c;
-// CHECK:      OpLine [[file]] 88 3
+// CHECK:      OpLine [[file]] 84 3
 // CHECK-NEXT: OpBranch %switch_4
   case 4:
     b = b + 4;
     break;
   default:
     b = a;
-// CHECK:      OpLine [[file]] 95 3
+// CHECK:      OpLine [[file]] 91 3
 // CHECK-NEXT: OpBranch %switch_merge
   }
 }

+ 17 - 17
tools/clang/test/CodeGenSPIRV/spirv.debug.opline.composite.hlsl

@@ -45,10 +45,10 @@ void main() {
 
   int4 a = {
       float2(1, 0),
-// CHECK: OpLine [[file]] 51 7
+// CHECK: OpLine [[file]] 50 7
 // CHECK: OpFunctionCall %int4_bool_float3_0 %test_struct
       test_struct().c.zx
-// CHECK:      OpLine [[file]] 47 12
+// CHECK:      OpLine [[file]] 46 12
 // CHECK:      OpCompositeExtract %float {{%\d+}} 0
 // CHECK-NEXT: OpCompositeExtract %float {{%\d+}} 1
 // CHECK-NEXT: OpConvertFToS %int
@@ -57,59 +57,59 @@ void main() {
   };
 
 // CHECK:                        OpFDiv %float {{%\d+}} %float_2
-// CHECK-NEXT:                   OpLine [[file]] 65 25
+// CHECK-NEXT:                   OpLine [[file]] 64 25
 // CHECK-NEXT:  [[first:%\d+]] = OpCompositeConstruct %v2float {{%\d+}} {{%\d+}}
 // CHECK-NEXT: [[second:%\d+]] = OpCompositeConstruct %v2float {{%\d+}} {{%\d+}}
 // CHECK-NEXT:        {{%\d+}} = OpCompositeConstruct %mat2v2float [[first]] [[second]]
   float2x2 b = float2x2(a.x, b._m00, 2 + a.y, b._m11 / 2);
 
-// CHECK:                   OpLine [[file]] 70 12
+// CHECK:                   OpLine [[file]] 69 12
 // CHECK-NEXT: [[y:%\d+]] = OpAccessChain %_ptr_Uniform_int4_bool_float3 %CONSTANTS %int_0
 // CHECK-NEXT:   {{%\d+}} = OpAccessChain %_ptr_Uniform_v4int [[y]] %int_0
   int4 c = y.a;
 
-// CHECK:                   OpLine [[file]] 77 3
+// CHECK:                   OpLine [[file]] 76 3
 // CHECK-NEXT: [[z:%\d+]] = OpLoad %type_2d_image %z
 // CHECK-NEXT: [[z:%\d+]] = OpImageRead %v4int [[z]] {{%\d+}} None
 // CHECK-NEXT: [[z:%\d+]] = OpVectorShuffle %v3int [[z]] [[z]] 0 1 2
 // CHECK-NEXT:   {{%\d+}} = OpCompositeInsert %v3int %int_16 [[z]] 0
   z[uint2(2, 3)].x = 16;
 
-// CHECK:      OpLine [[file]] 83 3
+// CHECK:      OpLine [[file]] 82 3
 // CHECK-NEXT: OpLoad %mat2v2float %b
-// CHECK:      OpLine [[file]] 83 4
+// CHECK:      OpLine [[file]] 82 4
 // CHECK-NEXT: OpFSub %v2float
   b--;
 
   int2x2 d;
-// CHECK:      OpLine [[file]] 92 8
+// CHECK:      OpLine [[file]] 91 8
 // CHECK-NEXT: OpLoad %mat2v2float %b
-// CHECK-NEXT: OpLine [[file]] 92 3
+// CHECK-NEXT: OpLine [[file]] 91 3
 // CHECK-NEXT: OpCompositeExtract %v2float
-// CHECK:      OpLine [[file]] 92 11
+// CHECK:      OpLine [[file]] 91 11
 // CHECK:      OpStore %d
   modf(b, d);
 
-// CHECK:      OpLine [[file]] 96 7
+// CHECK:      OpLine [[file]] 95 7
 // CHECK-NEXT: OpFunctionCall %void %S_inc %foo
   foo.inc();
 
-// CHECK:      OpLine [[file]] 100 10
+// CHECK:      OpLine [[file]] 99 10
 // CHECK-NEXT: OpFunctionCall %void %S_inc %temp_var_S
   getS().inc();
 
-// CHECK:      OpLine [[file]] 106 19
+// CHECK:      OpLine [[file]] 105 19
 // CHECK-NEXT: OpLoad %init %bar
-// CHECK:      OpLine [[file]] 106 12
+// CHECK:      OpLine [[file]] 105 12
 // CHECK-NEXT: OpConvertFToS %int
   int4 e = {1, 2, bar};
 
-// CHECK:      OpLine [[file]] 112 16
+// CHECK:      OpLine [[file]] 111 16
 // CHECK-NEXT: OpCompositeConstruct %v2float %float_1 %float_2
-// CHECK-NEXT: OpLine [[file]] 112 22
+// CHECK-NEXT: OpLine [[file]] 111 22
 // CHECK-NEXT: OpCompositeExtract %int
   b = float2x2(1, 2, bar);
-// CHECK:      OpLine [[file]] 112 3
+// CHECK:      OpLine [[file]] 111 3
 // CHECK-NEXT: OpStore %b
 
 // TODO(jaebaek): Update InitListHandler to properly emit debug info.

+ 13 - 18
tools/clang/test/CodeGenSPIRV/spirv.debug.opline.entry.hlsl

@@ -3,44 +3,39 @@
 // CHECK:      [[file:%\d+]] = OpString
 // CHECK-SAME: spirv.debug.opline.entry.hlsl
 
-// Note that preprocessor prepends a "#line 1 ..." line to the whole file,
-// removes comments from line 1 to 33 and line 40 to 49, and put two comments
-// just before the starting of main and the first line of code in main. As a
-// result, code lines in OpSource can be different from this file.
-
-// CHECK:                          OpLine [[file]] 3 1
+// CHECK:                          OpLine [[file]] 29 1
 // CHECK-NEXT:             %main = OpFunction %void None %16
 // CHECK-NEXT:          {{%\d+}} = OpLabel
-// CHECK-NEXT:                     OpLine [[file]] 3 20
+// CHECK-NEXT:                     OpLine [[file]] 29 20
 // CHECK-NEXT:      %param_var_a = OpVariable %_ptr_Function_v2float Function
-// CHECK-NEXT:                     OpLine [[file]] 4 20
+// CHECK-NEXT:                     OpLine [[file]] 30 20
 // CHECK-NEXT:      %param_var_b = OpVariable %_ptr_Function_v3float Function
-// CHECK-NEXT:                     OpLine [[file]] 5 20
+// CHECK-NEXT:                     OpLine [[file]] 31 20
 // CHECK-NEXT:      %param_var_c = OpVariable %_ptr_Function_v4float Function
-// CHECK-NEXT:                     OpLine [[file]] 3 20
+// CHECK-NEXT:                     OpLine [[file]] 29 20
 // CHECK-NEXT: [[texcoord:%\d+]] = OpLoad %v2float %in_var_TEXCOORD0
 // CHECK-NEXT:                     OpStore %param_var_a [[texcoord]]
-// CHECK-NEXT:                     OpLine [[file]] 4 20
+// CHECK-NEXT:                     OpLine [[file]] 30 20
 // CHECK-NEXT:   [[normal:%\d+]] = OpLoad %v3float %in_var_NORMAL
 // CHECK-NEXT:                     OpStore %param_var_b [[normal]]
-// CHECK-NEXT:                     OpLine [[file]] 5 20
+// CHECK-NEXT:                     OpLine [[file]] 31 20
 // CHECK-NEXT:    [[color:%\d+]] = OpLoad %v4float %in_var_COLOR
 // CHECK-NEXT:                     OpStore %param_var_c [[color]]
-// CHECK-NEXT:                     OpLine [[file]] 3 1
+// CHECK-NEXT:                     OpLine [[file]] 29 1
 // CHECK-NEXT:   [[result:%\d+]] = OpFunctionCall %v4float %src_main %param_var_a %param_var_b %param_var_c
-// CHECK-NEXT:                     OpLine [[file]] 5 33
+// CHECK-NEXT:                     OpLine [[file]] 31 33
 // CHECK-NEXT:                     OpStore %out_var_SV_Target [[result]]
 // CHECK-NEXT:                     OpReturn
 float4 main(float2 a : TEXCOORD0,
             float3 b : NORMAL,
             float4 c : COLOR) : SV_Target {
-// CHECK:                  OpLine [[file]] 3 1
+// CHECK:                  OpLine [[file]] 29 1
 // CHECK-NEXT: %src_main = OpFunction %v4float None %29
-// CHECK-NEXT:             OpLine [[file]] 3 20
+// CHECK-NEXT:             OpLine [[file]] 29 20
 // CHECK-NEXT:        %a = OpFunctionParameter %_ptr_Function_v2float
-// CHECK-NEXT:             OpLine [[file]] 4 20
+// CHECK-NEXT:             OpLine [[file]] 30 20
 // CHECK-NEXT:        %b = OpFunctionParameter %_ptr_Function_v3float
-// CHECK-NEXT:             OpLine [[file]] 5 20
+// CHECK-NEXT:             OpLine [[file]] 31 20
 // CHECK-NEXT:        %c = OpFunctionParameter %_ptr_Function_v4float
   float4 d = float4(a, b.xy + c.zw);
   return d;

+ 38 - 38
tools/clang/test/CodeGenSPIRV/spirv.debug.opline.function.hlsl

@@ -5,7 +5,7 @@
 
 void foo(in float4 a, out float3 b);
 
-// CHECK:              OpLine [[file]] 31 1
+// CHECK:              OpLine [[file]] 30 1
 // CHECK-NEXT: %main = OpFunction %void None
 
 void bar(int a, in float b, inout bool2 c, const float3 d, out uint4 e) {
@@ -31,114 +31,114 @@ void main() {
   float4 v4f;
   float3 v3f;
 
-// CHECK:                     OpLine [[file]] 37 7
+// CHECK:                     OpLine [[file]] 36 7
 // CHECK-NEXT: %param_var_a = OpVariable %_ptr_Function_v4float Function
   foo(v4f, v3f);
-// CHECK:                     OpLine [[file]] 40 14
+// CHECK:                     OpLine [[file]] 39 14
 // CHECK-NEXT: %param_var_x = OpVariable %_ptr_Function_float Function
   foo(getV4f(v4f.x,
-// CHECK:                     OpLine [[file]] 47 21
+// CHECK:                     OpLine [[file]] 46 21
 // CHECK-NEXT: %param_var_x_0 = OpVariable %_ptr_Function_float Function
-// CHECK-NEXT:                OpLine [[file]] 47 28
+// CHECK-NEXT:                OpLine [[file]] 46 28
 // CHECK-NEXT: %param_var_y = OpVariable %_ptr_Function_int Function
-// CHECK-NEXT:                OpLine [[file]] 47 35
+// CHECK-NEXT:                OpLine [[file]] 46 35
 // CHECK-NEXT: %param_var_z = OpVariable %_ptr_Function_bool Function
              getV4f(v4f.y, v4f.z, v4f.w).z,
-// CHECK:                     OpLine [[file]] 47 14
+// CHECK:                     OpLine [[file]] 46 14
 // CHECK-NEXT: %param_var_y_0 = OpVariable %_ptr_Function_int Function
-// CHECK-NEXT:                OpLine [[file]] 52 14
+// CHECK-NEXT:                OpLine [[file]] 51 14
 // CHECK-NEXT: %param_var_z_0 = OpVariable %_ptr_Function_bool Function
              v3f.y),
       v3f);
-// CHECK-NEXT:                OpLine [[file]] 40 7
+// CHECK-NEXT:                OpLine [[file]] 39 7
 // CHECK-NEXT: %param_var_a_0 = OpVariable %_ptr_Function_v4float Function
 
   r[0].incr();
   decr(r[0],
-// CHECK-NEXT:                OpLine [[file]] 63 13
+// CHECK-NEXT:                OpLine [[file]] 62 13
 // CHECK-NEXT: %param_var_i = OpVariable %_ptr_Function_uint Function
-// CHECK-NEXT:                OpLine [[file]] 63 8
+// CHECK-NEXT:                OpLine [[file]] 62 8
 // CHECK-NEXT: %param_var_b = OpVariable %_ptr_Function_R_0 Function
        getR(1),
        r[2],
-// CHECK-NEXT:                OpLine [[file]] 69 13
+// CHECK-NEXT:                OpLine [[file]] 68 13
 // CHECK-NEXT: %param_var_i_0 = OpVariable %_ptr_Function_uint Function
-// CHECK-NEXT:                OpLine [[file]] 69 8
+// CHECK-NEXT:                OpLine [[file]] 68 8
 // CHECK-NEXT: %param_var_d = OpVariable %_ptr_Function_R_0 Function
        getR(3),
-// CHECK-NEXT:                OpLine [[file]] 74 13
+// CHECK-NEXT:                OpLine [[file]] 73 13
 // CHECK-NEXT: %param_var_i_1 = OpVariable %_ptr_Function_uint Function
-// CHECK-NEXT:                OpLine [[file]] 74 8
+// CHECK-NEXT:                OpLine [[file]] 73 8
 // CHECK-NEXT: %param_var_e = OpVariable %_ptr_Function_R_0 Function
        getR(4));
 
   rwsb[0].incr();
 
   decr(rwsb[1],
-// CHECK-NEXT:                OpLine [[file]] 81 8
+// CHECK-NEXT:                OpLine [[file]] 80 8
 // CHECK-NEXT: %param_var_b_0 = OpVariable %_ptr_Function_R_0 Function
        rwsb[2],
        rwsb[3],
-// CHECK-NEXT:                OpLine [[file]] 85 8
+// CHECK-NEXT:                OpLine [[file]] 84 8
 // CHECK-NEXT: %param_var_d_0 = OpVariable %_ptr_Function_R_0 Function
        rwsb[4],
-// CHECK-NEXT:                OpLine [[file]] 88 8
+// CHECK-NEXT:                OpLine [[file]] 87 8
 // CHECK-NEXT: %param_var_e_0 = OpVariable %_ptr_Function_R_0 Function
        rwsb[5]);
 }
 
-// CHECK:             OpLine [[file]] 97 1
+// CHECK:             OpLine [[file]] 96 1
 // CHECK-NEXT: %foo = OpFunction %void None
-// CHECK-NEXT:        OpLine [[file]] 97 20
+// CHECK-NEXT:        OpLine [[file]] 96 20
 // CHECK-NEXT:   %a = OpFunctionParameter %_ptr_Function_v4float
-// CHECK-NEXT:        OpLine [[file]] 97 34
+// CHECK-NEXT:        OpLine [[file]] 96 34
 // CHECK-NEXT:   %b = OpFunctionParameter %_ptr_Function_v3float
 void foo(in float4 a, out float3 b) {
   a = b.xxzz;
   b = a.yzw;
-// CHECK:                     OpLine [[file]] 104 7
+// CHECK:                     OpLine [[file]] 103 7
 // CHECK-NEXT: %param_var_a_1 = OpVariable %_ptr_Function_int Function
-// CHECK-NEXT:                OpLine [[file]] 104 12
+// CHECK-NEXT:                OpLine [[file]] 103 12
 // CHECK-NEXT: %param_var_b_1 = OpVariable %_ptr_Function_float Function
   bar(a.x, b.y, a.yz, b, a);
 }
 
-// CHECK:                     OpLine [[file]] 113 1
+// CHECK:                     OpLine [[file]] 112 1
 // CHECK-NEXT:      %getV4f = OpFunction %v4float None
-// CHECK-NEXT:                OpLine [[file]] 113 21
+// CHECK-NEXT:                OpLine [[file]] 112 21
 // CHECK-NEXT:           %x = OpFunctionParameter %_ptr_Function_float
-// CHECK-NEXT:                OpLine [[file]] 113 28
+// CHECK-NEXT:                OpLine [[file]] 112 28
 // CHECK-NEXT:           %y = OpFunctionParameter %_ptr_Function_int
 float4 getV4f(float x, int y, bool z) { return float4(x, y, z, z); }
 
-// CHECK:                     OpLine [[file]] 118 1
+// CHECK:                     OpLine [[file]] 117 1
 // CHECK-NEXT:      %R_incr = OpFunction %void None
 // CHECK-NEXT:  %param_this = OpFunctionParameter %_ptr_Function_R_0
 void R::incr() { ++a; }
 
-// CHECK:                     OpLine [[file]] 124 1
+// CHECK:                     OpLine [[file]] 123 1
 // CHECK-NEXT:        %getR = OpFunction %R_0 None
-// CHECK-NEXT:                OpLine [[file]] 124 13
+// CHECK-NEXT:                OpLine [[file]] 123 13
 // CHECK-NEXT:           %i = OpFunctionParameter %_ptr_Function_uint
 R getR(uint i) { return r[i]; }
 
-// CHECK:                     OpLine [[file]] 132 1
+// CHECK:                     OpLine [[file]] 131 1
 // CHECK-NEXT:        %decr = OpFunction %void None
-// CHECK-NEXT:                OpLine [[file]] 132 19
+// CHECK-NEXT:                OpLine [[file]] 131 19
 // CHECK-NEXT:         %a_0 = OpFunctionParameter %_ptr_Function_R_0
-// CHECK-NEXT:                OpLine [[file]] 132 27
+// CHECK-NEXT:                OpLine [[file]] 131 27
 // CHECK-NEXT:         %b_0 = OpFunctionParameter %_ptr_Function_R_0
 void decr(inout R a, in R b, out R c, R d, const R e) { a.a--; }
 
-// CHECK:             OpLine [[file]] 12 1
+// CHECK:             OpLine [[file]] 11 1
 // CHECK-NEXT: %bar = OpFunction %void None
-// CHECK-NEXT:        OpLine [[file]] 12 14
+// CHECK-NEXT:        OpLine [[file]] 11 14
 // CHECK-NEXT: %a_1 = OpFunctionParameter %_ptr_Function_int
-// CHECK-NEXT:        OpLine [[file]] 12 26
+// CHECK-NEXT:        OpLine [[file]] 11 26
 // CHECK-NEXT: %b_1 = OpFunctionParameter %_ptr_Function_float
-// CHECK-NEXT:        OpLine [[file]] 12 41
+// CHECK-NEXT:        OpLine [[file]] 11 41
 // CHECK-NEXT: %c_0 = OpFunctionParameter %_ptr_Function_v2bool
-// CHECK-NEXT:        OpLine [[file]] 12 57
+// CHECK-NEXT:        OpLine [[file]] 11 57
 // CHECK-NEXT: %d_0 = OpFunctionParameter %_ptr_Function_v3float
-// CHECK-NEXT:        OpLine [[file]] 12 70
+// CHECK-NEXT:        OpLine [[file]] 11 70
 // CHECK-NEXT: %e_0 = OpFunctionParameter %_ptr_Function_v4uint

+ 12 - 17
tools/clang/test/CodeGenSPIRV/spirv.debug.opline.hlsl

@@ -10,27 +10,22 @@ uint foo(uint val) {
   return val;
 }
 
-// Note that we do two passes for debuging info: first preprocessing and then
-// compiling the preprocessed source code.
-// Because the preprocessor prepends a "#line 1 ..." line to the whole file,
-// the compliation sees line numbers incremented by 1.
-
 float4 main(uint val : A) : SV_Target {
-  // CHECK:      OpLine [[file]] 24 24
+  // CHECK:      OpLine [[file]] 18 24
   // CHECK-NEXT: OpLoad %uint %val
-  // CHECK-NEXT: OpLine [[file]] 24 12
+  // CHECK-NEXT: OpLine [[file]] 18 12
   // CHECK-NEXT: OpBitReverse
   uint a = reversebits(val);
 
-  // CHECK:      OpLine [[file]] 28 16
+  // CHECK:      OpLine [[file]] 22 16
   // CHECK-NEXT: OpLoad %uint %a
   uint b = foo(a);
 
-  // CHECK:      OpLine [[file]] 32 14
+  // CHECK:      OpLine [[file]] 26 14
   // CHECK-NEXT: OpLoad %type_2d_image %MyTexture
   float4 c = MyTexture.Sample(MySampler, float2(0.1, 0.2));
 
-  // CHECK:      OpLine [[file]] 36 7
+  // CHECK:      OpLine [[file]] 30 7
   // CHECK-NEXT: OpLoad %uint %val
   if (val > 10) {
     a = 5;
@@ -39,31 +34,31 @@ float4 main(uint val : A) : SV_Target {
   }
 
   for (
-  // CHECK:      OpLine [[file]] 45 7
+  // CHECK:      OpLine [[file]] 39 7
   // CHECK-NEXT: OpStore %b %uint_0
       b = 0;
-  // CHECK:      OpLine [[file]] 48 7
+  // CHECK:      OpLine [[file]] 42 7
   // CHECK-NEXT: OpBranch %for_check
       b < 10;
-  // CHECK:      OpLine [[file]] 51 9
+  // CHECK:      OpLine [[file]] 45 9
   // CHECK-NEXT: OpLoad %uint %b
       ++b) {
     a += 1;
   }
 
-  // CHECK:      OpLine [[file]] 57 12
+  // CHECK:      OpLine [[file]] 51 12
   // CHECK-NEXT: OpLoad %uint %b
   while (--b > 0);
 
   do {
     c++;
-  // CHECK:      OpLine [[file]] 63 12
+  // CHECK:      OpLine [[file]] 57 12
   // CHECK-NEXT: OpAccessChain %_ptr_Function_float %c %int_0
   } while (c.x < 10);
 
-// CHECK:      OpLine [[file]] 69 7
+// CHECK:      OpLine [[file]] 63 7
 // CHECK-NEXT: OpAccessChain %_ptr_Function_float %c %int_0
-// CHECK:      OpLine [[file]] 69 3
+// CHECK:      OpLine [[file]] 63 3
 // CHECK-NEXT: pStore %a
   a = c.x;
 

+ 3 - 0
tools/clang/test/CodeGenSPIRV/spirv.debug.opline.include-file-1.hlsl

@@ -0,0 +1,3 @@
+int function1() {
+  return 1;
+}

+ 4 - 0
tools/clang/test/CodeGenSPIRV/spirv.debug.opline.include-file-2.hlsl

@@ -0,0 +1,4 @@
+static int a;
+int function2() {
+  return a;
+}

+ 8 - 0
tools/clang/test/CodeGenSPIRV/spirv.debug.opline.include-file-3.hlsl

@@ -0,0 +1,8 @@
+groupshared int b;
+
+int function3() {
+  return b;
+}
+
+#define CALL_FUNCTION_3 \
+  return function3()

+ 125 - 0
tools/clang/test/CodeGenSPIRV/spirv.debug.opline.include.hlsl

@@ -0,0 +1,125 @@
+// Run: %dxc -T ps_6_0 -E main -Zi
+
+// CHECK:      [[main:%\d+]] = OpString
+// CHECK-SAME: spirv.debug.opline.include.hlsl
+// CHECK:      [[file2:%\d+]] = OpString
+// CHECK-SAME: spirv.debug.opline.include-file-2.hlsl
+// CHECK:      [[file3:%\d+]] = OpString
+// CHECK-SAME: spirv.debug.opline.include-file-3.hlsl
+// CHECK:      [[file1:%\d+]] = OpString
+// CHECK-SAME: spirv.debug.opline.include-file-1.hlsl
+
+// CHECK:              OpLine [[file2]] 1 12
+// CHECK-NEXT:    %a = OpVariable %_ptr_Private_int Private
+// CHECK:              OpLine [[file3]] 1 17
+// CHECK-NEXT:    %b = OpVariable %_ptr_Workgroup_int Workgroup
+// CHECK:              OpLine [[main]] 65 1
+// CHECK-NEXT: %main = OpFunction %void None
+
+#include "spirv.debug.opline.include-file-1.hlsl"
+
+int callFunction1() {
+  return function1();
+}
+
+#include "spirv.debug.opline.include-file-2.hlsl"
+
+int callFunction2() {
+  // This
+  // is
+  // an
+  // intentional
+  // multiple
+  // lines.
+  // It
+  // might
+  // be
+  // a
+  // single
+  // line
+  // in
+  // OpSource.
+  return function2();
+}
+
+#include "spirv.debug.opline.include-file-3.hlsl"
+
+int callFunction3() {
+  // This
+  // is
+  // an
+  // intentional
+  // multiple
+  // lines.
+  // It
+  // might
+  // be
+  // a
+  // single
+  // line
+  // in
+  // OpSource.
+  CALL_FUNCTION_3;
+}
+
+void main() {
+// CHECK:      OpLine [[main]] 68 3
+// CHECK-NEXT: OpFunctionCall %int %callFunction1
+  callFunction1();
+
+  // This
+  // is
+  // an
+  // intentional
+  // multiple
+  // lines.
+  // It
+  // might
+  // be
+  // a
+  // single
+  // line
+  // in
+  // OpSource.
+// CHECK:      OpLine [[main]] 86 3
+// CHECK-NEXT: OpFunctionCall %int %callFunction2
+  callFunction2();
+
+// CHECK:      OpLine [[main]] 90 3
+// CHECK-NEXT: OpFunctionCall %int %callFunction3
+  callFunction3();
+}
+
+// CHECK:      OpLine [[main]] 21 1
+// CHECK-NEXT: %callFunction1 = OpFunction %int None
+// CHECK:      OpLine [[main]] 22 10
+// CHECK-NEXT: OpFunctionCall %int %function1
+// CHECK:      OpLine [[main]] 22 3
+// CHECK-NEXT: OpReturnValue
+
+// CHECK:      OpLine [[main]] 27 1
+// CHECK-NEXT: %callFunction2 = OpFunction %int None
+// CHECK:      OpLine [[main]] 42 10
+// CHECK-NEXT: OpFunctionCall %int %function2
+// CHECK:      OpLine [[main]] 42 3
+// CHECK-NEXT: OpReturnValue
+
+// CHECK:      OpLine [[main]] 47 1
+// CHECK-NEXT: %callFunction3 = OpFunction %int None
+// CHECK:      OpLine [[main]] 62 10
+// CHECK-NEXT: OpFunctionCall %int %function3
+// CHECK:      OpLine [[main]] 62 3
+// CHECK-NEXT: OpReturnValue
+
+// CHECK:      OpLine [[file1]] 1 1
+// CHECK-NEXT: %function1 = OpFunction %int None
+
+// CHECK:      OpLine [[file2]] 2 1
+// CHECK-NEXT: %function2 = OpFunction %int None
+// CHECK:      OpLine [[file2]] 3 10
+// CHECK-NEXT: OpLoad %int %a
+
+// CHECK:      OpLine [[file3]] 3 1
+// CHECK-NEXT: %function3 = OpFunction %int None
+// CHECK:      OpLine [[file3]] 4 10
+// CHECK-NEXT: OpLoad %int %b

+ 3 - 7
tools/clang/test/CodeGenSPIRV/spirv.debug.opline.intrinsic.control.barrier.hlsl

@@ -5,20 +5,16 @@
 
 groupshared int dest_i;
 
-// Note that preprocessor prepends a "#line 1 ..." line to the whole file and
-// the compliation sees line numbers incremented by 1.
-
 void main() {
-
-// CHECK:      OpLine [[file]] 16 3
+// CHECK:      OpLine [[file]] 11 3
 // CHECK-NEXT: OpControlBarrier %uint_2 %uint_1 %uint_2376
   AllMemoryBarrierWithGroupSync();
 
-// CHECK-NEXT: OpLine [[file]] 20 3
+// CHECK-NEXT: OpLine [[file]] 15 3
 // CHECK-NEXT: OpMemoryBarrier %uint_1 %uint_2120
   DeviceMemoryBarrier();
 
-// CHECK-NEXT: OpLine [[file]] 24 3
+// CHECK-NEXT: OpLine [[file]] 19 3
 // CHECK-NEXT: OpMemoryBarrier %uint_2 %uint_264
   GroupMemoryBarrier();
 }

+ 52 - 55
tools/clang/test/CodeGenSPIRV/spirv.debug.opline.intrinsic.hlsl

@@ -5,185 +5,182 @@
 
 groupshared int dest_i;
 
-// Note that preprocessor prepends a "#line 1 ..." line to the whole file and
-// the compliation sees line numbers incremented by 1.
-
 void main() {
   float2 v2f;
   uint4 v4i;
   float2x2 m2x2f;
 
-// CHECK:                     OpLine [[file]] 20 3
+// CHECK:                     OpLine [[file]] 16 3
 // CHECK-NEXT: [[mod:%\d+]] = OpExtInst %ModfStructType {{%\d+}} ModfStruct {{%\d+}}
 // CHECK-NEXT:     {{%\d+}} = OpCompositeExtract %v2float [[mod]] 1
   modf(v2f,
-// CHECK:                     OpLine [[file]] 26 8
+// CHECK:                     OpLine [[file]] 22 8
 // CHECK-NEXT: [[mod:%\d+]] = OpConvertFToU %v2uint {{%\d+}}
 // CHECK-NEXT: [[v4i:%\d+]] = OpLoad %v4uint %v4i
 // CHECK-NEXT: [[v4i:%\d+]] = OpVectorShuffle %v4uint [[v4i]] [[mod]] 4 5 2 3
 // CHECK-NEXT:                OpStore %v4i [[v4i]]
        v4i.xy);
 
-// CHECK:                      OpLine [[file]] 33 9
+// CHECK:                      OpLine [[file]] 29 9
 // CHECK-NEXT: [[v4ix:%\d+]] = OpCompositeExtract %uint {{%\d+}} 0
 // CHECK-NEXT:      {{%\d+}} = OpShiftLeftLogical %uint [[v4ix]] %uint_8
 // CHECK-NEXT:      {{%\d+}} = OpShiftLeftLogical %uint [[v4ix]] %uint_16
 // CHECK-NEXT:      {{%\d+}} = OpShiftLeftLogical %uint [[v4ix]] %uint_24
   v4i = msad4(v4i.x, v4i.xy, v4i);
-// CHECK:      OpLine [[file]] 33 3
+// CHECK:      OpLine [[file]] 29 3
 // CHECK-NEXT: OpStore %v4i {{%\d+}}
 
-// CHECK:      OpLine [[file]] 39 23
+// CHECK:      OpLine [[file]] 35 23
 // CHECK-NEXT: OpExtInst %v2float {{%\d+}} Fma
   /* comment */ v4i = mad(m2x2f, float2x2(v4i), float2x2(v2f, v2f));
-// CHECK:      OpLine [[file]] 39 17
+// CHECK:      OpLine [[file]] 35 17
 // CHECK-NEXT: OpStore %v4i
 
-// CHECK:                 OpLine [[file]] 45 9
+// CHECK:                 OpLine [[file]] 41 9
 // CHECK-NEXT: {{%\d+}} = OpMatrixTimesVector %v2float
   v2f = mul(v2f, m2x2f);
 
-// CHECK:                 OpLine [[file]] 49 11
+// CHECK:                 OpLine [[file]] 45 11
 // CHECK-NEXT: {{%\d+}} = OpDot %float
   v2f.x = dot(v4i.xy, v2f);
 
-// CHECK:                 OpLine [[file]] 53 11
+// CHECK:                 OpLine [[file]] 49 11
 // CHECK-NEXT: {{%\d+}} = OpExtInst %v2float {{%\d+}} UnpackHalf2x16
   v2f.x = f16tof32(v4i.x);
 
-// CHECK:                 OpLine [[file]] 57 11
+// CHECK:                 OpLine [[file]] 53 11
 // CHECK-NEXT: {{%\d+}} = OpDPdx %v2float
   m2x2f = ddx(m2x2f);
 
-// CHECK:                       OpLine [[file]] 64 11
+// CHECK:                       OpLine [[file]] 60 11
 // CHECK-NEXT: [[fmod0:%\d+]] = OpFMod %v2float {{%\d+}} {{%\d+}}
-// CHECK:                       OpLine [[file]] 64 11
+// CHECK:                       OpLine [[file]] 60 11
 // CHECK-NEXT: [[fmod1:%\d+]] = OpFMod %v2float {{%\d+}} {{%\d+}}
 // CHECK-NEXT:       {{%\d+}} = OpCompositeConstruct %mat2v2float [[fmod0]] [[fmod1]]
   m2x2f = fmod(m2x2f, float2x2(v4i));
 
-// CHECK:                     OpLine [[file]] 69 7
+// CHECK:                     OpLine [[file]] 65 7
 // CHECK-NEXT: [[v2f:%\d+]] = OpFOrdNotEqual %v2bool
 // CHECK-NEXT:     {{%\d+}} = OpAll %bool [[v2f]]
   if (all(v2f))
-// CHECK:                      OpLine [[file]] 76 5
+// CHECK:                      OpLine [[file]] 72 5
 // CHECK:       [[sin:%\d+]] = OpExtInst %float {{%\d+}} Sin {{%\d+}}
-// CHECK-NEXT:                 OpLine [[file]] 76 19
+// CHECK-NEXT:                 OpLine [[file]] 72 19
 // CHECK-NEXT: [[v2fx:%\d+]] = OpAccessChain %_ptr_Function_float %v2f %int_1
-// CHECK-NEXT:                 OpLine [[file]] 76 5
+// CHECK-NEXT:                 OpLine [[file]] 72 5
 // CHECK-NEXT:                 OpStore [[v2fx]] [[sin]]
     sincos(v2f.x, v2f.y, v2f.x);
 
-// CHECK:                 OpLine [[file]] 80 9
+// CHECK:                 OpLine [[file]] 76 9
 // CHECK-NEXT: {{%\d+}} = OpExtInst %v2float {{%\d+}} FClamp
   v2f = saturate(v2f);
 
-// CHECK:      OpLine [[file]] 84 17
+// CHECK:      OpLine [[file]] 80 17
 // CHECK-NEXT: OpAtomicCompareExchange %int %dest_i %uint_1 %uint_0 %uint_0
   /* comment */ InterlockedCompareStore(dest_i, v4i.x, v4i.y);
 
-// CHECK:                     OpLine [[file]] 91 41
+// CHECK:                     OpLine [[file]] 87 41
 // CHECK-NEXT: [[idx:%\d+]] = OpIAdd %uint
-// CHECK-NEXT:                OpLine [[file]] 91 3
+// CHECK-NEXT:                OpLine [[file]] 87 3
 // CHECK-NEXT: [[v4i:%\d+]] = OpAccessChain %_ptr_Function_uint %v4i %int_0
 // CHECK-NEXT:                OpStore [[v4i]] [[idx]]
   v4i.x = NonUniformResourceIndex(v4i.y + v4i.z);
 
-// CHECK:      OpLine [[file]] 97 11
+// CHECK:      OpLine [[file]] 93 11
 // CHECK-NEXT: OpImageSparseTexelsResident %bool
-// CHECK:      OpLine [[file]] 97 3
+// CHECK:      OpLine [[file]] 93 3
 // CHECK-NEXT: OpAccessChain %_ptr_Function_uint %v4i %int_2
   v4i.z = CheckAccessFullyMapped(v4i.w);
 
-// CHECK:                     OpLine [[file]] 105 34
+// CHECK:                     OpLine [[file]] 101 34
 // CHECK-NEXT: [[add:%\d+]] = OpFAdd %v2float
-// CHECK-NEXT:                OpLine [[file]] 105 12
+// CHECK-NEXT:                OpLine [[file]] 101 12
 // CHECK-NEXT:                OpBitcast %v2uint [[add]]
-// CHECK-NEXT:                OpLine [[file]] 105 3
+// CHECK-NEXT:                OpLine [[file]] 101 3
 // CHECK-NEXT:                OpLoad %v4uint %v4i
   v4i.xy = asuint(m2x2f._m00_m11 + v2f);
 
-// CHECK:      OpLine [[file]] 111 15
+// CHECK:      OpLine [[file]] 107 15
 // CHECK-NEXT: OpFMul %v2float
-// CHECK-NEXT: OpLine [[file]] 111 3
+// CHECK-NEXT: OpLine [[file]] 107 3
 // CHECK-NEXT: OpFOrdLessThan %v2bool
   clip(v4i.yz * m2x2f._m00_m11);
 
   float4 v4f;
 
-// CHECK:      OpLine [[file]] 119 37
+// CHECK:      OpLine [[file]] 115 37
 // CHECK-NEXT: OpFMul %float
-// CHECK:      OpLine [[file]] 119 9
+// CHECK:      OpLine [[file]] 115 9
 // CHECK-NEXT: OpConvertFToU %v4uint
   v4i = dst(v4f + 3 * v4f, v4f - v4f);
 
-// CHECK:      OpLine [[file]] 125 17
+// CHECK:      OpLine [[file]] 121 17
 // CHECK-NEXT: OpExtInst %float {{%\d+}} Exp2
-// CHECK:      OpLine [[file]] 125 11
+// CHECK:      OpLine [[file]] 121 11
 // CHECK-NEXT: OpBitcast %int
   v4i.x = asint(ldexp(v4f.x + v4f.y, v4f.w));
 
-// CHECK:      OpLine [[file]] 133 25
+// CHECK:      OpLine [[file]] 129 25
 // CHECK-NEXT: OpFAdd %float
-// CHECK-NEXT: OpLine [[file]] 133 34
+// CHECK-NEXT: OpLine [[file]] 129 34
 // CHECK-NEXT: OpAccessChain %_ptr_Function_float %v4f %int_3
-// CHECK-NEXT: OpLine [[file]] 133 13
+// CHECK-NEXT: OpLine [[file]] 129 13
 // CHECK-NEXT: OpExtInst %FrexpStructType {{%\d+}} FrexpStruct
   v4f = lit(frexp(v4f.x + v4f.y, v4f.w),
-// CHECK:                     OpLine [[file]] 137 13
+// CHECK:                     OpLine [[file]] 133 13
 // CHECK-NEXT: [[v4f:%\d+]] = OpAccessChain %_ptr_Function_float %v4f %int_2
 // CHECK-NEXT:                OpLoad %float [[v4f]]
             v4f.z,
-// CHECK:                       OpLine [[file]] 144 13
+// CHECK:                       OpLine [[file]] 140 13
 // CHECK-NEXT: [[clamp:%\d+]] = OpExtInst %uint {{%\d+}} UClamp
 // CHECK-NEXT:                  OpConvertUToF %float [[clamp]]
-// CHECK-NEXT:                  OpLine [[file]] 133 9
+// CHECK-NEXT:                  OpLine [[file]] 129 9
 // CHECK-NEXT:                  OpExtInst %float {{%\d+}} FMax %float_0
 // CHECK-NEXT:                  OpExtInst %float {{%\d+}} FMin
             clamp(v4i.x + v4i.y, 2 * v4i.z, v4i.w - v4i.z));
 
-// CHECK:                      OpLine [[file]] 150 33
+// CHECK:                      OpLine [[file]] 146 33
 // CHECK-NEXT: [[sign:%\d+]] = OpExtInst %v3float {{%\d+}} FSign
-// CHECK-NEXT:                 OpLine [[file]] 150 38
+// CHECK-NEXT:                 OpLine [[file]] 146 38
 // CHECK-NEXT:                 OpConvertFToS %v3int [[sign]]
   v4i = D3DCOLORtoUBYTE4(float4(sign(v4f.xyz - 2 * v4f.xyz),
-// CHECK:      OpLine [[file]] 153 33
+// CHECK:      OpLine [[file]] 149 33
 // CHECK-NEXT: OpExtInst %float {{%\d+}} FSign
                                 sign(v4f.w)));
-// CHECK:                     OpLine [[file]] 150 9
+// CHECK:                     OpLine [[file]] 146 9
 // CHECK-NEXT: [[arg:%\d+]] = OpVectorShuffle %v4float {{%\d+}} {{%\d+}} 2 1 0 3
 // CHECK-NEXT:                OpVectorTimesScalar %v4float [[arg]]
 
-// CHECK:      OpLine [[file]] 160 7
+// CHECK:      OpLine [[file]] 156 7
 // CHECK-NEXT: OpIsNan %v4bool
   if (isfinite(v4f).x)
-// CHECK:                     OpLine [[file]] 165 15
+// CHECK:                     OpLine [[file]] 161 15
 // CHECK-NEXT: [[rcp:%\d+]] = OpFDiv %v4float
-// CHECK-NEXT:                OpLine [[file]] 165 11
+// CHECK-NEXT:                OpLine [[file]] 161 11
 // CHECK-NEXT:                OpExtInst %v4float {{%\d+}} Sin [[rcp]]
     v4f = sin(rcp(v4f / v4i.x));
 
-// CHECK:                     OpLine [[file]] 172 20
+// CHECK:                     OpLine [[file]] 168 20
 // CHECK-NEXT:                OpExtInst %float {{%\d+}} Log2
-// CHECK:                     OpLine [[file]] 172 11
+// CHECK:                     OpLine [[file]] 168 11
 // CHECK-NEXT: [[arg:%\d+]] = OpCompositeConstruct %v2float
 // CHECK-NEXT:                OpExtInst %uint {{%\d+}} PackHalf2x16 [[arg]]
   v4i.x = f32tof16(log10(v2f.x * v2f.y + v4f.x));
 
-// CHECK:      OpLine [[file]] 176 3
+// CHECK:      OpLine [[file]] 172 3
 // CHECK-NEXT: OpTranspose %mat2v2float
   transpose(m2x2f + m2x2f);
 
-// CHECK:                     OpLine [[file]] 184 25
+// CHECK:                     OpLine [[file]] 180 25
 // CHECK-NEXT: [[abs:%\d+]] = OpExtInst %float {{%\d+}} FAbs
-// CHECK-NEXT:                OpLine [[file]] 184 20
+// CHECK-NEXT:                OpLine [[file]] 180 20
 // CHECK-NEXT:                OpExtInst %float {{%\d+}} Sqrt [[abs]]
-// CHECK:      OpLine [[file]] 184 7
+// CHECK:      OpLine [[file]] 180 7
 // CHECK-NEXT: OpExtInst %uint {{%\d+}} FindUMsb
   max(firstbithigh(sqrt(abs(v2f.x * v4f.w)) + v4i.x),
-// CHECK:      OpLine [[file]] 187 7
+// CHECK:      OpLine [[file]] 183 7
 // CHECK-NEXT: OpExtInst %float {{%\d+}} Cos %468
       cos(v4f.x));
-// CHECK:      OpLine [[file]] 184 3
+// CHECK:      OpLine [[file]] 180 3
 // CHECK-NEXT: OpExtInst %float {{%\d+}} FMax
 }

+ 13 - 15
tools/clang/test/CodeGenSPIRV/spirv.debug.opline.intrinsic.vulkan1.1.hlsl

@@ -3,58 +3,56 @@
 // CHECK:      [[file:%\d+]] = OpString
 // CHECK-SAME: spirv.debug.opline.intrinsic.vulkan1.1.hlsl
 
-// Note that preprocessor prepends a "#line 1 ..." line to the whole file and
-// the compliation sees line numbers incremented by 1.
 void main() {
-// CHECK:      OpLine [[file]] 14 11
+// CHECK:      OpLine [[file]] 11 11
 // CHECK:      OpLoad %uint %SubgroupSize
-// CHECK-NEXT: OpLine [[file]] 14 32
+// CHECK-NEXT: OpLine [[file]] 11 32
 // CHECK-NEXT: OpLoad %uint %SubgroupLocalInvocationId
   int i = WaveGetLaneCount() + WaveGetLaneIndex();
 
-// CHECK:      OpLine [[file]] 18 3
+// CHECK:      OpLine [[file]] 15 3
 // CHECK-NEXT: OpGroupNonUniformElect %bool %uint_3
   WaveIsFirstLane();
 
-// CHECK:      OpLine [[file]] 22 3
+// CHECK:      OpLine [[file]] 19 3
 // CHECK-NEXT: OpGroupNonUniformAll %bool %uint_3
   WaveActiveAllTrue(i == 1);
 
-// CHECK:      OpLine [[file]] 26 3
+// CHECK:      OpLine [[file]] 23 3
 // CHECK-NEXT: OpGroupNonUniformAny %bool %uint_3
   WaveActiveAnyTrue(i == 0);
 
-// CHECK:      OpLine [[file]] 30 3
+// CHECK:      OpLine [[file]] 27 3
 // CHECK-NEXT: OpGroupNonUniformBallot %v4uint %uint_3
   WaveActiveBallot(i == 2);
 
-// CHECK:      OpLine [[file]] 34 3
+// CHECK:      OpLine [[file]] 31 3
 // CHECK-NEXT: OpGroupNonUniformAllEqual %bool %uint_3
   WaveActiveAllEqual(i);
 
-// CHECK:      OpLine [[file]] 39 3
+// CHECK:      OpLine [[file]] 36 3
 // CHECK-NEXT: OpGroupNonUniformBallot %v4uint %uint_3
 // CHECK-NEXT: OpGroupNonUniformBallotBitCount %uint %uint_3 Reduce
   WaveActiveCountBits(i);
 
-// CHECK:      OpLine [[file]] 43 3
+// CHECK:      OpLine [[file]] 40 3
 // CHECK-NEXT: OpGroupNonUniformIAdd %int %uint_3 Reduce
   WaveActiveSum(i);
 
-// CHECK:      OpLine [[file]] 47 3
+// CHECK:      OpLine [[file]] 44 3
 // CHECK-NEXT: OpGroupNonUniformIAdd %int %uint_3 ExclusiveScan
   WavePrefixSum(i);
 
-// CHECK:      OpLine [[file]] 52 3
+// CHECK:      OpLine [[file]] 49 3
 // CHECK-NEXT: OpGroupNonUniformBallot %v4uint %uint_3
 // CHECK-NEXT: OpGroupNonUniformBallotBitCount %uint %uint_3 ExclusiveScan
   WavePrefixCountBits(i == 1);
 
-// CHECK:      OpLine [[file]] 56 3
+// CHECK:      OpLine [[file]] 53 3
 // CHECK-NEXT: OpGroupNonUniformBroadcast %int %uint_3
   WaveReadLaneAt(i, 15);
 
-// CHECK:      OpLine [[file]] 60 3
+// CHECK:      OpLine [[file]] 57 3
 // CHECK-NEXT: OpGroupNonUniformQuadBroadcast %int %uint_3
   QuadReadLaneAt(i, 15);
 }

+ 47 - 50
tools/clang/test/CodeGenSPIRV/spirv.debug.opline.operators.hlsl

@@ -5,171 +5,168 @@
 
 static int a, b, c;
 
-// Note that preprocessor prepends a "#line 1 ..." line to the whole file and
-// the compliation sees line numbers incremented by 1.
-
 void main() {
-// CHECK:      OpLine [[file]] 15 13
+// CHECK:      OpLine [[file]] 11 13
 // CHECK-NEXT: OpIAdd %int
   int d = a + b;
 
-// CHECK:      OpLine [[file]] 19 9
+// CHECK:      OpLine [[file]] 15 9
 // CHECK-NEXT: OpIMul %int
   c = a * b;
 
-// CHECK:      OpLine [[file]] 23 23
+// CHECK:      OpLine [[file]] 19 23
 // CHECK-NEXT: OpISub %int
   /* comment */ c = a - b;
 
-// CHECK:      OpLine [[file]] 27 9
+// CHECK:      OpLine [[file]] 23 9
 // CHECK-NEXT: OpSDiv %int
   c = a / b;
 
-// CHECK:      OpLine [[file]] 31 10
+// CHECK:      OpLine [[file]] 27 10
 // CHECK-NEXT: OpSLessThan %bool
   c = (a < b);
 
-// CHECK:      OpLine [[file]] 35 9
+// CHECK:      OpLine [[file]] 31 9
 // CHECK-NEXT: OpSGreaterThan %bool
   c = a > b;
 
-// CHECK:      OpLine [[file]] 39 11
+// CHECK:      OpLine [[file]] 35 11
 // CHECK-NEXT: OpLogicalAnd %bool
   c = (a) && b;
 
-// CHECK:      OpLine [[file]] 43 5
+// CHECK:      OpLine [[file]] 39 5
 // CHECK-NEXT: OpLogicalOr %bool
   a || b;
 
-// CHECK: OpLine [[file]] 47 5
+// CHECK: OpLine [[file]] 43 5
 // CHECK: OpShiftLeftLogical %int
   a << b;
 
-// CHECK: OpLine [[file]] 51 9
+// CHECK: OpLine [[file]] 47 9
 // CHECK: OpShiftRightArithmetic %int
   c = a >> b;
 
-// CHECK:      OpLine [[file]] 55 9
+// CHECK:      OpLine [[file]] 51 9
 // CHECK-NEXT: OpBitwiseAnd %int
   c = a & b;
 
-// CHECK:      OpLine [[file]] 59 7
+// CHECK:      OpLine [[file]] 55 7
 // CHECK-NEXT: OpNot %int
   c = ~b;
 
-// CHECK:      OpLine [[file]] 63 9
+// CHECK:      OpLine [[file]] 59 9
 // CHECK-NEXT: OpBitwiseXor %int
   c = a ^ b;
 
-// CHECK:      OpLine [[file]] 71 5
+// CHECK:      OpLine [[file]] 67 5
 // CHECK-NEXT: OpIAdd %int
-// CHECK:      OpLine [[file]] 71 11
+// CHECK:      OpLine [[file]] 67 11
 // CHECK-NEXT: OpNot %int
-// CHECK-NEXT: OpLine [[file]] 71 9
+// CHECK-NEXT: OpLine [[file]] 67 9
 // CHECK-NEXT: OpBitwiseXor %int
   c + a ^ ~b;
 
-// CHECK:      OpLine [[file]] 75 3
+// CHECK:      OpLine [[file]] 71 3
 // CHECK-NEXT: OpIAdd %int
   ++a;
 
-// CHECK:      OpLine [[file]] 79 4
+// CHECK:      OpLine [[file]] 75 4
 // CHECK-NEXT: OpIAdd %int
   a++;
 
-// CHECK:      OpLine [[file]] 83 4
+// CHECK:      OpLine [[file]] 79 4
 // CHECK-NEXT: OpISub %int
   a--;
 
-// CHECK:      OpLine [[file]] 87 3
+// CHECK:      OpLine [[file]] 83 3
 // CHECK-NEXT: OpISub %int
   --a;
 
-// CHECK: OpLine [[file]] 91 5
+// CHECK: OpLine [[file]] 87 5
 // CHECK: OpShiftLeftLogical %int
   a <<= 10;
 
-// CHECK:      OpLine [[file]] 95 5
+// CHECK:      OpLine [[file]] 91 5
 // CHECK-NEXT: OpISub %int
   a -= 10;
 
-// CHECK:      OpLine [[file]] 99 5
+// CHECK:      OpLine [[file]] 95 5
 // CHECK-NEXT: OpIMul %int
   a *= 10;
 
-// CHECK:      OpLine [[file]] 107 15
+// CHECK:      OpLine [[file]] 103 15
 // CHECK-NEXT: OpIAdd %int
-// CHECK-NEXT: OpLine [[file]] 107 10
+// CHECK-NEXT: OpLine [[file]] 103 10
 // CHECK-NEXT: OpIAdd %int
-// CHECK:      OpLine [[file]] 107 5
+// CHECK:      OpLine [[file]] 103 5
 // CHECK-NEXT: OpSDiv %int
   a /= d + (b + c);
 
-// CHECK:      OpLine [[file]] 113 10
+// CHECK:      OpLine [[file]] 109 10
 // CHECK-NEXT: OpSLessThan %bool
-// CHECK-NEXT: OpLine [[file]] 113 15
+// CHECK-NEXT: OpLine [[file]] 109 15
 // CHECK-NEXT: OpLogicalAnd %bool
   b = (a < c) && true;
 
-// CHECK:      OpLine [[file]] 117 5
+// CHECK:      OpLine [[file]] 113 5
 // CHECK-NEXT: OpIAdd %int
   a += c;
 
-// CHECK:      OpLine [[file]] 125 15
+// CHECK:      OpLine [[file]] 121 15
 // CHECK-NEXT: OpIMul %int %int_100
-// CHECK:      OpLine [[file]] 125 25
+// CHECK:      OpLine [[file]] 121 25
 // CHECK-NEXT: OpISub %int %int_20
-// CHECK-NEXT: OpLine [[file]] 125 19
+// CHECK-NEXT: OpLine [[file]] 121 19
 // CHECK-NEXT: OpSDiv %int
   d = a + 100 * b / (20 - c);
-// CHECK-NEXT: OpLine [[file]] 125 9
+// CHECK-NEXT: OpLine [[file]] 121 9
 // CHECK-NEXT: OpIAdd %int
 
   float2x2 m2x2f;
   int2x2 m2x2i;
 
-// CHECK:      OpLine [[file]] 136 13
+// CHECK:      OpLine [[file]] 132 13
 // CHECK-NEXT: OpMatrixTimesScalar %mat2v2float
-// CHECK:      OpLine [[file]] 136 21
+// CHECK:      OpLine [[file]] 132 21
 // CHECK-NEXT: OpFAdd %v2float
   m2x2f = 2 * m2x2f + m2x2i;
 
-// CHECK:      OpLine [[file]] 144 17
+// CHECK:      OpLine [[file]] 140 17
 // CHECK-NEXT: OpFMul %v2float
-// CHECK:      OpLine [[file]] 144 17
+// CHECK:      OpLine [[file]] 140 17
 // CHECK-NEXT: OpFMul %v2float
-// CHECK-NEXT: OpLine [[file]] 144 11
+// CHECK-NEXT: OpLine [[file]] 140 11
 // CHECK-NEXT: OpCompositeConstruct %mat2v2float
   m2x2f = m2x2f * m2x2i;
 
   float4 v4f;
   int4 v4i;
 
-// CHECK:      OpLine [[file]] 151 13
+// CHECK:      OpLine [[file]] 147 13
 // CHECK-NEXT: OpFDiv %v4float
   v4i = v4f / v4i;
 
-// CHECK:      OpLine [[file]] 159 17
+// CHECK:      OpLine [[file]] 155 17
 // CHECK-NEXT: OpFMul %v2float
-// CHECK:      OpLine [[file]] 159 17
+// CHECK:      OpLine [[file]] 155 17
 // CHECK-NEXT: OpFMul %v2float
-// CHECK-NEXT: OpLine [[file]] 159 11
+// CHECK-NEXT: OpLine [[file]] 155 11
 // CHECK-NEXT: OpCompositeConstruct %mat2v2float
   m2x2f = m2x2f * v4f;
 
-// CHECK:      OpLine [[file]] 163 17
+// CHECK:      OpLine [[file]] 159 17
 // CHECK-NEXT: OpMatrixTimesScalar %mat2v2float
   m2x2f = m2x2f * v4f.x;
 
-// CHECK:      OpLine [[file]] 169 8
+// CHECK:      OpLine [[file]] 165 8
 // CHECK-NEXT: OpIMul %v4int
-// CHECK:      OpLine [[file]] 169 13
+// CHECK:      OpLine [[file]] 165 13
 // CHECK-NEXT: OpFOrdLessThan %v4bool
   (v4i * a) < m2x2f;
 
-// CHECK:      OpLine [[file]] 175 8
+// CHECK:      OpLine [[file]] 171 8
 // CHECK-NEXT: OpSDiv %v4int
-// CHECK:      OpLine [[file]] 175 13
+// CHECK:      OpLine [[file]] 171 13
 // CHECK-NEXT: OpLogicalAnd %v4bool
   (v4i / a) && v4f;
 }

+ 2 - 2
tools/clang/test/CodeGenSPIRV/spirv.debug.opline.precedence.hlsl

@@ -7,7 +7,7 @@ void main() {
   int a;
   int b;
 
-//CHECK:      OpLine [[file]] 13 3
+//CHECK:      OpLine [[file]] 12 3
 //CHECK-NEXT: OpSelectionMerge %switch_merge None
   switch (a) {
   default:
@@ -19,7 +19,7 @@ void main() {
     b = 2;
   }
 
-//CHECK:      OpLine [[file]] 25 23
+//CHECK:      OpLine [[file]] 24 23
 //CHECK-NEXT: OpLoopMerge %for_merge %for_continue None
   for (int i = 0; i < 4; i++) {
     b += i;

+ 18 - 21
tools/clang/test/CodeGenSPIRV/spirv.debug.opline.variables.hlsl

@@ -7,22 +7,19 @@ struct S {
   float4 f;
 };
 
-// Note that preprocessor prepends a "#line 1 ..." line to the whole file,
-// the compliation sees line numbers incremented by 1.
-
-// CHECK:                        OpLine [[file]] 16 32
+// CHECK:                        OpLine [[file]] 12 32
 // CHECK-NEXT: %consume_v2bool = OpVariable %_ptr_Uniform_type_ConsumeStructuredBuffer_v2bool Uniform
 ConsumeStructuredBuffer<bool2> consume_v2bool;
 
-// CHECK:                        OpLine [[file]] 20 32
+// CHECK:                        OpLine [[file]] 16 32
 // CHECK-NEXT: %append_v2float = OpVariable %_ptr_Uniform_type_AppendStructuredBuffer_v2float Uniform
 AppendStructuredBuffer<float2> append_v2float;
 
-// CHECK:                       OpLine [[file]] 24 19
+// CHECK:                       OpLine [[file]] 20 19
 // CHECK-NEXT: %byte_addr_buf = OpVariable %_ptr_Uniform_type_ByteAddressBuffer Uniform
 ByteAddressBuffer byte_addr_buf;
 
-// CHECK:                    OpLine [[file]] 28 19
+// CHECK:                    OpLine [[file]] 24 19
 // CHECK-NEXT: %rw_texture = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
 RWTexture2D<int3> rw_texture;
 
@@ -30,33 +27,33 @@ RWTexture2D<int3> rw_texture;
 //                we must emit "OpLine .." here.
 TextureBuffer<S> texture_buf;
 
-// CHECK:             OpLine [[file]] 36 14
+// CHECK:             OpLine [[file]] 32 14
 // CHECK-NEXT: %sam = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
 SamplerState sam;
 
-// CHECK:                     OpLine [[file]] 40 19
+// CHECK:                     OpLine [[file]] 36 19
 // CHECK-NEXT: %float_array = OpVariable %_ptr_Workgroup__arr_float_uint_10 Workgroup
 groupshared float float_array[10];
 
-// CHECK:                     OpLine [[file]] 44 12
+// CHECK:                     OpLine [[file]] 40 12
 // CHECK-NEXT:   %int_array = OpVariable %_ptr_Private__arr_int_uint_10 Private
 static int int_array[10];
 
 // "static" variables in functions must be defined first.
-// CHECK:                     OpLine [[file]] 65 16
+// CHECK:                     OpLine [[file]] 61 16
 // CHECK-NEXT:           %c = OpVariable %_ptr_Private_v3bool Private
 // CHECK-NEXT: %init_done_c = OpVariable %_ptr_Private_bool Private %false
 
 bool3 test_function_variables() {
-// CHECK:                     OpLine [[file]] 54 9
+// CHECK:                     OpLine [[file]] 50 9
 // CHECK-NEXT:         %a_0 = OpVariable %_ptr_Function_v3bool Function
   bool3 a;
 
-// CHECK-NEXT:                OpLine [[file]] 58 22
+// CHECK-NEXT:                OpLine [[file]] 54 22
 // CHECK-NEXT:         %b_0 = OpVariable %_ptr_Function_mat2v3float Function
   row_major float2x3 b;
 
-// CHECK:                      OpLine [[file]] 65 20
+// CHECK:                      OpLine [[file]] 61 20
 // CHECK-NEXT: [[init:%\d+]] = OpLoad %bool %init_done_c
 // CHECK-NEXT:                 OpSelectionMerge %if_init_done None
 // CHECK-NEXT:                 OpBranchConditional [[init]] %if_init_done %if_init_todo
@@ -69,22 +66,22 @@ bool3 test_function_variables() {
   return c;
 }
 
-// CHECK:                     OpLine [[file]] 79 1
+// CHECK:                     OpLine [[file]] 75 1
 // CHECK-NEXT: %test_function_param = OpFunction %v2float None
-// CHECK-NEXT:                OpLine [[file]] 79 35
+// CHECK-NEXT:                OpLine [[file]] 75 35
 // CHECK-NEXT:         %a_1 = OpFunctionParameter %_ptr_Function_v2float
-// CHECK-NEXT:                OpLine [[file]] 79 50
+// CHECK-NEXT:                OpLine [[file]] 75 50
 // CHECK-NEXT:         %b_1 = OpFunctionParameter %_ptr_Function_v3bool
 float2 test_function_param(float2 a, inout bool3 b,
-// CHECK-NEXT:                OpLine [[file]] 84 38
+// CHECK-NEXT:                OpLine [[file]] 80 38
 // CHECK-NEXT:         %c_1 = OpFunctionParameter %_ptr_Function_int
-// CHECK-NEXT:                OpLine [[file]] 84 52
+// CHECK-NEXT:                OpLine [[file]] 80 52
 // CHECK-NEXT:         %d_0 = OpFunctionParameter %_ptr_Function_v3float
                            const int c, out float3 d,
-// CHECK-NEXT:                OpLine [[file]] 87 33
+// CHECK-NEXT:                OpLine [[file]] 83 33
 // CHECK-NEXT:           %e = OpFunctionParameter %_ptr_Function_bool
                            bool e) {
-// CHECK:                     OpLine [[file]] 90 9
+// CHECK:                     OpLine [[file]] 86 9
 // CHECK-NEXT:           %f = OpVariable %_ptr_Function__arr_float_uint_2 Function
   float f[2];
   return a + d.xy + float2(f);

+ 3 - 0
tools/clang/unittests/SPIRV/CodeGenSpirvTest.cpp

@@ -1476,6 +1476,9 @@ TEST_F(FileTest, SpirvDebugOpLineOperators) {
 TEST_F(FileTest, SpirvDebugOpLineVariables) {
   runFileTest("spirv.debug.opline.variables.hlsl");
 }
+TEST_F(FileTest, SpirvDebugOpLineInclude) {
+  runFileTest("spirv.debug.opline.include.hlsl");
+}
 
 TEST_F(FileTest, SpirvDebugDxcCommitInfo) {
   useVulkan1p1();