[llvm] [SPIRV] Emitting DebugSource, DebugCompileUnit (PR #97558)

via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 19 03:26:03 PDT 2024


https://github.com/bwlodarcz updated https://github.com/llvm/llvm-project/pull/97558

>From cd77f0ebb85ea2f607fc71a2c7e17799d1814c08 Mon Sep 17 00:00:00 2001
From: "Wlodarczyk, Bertrand" <bertrand.wlodarczyk at intel.com>
Date: Fri, 28 Jun 2024 13:17:42 +0200
Subject: [PATCH 01/16] [SPIRV] Added new stub pass for NonSemantic DI

The commit adds new empty pass for emission of
NonSemantic.Shader.DebugInfo.100 instructions.
The pass is a basis for future development and
can be (and likely will be) a subject of change.
In addition to that there is additional unused function
which main purpose is to be basis of accessing global
metadata which is inaccessible in MIR. Accessing such
metadata is necessary for emitting such instructions
like DebugCompilationUnit or DebugSource.
---
 llvm/lib/Target/SPIRV/CMakeLists.txt          |  1 +
 llvm/lib/Target/SPIRV/SPIRV.h                 |  2 +
 .../Target/SPIRV/SPIRVEmitNonSemanticDI.cpp   | 55 +++++++++++++++++++
 llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp  |  1 +
 4 files changed, 59 insertions(+)
 create mode 100644 llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp

diff --git a/llvm/lib/Target/SPIRV/CMakeLists.txt b/llvm/lib/Target/SPIRV/CMakeLists.txt
index 14647e92f5d088..5f8aea5fc8d84d 100644
--- a/llvm/lib/Target/SPIRV/CMakeLists.txt
+++ b/llvm/lib/Target/SPIRV/CMakeLists.txt
@@ -40,6 +40,7 @@ add_llvm_target(SPIRVCodeGen
   SPIRVSubtarget.cpp
   SPIRVTargetMachine.cpp
   SPIRVUtils.cpp
+  SPIRVEmitNonSemanticDI.cpp
 
   LINK_COMPONENTS
   Analysis
diff --git a/llvm/lib/Target/SPIRV/SPIRV.h b/llvm/lib/Target/SPIRV/SPIRV.h
index e597a1dc8dc06c..c32bf6f5a863d5 100644
--- a/llvm/lib/Target/SPIRV/SPIRV.h
+++ b/llvm/lib/Target/SPIRV/SPIRV.h
@@ -26,6 +26,7 @@ FunctionPass *createSPIRVRegularizerPass();
 FunctionPass *createSPIRVPreLegalizerPass();
 FunctionPass *createSPIRVPostLegalizerPass();
 ModulePass *createSPIRVEmitIntrinsicsPass(SPIRVTargetMachine *TM);
+MachineFunctionPass *createSPIRVEmitNonSemanticDIPass();
 InstructionSelector *
 createSPIRVInstructionSelector(const SPIRVTargetMachine &TM,
                                const SPIRVSubtarget &Subtarget,
@@ -36,6 +37,7 @@ void initializeSPIRVConvergenceRegionAnalysisWrapperPassPass(PassRegistry &);
 void initializeSPIRVPreLegalizerPass(PassRegistry &);
 void initializeSPIRVPostLegalizerPass(PassRegistry &);
 void initializeSPIRVEmitIntrinsicsPass(PassRegistry &);
+void initializeSPIRVEmitNonSemanticDIPass(PassRegistry &);
 } // namespace llvm
 
 #endif // LLVM_LIB_TARGET_SPIRV_SPIRV_H
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
new file mode 100644
index 00000000000000..5b938047025d13
--- /dev/null
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -0,0 +1,55 @@
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/PassRegistry.h"
+#include "llvm/Support/Casting.h"
+
+namespace llvm {
+struct SPIRVEmitNonSemanticDI : public MachineFunctionPass {
+  static char ID;
+  SPIRVEmitNonSemanticDI();
+
+  bool runOnMachineFunction(MachineFunction &MF) override;
+};
+
+void initializeSPIRVEmitNonSemanticDIPass(PassRegistry &);
+
+FunctionPass *createSPIRVEmitNonSemanticDIPass() {
+  return new SPIRVEmitNonSemanticDI();
+}
+} // namespace llvm
+
+using namespace llvm;
+
+INITIALIZE_PASS(SPIRVEmitNonSemanticDI, "spirv-nonsemantic-debug-info",
+                "SPIRV NonSemantic.Shader.DebugInfo.100 emitter", false, false)
+
+char SPIRVEmitNonSemanticDI::ID = 0;
+
+SPIRVEmitNonSemanticDI::SPIRVEmitNonSemanticDI() : MachineFunctionPass(ID) {
+  initializeSPIRVEmitNonSemanticDIPass(*PassRegistry::getPassRegistry());
+}
+
+[[maybe_unused]]
+static void findCompileUnitDI(const MachineFunction &MF) {
+  MachineModuleInfo &MMI = MF.getMMI();
+  const Module *M = MMI.getModule();
+  NamedMDNode *DbgCu = M->getNamedMetadata("llvm.dbg.cu");
+  std::string FilePath;
+  if (DbgCu) {
+    unsigned NumOp = DbgCu->getNumOperands();
+    if (NumOp) {
+      if (const auto *CompileUnit =
+              dyn_cast<DICompileUnit>(DbgCu->getOperand(0))) {
+        DIFile *File = CompileUnit->getFile();
+        FilePath = ((File->getDirectory() + "/" + File->getFilename())).str();
+      }
+    }
+  }
+}
+
+bool SPIRVEmitNonSemanticDI::runOnMachineFunction(MachineFunction &MF) {
+  return false;
+}
diff --git a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
index 52fc6f33b4ef14..ee71190bc02ffd 100644
--- a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
@@ -199,6 +199,7 @@ void SPIRVPassConfig::addPreLegalizeMachineIR() {
 bool SPIRVPassConfig::addLegalizeMachineIR() {
   addPass(new Legalizer());
   addPass(createSPIRVPostLegalizerPass());
+  addPass(createSPIRVEmitNonSemanticDIPass());
   return false;
 }
 

>From e0d1346386262cf7f440fa4567a019050c6c23ef Mon Sep 17 00:00:00 2001
From: "Wlodarczyk, Bertrand" <bertrand.wlodarczyk at intel.com>
Date: Wed, 3 Jul 2024 12:59:41 +0200
Subject: [PATCH 02/16] [SPIRV] Emitting DebugSource, DebugCompileUnit
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This commit introduces emission of DebugSource, DebugCompileUnit from NonSemantic.Shader.DebugInfo.100 and required OpString with filename.
NonSemantic.Shader.DebugInfo.100 is divided, following DWARF into two main concepts – emitting DIE and Line . In DWARF .debug_abbriev and .debug_line sections
are responsible for emitting tree with information (DEIs) about e.g. types, compilation unit.
Corresponding to that in NonSemantic.Shader.DebugInfo.100 have instructions like DebugSource, DebugCompileUnit etc. which preforms same role in SPIR-V file. The difference is in fact that in SPIR-V there are no sections but logical layout
which forces order of the instruction emission.
The NonSemantic.Shader.DebugInfo.100 requires for this type of global information to be emitted after OpTypeXXX
and OpConstantXXX instructions.
One of the goals was to minimize changes and interaction with SPIRVModuleAnalysis as possible which current commit achieves by emitting it’s instructions
directly into MachineFunction. The possibility of duplicates are mitigated by guard inside pass which emits the global information only once in one function.
By that method duplicates don’t have chance to be emitted.
>From that point, adding new debug global instructions should be straightforward.
---
 llvm/lib/Target/SPIRV/SPIRV.h                 |   2 +-
 llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp     |   8 +-
 .../Target/SPIRV/SPIRVEmitNonSemanticDI.cpp   | 119 ++++++++++++++++--
 llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp |  18 ++-
 llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h   |   3 +-
 llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp  |   2 +-
 6 files changed, 132 insertions(+), 20 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRV.h b/llvm/lib/Target/SPIRV/SPIRV.h
index c32bf6f5a863d5..6c35a467f53bef 100644
--- a/llvm/lib/Target/SPIRV/SPIRV.h
+++ b/llvm/lib/Target/SPIRV/SPIRV.h
@@ -26,7 +26,7 @@ FunctionPass *createSPIRVRegularizerPass();
 FunctionPass *createSPIRVPreLegalizerPass();
 FunctionPass *createSPIRVPostLegalizerPass();
 ModulePass *createSPIRVEmitIntrinsicsPass(SPIRVTargetMachine *TM);
-MachineFunctionPass *createSPIRVEmitNonSemanticDIPass();
+MachineFunctionPass *createSPIRVEmitNonSemanticDIPass(SPIRVTargetMachine *TM);
 InstructionSelector *
 createSPIRVInstructionSelector(const SPIRVTargetMachine &TM,
                                const SPIRVSubtarget &Subtarget,
diff --git a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
index 7fe8e11aaa4209..55b41627802096 100644
--- a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
@@ -274,6 +274,8 @@ void SPIRVAsmPrinter::outputDebugSourceAndStrings(const Module &M) {
     addStringImm(Str.first(), Inst);
     outputMCInst(Inst);
   }
+  // Output OpString.
+  outputModuleSection(SPIRV::MB_DebugStrings);
   // Output OpSource.
   MCInst Inst;
   Inst.setOpcode(SPIRV::OpSource);
@@ -589,9 +591,11 @@ void SPIRVAsmPrinter::outputModuleSections() {
   // the first section to allow use of: OpLine and OpNoLine debug information;
   // non-semantic instructions with OpExtInst.
   outputModuleSection(SPIRV::MB_TypeConstVars);
-  // 10. All function declarations (functions without a body).
+  // 10. All global NonSemantic.Shader.DebugInfo.100 instructions.
+  outputModuleSection(SPIRV::MB_NonSemanticGlobalDI);
+  // 11. All function declarations (functions without a body).
   outputExtFuncDecls();
-  // 11. All function definitions (functions with a body).
+  // 12. All function definitions (functions with a body).
   // This is done in regular function output.
 }
 
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
index 5b938047025d13..f630685d98ac8b 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -1,6 +1,14 @@
+#include "MCTargetDesc/SPIRVBaseInfo.h"
+#include "SPIRVGlobalRegistry.h"
+#include "SPIRVRegisterInfo.h"
+#include "SPIRVTargetMachine.h"
+#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineOperand.h"
 #include "llvm/IR/DebugInfoMetadata.h"
 #include "llvm/IR/Metadata.h"
 #include "llvm/PassRegistry.h"
@@ -9,15 +17,21 @@
 namespace llvm {
 struct SPIRVEmitNonSemanticDI : public MachineFunctionPass {
   static char ID;
+  SPIRVTargetMachine *TM;
+  SPIRVEmitNonSemanticDI(SPIRVTargetMachine *TM);
   SPIRVEmitNonSemanticDI();
 
   bool runOnMachineFunction(MachineFunction &MF) override;
+
+private:
+  bool IsGlobalDIEmitted = false;
+  bool emitGlobalDI(MachineFunction &MF);
 };
 
 void initializeSPIRVEmitNonSemanticDIPass(PassRegistry &);
 
-FunctionPass *createSPIRVEmitNonSemanticDIPass() {
-  return new SPIRVEmitNonSemanticDI();
+FunctionPass *createSPIRVEmitNonSemanticDIPass(SPIRVTargetMachine *TM) {
+  return new SPIRVEmitNonSemanticDI(TM);
 }
 } // namespace llvm
 
@@ -28,28 +42,107 @@ INITIALIZE_PASS(SPIRVEmitNonSemanticDI, "spirv-nonsemantic-debug-info",
 
 char SPIRVEmitNonSemanticDI::ID = 0;
 
+SPIRVEmitNonSemanticDI::SPIRVEmitNonSemanticDI(SPIRVTargetMachine *TM)
+    : MachineFunctionPass(ID), TM(TM) {
+  initializeSPIRVEmitNonSemanticDIPass(*PassRegistry::getPassRegistry());
+}
+
 SPIRVEmitNonSemanticDI::SPIRVEmitNonSemanticDI() : MachineFunctionPass(ID) {
   initializeSPIRVEmitNonSemanticDIPass(*PassRegistry::getPassRegistry());
 }
 
-[[maybe_unused]]
-static void findCompileUnitDI(const MachineFunction &MF) {
+bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
   MachineModuleInfo &MMI = MF.getMMI();
   const Module *M = MMI.getModule();
   NamedMDNode *DbgCu = M->getNamedMetadata("llvm.dbg.cu");
+  if (!DbgCu) {
+    return false;
+  }
   std::string FilePath;
-  if (DbgCu) {
-    unsigned NumOp = DbgCu->getNumOperands();
-    if (NumOp) {
-      if (const auto *CompileUnit =
-              dyn_cast<DICompileUnit>(DbgCu->getOperand(0))) {
-        DIFile *File = CompileUnit->getFile();
-        FilePath = ((File->getDirectory() + "/" + File->getFilename())).str();
-      }
+  unsigned SourceLanguage;
+  unsigned NumOp = DbgCu->getNumOperands();
+  if (NumOp) {
+    if (const auto *CompileUnit =
+            dyn_cast<DICompileUnit>(DbgCu->getOperand(0))) {
+      DIFile *File = CompileUnit->getFile();
+      FilePath = ((File->getDirectory() + "/" + File->getFilename())).str();
+      SourceLanguage = CompileUnit->getSourceLanguage();
+    }
+  }
+  NamedMDNode *ModuleFlags = M->getNamedMetadata("llvm.module.flags");
+  int64_t DwarfVersion = 0;
+  int64_t DebugInfoVersion = 0;
+  for (auto *Op : ModuleFlags->operands()) {
+    const MDOperand &StrOp = Op->getOperand(1);
+    if (StrOp.equalsStr("Dwarf Version")) {
+      DwarfVersion =
+          cast<ConstantInt>(
+              cast<ConstantAsMetadata>(Op->getOperand(2))->getValue())
+              ->getSExtValue();
+    } else if (StrOp.equalsStr("Debug Info Version")) {
+      DebugInfoVersion =
+          cast<ConstantInt>(
+              cast<ConstantAsMetadata>(Op->getOperand(2))->getValue())
+              ->getSExtValue();
     }
   }
+  const SPIRVInstrInfo *TII = TM->getSubtargetImpl()->getInstrInfo();
+  const SPIRVRegisterInfo *TRI = TM->getSubtargetImpl()->getRegisterInfo();
+  const RegisterBankInfo *RBI = TM->getSubtargetImpl()->getRegBankInfo();
+  SPIRVGlobalRegistry *GR = TM->getSubtargetImpl()->getSPIRVGlobalRegistry();
+  MachineRegisterInfo &MRI = MF.getRegInfo();
+  for (MachineBasicBlock &MBB : MF) {
+    MachineIRBuilder MIRBuilder(MBB, MBB.begin());
+
+    MachineInstrBuilder MIB = MIRBuilder.buildInstr(SPIRV::OpString);
+    Register StrReg = MRI.createVirtualRegister(&SPIRV::IDRegClass);
+    MachineOperand StrRegOp = MachineOperand::CreateReg(StrReg, true);
+    MIB.add(StrRegOp);
+    addStringImm(FilePath, MIB);
+
+    const MachineInstr *VoidTyMI =
+        GR->getOrCreateSPIRVType(Type::getVoidTy(M->getContext()), MIRBuilder);
+
+    MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst);
+    Register DebugSourceResIdReg =
+        MRI.createVirtualRegister(&SPIRV::IDRegClass);
+    MIB.addDef(DebugSourceResIdReg);              // Result ID
+    MIB.addUse(VoidTyMI->getOperand(0).getReg()); // Result Type
+    MIB.addImm(static_cast<int64_t>(
+        SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100)); // Set ID
+    MIB.addImm(SPIRV::NonSemanticExtInst::DebugSource);            //
+    MIB.addUse(StrReg);
+    MIB.constrainAllUses(*TII, *TRI, *RBI);
+
+    Register DwarfVersionReg = GR->buildConstantInt(DwarfVersion, MIRBuilder);
+    Register DebugInfoVersionReg =
+        GR->buildConstantInt(DebugInfoVersion, MIRBuilder);
+    Register SourceLanguageReg =
+        GR->buildConstantInt(SourceLanguage, MIRBuilder);
+
+    MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst);
+    Register DebugCompUnitResIdReg =
+        MRI.createVirtualRegister(&SPIRV::IDRegClass);
+    MIB.addDef(DebugCompUnitResIdReg);            // Result ID
+    MIB.addUse(VoidTyMI->getOperand(0).getReg()); // Result Type
+    MIB.addImm(static_cast<int64_t>(
+        SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100)); // Set ID
+    MIB.addImm(SPIRV::NonSemanticExtInst::DebugCompilationUnit);
+    MIB.addUse(DebugInfoVersionReg);
+    MIB.addUse(DwarfVersionReg);
+    MIB.addUse(DebugSourceResIdReg);
+    MIB.addUse(SourceLanguageReg);
+    MIB.constrainAllUses(*TII, *TRI, *RBI);
+  }
+
+  return true;
 }
 
 bool SPIRVEmitNonSemanticDI::runOnMachineFunction(MachineFunction &MF) {
-  return false;
+  bool Res = false;
+  if (!IsGlobalDIEmitted) {
+    Res = emitGlobalDI(MF);
+    IsGlobalDIEmitted = true;
+  }
+  return Res;
 }
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index ac0aa682ea4beb..32ca6c4155dfed 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -21,7 +21,6 @@
 #include "SPIRVSubtarget.h"
 #include "SPIRVTargetMachine.h"
 #include "SPIRVUtils.h"
-#include "TargetInfo/SPIRVTargetInfo.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/TargetPassConfig.h"
@@ -427,7 +426,22 @@ void SPIRVModuleAnalysis::processOtherInstrs(const Module &M) {
         if (MAI.getSkipEmission(&MI))
           continue;
         const unsigned OpCode = MI.getOpcode();
-        if (OpCode == SPIRV::OpName || OpCode == SPIRV::OpMemberName) {
+        if (OpCode == SPIRV::OpString) {
+          collectOtherInstr(MI, MAI, SPIRV::MB_DebugStrings, IS);
+        } else if (OpCode == SPIRV::OpExtInst) {
+          MachineOperand Ins = MI.getOperand(3);
+          namespace NS = SPIRV::NonSemanticExtInst;
+          static constexpr int64_t GlobalNonSemanticDITy[] = {
+              NS::DebugSource, NS::DebugCompilationUnit};
+          bool IsGlobalDI = false;
+          for (unsigned Idx = 0; Idx < std::size(GlobalNonSemanticDITy);
+               ++Idx) {
+            IsGlobalDI |= Ins.getImm() == GlobalNonSemanticDITy[Idx];
+          }
+          if (IsGlobalDI) {
+            collectOtherInstr(MI, MAI, SPIRV::MB_NonSemanticGlobalDI, IS);
+          }
+        } else if (OpCode == SPIRV::OpName || OpCode == SPIRV::OpMemberName) {
           collectOtherInstr(MI, MAI, SPIRV::MB_DebugNames, IS);
         } else if (OpCode == SPIRV::OpEntryPoint) {
           collectOtherInstr(MI, MAI, SPIRV::MB_EntryPoints, IS);
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h
index 79226d6d93efb2..024728c347e8a8 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h
@@ -20,7 +20,6 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
 
 namespace llvm {
 class SPIRVSubtarget;
@@ -34,9 +33,11 @@ enum ModuleSectionType {
   MB_EntryPoints, // All OpEntryPoint instructions (if any).
   //  MB_ExecutionModes, MB_DebugSourceAndStrings,
   MB_DebugNames,           // All OpName and OpMemberName intrs.
+  MB_DebugStrings,         // All OpString intrs.
   MB_DebugModuleProcessed, // All OpModuleProcessed instructions.
   MB_Annotations,          // OpDecorate, OpMemberDecorate etc.
   MB_TypeConstVars,        // OpTypeXXX, OpConstantXXX, and global OpVariables.
+  MB_NonSemanticGlobalDI,  // OpExtInst with e.g. DebugSource, DebugTypeBasic.
   MB_ExtFuncDecls,         // OpFunction etc. to declare for external funcs.
   NUM_MODULE_SECTIONS      // Total number of sections requiring basic blocks.
 };
diff --git a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
index ee71190bc02ffd..bffc079981bc11 100644
--- a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
@@ -199,7 +199,7 @@ void SPIRVPassConfig::addPreLegalizeMachineIR() {
 bool SPIRVPassConfig::addLegalizeMachineIR() {
   addPass(new Legalizer());
   addPass(createSPIRVPostLegalizerPass());
-  addPass(createSPIRVEmitNonSemanticDIPass());
+  addPass(createSPIRVEmitNonSemanticDIPass(&getTM<SPIRVTargetMachine>()));
   return false;
 }
 

>From 5f69997fe8dcbdaf1e570212a3b39212da742bb5 Mon Sep 17 00:00:00 2001
From: "Wlodarczyk, Bertrand" <bertrand.wlodarczyk at intel.com>
Date: Thu, 4 Jul 2024 17:49:29 +0200
Subject: [PATCH 03/16] Fixes after CR

---
 .../Target/SPIRV/SPIRVEmitNonSemanticDI.cpp   | 122 ++++++++++--------
 llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp |   7 +-
 2 files changed, 67 insertions(+), 62 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
index f630685d98ac8b..bc39ce11222be0 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -3,6 +3,7 @@
 #include "SPIRVRegisterInfo.h"
 #include "SPIRVTargetMachine.h"
 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineInstr.h"
@@ -13,6 +14,9 @@
 #include "llvm/IR/Metadata.h"
 #include "llvm/PassRegistry.h"
 #include "llvm/Support/Casting.h"
+#include "llvm/Support/Path.h"
+
+#define DEBUG_TYPE "spirv-nonsemantic-debug-info"
 
 namespace llvm {
 struct SPIRVEmitNonSemanticDI : public MachineFunctionPass {
@@ -37,7 +41,7 @@ FunctionPass *createSPIRVEmitNonSemanticDIPass(SPIRVTargetMachine *TM) {
 
 using namespace llvm;
 
-INITIALIZE_PASS(SPIRVEmitNonSemanticDI, "spirv-nonsemantic-debug-info",
+INITIALIZE_PASS(SPIRVEmitNonSemanticDI, DEBUG_TYPE,
                 "SPIRV NonSemantic.Shader.DebugInfo.100 emitter", false, false)
 
 char SPIRVEmitNonSemanticDI::ID = 0;
@@ -52,88 +56,92 @@ SPIRVEmitNonSemanticDI::SPIRVEmitNonSemanticDI() : MachineFunctionPass(ID) {
 }
 
 bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
+  if (MF.begin() == MF.end()) {
+    IsGlobalDIEmitted = false;
+    return false;
+  }
   MachineModuleInfo &MMI = MF.getMMI();
   const Module *M = MMI.getModule();
   NamedMDNode *DbgCu = M->getNamedMetadata("llvm.dbg.cu");
-  if (!DbgCu) {
+  if (!DbgCu)
     return false;
-  }
   std::string FilePath;
-  unsigned SourceLanguage;
-  unsigned NumOp = DbgCu->getNumOperands();
-  if (NumOp) {
-    if (const auto *CompileUnit =
-            dyn_cast<DICompileUnit>(DbgCu->getOperand(0))) {
+  unsigned SourceLanguage = 0;
+  for (auto *Op : DbgCu->operands()) {
+    if (const auto *CompileUnit = dyn_cast<DICompileUnit>(Op)) {
       DIFile *File = CompileUnit->getFile();
-      FilePath = ((File->getDirectory() + "/" + File->getFilename())).str();
+      FilePath = ((File->getDirectory() + sys::path::get_separator() +
+                   File->getFilename()))
+                     .str();
       SourceLanguage = CompileUnit->getSourceLanguage();
+      break;
     }
   }
   NamedMDNode *ModuleFlags = M->getNamedMetadata("llvm.module.flags");
   int64_t DwarfVersion = 0;
   int64_t DebugInfoVersion = 0;
   for (auto *Op : ModuleFlags->operands()) {
-    const MDOperand &StrOp = Op->getOperand(1);
-    if (StrOp.equalsStr("Dwarf Version")) {
+    const MDOperand &MaybeStrOp = Op->getOperand(1);
+    if (MaybeStrOp.equalsStr("Dwarf Version"))
       DwarfVersion =
           cast<ConstantInt>(
               cast<ConstantAsMetadata>(Op->getOperand(2))->getValue())
               ->getSExtValue();
-    } else if (StrOp.equalsStr("Debug Info Version")) {
+    else if (MaybeStrOp.equalsStr("Debug Info Version"))
       DebugInfoVersion =
           cast<ConstantInt>(
               cast<ConstantAsMetadata>(Op->getOperand(2))->getValue())
               ->getSExtValue();
-    }
   }
   const SPIRVInstrInfo *TII = TM->getSubtargetImpl()->getInstrInfo();
   const SPIRVRegisterInfo *TRI = TM->getSubtargetImpl()->getRegisterInfo();
   const RegisterBankInfo *RBI = TM->getSubtargetImpl()->getRegBankInfo();
   SPIRVGlobalRegistry *GR = TM->getSubtargetImpl()->getSPIRVGlobalRegistry();
   MachineRegisterInfo &MRI = MF.getRegInfo();
-  for (MachineBasicBlock &MBB : MF) {
-    MachineIRBuilder MIRBuilder(MBB, MBB.begin());
-
-    MachineInstrBuilder MIB = MIRBuilder.buildInstr(SPIRV::OpString);
-    Register StrReg = MRI.createVirtualRegister(&SPIRV::IDRegClass);
-    MachineOperand StrRegOp = MachineOperand::CreateReg(StrReg, true);
-    MIB.add(StrRegOp);
-    addStringImm(FilePath, MIB);
-
-    const MachineInstr *VoidTyMI =
-        GR->getOrCreateSPIRVType(Type::getVoidTy(M->getContext()), MIRBuilder);
-
-    MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst);
-    Register DebugSourceResIdReg =
-        MRI.createVirtualRegister(&SPIRV::IDRegClass);
-    MIB.addDef(DebugSourceResIdReg);              // Result ID
-    MIB.addUse(VoidTyMI->getOperand(0).getReg()); // Result Type
-    MIB.addImm(static_cast<int64_t>(
-        SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100)); // Set ID
-    MIB.addImm(SPIRV::NonSemanticExtInst::DebugSource);            //
-    MIB.addUse(StrReg);
-    MIB.constrainAllUses(*TII, *TRI, *RBI);
-
-    Register DwarfVersionReg = GR->buildConstantInt(DwarfVersion, MIRBuilder);
-    Register DebugInfoVersionReg =
-        GR->buildConstantInt(DebugInfoVersion, MIRBuilder);
-    Register SourceLanguageReg =
-        GR->buildConstantInt(SourceLanguage, MIRBuilder);
-
-    MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst);
-    Register DebugCompUnitResIdReg =
-        MRI.createVirtualRegister(&SPIRV::IDRegClass);
-    MIB.addDef(DebugCompUnitResIdReg);            // Result ID
-    MIB.addUse(VoidTyMI->getOperand(0).getReg()); // Result Type
-    MIB.addImm(static_cast<int64_t>(
-        SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100)); // Set ID
-    MIB.addImm(SPIRV::NonSemanticExtInst::DebugCompilationUnit);
-    MIB.addUse(DebugInfoVersionReg);
-    MIB.addUse(DwarfVersionReg);
-    MIB.addUse(DebugSourceResIdReg);
-    MIB.addUse(SourceLanguageReg);
-    MIB.constrainAllUses(*TII, *TRI, *RBI);
-  }
+  MachineBasicBlock &MBB = *MF.begin();
+  MachineIRBuilder MIRBuilder(MBB, MBB.begin());
+
+  MachineInstrBuilder MIB = MIRBuilder.buildInstr(SPIRV::OpString);
+  Register StrReg = MRI.createVirtualRegister(&SPIRV::IDRegClass);
+  MRI.setType(StrReg, LLT::scalar(32));
+
+  MachineOperand StrRegOp = MachineOperand::CreateReg(StrReg, true);
+  MIB.add(StrRegOp);
+  addStringImm(FilePath, MIB);
+
+  SPIRVType *VoidTyMI =
+      GR->getOrCreateSPIRVType(Type::getVoidTy(M->getContext()), MIRBuilder);
+
+  Register DebugSourceResIdReg = MRI.createVirtualRegister(&SPIRV::IDRegClass);
+  MRI.setType(DebugSourceResIdReg, LLT::scalar(32));
+  MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst)
+            .addDef(DebugSourceResIdReg)
+            .addUse(GR->getSPIRVTypeID(VoidTyMI))
+            .addImm(static_cast<int64_t>(
+                SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100))
+            .addImm(SPIRV::NonSemanticExtInst::DebugSource)
+            .addUse(StrReg);
+  MIB.constrainAllUses(*TII, *TRI, *RBI);
+
+  Register DwarfVersionReg = GR->buildConstantInt(DwarfVersion, MIRBuilder);
+  Register DebugInfoVersionReg =
+      GR->buildConstantInt(DebugInfoVersion, MIRBuilder);
+  Register SourceLanguageReg = GR->buildConstantInt(SourceLanguage, MIRBuilder);
+
+  Register DebugCompUnitResIdReg =
+      MRI.createVirtualRegister(&SPIRV::IDRegClass);
+  MRI.setType(DebugCompUnitResIdReg, LLT::scalar(32));
+  MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst)
+            .addDef(DebugCompUnitResIdReg)
+            .addUse(GR->getSPIRVTypeID(VoidTyMI))
+            .addImm(static_cast<int64_t>(
+                SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100))
+            .addImm(SPIRV::NonSemanticExtInst::DebugCompilationUnit)
+            .addUse(DebugInfoVersionReg)
+            .addUse(DwarfVersionReg)
+            .addUse(DebugSourceResIdReg)
+            .addUse(SourceLanguageReg);
+  MIB.constrainAllUses(*TII, *TRI, *RBI);
 
   return true;
 }
@@ -141,8 +149,8 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
 bool SPIRVEmitNonSemanticDI::runOnMachineFunction(MachineFunction &MF) {
   bool Res = false;
   if (!IsGlobalDIEmitted) {
-    Res = emitGlobalDI(MF);
     IsGlobalDIEmitted = true;
+    Res = emitGlobalDI(MF);
   }
   return Res;
 }
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index 32ca6c4155dfed..45518d79edf9ed 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -434,13 +434,10 @@ void SPIRVModuleAnalysis::processOtherInstrs(const Module &M) {
           static constexpr int64_t GlobalNonSemanticDITy[] = {
               NS::DebugSource, NS::DebugCompilationUnit};
           bool IsGlobalDI = false;
-          for (unsigned Idx = 0; Idx < std::size(GlobalNonSemanticDITy);
-               ++Idx) {
+          for (unsigned Idx = 0; Idx < std::size(GlobalNonSemanticDITy); ++Idx)
             IsGlobalDI |= Ins.getImm() == GlobalNonSemanticDITy[Idx];
-          }
-          if (IsGlobalDI) {
+          if (IsGlobalDI)
             collectOtherInstr(MI, MAI, SPIRV::MB_NonSemanticGlobalDI, IS);
-          }
         } else if (OpCode == SPIRV::OpName || OpCode == SPIRV::OpMemberName) {
           collectOtherInstr(MI, MAI, SPIRV::MB_DebugNames, IS);
         } else if (OpCode == SPIRV::OpEntryPoint) {

>From 1d90e58b1d0b6ea187244038f73b757718c4262b Mon Sep 17 00:00:00 2001
From: "Wlodarczyk, Bertrand" <bertrand.wlodarczyk at intel.com>
Date: Thu, 4 Jul 2024 18:15:21 +0200
Subject: [PATCH 04/16] Add assignSPIRVTypeToVReg

---
 llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
index bc39ce11222be0..8f3aeede9169ca 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -111,6 +111,7 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
 
   SPIRVType *VoidTyMI =
       GR->getOrCreateSPIRVType(Type::getVoidTy(M->getContext()), MIRBuilder);
+  GR->assignSPIRVTypeToVReg(VoidTyMI, GR->getSPIRVTypeID(VoidTyMI), MF);
 
   Register DebugSourceResIdReg = MRI.createVirtualRegister(&SPIRV::IDRegClass);
   MRI.setType(DebugSourceResIdReg, LLT::scalar(32));

>From 1c50a6a3f685be49a6091f39888d0a382bad7640 Mon Sep 17 00:00:00 2001
From: "Wlodarczyk, Bertrand" <bertrand.wlodarczyk at intel.com>
Date: Fri, 5 Jul 2024 12:47:15 +0200
Subject: [PATCH 05/16] Pass moved to the end

---
 .../Target/SPIRV/SPIRVEmitNonSemanticDI.cpp   | 57 +++++++++++++------
 llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp  |  7 ++-
 2 files changed, 46 insertions(+), 18 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
index 8f3aeede9169ca..fe3b0baf4df685 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -1,4 +1,5 @@
 #include "MCTargetDesc/SPIRVBaseInfo.h"
+#include "MCTargetDesc/SPIRVMCTargetDesc.h"
 #include "SPIRVGlobalRegistry.h"
 #include "SPIRVRegisterInfo.h"
 #include "SPIRVTargetMachine.h"
@@ -60,14 +61,14 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
     IsGlobalDIEmitted = false;
     return false;
   }
-  MachineModuleInfo &MMI = MF.getMMI();
+  const MachineModuleInfo &MMI = MF.getMMI();
   const Module *M = MMI.getModule();
-  NamedMDNode *DbgCu = M->getNamedMetadata("llvm.dbg.cu");
+  const NamedMDNode *DbgCu = M->getNamedMetadata("llvm.dbg.cu");
   if (!DbgCu)
     return false;
   std::string FilePath;
   unsigned SourceLanguage = 0;
-  for (auto *Op : DbgCu->operands()) {
+  for (const auto *Op : DbgCu->operands()) {
     if (const auto *CompileUnit = dyn_cast<DICompileUnit>(Op)) {
       DIFile *File = CompileUnit->getFile();
       FilePath = ((File->getDirectory() + sys::path::get_separator() +
@@ -77,10 +78,10 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
       break;
     }
   }
-  NamedMDNode *ModuleFlags = M->getNamedMetadata("llvm.module.flags");
+  const NamedMDNode *ModuleFlags = M->getNamedMetadata("llvm.module.flags");
   int64_t DwarfVersion = 0;
   int64_t DebugInfoVersion = 0;
-  for (auto *Op : ModuleFlags->operands()) {
+  for (const auto *Op : ModuleFlags->operands()) {
     const MDOperand &MaybeStrOp = Op->getOperand(1);
     if (MaybeStrOp.equalsStr("Dwarf Version"))
       DwarfVersion =
@@ -101,19 +102,18 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
   MachineBasicBlock &MBB = *MF.begin();
   MachineIRBuilder MIRBuilder(MBB, MBB.begin());
 
-  MachineInstrBuilder MIB = MIRBuilder.buildInstr(SPIRV::OpString);
-  Register StrReg = MRI.createVirtualRegister(&SPIRV::IDRegClass);
+  const Register StrReg = MRI.createVirtualRegister(&SPIRV::IDRegClass);
   MRI.setType(StrReg, LLT::scalar(32));
-
-  MachineOperand StrRegOp = MachineOperand::CreateReg(StrReg, true);
-  MIB.add(StrRegOp);
+  MachineInstrBuilder MIB = MIRBuilder.buildInstr(SPIRV::OpString);
+  MIB.addDef(StrReg);
   addStringImm(FilePath, MIB);
 
-  SPIRVType *VoidTyMI =
+  const SPIRVType *VoidTyMI =
       GR->getOrCreateSPIRVType(Type::getVoidTy(M->getContext()), MIRBuilder);
   GR->assignSPIRVTypeToVReg(VoidTyMI, GR->getSPIRVTypeID(VoidTyMI), MF);
 
-  Register DebugSourceResIdReg = MRI.createVirtualRegister(&SPIRV::IDRegClass);
+  const Register DebugSourceResIdReg =
+      MRI.createVirtualRegister(&SPIRV::IDRegClass);
   MRI.setType(DebugSourceResIdReg, LLT::scalar(32));
   MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst)
             .addDef(DebugSourceResIdReg)
@@ -124,12 +124,35 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
             .addUse(StrReg);
   MIB.constrainAllUses(*TII, *TRI, *RBI);
 
-  Register DwarfVersionReg = GR->buildConstantInt(DwarfVersion, MIRBuilder);
-  Register DebugInfoVersionReg =
-      GR->buildConstantInt(DebugInfoVersion, MIRBuilder);
-  Register SourceLanguageReg = GR->buildConstantInt(SourceLanguage, MIRBuilder);
+  const SPIRVType *I32Ty =
+      GR->getOrCreateSPIRVType(Type::getInt32Ty(M->getContext()), MIRBuilder);
+  GR->assignSPIRVTypeToVReg(I32Ty, GR->getSPIRVTypeID(I32Ty), MF);
+
+  const Register DwarfVersionReg =
+      MRI.createVirtualRegister(&SPIRV::IDRegClass);
+  MRI.setType(DwarfVersionReg, LLT::scalar(32));
+  MIRBuilder.buildInstr(SPIRV::OpConstantI)
+      .addDef(DwarfVersionReg)
+      .addUse(GR->getSPIRVTypeID(I32Ty))
+      .addImm(DwarfVersion);
+
+  const Register DebugInfoVersionReg =
+      MRI.createVirtualRegister(&SPIRV::IDRegClass);
+  MRI.setType(DebugInfoVersionReg, LLT::scalar(32));
+  MIRBuilder.buildInstr(SPIRV::OpConstantI)
+      .addDef(DebugInfoVersionReg)
+      .addUse(GR->getSPIRVTypeID(I32Ty))
+      .addImm(DebugInfoVersion);
+
+  const Register SourceLanguageReg =
+      MRI.createVirtualRegister(&SPIRV::IDRegClass);
+  MRI.setType(SourceLanguageReg, LLT::scalar(32));
+  MIRBuilder.buildInstr(SPIRV::OpConstantI)
+      .addDef(SourceLanguageReg)
+      .addUse(GR->getSPIRVTypeID(I32Ty))
+      .addImm(SourceLanguage);
 
-  Register DebugCompUnitResIdReg =
+  const Register DebugCompUnitResIdReg =
       MRI.createVirtualRegister(&SPIRV::IDRegClass);
   MRI.setType(DebugCompUnitResIdReg, LLT::scalar(32));
   MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst)
diff --git a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
index bffc079981bc11..2470bce56faf73 100644
--- a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
@@ -115,6 +115,7 @@ class SPIRVPassConfig : public TargetPassConfig {
   void addOptimizedRegAlloc() override {}
 
   void addPostRegAlloc() override;
+  void addMachinePasses() override;
 
 private:
   const SPIRVTargetMachine &TM;
@@ -199,7 +200,6 @@ void SPIRVPassConfig::addPreLegalizeMachineIR() {
 bool SPIRVPassConfig::addLegalizeMachineIR() {
   addPass(new Legalizer());
   addPass(createSPIRVPostLegalizerPass());
-  addPass(createSPIRVEmitNonSemanticDIPass(&getTM<SPIRVTargetMachine>()));
   return false;
 }
 
@@ -209,6 +209,11 @@ bool SPIRVPassConfig::addRegBankSelect() {
   return false;
 }
 
+void SPIRVPassConfig::addMachinePasses() {
+  TargetPassConfig::addMachinePasses();
+  addPass(createSPIRVEmitNonSemanticDIPass(&getTM<SPIRVTargetMachine>()));
+}
+
 namespace {
 // A custom subclass of InstructionSelect, which is mostly the same except from
 // not requiring RegBankSelect to occur previously.

>From b820c6131a37bf76e2c6c0c4eb5a57803d474dda Mon Sep 17 00:00:00 2001
From: "Wlodarczyk, Bertrand" <bertrand.wlodarczyk at intel.com>
Date: Fri, 5 Jul 2024 14:30:55 +0200
Subject: [PATCH 06/16] Adding braces and comments

---
 .../Target/SPIRV/SPIRVEmitNonSemanticDI.cpp   | 223 ++++++++++--------
 1 file changed, 122 insertions(+), 101 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
index fe3b0baf4df685..857d07f79d254b 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -57,121 +57,142 @@ SPIRVEmitNonSemanticDI::SPIRVEmitNonSemanticDI() : MachineFunctionPass(ID) {
 }
 
 bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
+  // If this MachineFunction doesn't have any BB repeat procedure
+  // for the next
   if (MF.begin() == MF.end()) {
     IsGlobalDIEmitted = false;
     return false;
   }
-  const MachineModuleInfo &MMI = MF.getMMI();
-  const Module *M = MMI.getModule();
-  const NamedMDNode *DbgCu = M->getNamedMetadata("llvm.dbg.cu");
-  if (!DbgCu)
-    return false;
+
+  // Required variables to get from metadata search
+  LLVMContext *Context;
   std::string FilePath;
   unsigned SourceLanguage = 0;
-  for (const auto *Op : DbgCu->operands()) {
-    if (const auto *CompileUnit = dyn_cast<DICompileUnit>(Op)) {
-      DIFile *File = CompileUnit->getFile();
-      FilePath = ((File->getDirectory() + sys::path::get_separator() +
-                   File->getFilename()))
-                     .str();
-      SourceLanguage = CompileUnit->getSourceLanguage();
-      break;
-    }
-  }
-  const NamedMDNode *ModuleFlags = M->getNamedMetadata("llvm.module.flags");
   int64_t DwarfVersion = 0;
   int64_t DebugInfoVersion = 0;
-  for (const auto *Op : ModuleFlags->operands()) {
-    const MDOperand &MaybeStrOp = Op->getOperand(1);
-    if (MaybeStrOp.equalsStr("Dwarf Version"))
-      DwarfVersion =
-          cast<ConstantInt>(
-              cast<ConstantAsMetadata>(Op->getOperand(2))->getValue())
-              ->getSExtValue();
-    else if (MaybeStrOp.equalsStr("Debug Info Version"))
-      DebugInfoVersion =
-          cast<ConstantInt>(
-              cast<ConstantAsMetadata>(Op->getOperand(2))->getValue())
-              ->getSExtValue();
-  }
-  const SPIRVInstrInfo *TII = TM->getSubtargetImpl()->getInstrInfo();
-  const SPIRVRegisterInfo *TRI = TM->getSubtargetImpl()->getRegisterInfo();
-  const RegisterBankInfo *RBI = TM->getSubtargetImpl()->getRegBankInfo();
-  SPIRVGlobalRegistry *GR = TM->getSubtargetImpl()->getSPIRVGlobalRegistry();
-  MachineRegisterInfo &MRI = MF.getRegInfo();
-  MachineBasicBlock &MBB = *MF.begin();
-  MachineIRBuilder MIRBuilder(MBB, MBB.begin());
-
-  const Register StrReg = MRI.createVirtualRegister(&SPIRV::IDRegClass);
-  MRI.setType(StrReg, LLT::scalar(32));
-  MachineInstrBuilder MIB = MIRBuilder.buildInstr(SPIRV::OpString);
-  MIB.addDef(StrReg);
-  addStringImm(FilePath, MIB);
-
-  const SPIRVType *VoidTyMI =
-      GR->getOrCreateSPIRVType(Type::getVoidTy(M->getContext()), MIRBuilder);
-  GR->assignSPIRVTypeToVReg(VoidTyMI, GR->getSPIRVTypeID(VoidTyMI), MF);
-
-  const Register DebugSourceResIdReg =
-      MRI.createVirtualRegister(&SPIRV::IDRegClass);
-  MRI.setType(DebugSourceResIdReg, LLT::scalar(32));
-  MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst)
-            .addDef(DebugSourceResIdReg)
-            .addUse(GR->getSPIRVTypeID(VoidTyMI))
-            .addImm(static_cast<int64_t>(
-                SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100))
-            .addImm(SPIRV::NonSemanticExtInst::DebugSource)
-            .addUse(StrReg);
-  MIB.constrainAllUses(*TII, *TRI, *RBI);
-
-  const SPIRVType *I32Ty =
-      GR->getOrCreateSPIRVType(Type::getInt32Ty(M->getContext()), MIRBuilder);
-  GR->assignSPIRVTypeToVReg(I32Ty, GR->getSPIRVTypeID(I32Ty), MF);
-
-  const Register DwarfVersionReg =
-      MRI.createVirtualRegister(&SPIRV::IDRegClass);
-  MRI.setType(DwarfVersionReg, LLT::scalar(32));
-  MIRBuilder.buildInstr(SPIRV::OpConstantI)
-      .addDef(DwarfVersionReg)
-      .addUse(GR->getSPIRVTypeID(I32Ty))
-      .addImm(DwarfVersion);
-
-  const Register DebugInfoVersionReg =
-      MRI.createVirtualRegister(&SPIRV::IDRegClass);
-  MRI.setType(DebugInfoVersionReg, LLT::scalar(32));
-  MIRBuilder.buildInstr(SPIRV::OpConstantI)
-      .addDef(DebugInfoVersionReg)
-      .addUse(GR->getSPIRVTypeID(I32Ty))
-      .addImm(DebugInfoVersion);
-
-  const Register SourceLanguageReg =
-      MRI.createVirtualRegister(&SPIRV::IDRegClass);
-  MRI.setType(SourceLanguageReg, LLT::scalar(32));
-  MIRBuilder.buildInstr(SPIRV::OpConstantI)
-      .addDef(SourceLanguageReg)
-      .addUse(GR->getSPIRVTypeID(I32Ty))
-      .addImm(SourceLanguage);
-
-  const Register DebugCompUnitResIdReg =
-      MRI.createVirtualRegister(&SPIRV::IDRegClass);
-  MRI.setType(DebugCompUnitResIdReg, LLT::scalar(32));
-  MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst)
-            .addDef(DebugCompUnitResIdReg)
-            .addUse(GR->getSPIRVTypeID(VoidTyMI))
-            .addImm(static_cast<int64_t>(
-                SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100))
-            .addImm(SPIRV::NonSemanticExtInst::DebugCompilationUnit)
-            .addUse(DebugInfoVersionReg)
-            .addUse(DwarfVersionReg)
-            .addUse(DebugSourceResIdReg)
-            .addUse(SourceLanguageReg);
-  MIB.constrainAllUses(*TII, *TRI, *RBI);
 
+  // Searching through the Module metadata to find nescessary
+  // information like DwarfVersion or SourceLanguage
+  {
+    const MachineModuleInfo &MMI = MF.getMMI();
+    const Module *M = MMI.getModule();
+    Context = &M->getContext();
+    const NamedMDNode *DbgCu = M->getNamedMetadata("llvm.dbg.cu");
+    if (!DbgCu)
+      return false;
+    for (const auto *Op : DbgCu->operands()) {
+      if (const auto *CompileUnit = dyn_cast<DICompileUnit>(Op)) {
+        DIFile *File = CompileUnit->getFile();
+        FilePath = ((File->getDirectory() + sys::path::get_separator() +
+                     File->getFilename()))
+                       .str();
+        SourceLanguage = CompileUnit->getSourceLanguage();
+        break;
+      }
+    }
+    const NamedMDNode *ModuleFlags = M->getNamedMetadata("llvm.module.flags");
+    for (const auto *Op : ModuleFlags->operands()) {
+      const MDOperand &MaybeStrOp = Op->getOperand(1);
+      if (MaybeStrOp.equalsStr("Dwarf Version"))
+        DwarfVersion =
+            cast<ConstantInt>(
+                cast<ConstantAsMetadata>(Op->getOperand(2))->getValue())
+                ->getSExtValue();
+      else if (MaybeStrOp.equalsStr("Debug Info Version"))
+        DebugInfoVersion =
+            cast<ConstantInt>(
+                cast<ConstantAsMetadata>(Op->getOperand(2))->getValue())
+                ->getSExtValue();
+    }
+  }
+  // NonSemantic.Shader.DebugInfo.100 global DI intruction emitting
+  {
+    // Required LLVM variables for emitting logic
+    const SPIRVInstrInfo *TII = TM->getSubtargetImpl()->getInstrInfo();
+    const SPIRVRegisterInfo *TRI = TM->getSubtargetImpl()->getRegisterInfo();
+    const RegisterBankInfo *RBI = TM->getSubtargetImpl()->getRegBankInfo();
+    SPIRVGlobalRegistry *GR = TM->getSubtargetImpl()->getSPIRVGlobalRegistry();
+    MachineRegisterInfo &MRI = MF.getRegInfo();
+    MachineBasicBlock &MBB = *MF.begin();
+    MachineIRBuilder MIRBuilder(MBB, MBB.begin());
+
+    // Emit OpString with FilePath which is required by DebugSource
+    const Register StrReg = MRI.createVirtualRegister(&SPIRV::IDRegClass);
+    MRI.setType(StrReg, LLT::scalar(32));
+    MachineInstrBuilder MIB = MIRBuilder.buildInstr(SPIRV::OpString);
+    MIB.addDef(StrReg);
+    addStringImm(FilePath, MIB);
+
+    const SPIRVType *VoidTyMI =
+        GR->getOrCreateSPIRVType(Type::getVoidTy(*Context), MIRBuilder);
+    GR->assignSPIRVTypeToVReg(VoidTyMI, GR->getSPIRVTypeID(VoidTyMI), MF);
+
+    // Emit DebugSource which is required by DebugCompilationUnit
+    const Register DebugSourceResIdReg =
+        MRI.createVirtualRegister(&SPIRV::IDRegClass);
+    MRI.setType(DebugSourceResIdReg, LLT::scalar(32));
+    MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst)
+              .addDef(DebugSourceResIdReg)
+              .addUse(GR->getSPIRVTypeID(VoidTyMI))
+              .addImm(static_cast<int64_t>(
+                  SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100))
+              .addImm(SPIRV::NonSemanticExtInst::DebugSource)
+              .addUse(StrReg);
+    MIB.constrainAllUses(*TII, *TRI, *RBI);
+
+    const SPIRVType *I32Ty =
+        GR->getOrCreateSPIRVType(Type::getInt32Ty(*Context), MIRBuilder);
+    GR->assignSPIRVTypeToVReg(I32Ty, GR->getSPIRVTypeID(I32Ty), MF);
+
+    // Convert DwarfVersion, DebugInfo and SourceLanguage integers to OpConstant
+    // instructions required by DebugCompilationUnit
+    const Register DwarfVersionReg =
+        MRI.createVirtualRegister(&SPIRV::IDRegClass);
+    MRI.setType(DwarfVersionReg, LLT::scalar(32));
+    MIRBuilder.buildInstr(SPIRV::OpConstantI)
+        .addDef(DwarfVersionReg)
+        .addUse(GR->getSPIRVTypeID(I32Ty))
+        .addImm(DwarfVersion);
+
+    const Register DebugInfoVersionReg =
+        MRI.createVirtualRegister(&SPIRV::IDRegClass);
+    MRI.setType(DebugInfoVersionReg, LLT::scalar(32));
+    MIRBuilder.buildInstr(SPIRV::OpConstantI)
+        .addDef(DebugInfoVersionReg)
+        .addUse(GR->getSPIRVTypeID(I32Ty))
+        .addImm(DebugInfoVersion);
+
+    const Register SourceLanguageReg =
+        MRI.createVirtualRegister(&SPIRV::IDRegClass);
+    MRI.setType(SourceLanguageReg, LLT::scalar(32));
+    MIRBuilder.buildInstr(SPIRV::OpConstantI)
+        .addDef(SourceLanguageReg)
+        .addUse(GR->getSPIRVTypeID(I32Ty))
+        .addImm(SourceLanguage);
+
+    // Emit DebugCompilationUnit
+    const Register DebugCompUnitResIdReg =
+        MRI.createVirtualRegister(&SPIRV::IDRegClass);
+    MRI.setType(DebugCompUnitResIdReg, LLT::scalar(32));
+    MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst)
+              .addDef(DebugCompUnitResIdReg)
+              .addUse(GR->getSPIRVTypeID(VoidTyMI))
+              .addImm(static_cast<int64_t>(
+                  SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100))
+              .addImm(SPIRV::NonSemanticExtInst::DebugCompilationUnit)
+              .addUse(DebugInfoVersionReg)
+              .addUse(DwarfVersionReg)
+              .addUse(DebugSourceResIdReg)
+              .addUse(SourceLanguageReg);
+    MIB.constrainAllUses(*TII, *TRI, *RBI);
+  }
   return true;
 }
 
 bool SPIRVEmitNonSemanticDI::runOnMachineFunction(MachineFunction &MF) {
   bool Res = false;
+  // emitGlobalDI needs to be executed only once to avoid
+  // emitting duplicates
   if (!IsGlobalDIEmitted) {
     IsGlobalDIEmitted = true;
     Res = emitGlobalDI(MF);

>From 982529559e7cc702684226c766f2a5e9d9749dbf Mon Sep 17 00:00:00 2001
From: "Wlodarczyk, Bertrand" <bertrand.wlodarczyk at intel.com>
Date: Mon, 8 Jul 2024 13:59:28 +0200
Subject: [PATCH 07/16] Added test

---
 .../SPIRV/debug-info/basic-global-di.ll       | 129 ++++++++++++++++++
 1 file changed, 129 insertions(+)
 create mode 100644 llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll

diff --git a/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll b/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll
new file mode 100644
index 00000000000000..eef31da57831c6
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll
@@ -0,0 +1,129 @@
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
+
+source_filename = "example.c"
+target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1"
+target triple = "spir"
+
+%struct.A = type { i32, float }
+
+; CHECK-SPIRV: [[ext_inst_non_semantic:%[0-9]+]] = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
+; CHECK-SPIRV: [[filename_str:%[0-9]+]] = OpString "/AAAAAAAAAA/BBBBBBBB/CCCCCCCCC/example.c" 
+; CHECK-SPIRV-DAG: [[type_void:%[0-9]+]] = OpTypeVoid
+; CHECK-SPIRV-DAG: [[type_i32:%[0-9]+]] = OpTypeInt 32 0
+; CHECK-SPIRV-DAG: [[dwarf_version:%[0-9]+]] = OpConstant [[type_i32]] 5 
+; CHECK-SPIRV-DAG: [[debug_info_version:%[0-9]+]] = OpConstant [[type_i32]] 21 
+; CHECK-SPIRV-DAG: [[source_language:%[0-9]+]] = OpConstant [[type_i32]] 3 
+; CHECK-SPIRV: [[debug_source:%[0-9]+]] = OpExtInst [[type_void]] [[ext_inst_non_semantic]] DebugSource [[filename_str]]
+; CHECK-SPIRV: [[debug_compiation_unit:%[0-9]+]] = OpExtInst [[type_void]] [[ext_inst_non_semantic]] DebugCompilationUnit [[source_language]] [[dwarf_version]] [[debug_source]] [[debug_info_version]]
+
+; Function Attrs: convergent noinline norecurse nounwind optnone
+define dso_local spir_func i32 @bar(i32 noundef %n) #0 !dbg !8 {
+entry:
+  %n.addr = alloca i32, align 4
+  store i32 %n, ptr %n.addr, align 4
+    #dbg_declare(ptr %n.addr, !13, !DIExpression(DW_OP_constu, 0, DW_OP_swap, DW_OP_xderef), !14)
+  %0 = load i32, ptr %n.addr, align 4, !dbg !15
+  %1 = load i32, ptr %n.addr, align 4, !dbg !16
+  %mul = mul nsw i32 %0, %1, !dbg !17
+  %2 = load i32, ptr %n.addr, align 4, !dbg !18
+  %add = add nsw i32 %mul, %2, !dbg !19
+  ret i32 %add, !dbg !20
+}
+
+; Function Attrs: convergent noinline norecurse nounwind optnone
+define dso_local spir_func i32 @foo(i32 noundef %num, ptr addrspace(4) noundef %a) #0 !dbg !21 {
+entry:
+  %num.addr = alloca i32, align 4
+  %a.addr = alloca ptr addrspace(4), align 4
+  store i32 %num, ptr %num.addr, align 4
+    #dbg_declare(ptr %num.addr, !30, !DIExpression(DW_OP_constu, 0, DW_OP_swap, DW_OP_xderef), !31)
+  store ptr addrspace(4) %a, ptr %a.addr, align 4
+    #dbg_declare(ptr %a.addr, !32, !DIExpression(DW_OP_constu, 0, DW_OP_swap, DW_OP_xderef), !33)
+  %0 = load i32, ptr %num.addr, align 4, !dbg !34
+  %1 = load i32, ptr %num.addr, align 4, !dbg !35
+  %mul = mul nsw i32 %0, %1, !dbg !36
+  %2 = load ptr addrspace(4), ptr %a.addr, align 4, !dbg !37
+  %a1 = getelementptr inbounds %struct.A, ptr addrspace(4) %2, i32 0, i32 0, !dbg !38
+  %3 = load i32, ptr addrspace(4) %a1, align 4, !dbg !38
+  %mul2 = mul nsw i32 %mul, %3, !dbg !39
+  %conv = sitofp i32 %mul2 to float, !dbg !34
+  %4 = load ptr addrspace(4), ptr %a.addr, align 4, !dbg !40
+  %b = getelementptr inbounds %struct.A, ptr addrspace(4) %4, i32 0, i32 1, !dbg !41
+  %5 = load float, ptr addrspace(4) %b, align 4, !dbg !41
+  %6 = load i32, ptr %num.addr, align 4, !dbg !42
+  %call = call spir_func i32 @bar(i32 noundef %6) #2, !dbg !43
+  %conv4 = sitofp i32 %call to float, !dbg !43
+  %7 = call float @llvm.fmuladd.f32(float %conv, float %5, float %conv4), !dbg !44
+  %conv5 = fptosi float %7 to i32, !dbg !34
+  ret i32 %conv5, !dbg !45
+}
+
+; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
+declare float @llvm.fmuladd.f32(float, float, float) #1
+
+; Function Attrs: convergent noinline norecurse nounwind optnone
+define dso_local spir_func void @zar() #0 !dbg !46 {
+entry:
+  ret void, !dbg !49
+}
+
+attributes #0 = { convergent noinline norecurse nounwind optnone "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
+attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
+attributes #2 = { convergent nounwind }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3, !4, !5}
+!opencl.ocl.version = !{!6}
+!opencl.spir.version = !{!6}
+!llvm.ident = !{!7}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_OpenCL, file: !1, producer: "clang version 19.0.0git (fffffffffffffffffffffffffffffffffffffffff zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "example.c", directory: "/AAAAAAAAAA/BBBBBBBB/CCCCCCCCC", checksumkind: CSK_MD5, checksum: "ffffffffffffffffffffffffffffffff")
+!2 = !{i32 7, !"Dwarf Version", i32 5}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!4 = !{i32 1, !"wchar_size", i32 4}
+!5 = !{i32 7, !"frame-pointer", i32 2}
+!6 = !{i32 3, i32 0}
+!7 = !{!"clang version 19.0.0git (fffffffffffffffffffffffffffffffffffffffff zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz)"}
+!8 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 6, type: !9, scopeLine: 6, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !12)
+!9 = !DISubroutineType(cc: DW_CC_LLVM_SpirFunction, types: !10)
+!10 = !{!11, !11}
+!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!12 = !{}
+!13 = !DILocalVariable(name: "n", arg: 1, scope: !8, file: !1, line: 6, type: !11)
+!14 = !DILocation(line: 6, column: 13, scope: !8)
+!15 = !DILocation(line: 6, column: 25, scope: !8)
+!16 = !DILocation(line: 6, column: 29, scope: !8)
+!17 = !DILocation(line: 6, column: 27, scope: !8)
+!18 = !DILocation(line: 6, column: 33, scope: !8)
+!19 = !DILocation(line: 6, column: 31, scope: !8)
+!20 = !DILocation(line: 6, column: 18, scope: !8)
+!21 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 8, type: !22, scopeLine: 8, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !12)
+!22 = !DISubroutineType(cc: DW_CC_LLVM_SpirFunction, types: !23)
+!23 = !{!11, !11, !24}
+!24 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !25, size: 32, dwarfAddressSpace: 4)
+!25 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "A", file: !1, line: 1, size: 64, elements: !26)
+!26 = !{!27, !28}
+!27 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !25, file: !1, line: 2, baseType: !11, size: 32)
+!28 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !25, file: !1, line: 3, baseType: !29, size: 32, offset: 32)
+!29 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
+!30 = !DILocalVariable(name: "num", arg: 1, scope: !21, file: !1, line: 8, type: !11)
+!31 = !DILocation(line: 8, column: 13, scope: !21)
+!32 = !DILocalVariable(name: "a", arg: 2, scope: !21, file: !1, line: 8, type: !24)
+!33 = !DILocation(line: 8, column: 28, scope: !21)
+!34 = !DILocation(line: 8, column: 40, scope: !21)
+!35 = !DILocation(line: 8, column: 46, scope: !21)
+!36 = !DILocation(line: 8, column: 44, scope: !21)
+!37 = !DILocation(line: 8, column: 52, scope: !21)
+!38 = !DILocation(line: 8, column: 55, scope: !21)
+!39 = !DILocation(line: 8, column: 50, scope: !21)
+!40 = !DILocation(line: 8, column: 59, scope: !21)
+!41 = !DILocation(line: 8, column: 62, scope: !21)
+!42 = !DILocation(line: 8, column: 70, scope: !21)
+!43 = !DILocation(line: 8, column: 66, scope: !21)
+!44 = !DILocation(line: 8, column: 64, scope: !21)
+!45 = !DILocation(line: 8, column: 33, scope: !21)
+!46 = distinct !DISubprogram(name: "zar", scope: !1, file: !1, line: 10, type: !47, scopeLine: 10, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0)
+!47 = !DISubroutineType(cc: DW_CC_LLVM_SpirFunction, types: !48)
+!48 = !{null}
+!49 = !DILocation(line: 10, column: 13, scope: !46)

>From 059affae3fe73b20db11f863f364732b2e184535 Mon Sep 17 00:00:00 2001
From: "Wlodarczyk, Bertrand" <bertrand.wlodarczyk at intel.com>
Date: Mon, 8 Jul 2024 14:21:57 +0200
Subject: [PATCH 08/16] Fix comment typo

---
 llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
index 857d07f79d254b..2868c7a3073654 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -105,7 +105,7 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
                 ->getSExtValue();
     }
   }
-  // NonSemantic.Shader.DebugInfo.100 global DI intruction emitting
+  // NonSemantic.Shader.DebugInfo.100 global DI instruction emitting
   {
     // Required LLVM variables for emitting logic
     const SPIRVInstrInfo *TII = TM->getSubtargetImpl()->getInstrInfo();

>From 3a0f96bc12be1cb8293e3488917be991577846bc Mon Sep 17 00:00:00 2001
From: "Wlodarczyk, Bertrand" <bertrand.wlodarczyk at intel.com>
Date: Wed, 10 Jul 2024 18:43:44 +0200
Subject: [PATCH 09/16] Fix after review plus mir test

---
 .../Target/SPIRV/SPIRVEmitNonSemanticDI.cpp   |  13 +-
 llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp  |   5 +-
 .../SPIRV/debug-info/basic-global-di.ll       | 119 +++---------------
 3 files changed, 26 insertions(+), 111 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
index 2868c7a3073654..d866af2c873925 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -123,9 +123,8 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
     MIB.addDef(StrReg);
     addStringImm(FilePath, MIB);
 
-    const SPIRVType *VoidTyMI =
+    const SPIRVType *VoidTy =
         GR->getOrCreateSPIRVType(Type::getVoidTy(*Context), MIRBuilder);
-    GR->assignSPIRVTypeToVReg(VoidTyMI, GR->getSPIRVTypeID(VoidTyMI), MF);
 
     // Emit DebugSource which is required by DebugCompilationUnit
     const Register DebugSourceResIdReg =
@@ -133,16 +132,16 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
     MRI.setType(DebugSourceResIdReg, LLT::scalar(32));
     MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst)
               .addDef(DebugSourceResIdReg)
-              .addUse(GR->getSPIRVTypeID(VoidTyMI))
+              .addUse(GR->getSPIRVTypeID(VoidTy))
               .addImm(static_cast<int64_t>(
                   SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100))
               .addImm(SPIRV::NonSemanticExtInst::DebugSource)
               .addUse(StrReg);
     MIB.constrainAllUses(*TII, *TRI, *RBI);
+    GR->assignSPIRVTypeToVReg(VoidTy, DebugSourceResIdReg, MF);
 
     const SPIRVType *I32Ty =
         GR->getOrCreateSPIRVType(Type::getInt32Ty(*Context), MIRBuilder);
-    GR->assignSPIRVTypeToVReg(I32Ty, GR->getSPIRVTypeID(I32Ty), MF);
 
     // Convert DwarfVersion, DebugInfo and SourceLanguage integers to OpConstant
     // instructions required by DebugCompilationUnit
@@ -153,6 +152,7 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
         .addDef(DwarfVersionReg)
         .addUse(GR->getSPIRVTypeID(I32Ty))
         .addImm(DwarfVersion);
+    GR->assignSPIRVTypeToVReg(I32Ty, DwarfVersionReg, MF);
 
     const Register DebugInfoVersionReg =
         MRI.createVirtualRegister(&SPIRV::IDRegClass);
@@ -161,6 +161,7 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
         .addDef(DebugInfoVersionReg)
         .addUse(GR->getSPIRVTypeID(I32Ty))
         .addImm(DebugInfoVersion);
+    GR->assignSPIRVTypeToVReg(I32Ty, DebugInfoVersionReg, MF);
 
     const Register SourceLanguageReg =
         MRI.createVirtualRegister(&SPIRV::IDRegClass);
@@ -169,6 +170,7 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
         .addDef(SourceLanguageReg)
         .addUse(GR->getSPIRVTypeID(I32Ty))
         .addImm(SourceLanguage);
+    GR->assignSPIRVTypeToVReg(I32Ty, SourceLanguageReg, MF);
 
     // Emit DebugCompilationUnit
     const Register DebugCompUnitResIdReg =
@@ -176,7 +178,7 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
     MRI.setType(DebugCompUnitResIdReg, LLT::scalar(32));
     MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst)
               .addDef(DebugCompUnitResIdReg)
-              .addUse(GR->getSPIRVTypeID(VoidTyMI))
+              .addUse(GR->getSPIRVTypeID(VoidTy))
               .addImm(static_cast<int64_t>(
                   SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100))
               .addImm(SPIRV::NonSemanticExtInst::DebugCompilationUnit)
@@ -185,6 +187,7 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
               .addUse(DebugSourceResIdReg)
               .addUse(SourceLanguageReg);
     MIB.constrainAllUses(*TII, *TRI, *RBI);
+    GR->assignSPIRVTypeToVReg(VoidTy, DebugCompUnitResIdReg, MF);
   }
   return true;
 }
diff --git a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
index 2470bce56faf73..32a9b3f71cf08e 100644
--- a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
@@ -115,7 +115,7 @@ class SPIRVPassConfig : public TargetPassConfig {
   void addOptimizedRegAlloc() override {}
 
   void addPostRegAlloc() override;
-  void addMachinePasses() override;
+  void addPreEmitPass() override;
 
 private:
   const SPIRVTargetMachine &TM;
@@ -209,8 +209,7 @@ bool SPIRVPassConfig::addRegBankSelect() {
   return false;
 }
 
-void SPIRVPassConfig::addMachinePasses() {
-  TargetPassConfig::addMachinePasses();
+void SPIRVPassConfig::addPreEmitPass() {
   addPass(createSPIRVEmitNonSemanticDIPass(&getTM<SPIRVTargetMachine>()));
 }
 
diff --git a/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll b/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll
index eef31da57831c6..6b7a13a24d7e8c 100644
--- a/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll
+++ b/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll
@@ -1,10 +1,15 @@
+; RUN: llc --print-after=spirv-nonsemantic-debug-info -O0 -mtriple=spirv64-unknown-unknown %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-MIR
 ; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
 
-source_filename = "example.c"
-target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1"
-target triple = "spir"
-
-%struct.A = type { i32, float }
+; CHECK-MIR-DAG: [[type_void:%[0-9]+\:type]] = OpTypeVoid
+; CHECK-MIR-DAG: [[type_i32:%[0-9]+\:type\(s32\)]] = OpTypeInt 32, 0
+; CHECK-MIR-DAG: [[dwarf_version:%[0-9]+\:id\(s32\)]] = OpConstantI [[type_i32]], 5
+; CHECK-MIR-DAG: [[source_language:%[0-9]+\:id\(s32\)]] = OpConstantI [[type_i32]], 3
+; CHECK-MIR-DAG: [[debug_info_version:%[0-9]+\:id\(s32\)]] = OpConstantI [[type_i32]], 21
+; CHECK-MIR-DAG: [[filename_str:%[0-9]+\:id\(s32\)]] = OpString 1094795567, 1094795585, 792805697, 1111638594, 1111638594, 1128481583, 1128481603, 1697596227, 1886216568, 1663985004, 0 
+; CHECK-MIR-DAG: [[debug_source:%[0-9]+\:id\(s32\)]] = OpExtInst [[type_void]], 3, 35, [[filename_str]]
+; CHECK-MIR-DAG: [[debug_compilation_unit:%[0-9]+\:id\(s32\)]] = OpExtInst [[type_void]], 3, 1, [[source_language]], [[dwarf_version]], [[debug_source]], [[debug_info_version]]
 
 ; CHECK-SPIRV: [[ext_inst_non_semantic:%[0-9]+]] = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
 ; CHECK-SPIRV: [[filename_str:%[0-9]+]] = OpString "/AAAAAAAAAA/BBBBBBBB/CCCCCCCCC/example.c" 
@@ -16,114 +21,22 @@ target triple = "spir"
 ; CHECK-SPIRV: [[debug_source:%[0-9]+]] = OpExtInst [[type_void]] [[ext_inst_non_semantic]] DebugSource [[filename_str]]
 ; CHECK-SPIRV: [[debug_compiation_unit:%[0-9]+]] = OpExtInst [[type_void]] [[ext_inst_non_semantic]] DebugCompilationUnit [[source_language]] [[dwarf_version]] [[debug_source]] [[debug_info_version]]
 
-; Function Attrs: convergent noinline norecurse nounwind optnone
-define dso_local spir_func i32 @bar(i32 noundef %n) #0 !dbg !8 {
-entry:
-  %n.addr = alloca i32, align 4
-  store i32 %n, ptr %n.addr, align 4
-    #dbg_declare(ptr %n.addr, !13, !DIExpression(DW_OP_constu, 0, DW_OP_swap, DW_OP_xderef), !14)
-  %0 = load i32, ptr %n.addr, align 4, !dbg !15
-  %1 = load i32, ptr %n.addr, align 4, !dbg !16
-  %mul = mul nsw i32 %0, %1, !dbg !17
-  %2 = load i32, ptr %n.addr, align 4, !dbg !18
-  %add = add nsw i32 %mul, %2, !dbg !19
-  ret i32 %add, !dbg !20
-}
-
-; Function Attrs: convergent noinline norecurse nounwind optnone
-define dso_local spir_func i32 @foo(i32 noundef %num, ptr addrspace(4) noundef %a) #0 !dbg !21 {
+define spir_func void @foo() {
 entry:
-  %num.addr = alloca i32, align 4
-  %a.addr = alloca ptr addrspace(4), align 4
-  store i32 %num, ptr %num.addr, align 4
-    #dbg_declare(ptr %num.addr, !30, !DIExpression(DW_OP_constu, 0, DW_OP_swap, DW_OP_xderef), !31)
-  store ptr addrspace(4) %a, ptr %a.addr, align 4
-    #dbg_declare(ptr %a.addr, !32, !DIExpression(DW_OP_constu, 0, DW_OP_swap, DW_OP_xderef), !33)
-  %0 = load i32, ptr %num.addr, align 4, !dbg !34
-  %1 = load i32, ptr %num.addr, align 4, !dbg !35
-  %mul = mul nsw i32 %0, %1, !dbg !36
-  %2 = load ptr addrspace(4), ptr %a.addr, align 4, !dbg !37
-  %a1 = getelementptr inbounds %struct.A, ptr addrspace(4) %2, i32 0, i32 0, !dbg !38
-  %3 = load i32, ptr addrspace(4) %a1, align 4, !dbg !38
-  %mul2 = mul nsw i32 %mul, %3, !dbg !39
-  %conv = sitofp i32 %mul2 to float, !dbg !34
-  %4 = load ptr addrspace(4), ptr %a.addr, align 4, !dbg !40
-  %b = getelementptr inbounds %struct.A, ptr addrspace(4) %4, i32 0, i32 1, !dbg !41
-  %5 = load float, ptr addrspace(4) %b, align 4, !dbg !41
-  %6 = load i32, ptr %num.addr, align 4, !dbg !42
-  %call = call spir_func i32 @bar(i32 noundef %6) #2, !dbg !43
-  %conv4 = sitofp i32 %call to float, !dbg !43
-  %7 = call float @llvm.fmuladd.f32(float %conv, float %5, float %conv4), !dbg !44
-  %conv5 = fptosi float %7 to i32, !dbg !34
-  ret i32 %conv5, !dbg !45
+  ret void
 }
 
-; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
-declare float @llvm.fmuladd.f32(float, float, float) #1
-
-; Function Attrs: convergent noinline norecurse nounwind optnone
-define dso_local spir_func void @zar() #0 !dbg !46 {
+define spir_func void @bar() {
 entry:
-  ret void, !dbg !49
+  ret void
 }
 
-attributes #0 = { convergent noinline norecurse nounwind optnone "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
-attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
-attributes #2 = { convergent nounwind }
-
 !llvm.dbg.cu = !{!0}
 !llvm.module.flags = !{!2, !3, !4, !5}
-!opencl.ocl.version = !{!6}
-!opencl.spir.version = !{!6}
-!llvm.ident = !{!7}
 
-!0 = distinct !DICompileUnit(language: DW_LANG_OpenCL, file: !1, producer: "clang version 19.0.0git (fffffffffffffffffffffffffffffffffffffffff zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
-!1 = !DIFile(filename: "example.c", directory: "/AAAAAAAAAA/BBBBBBBB/CCCCCCCCC", checksumkind: CSK_MD5, checksum: "ffffffffffffffffffffffffffffffff")
+!0 = distinct !DICompileUnit(language: DW_LANG_OpenCL, file: !1, producer: "clang version XX.X.XXXX (FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "example.c", directory: "/AAAAAAAAAA/BBBBBBBB/CCCCCCCCC", checksumkind: CSK_MD5, checksum: "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")
 !2 = !{i32 7, !"Dwarf Version", i32 5}
 !3 = !{i32 2, !"Debug Info Version", i32 3}
 !4 = !{i32 1, !"wchar_size", i32 4}
 !5 = !{i32 7, !"frame-pointer", i32 2}
-!6 = !{i32 3, i32 0}
-!7 = !{!"clang version 19.0.0git (fffffffffffffffffffffffffffffffffffffffff zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz)"}
-!8 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 6, type: !9, scopeLine: 6, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !12)
-!9 = !DISubroutineType(cc: DW_CC_LLVM_SpirFunction, types: !10)
-!10 = !{!11, !11}
-!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-!12 = !{}
-!13 = !DILocalVariable(name: "n", arg: 1, scope: !8, file: !1, line: 6, type: !11)
-!14 = !DILocation(line: 6, column: 13, scope: !8)
-!15 = !DILocation(line: 6, column: 25, scope: !8)
-!16 = !DILocation(line: 6, column: 29, scope: !8)
-!17 = !DILocation(line: 6, column: 27, scope: !8)
-!18 = !DILocation(line: 6, column: 33, scope: !8)
-!19 = !DILocation(line: 6, column: 31, scope: !8)
-!20 = !DILocation(line: 6, column: 18, scope: !8)
-!21 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 8, type: !22, scopeLine: 8, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !12)
-!22 = !DISubroutineType(cc: DW_CC_LLVM_SpirFunction, types: !23)
-!23 = !{!11, !11, !24}
-!24 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !25, size: 32, dwarfAddressSpace: 4)
-!25 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "A", file: !1, line: 1, size: 64, elements: !26)
-!26 = !{!27, !28}
-!27 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !25, file: !1, line: 2, baseType: !11, size: 32)
-!28 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !25, file: !1, line: 3, baseType: !29, size: 32, offset: 32)
-!29 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
-!30 = !DILocalVariable(name: "num", arg: 1, scope: !21, file: !1, line: 8, type: !11)
-!31 = !DILocation(line: 8, column: 13, scope: !21)
-!32 = !DILocalVariable(name: "a", arg: 2, scope: !21, file: !1, line: 8, type: !24)
-!33 = !DILocation(line: 8, column: 28, scope: !21)
-!34 = !DILocation(line: 8, column: 40, scope: !21)
-!35 = !DILocation(line: 8, column: 46, scope: !21)
-!36 = !DILocation(line: 8, column: 44, scope: !21)
-!37 = !DILocation(line: 8, column: 52, scope: !21)
-!38 = !DILocation(line: 8, column: 55, scope: !21)
-!39 = !DILocation(line: 8, column: 50, scope: !21)
-!40 = !DILocation(line: 8, column: 59, scope: !21)
-!41 = !DILocation(line: 8, column: 62, scope: !21)
-!42 = !DILocation(line: 8, column: 70, scope: !21)
-!43 = !DILocation(line: 8, column: 66, scope: !21)
-!44 = !DILocation(line: 8, column: 64, scope: !21)
-!45 = !DILocation(line: 8, column: 33, scope: !21)
-!46 = distinct !DISubprogram(name: "zar", scope: !1, file: !1, line: 10, type: !47, scopeLine: 10, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0)
-!47 = !DISubroutineType(cc: DW_CC_LLVM_SpirFunction, types: !48)
-!48 = !{null}
-!49 = !DILocation(line: 10, column: 13, scope: !46)

>From 24fa56f98bd931ec84d32b874bf2141807465d9e Mon Sep 17 00:00:00 2001
From: "Wlodarczyk, Bertrand" <bertrand.wlodarczyk at intel.com>
Date: Thu, 11 Jul 2024 15:32:11 +0200
Subject: [PATCH 10/16] Fixed spirv-val OpLabel issue

---
 llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp            | 3 ++-
 llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp      | 5 ++++-
 llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp         | 8 ++++++++
 llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll | 6 +++---
 4 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp b/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
index c7c244cfa89770..90a9ab1d33ced4 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
@@ -68,7 +68,8 @@ static const std::map<std::string, SPIRV::Extension::Extension>
          SPIRV::Extension::Extension::SPV_KHR_shader_clock},
         {"SPV_KHR_cooperative_matrix",
          SPIRV::Extension::Extension::SPV_KHR_cooperative_matrix},
-};
+        {"SPV_KHR_non_semantic_info",
+         SPIRV::Extension::Extension::SPV_KHR_non_semantic_info}};
 
 bool SPIRVExtensionsParser::parse(cl::Option &O, llvm::StringRef ArgName,
                                   llvm::StringRef ArgValue,
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
index d866af2c873925..cc17fa14eec856 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -114,7 +114,10 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
     SPIRVGlobalRegistry *GR = TM->getSubtargetImpl()->getSPIRVGlobalRegistry();
     MachineRegisterInfo &MRI = MF.getRegInfo();
     MachineBasicBlock &MBB = *MF.begin();
-    MachineIRBuilder MIRBuilder(MBB, MBB.begin());
+
+    // To correct placement of a OpLabel instruction during SPIRVAsmPrinter
+    // emission all new instructions needs to be placed after OpFunction
+    MachineIRBuilder MIRBuilder(MBB, MBB.end());
 
     // Emit OpString with FilePath which is required by DebugSource
     const Register StrReg = MRI.createVirtualRegister(&SPIRV::IDRegClass);
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index 45518d79edf9ed..a2fcfc636e3684 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -910,6 +910,14 @@ void addInstrRequirements(const MachineInstr &MI,
       Reqs.addCapability(SPIRV::Capability::Float16Buffer);
     break;
   }
+  case SPIRV::OpExtInst: {
+    if (MI.getOperand(2).getImm() ==
+        static_cast<int64_t>(
+            SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100)) {
+      Reqs.addExtension(SPIRV::Extension::SPV_KHR_non_semantic_info);
+    }
+    break;
+  }
   case SPIRV::OpBitReverse:
   case SPIRV::OpBitFieldInsert:
   case SPIRV::OpBitFieldSExtract:
diff --git a/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll b/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll
index 6b7a13a24d7e8c..1b5979187a7cd3 100644
--- a/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll
+++ b/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll
@@ -1,6 +1,6 @@
-; RUN: llc --print-after=spirv-nonsemantic-debug-info -O0 -mtriple=spirv64-unknown-unknown %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-MIR
-; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
-; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+; RUN: llc --spirv-ext=+SPV_KHR_non_semantic_info --print-after=spirv-nonsemantic-debug-info -O0 -mtriple=spirv64-unknown-unknown %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-MIR
+; RUN: llc --spirv-ext=+SPV_KHR_non_semantic_info -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
+; RUN: %if spirv-tools %{ llc --spirv-ext=+SPV_KHR_non_semantic_info -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
 
 ; CHECK-MIR-DAG: [[type_void:%[0-9]+\:type]] = OpTypeVoid
 ; CHECK-MIR-DAG: [[type_i32:%[0-9]+\:type\(s32\)]] = OpTypeInt 32, 0

>From d59c78b4a3ecd227097010c236861e0f35e87cf8 Mon Sep 17 00:00:00 2001
From: "Wlodarczyk, Bertrand" <bertrand.wlodarczyk at intel.com>
Date: Thu, 11 Jul 2024 17:51:52 +0200
Subject: [PATCH 11/16] Updated SPIRVUsage.rst

---
 llvm/docs/SPIRVUsage.rst | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/llvm/docs/SPIRVUsage.rst b/llvm/docs/SPIRVUsage.rst
index 70865b95cb3932..484428afdbbaf8 100644
--- a/llvm/docs/SPIRVUsage.rst
+++ b/llvm/docs/SPIRVUsage.rst
@@ -181,6 +181,8 @@ list of supported SPIR-V extensions, sorted alphabetically by their extension na
      - Adds a new instruction that enables rotating values across invocations within a subgroup.
    * - ``SPV_KHR_uniform_group_instructions``
      - Allows support for additional group operations within uniform control flow.
+   * - ``SPV_KHR_non_semantic_info``
+     - Adds the ability to declare extended instruction sets that have no semantic impact and can be safely removed from a module.
 
 To enable multiple extensions, list them separated by spaces. For example, to enable support for atomic operations on floating-point numbers and arbitrary precision integers, use:
 

>From ec3fb99facd1ec7daf83130892a76178d7ca2ef6 Mon Sep 17 00:00:00 2001
From: "Wlodarczyk, Bertrand" <bertrand.wlodarczyk at intel.com>
Date: Mon, 12 Aug 2024 12:55:54 +0200
Subject: [PATCH 12/16] Replacement of getMMI method

---
 llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
index cc17fa14eec856..3ac1cad62b5844 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -74,7 +74,7 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
   // Searching through the Module metadata to find nescessary
   // information like DwarfVersion or SourceLanguage
   {
-    const MachineModuleInfo &MMI = MF.getMMI();
+    const MachineModuleInfo &MMI = getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
     const Module *M = MMI.getModule();
     Context = &M->getContext();
     const NamedMDNode *DbgCu = M->getNamedMetadata("llvm.dbg.cu");

>From 64c99215dd0bcc83360e142333877d86c19b8ac7 Mon Sep 17 00:00:00 2001
From: "Wlodarczyk, Bertrand" <bertrand.wlodarczyk at intel.com>
Date: Mon, 12 Aug 2024 14:29:34 +0200
Subject: [PATCH 13/16] Format fix

---
 llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
index 3ac1cad62b5844..7736f1c5f3554d 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -74,7 +74,8 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
   // Searching through the Module metadata to find nescessary
   // information like DwarfVersion or SourceLanguage
   {
-    const MachineModuleInfo &MMI = getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
+    const MachineModuleInfo &MMI =
+        getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
     const Module *M = MMI.getModule();
     Context = &M->getContext();
     const NamedMDNode *DbgCu = M->getNamedMetadata("llvm.dbg.cu");

>From a3682f7b1ca5271ff7f7e2c2921154460807515c Mon Sep 17 00:00:00 2001
From: "Wlodarczyk, Bertrand" <bertrand.wlodarczyk at intel.com>
Date: Mon, 12 Aug 2024 15:54:35 +0200
Subject: [PATCH 14/16] Added command line option for DI emission

---
 llvm/docs/SPIRVUsage.rst                       |  6 +++++-
 llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp   |  9 ++++++++-
 .../SPIRV/debug-info/basic-global-di.ll        | 18 +++++++++++-------
 3 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/llvm/docs/SPIRVUsage.rst b/llvm/docs/SPIRVUsage.rst
index 484428afdbbaf8..0f0b21fb237703 100644
--- a/llvm/docs/SPIRVUsage.rst
+++ b/llvm/docs/SPIRVUsage.rst
@@ -33,7 +33,11 @@ Static Compiler Commands
    Command: `llc -O1 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_arbitrary_precision_integers input.ll -o output.spvt`
    Description: Compiles an LLVM IL file to SPIR-V with (`-O1`) optimizations, targeting a 64-bit architecture. It enables the SPV_INTEL_arbitrary_precision_integers extension.
 
-3. **SPIR-V Binary Generation**
+3. **Compilation with experimental NonSemantic.Shader.DebugInfo.100 support**
+   Command: `llc --spv-emit-nonsemantic-debug-info --spirv-ext=+SPV_KHR_non_semantic_info input.ll -o output.spvt`
+   Description: Compiles an LLVM IL file to SPIR-V with additional NonSemantic.Shader.DebugInfo.100 instructions. It enables the required SPV_KHR_non_semantic_info extension.
+
+4. **SPIR-V Binary Generation**
    Command: `llc -O0 -mtriple=spirv64-unknown-unknown -filetype=obj input.ll -o output.spvt`
    Description: Generates a SPIR-V object file (`output.spvt`) from an LLVM module, targeting a 64-bit SPIR-V architecture with no optimizations.
 
diff --git a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
index 32a9b3f71cf08e..48a2ce89bad390 100644
--- a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
@@ -209,8 +209,15 @@ bool SPIRVPassConfig::addRegBankSelect() {
   return false;
 }
 
+static cl::opt<bool> SPVEnableNonSemanticDI(
+    "spv-emit-nonsemantic-debug-info",
+    cl::desc("Emit SPIR-V NonSemantic.Shader.DebugInfo.100 instructions"),
+    cl::Optional, cl::init(false));
+
 void SPIRVPassConfig::addPreEmitPass() {
-  addPass(createSPIRVEmitNonSemanticDIPass(&getTM<SPIRVTargetMachine>()));
+  if (SPVEnableNonSemanticDI) {
+    addPass(createSPIRVEmitNonSemanticDIPass(&getTM<SPIRVTargetMachine>()));
+  }
 }
 
 namespace {
diff --git a/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll b/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll
index 1b5979187a7cd3..4a38cab59ee775 100644
--- a/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll
+++ b/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll
@@ -1,5 +1,6 @@
-; RUN: llc --spirv-ext=+SPV_KHR_non_semantic_info --print-after=spirv-nonsemantic-debug-info -O0 -mtriple=spirv64-unknown-unknown %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-MIR
-; RUN: llc --spirv-ext=+SPV_KHR_non_semantic_info -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
+; RUN: llc --spv-emit-nonsemantic-debug-info --spirv-ext=+SPV_KHR_non_semantic_info --print-after=spirv-nonsemantic-debug-info -O0 -mtriple=spirv64-unknown-unknown %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-MIR
+; RUN: llc --spv-emit-nonsemantic-debug-info --spirv-ext=+SPV_KHR_non_semantic_info -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_KHR_non_semantic_info %s -o - | FileCheck %s --check-prefix=CHECK-OPTION 
 ; RUN: %if spirv-tools %{ llc --spirv-ext=+SPV_KHR_non_semantic_info -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
 
 ; CHECK-MIR-DAG: [[type_void:%[0-9]+\:type]] = OpTypeVoid
@@ -7,20 +8,23 @@
 ; CHECK-MIR-DAG: [[dwarf_version:%[0-9]+\:id\(s32\)]] = OpConstantI [[type_i32]], 5
 ; CHECK-MIR-DAG: [[source_language:%[0-9]+\:id\(s32\)]] = OpConstantI [[type_i32]], 3
 ; CHECK-MIR-DAG: [[debug_info_version:%[0-9]+\:id\(s32\)]] = OpConstantI [[type_i32]], 21
-; CHECK-MIR-DAG: [[filename_str:%[0-9]+\:id\(s32\)]] = OpString 1094795567, 1094795585, 792805697, 1111638594, 1111638594, 1128481583, 1128481603, 1697596227, 1886216568, 1663985004, 0 
+; CHECK-MIR-DAG: [[filename_str:%[0-9]+\:id\(s32\)]] = OpString 1094795567, 1094795585, 792805697, 1111638594, 1111638594, 1128481583, 1128481603, 1697596227, 1886216568, 1663985004, 0
 ; CHECK-MIR-DAG: [[debug_source:%[0-9]+\:id\(s32\)]] = OpExtInst [[type_void]], 3, 35, [[filename_str]]
 ; CHECK-MIR-DAG: [[debug_compilation_unit:%[0-9]+\:id\(s32\)]] = OpExtInst [[type_void]], 3, 1, [[source_language]], [[dwarf_version]], [[debug_source]], [[debug_info_version]]
 
 ; CHECK-SPIRV: [[ext_inst_non_semantic:%[0-9]+]] = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
-; CHECK-SPIRV: [[filename_str:%[0-9]+]] = OpString "/AAAAAAAAAA/BBBBBBBB/CCCCCCCCC/example.c" 
+; CHECK-SPIRV: [[filename_str:%[0-9]+]] = OpString "/AAAAAAAAAA/BBBBBBBB/CCCCCCCCC/example.c"
 ; CHECK-SPIRV-DAG: [[type_void:%[0-9]+]] = OpTypeVoid
 ; CHECK-SPIRV-DAG: [[type_i32:%[0-9]+]] = OpTypeInt 32 0
-; CHECK-SPIRV-DAG: [[dwarf_version:%[0-9]+]] = OpConstant [[type_i32]] 5 
-; CHECK-SPIRV-DAG: [[debug_info_version:%[0-9]+]] = OpConstant [[type_i32]] 21 
-; CHECK-SPIRV-DAG: [[source_language:%[0-9]+]] = OpConstant [[type_i32]] 3 
+; CHECK-SPIRV-DAG: [[dwarf_version:%[0-9]+]] = OpConstant [[type_i32]] 5
+; CHECK-SPIRV-DAG: [[debug_info_version:%[0-9]+]] = OpConstant [[type_i32]] 21
+; CHECK-SPIRV-DAG: [[source_language:%[0-9]+]] = OpConstant [[type_i32]] 3
 ; CHECK-SPIRV: [[debug_source:%[0-9]+]] = OpExtInst [[type_void]] [[ext_inst_non_semantic]] DebugSource [[filename_str]]
 ; CHECK-SPIRV: [[debug_compiation_unit:%[0-9]+]] = OpExtInst [[type_void]] [[ext_inst_non_semantic]] DebugCompilationUnit [[source_language]] [[dwarf_version]] [[debug_source]] [[debug_info_version]]
 
+; CHECK-OPTION-NOT: OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
+; CHECK-OPTION-NOT: OpString "/AAAAAAAAAA/BBBBBBBB/CCCCCCCCC/example.c"
+
 define spir_func void @foo() {
 entry:
   ret void

>From a2247c5dfce603f142c9f4e6e6b24ded7f75e87a Mon Sep 17 00:00:00 2001
From: "Wlodarczyk, Bertrand" <bertrand.wlodarczyk at intel.com>
Date: Wed, 14 Aug 2024 16:50:41 +0200
Subject: [PATCH 15/16] Additional fixes

---
 .../Target/SPIRV/SPIRVEmitNonSemanticDI.cpp   | 33 ++++---------------
 1 file changed, 6 insertions(+), 27 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
index 7736f1c5f3554d..2940ffe48e20c6 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -3,6 +3,7 @@
 #include "SPIRVGlobalRegistry.h"
 #include "SPIRVRegisterInfo.h"
 #include "SPIRVTargetMachine.h"
+#include "llvm/ADT/SmallString.h"
 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
 #include "llvm/CodeGen/MachineBasicBlock.h"
 #include "llvm/CodeGen/MachineFunction.h"
@@ -66,7 +67,7 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
 
   // Required variables to get from metadata search
   LLVMContext *Context;
-  std::string FilePath;
+  SmallString<128> FilePath;
   unsigned SourceLanguage = 0;
   int64_t DwarfVersion = 0;
   int64_t DebugInfoVersion = 0;
@@ -84,9 +85,7 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
     for (const auto *Op : DbgCu->operands()) {
       if (const auto *CompileUnit = dyn_cast<DICompileUnit>(Op)) {
         DIFile *File = CompileUnit->getFile();
-        FilePath = ((File->getDirectory() + sys::path::get_separator() +
-                     File->getFilename()))
-                       .str();
+        sys::path::append(FilePath, File->getDirectory(), File->getFilename());
         SourceLanguage = CompileUnit->getSourceLanguage();
         break;
       }
@@ -150,31 +149,11 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
     // Convert DwarfVersion, DebugInfo and SourceLanguage integers to OpConstant
     // instructions required by DebugCompilationUnit
     const Register DwarfVersionReg =
-        MRI.createVirtualRegister(&SPIRV::IDRegClass);
-    MRI.setType(DwarfVersionReg, LLT::scalar(32));
-    MIRBuilder.buildInstr(SPIRV::OpConstantI)
-        .addDef(DwarfVersionReg)
-        .addUse(GR->getSPIRVTypeID(I32Ty))
-        .addImm(DwarfVersion);
-    GR->assignSPIRVTypeToVReg(I32Ty, DwarfVersionReg, MF);
-
+        GR->buildConstantInt(DwarfVersion, MIRBuilder, I32Ty, false);
     const Register DebugInfoVersionReg =
-        MRI.createVirtualRegister(&SPIRV::IDRegClass);
-    MRI.setType(DebugInfoVersionReg, LLT::scalar(32));
-    MIRBuilder.buildInstr(SPIRV::OpConstantI)
-        .addDef(DebugInfoVersionReg)
-        .addUse(GR->getSPIRVTypeID(I32Ty))
-        .addImm(DebugInfoVersion);
-    GR->assignSPIRVTypeToVReg(I32Ty, DebugInfoVersionReg, MF);
-
+        GR->buildConstantInt(DebugInfoVersion, MIRBuilder, I32Ty, false);
     const Register SourceLanguageReg =
-        MRI.createVirtualRegister(&SPIRV::IDRegClass);
-    MRI.setType(SourceLanguageReg, LLT::scalar(32));
-    MIRBuilder.buildInstr(SPIRV::OpConstantI)
-        .addDef(SourceLanguageReg)
-        .addUse(GR->getSPIRVTypeID(I32Ty))
-        .addImm(SourceLanguage);
-    GR->assignSPIRVTypeToVReg(I32Ty, SourceLanguageReg, MF);
+        GR->buildConstantInt(SourceLanguage, MIRBuilder, I32Ty, false);
 
     // Emit DebugCompilationUnit
     const Register DebugCompUnitResIdReg =

>From a6cafc5410af36523860db2e3a096ae1032b1862 Mon Sep 17 00:00:00 2001
From: "Wlodarczyk, Bertrand" <bertrand.wlodarczyk at intel.com>
Date: Mon, 19 Aug 2024 12:25:25 +0200
Subject: [PATCH 16/16] Change from id to iid in CHECK-MIR

---
 llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll b/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll
index 4a38cab59ee775..2849158012b4ce 100644
--- a/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll
+++ b/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll
@@ -5,9 +5,9 @@
 
 ; CHECK-MIR-DAG: [[type_void:%[0-9]+\:type]] = OpTypeVoid
 ; CHECK-MIR-DAG: [[type_i32:%[0-9]+\:type\(s32\)]] = OpTypeInt 32, 0
-; CHECK-MIR-DAG: [[dwarf_version:%[0-9]+\:id\(s32\)]] = OpConstantI [[type_i32]], 5
-; CHECK-MIR-DAG: [[source_language:%[0-9]+\:id\(s32\)]] = OpConstantI [[type_i32]], 3
-; CHECK-MIR-DAG: [[debug_info_version:%[0-9]+\:id\(s32\)]] = OpConstantI [[type_i32]], 21
+; CHECK-MIR-DAG: [[dwarf_version:%[0-9]+\:iid\(s32\)]] = OpConstantI [[type_i32]], 5
+; CHECK-MIR-DAG: [[source_language:%[0-9]+\:iid\(s32\)]] = OpConstantI [[type_i32]], 3
+; CHECK-MIR-DAG: [[debug_info_version:%[0-9]+\:iid\(s32\)]] = OpConstantI [[type_i32]], 21
 ; CHECK-MIR-DAG: [[filename_str:%[0-9]+\:id\(s32\)]] = OpString 1094795567, 1094795585, 792805697, 1111638594, 1111638594, 1128481583, 1128481603, 1697596227, 1886216568, 1663985004, 0
 ; CHECK-MIR-DAG: [[debug_source:%[0-9]+\:id\(s32\)]] = OpExtInst [[type_void]], 3, 35, [[filename_str]]
 ; CHECK-MIR-DAG: [[debug_compilation_unit:%[0-9]+\:id\(s32\)]] = OpExtInst [[type_void]], 3, 1, [[source_language]], [[dwarf_version]], [[debug_source]], [[debug_info_version]]



More information about the llvm-commits mailing list