Skip to content

Conversation

@aadeshps-mcw
Copy link
Contributor

--Added support for the extension SPV_KHR_non_semantic_info
--Added 19 instructions from the documentation.
--Added supporting tests for the same.

@aadeshps-mcw aadeshps-mcw marked this pull request as draft October 27, 2025 19:28
@llvmbot
Copy link
Member

llvmbot commented Oct 27, 2025

@llvm/pr-subscribers-backend-spir-v

Author: Aadesh Premkumar (aadeshps-mcw)

Changes

--Added support for the extension SPV_KHR_non_semantic_info
--Added 19 instructions from the documentation.
--Added supporting tests for the same.


Patch is 659.07 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/165302.diff

18 Files Affected:

  • (modified) llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp (+1408-168)
  • (modified) llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h (+11)
  • (modified) llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp (+26-2)
  • (added) llvm/test/CodeGen/SPIRV/debug-info/debug-build-identifier-storagepath.ll (+56)
  • (added) llvm/test/CodeGen/SPIRV/debug-info/debug-function.ll (+54)
  • (added) llvm/test/CodeGen/SPIRV/debug-info/debug-imported-entity.ll (+66)
  • (added) llvm/test/CodeGen/SPIRV/debug-info/debug-lexical-scope.ll (+60)
  • (added) llvm/test/CodeGen/SPIRV/debug-info/debug-macro-def-undef.ll (+88)
  • (added) llvm/test/CodeGen/SPIRV/debug-info/debug-qualifier.ll (+58)
  • (added) llvm/test/CodeGen/SPIRV/debug-info/debug-source-continued.ll (+52)
  • (added) llvm/test/CodeGen/SPIRV/debug-info/debug-type-array.ll (+74)
  • (modified) llvm/test/CodeGen/SPIRV/debug-info/debug-type-basic.ll (+1)
  • (added) llvm/test/CodeGen/SPIRV/debug-info/debug-type-composite.ll (+69)
  • (added) llvm/test/CodeGen/SPIRV/debug-info/debug-type-inheritance.ll (+88)
  • (modified) llvm/test/CodeGen/SPIRV/debug-info/debug-type-pointer.ll (+2-2)
  • (added) llvm/test/CodeGen/SPIRV/debug-info/debug-type-ptrtomember.ll (+78)
  • (added) llvm/test/CodeGen/SPIRV/debug-info/debug-type-template.ll (+85)
  • (added) llvm/test/CodeGen/SPIRV/debug-info/debug-typedef.ll (+86)
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
index 318ef0679ba03..416a87559d6b4 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -18,6 +18,7 @@
 #include "llvm/CodeGen/MachineOperand.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/Register.h"
+#include "llvm/Config/llvm-config.h"
 #include "llvm/IR/DebugInfoMetadata.h"
 #include "llvm/IR/DebugProgramInstruction.h"
 #include "llvm/IR/Metadata.h"
@@ -29,6 +30,71 @@
 using namespace llvm;
 
 namespace {
+struct SPIRVCodeGenContext {
+  MachineIRBuilder &MIRBuilder;
+  MachineRegisterInfo &MRI;
+  SPIRVGlobalRegistry *GR;
+  const SPIRVType *VoidTy;
+  const SPIRVType *I32Ty;
+  const SPIRVInstrInfo *TII;
+  const SPIRVRegisterInfo *TRI;
+  const RegisterBankInfo *RBI;
+  MachineFunction &MF;
+  const Register &I32ZeroReg;
+  SPIRVTargetMachine *TM;
+  SmallVector<std::pair<const DIFile *const, const Register>, 12>
+      &SourceRegPairs;
+  SmallVector<std::pair<const DIScope *const, const Register>, 12>
+      &ScopeRegPairs;
+  SmallVector<std::pair<const DISubroutineType *const, const Register>, 12>
+      &SubRoutineTypeRegPairs;
+  SmallVector<std::pair<const DIBasicType *const, const Register>, 12>
+      &BasicTypeRegPairs;
+  SmallVector<std::pair<const DICompositeType *const, const Register>, 12>
+      &CompositeTypeRegPairs;
+
+  SPIRVCodeGenContext(
+      MachineIRBuilder &Builder, MachineRegisterInfo &RegInfo,
+      SPIRVGlobalRegistry *Registry, const SPIRVType *VTy,
+      const SPIRVType *I32Ty, const SPIRVInstrInfo *TI,
+      const SPIRVRegisterInfo *TR, const RegisterBankInfo *RB,
+      MachineFunction &Function, const Register &ZeroReg,
+      SPIRVTargetMachine *TargetMachine,
+      SmallVector<std::pair<const DIFile *const, const Register>, 12>
+          &SourceRegisterPairs,
+      SmallVector<std::pair<const DIScope *const, const Register>, 12>
+          &ScopeRegisterPairs,
+      SmallVector<std::pair<const DISubroutineType *const, const Register>, 12>
+          &SubRoutineTypeRegisterPairs,
+      SmallVector<std::pair<const DIBasicType *const, const Register>, 12>
+          &BasicTypePairs,
+      SmallVector<std::pair<const DICompositeType *const, const Register>, 12>
+          &CompositeTypePairs)
+      : MIRBuilder(Builder), MRI(RegInfo), GR(Registry), VoidTy(VTy),
+        I32Ty(I32Ty), TII(TI), TRI(TR), RBI(RB), MF(Function),
+        I32ZeroReg(ZeroReg), TM(TargetMachine),
+        SourceRegPairs(SourceRegisterPairs), ScopeRegPairs(ScopeRegisterPairs),
+        SubRoutineTypeRegPairs(SubRoutineTypeRegisterPairs),
+        BasicTypeRegPairs(BasicTypePairs),
+        CompositeTypeRegPairs(CompositeTypePairs) {}
+};
+struct DebugInfoCollector {
+  SmallPtrSet<DIBasicType *, 12> BasicTypes;
+  SmallPtrSet<DIDerivedType *, 12> PointerDerivedTypes;
+  SmallPtrSet<DIDerivedType *, 12> QualifiedDerivedTypes;
+  SmallPtrSet<DIDerivedType *, 12> TypedefTypes;
+  SmallPtrSet<DIDerivedType *, 12> InheritedTypes;
+  SmallPtrSet<DIDerivedType *, 12> PtrToMemberTypes;
+  SmallVector<const DIImportedEntity *, 5> ImportedEntities;
+  SmallPtrSet<DISubprogram *, 12> SubPrograms;
+  SmallPtrSet<DISubroutineType *, 12> SubRoutineTypes;
+  SmallPtrSet<DIScope *, 12> LexicalScopes;
+  SmallPtrSet<DICompositeType *, 12> ArrayTypes;
+  SmallPtrSet<const DICompositeType *, 8> CompositeTypesWithTemplates;
+  SmallPtrSet<const DICompositeType *, 8> CompositeTypes;
+  SmallPtrSet<const DICompositeType *, 8> EnumTypes;
+  DenseSet<const DIType *> visitedTypes;
+};
 struct SPIRVEmitNonSemanticDI : public MachineFunctionPass {
   static char ID;
   SPIRVTargetMachine *TM;
@@ -40,6 +106,115 @@ struct SPIRVEmitNonSemanticDI : public MachineFunctionPass {
 private:
   bool IsGlobalDIEmitted = false;
   bool emitGlobalDI(MachineFunction &MF);
+  Register EmitOpString(StringRef, SPIRVCodeGenContext &Ctx);
+  uint32_t transDebugFlags(const DINode *DN);
+  uint32_t mapTagToCompositeEncoding(const DICompositeType *CT);
+  uint32_t mapTagToQualifierEncoding(unsigned Tag);
+  uint32_t mapDebugFlags(DINode::DIFlags DFlags);
+  uint32_t mapImportedTagToEncoding(const DIImportedEntity *Imported);
+
+  Register EmitDIInstruction(SPIRV::NonSemanticExtInst::NonSemanticExtInst Inst,
+                             ArrayRef<Register> Operands,
+                             SPIRVCodeGenContext &Ctx);
+
+  Register findEmittedBasicTypeReg(
+      const DIType *BaseType,
+      const SmallVectorImpl<std::pair<const DIBasicType *const, const Register>>
+          &BasicTypeRegPairs);
+
+  Register findEmittedCompositeTypeReg(
+      const DIType *BaseType,
+      const SmallVectorImpl<std::pair<const DICompositeType *const,
+                                      const Register>> &CompositeTypeRegPairs);
+
+  void extractTypeMetadata(DIType *Ty, DebugInfoCollector &Collector);
+
+  void handleCompositeType(DICompositeType *CT, DebugInfoCollector &Collector);
+  void handleDerivedType(DIDerivedType *DT, DebugInfoCollector &Collector);
+
+  void emitDebugBuildIdentifier(StringRef BuildIdentifier,
+                                SPIRVCodeGenContext &Ctx);
+
+  void emitDebugStoragePath(StringRef BuildStoragePath,
+                            SPIRVCodeGenContext &Ctx);
+
+  void emitDebugBasicTypes(const SmallPtrSetImpl<DIBasicType *> &BasicTypes,
+                           SPIRVCodeGenContext &Ctx);
+
+  void emitDebugPointerTypes(
+      const SmallPtrSetImpl<DIDerivedType *> &PointerDerivedTypes,
+      SPIRVCodeGenContext &Ctx);
+
+  void emitSingleCompilationUnit(StringRef FilePath, int64_t SourceLanguage,
+                                 SPIRVCodeGenContext &Ctx,
+                                 Register DebugInfoVersionReg,
+                                 Register DwarfVersionReg,
+                                 Register &DebugSourceResIdReg,
+                                 Register &DebugCompUnitResIdReg);
+
+  // void emitDebugTypeInheritance(
+  //     const SmallPtrSetImpl<DIDerivedType *> &InheritedTypes,
+  //     SPIRVCodeGenContext &Ctx);
+
+  void emitLexicalScopes(const SmallPtrSetImpl<DIScope *> &LexicalScopes,
+                         SPIRVCodeGenContext &Ctx);
+
+  void emitDebugArrayTypes(const SmallPtrSetImpl<DICompositeType *> &ArrayTypes,
+                           SPIRVCodeGenContext &Ctx);
+
+  void emitDebugVectorTypes(DICompositeType *ArrayTy, Register BaseTypeReg,
+                            SPIRVCodeGenContext &Ctx);
+
+  void emitDebugTypeComposite(const DICompositeType *CompTy,
+                              SPIRVCodeGenContext &Ctx);
+
+  void emitAllTemplateDebugInstructions(
+      const SmallPtrSetImpl<const DICompositeType *> &TemplatedTypes,
+      SPIRVCodeGenContext &Ctx);
+
+  void emitAllDebugTypeComposites(
+      const SmallPtrSetImpl<const DICompositeType *> &CompositeTypes,
+      SPIRVCodeGenContext &Ctx);
+
+  void emitSubroutineTypes(
+      const SmallPtrSet<DISubroutineType *, 12> &SubRoutineTypes,
+      SPIRVCodeGenContext &Ctx);
+
+  void emitSubprograms(const SmallPtrSet<DISubprogram *, 12> &SubPrograms,
+                       SPIRVCodeGenContext &Ctx);
+
+  void emitDebugTypeMember(const DIDerivedType *Member,
+                           SPIRVCodeGenContext &Ctx,
+                           const Register &CompositeReg,
+                           SmallVectorImpl<Register> &MemberRegs,
+                           Register DebugSourceReg);
+
+  void emitDebugMacroDefs(MachineFunction &MF, SPIRVCodeGenContext &Ctx);
+
+  void emitDebugMacroUndef(const DIMacro *MacroUndef, StringRef FileName,
+                           SPIRVCodeGenContext &Ctx,
+                           const DenseMap<StringRef, Register> &MacroDefRegs);
+
+  void emitDebugQualifiedTypes(
+      const SmallPtrSetImpl<DIDerivedType *> &QualifiedDerivedTypes,
+      SPIRVCodeGenContext &Ctx);
+
+  void emitDebugTypedefs(const SmallPtrSetImpl<DIDerivedType *> &TypedefTypes,
+                         SPIRVCodeGenContext &Ctx);
+
+  void emitDebugImportedEntities(
+      const SmallVectorImpl<const DIImportedEntity *> &ImportedEntities,
+      SPIRVCodeGenContext &Ctx);
+
+  Register emitDebugGlobalVariable(const DIGlobalVariableExpression *GVE,
+                                   SPIRVCodeGenContext &Ctx);
+
+  void emitAllDebugGlobalVariables(MachineFunction &MF,
+                                   SPIRVCodeGenContext &Ctx);
+
+  void emitDebugTypePtrToMember(
+      const SmallPtrSetImpl<DIDerivedType *> &PtrToMemberTypes,
+      SPIRVCodeGenContext &Ctx);
 };
 } // anonymous namespace
 
@@ -64,6 +239,12 @@ enum BaseTypeAttributeEncoding {
   UnsignedChar = 7
 };
 
+enum CompositeTypeAttributeEncoding { Class = 0, Struct = 1, Union = 2 };
+enum ImportedEnityAttributeEncoding {
+  ImportedModule = 0,
+  ImportedDeclaration = 1
+};
+
 enum SourceLanguage {
   Unknown = 0,
   ESSL = 1,
@@ -77,9 +258,53 @@ enum SourceLanguage {
   NZSL = 9,
   WGSL = 10,
   Slang = 11,
-  Zig = 12
+  Zig = 12,
+  CPP = 13
+};
+
+enum QualifierTypeAttributeEncoding {
+  ConstType = 0,
+  VolatileType = 1,
+  RestrictType = 2,
+  AtomicType = 3
+};
+
+enum Flag {
+  FlagIsProtected = 1 << 0,
+  FlagIsPrivate = 1 << 1,
+  FlagIsPublic = FlagIsPrivate | FlagIsProtected,
+  FlagAccess = FlagIsPublic,
+  FlagIsLocal = 1 << 2,
+  FlagIsDefinition = 1 << 3,
+  FlagIsFwdDecl = 1 << 4,
+  FlagIsArtificial = 1 << 5,
+  FlagIsExplicit = 1 << 6,
+  FlagIsPrototyped = 1 << 7,
+  FlagIsObjectPointer = 1 << 8,
+  FlagIsStaticMember = 1 << 9,
+  FlagIsIndirectVariable = 1 << 10,
+  FlagIsLValueReference = 1 << 11,
+  FlagIsRValueReference = 1 << 12,
+  FlagIsOptimized = 1 << 13,
+  FlagIsEnumClass = 1 << 14,
+  FlagTypePassByValue = 1 << 15,
+  FlagTypePassByReference = 1 << 16,
+  FlagUnknownPhysicalLayout = 1 << 17,
+  FlagBitField = 1 << 18
 };
 
+template <typename T, typename Container>
+Register findRegisterFromMap(const T *DIType, const Container &RegPairs,
+                             Register DefaultReg = Register()) {
+  if (!DIType)
+    return DefaultReg;
+  for (const auto &[DefinedType, Reg] : RegPairs) {
+    if (DefinedType == DIType)
+      return Reg;
+  }
+  return DefaultReg;
+}
+
 bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
   // If this MachineFunction doesn't have any BB repeat procedure
   // for the next
@@ -88,16 +313,17 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
     return false;
   }
 
-  // Required variables to get from metadata search
   LLVMContext *Context;
   SmallVector<SmallString<128>> FilePaths;
   SmallVector<int64_t> LLVMSourceLanguages;
   int64_t DwarfVersion = 0;
   int64_t DebugInfoVersion = 0;
-  SmallPtrSet<DIBasicType *, 12> BasicTypes;
-  SmallPtrSet<DIDerivedType *, 12> PointerDerivedTypes;
-  // Searching through the Module metadata to find nescessary
-  // information like DwarfVersion or SourceLanguage
+  SmallString<128> BuildIdentifier;
+  SmallString<128> BuildStoragePath;
+  Register DebugCompUnitResIdReg;
+  Register DebugSourceResIdReg;
+  DebugInfoCollector Collector;
+
   {
     const MachineModuleInfo &MMI =
         getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
@@ -108,6 +334,22 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
       return false;
     for (const auto *Op : DbgCu->operands()) {
       if (const auto *CompileUnit = dyn_cast<DICompileUnit>(Op)) {
+        if (CompileUnit->getDWOId())
+          BuildIdentifier = std::to_string(CompileUnit->getDWOId());
+        if (!CompileUnit->getSplitDebugFilename().empty())
+          BuildStoragePath = CompileUnit->getSplitDebugFilename();
+
+        for (auto *GVE : CompileUnit->getGlobalVariables()) {
+          if (auto *DIGV = dyn_cast<DIGlobalVariable>(GVE->getVariable())) {
+            extractTypeMetadata(DIGV->getType(), Collector);
+          }
+        }
+        for (const auto *IE : CompileUnit->getImportedEntities()) {
+          if (const auto *Imported = dyn_cast<DIImportedEntity>(IE)) {
+            Collector.ImportedEntities.push_back(Imported);
+          }
+        }
+
         DIFile *File = CompileUnit->getFile();
         FilePaths.emplace_back();
         sys::path::append(FilePaths.back(), File->getDirectory(),
@@ -135,25 +377,25 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
     // This traversal is the only supported way to access
     // instruction related DI metadata like DIBasicType
     for (auto &F : *M) {
+      if (DISubprogram *SP = F.getSubprogram()) {
+        Collector.SubPrograms.insert(SP);
+        if (auto *SubType = dyn_cast<DISubroutineType>(SP->getType()))
+          Collector.SubRoutineTypes.insert(SubType);
+      }
       for (auto &BB : F) {
         for (auto &I : BB) {
           for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) {
-            DILocalVariable *LocalVariable = DVR.getVariable();
-            if (auto *BasicType =
-                    dyn_cast<DIBasicType>(LocalVariable->getType())) {
-              BasicTypes.insert(BasicType);
-            } else if (auto *DerivedType =
-                           dyn_cast<DIDerivedType>(LocalVariable->getType())) {
-              if (DerivedType->getTag() == dwarf::DW_TAG_pointer_type) {
-                PointerDerivedTypes.insert(DerivedType);
-                // DIBasicType can be unreachable from DbgRecord and only
-                // pointed on from other DI types
-                // DerivedType->getBaseType is null when pointer
-                // is representing a void type
-                if (auto *BT = dyn_cast_or_null<DIBasicType>(
-                        DerivedType->getBaseType()))
-                  BasicTypes.insert(BT);
-              }
+            if (DILocalVariable *LocalVariable = DVR.getVariable())
+              extractTypeMetadata(LocalVariable->getType(), Collector);
+          }
+          if (const DebugLoc &DL = I.getDebugLoc()) {
+            if (const DILocation *Loc = DL.get()) {
+              DIScope *Scope = Loc->getScope();
+              if (auto *SP = dyn_cast<DISubprogram>(Scope))
+                Collector.SubPrograms.insert(SP);
+              else if (isa<DILexicalBlock>(Scope) ||
+                       isa<DILexicalBlockFile>(Scope))
+                Collector.LexicalScopes.insert(Scope);
             }
           }
         }
@@ -175,185 +417,1183 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
     // and before first terminator
     MachineIRBuilder MIRBuilder(MBB, MBB.getFirstTerminator());
 
-    const auto EmitOpString = [&](StringRef SR) {
-      const Register StrReg = MRI.createVirtualRegister(&SPIRV::IDRegClass);
-      MRI.setType(StrReg, LLT::scalar(32));
-      MachineInstrBuilder MIB = MIRBuilder.buildInstr(SPIRV::OpString);
-      MIB.addDef(StrReg);
-      addStringImm(SR, MIB);
-      return StrReg;
-    };
+    SmallVector<std::pair<const DIBasicType *const, const Register>, 12>
+        BasicTypeRegPairs;
+    SmallVector<std::pair<const DICompositeType *const, const Register>, 12>
+        CompositeTypeRegPairs;
+    SmallVector<std::pair<const DIFile *const, const Register>, 12>
+        SourceRegPairs;
+    SmallVector<std::pair<const DIScope *const, const Register>, 12>
+        ScopeRegPairs;
+    SmallVector<std::pair<const DISubroutineType *const, const Register>, 12>
+        SubRoutineTypeRegPairs;
 
     const SPIRVType *VoidTy =
         GR->getOrCreateSPIRVType(Type::getVoidTy(*Context), MIRBuilder,
                                  SPIRV::AccessQualifier::ReadWrite, false);
-
-    const auto EmitDIInstruction =
-        [&](SPIRV::NonSemanticExtInst::NonSemanticExtInst Inst,
-            std::initializer_list<Register> Registers) {
-          const Register InstReg =
-              MRI.createVirtualRegister(&SPIRV::IDRegClass);
-          MRI.setType(InstReg, LLT::scalar(32));
-          MachineInstrBuilder MIB =
-              MIRBuilder.buildInstr(SPIRV::OpExtInst)
-                  .addDef(InstReg)
-                  .addUse(GR->getSPIRVTypeID(VoidTy))
-                  .addImm(static_cast<int64_t>(
-                      SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100))
-                  .addImm(Inst);
-          for (auto Reg : Registers) {
-            MIB.addUse(Reg);
-          }
-          MIB.constrainAllUses(*TII, *TRI, *RBI);
-          GR->assignSPIRVTypeToVReg(VoidTy, InstReg, MF);
-          return InstReg;
-        };
-
     const SPIRVType *I32Ty =
         GR->getOrCreateSPIRVType(Type::getInt32Ty(*Context), MIRBuilder,
                                  SPIRV::AccessQualifier::ReadWrite, false);
 
+    const Register I32ZeroReg =
+        GR->buildConstantInt(1, MIRBuilder, I32Ty, false);
+
     const Register DwarfVersionReg =
         GR->buildConstantInt(DwarfVersion, MIRBuilder, I32Ty, false);
 
     const Register DebugInfoVersionReg =
         GR->buildConstantInt(DebugInfoVersion, MIRBuilder, I32Ty, false);
 
+    SPIRVCodeGenContext Ctx(MIRBuilder, MRI, GR, VoidTy, I32Ty, TII, TRI, RBI,
+                            MF, I32ZeroReg, TM, SourceRegPairs, ScopeRegPairs,
+                            SubRoutineTypeRegPairs, BasicTypeRegPairs,
+                            CompositeTypeRegPairs);
+
     for (unsigned Idx = 0; Idx < LLVMSourceLanguages.size(); ++Idx) {
-      const Register FilePathStrReg = EmitOpString(FilePaths[Idx]);
-
-      const Register DebugSourceResIdReg = EmitDIInstruction(
-          SPIRV::NonSemanticExtInst::DebugSource, {FilePathStrReg});
-
-      SourceLanguage SpirvSourceLanguage = SourceLanguage::Unknown;
-      switch (LLVMSourceLanguages[Idx]) {
-      case dwarf::DW_LANG_OpenCL:
-        SpirvSourceLanguage = SourceLanguage::OpenCL_C;
-        break;
-      case dwarf::DW_LANG_OpenCL_CPP:
-        SpirvSourceLanguage = SourceLanguage::OpenCL_CPP;
-        break;
-      case dwarf::DW_LANG_CPP_for_OpenCL:
-        SpirvSourceLanguage = SourceLanguage::CPP_for_OpenCL;
-        break;
-      case dwarf::DW_LANG_GLSL:
-        SpirvSourceLanguage = SourceLanguage::GLSL;
-        break;
-      case dwarf::DW_LANG_HLSL:
-        SpirvSourceLanguage = SourceLanguage::HLSL;
-        break;
-      case dwarf::DW_LANG_SYCL:
-        SpirvSourceLanguage = SourceLanguage::SYCL;
-        break;
-      case dwarf::DW_LANG_Zig:
-        SpirvSourceLanguage = SourceLanguage::Zig;
+      emitSingleCompilationUnit(FilePaths[Idx], LLVMSourceLanguages[Idx], Ctx,
+                                DebugInfoVersionReg, DwarfVersionReg,
+                                DebugSourceResIdReg, DebugCompUnitResIdReg);
+
+      if (const DISubprogram *SP = Ctx.MF.getFunction().getSubprogram()) {
+        if (const DIFile *File = SP->getFile())
+          Ctx.GR->addDebugValue(File, DebugCompUnitResIdReg);
+        if (const DICompileUnit *Unit = SP->getUnit())
+          Ctx.GR->addDebugValue(Unit, DebugCompUnitResIdReg);
+      }
+    }
+    emitDebugMacroDefs(MF, Ctx);
+    emitSubroutineTypes(Collector.SubRoutineTypes, Ctx);
+    emitSubprograms(Collector.SubPrograms, Ctx);
+    emitLexicalScopes(Collector.LexicalScopes, Ctx);
+    emitDebugBuildIdentifier(BuildIdentifier, Ctx);
+    emitDebugStoragePath(BuildStoragePath, Ctx);
+    emitDebugBasicTypes(Collector.BasicTypes, Ctx);
+    emitDebugPointerTypes(Collector.PointerDerivedTypes, Ctx);
+    emitDebugArrayTypes(Collector.ArrayTypes, Ctx);
+    emitAllDebugTypeComposites(Collector.CompositeTypes, Ctx);
+    emitAllTemplateDebugInstructions(Collector.CompositeTypesWithTemplates,
+                                     Ctx);
+    emitAllDebugGlobalVariables(MF, Ctx);
+    emitDebugQualifiedTypes(Collector.QualifiedDerivedTypes, Ctx);
+    emitDebugTypedefs(Collector.TypedefTypes, Ctx);
+    emitDebugImportedEntities(Collector.ImportedEntities, Ctx);
+    // emitDebugTypeInheritance(Collector.InheritedTypes, Ctx);
+    emitDebugTypePtrToMember(Collector.PtrToMemberTypes, Ctx);
+  }
+  return true;
+}
+
+bool SPIRVEmitNonSemanticDI::runOnMachineFunction(MachineFunction &MF) {
+  bool Res = false;
+  if (!IsGlobalDIEmitted) {
+    IsGlobalDIEmitted = true;
+    Res = emitGlobalDI(MF);
+  }
+  return Res;
+}
+
+Register SPIRVEmitNonSemanticDI::EmitOpString(StringRef SR,
+                                              SPIRVCodeGenContext &Ctx) {
+  const Register StrReg = Ctx.MRI.createVirtual...
[truncated]

@github-actions
Copy link

github-actions bot commented Oct 27, 2025

✅ With the latest revision this PR passed the undef deprecator.

@aadeshps-mcw aadeshps-mcw force-pushed the semantic_info branch 9 times, most recently from 6bcf16f to 8490f30 Compare October 28, 2025 06:41
--Added 19 instructions from the documentation.
--Added supporting tests for the same.
@Keenuts
Copy link
Contributor

Keenuts commented Oct 28, 2025

You might want to take a look at:
https://github.khronos.org/SPIRV-Registry/extensions/KHR/SPV_KHR_relaxed_extended_instruction.html

and

https://github.com/KhronosGroup/SPIRV-Tools/pull/5698/files

When declaring a class with methods, you can end-up with forward references in non-semantic info. In such case, you need to generate OpExtInstWithForwardRef instruction instead, and user this extension.

@aadeshps-mcw
Copy link
Contributor Author

aadeshps-mcw commented Oct 28, 2025

Is this extension needed for the instructions I am trying to implement in this PR @Keenuts ?

@Keenuts
Copy link
Contributor

Keenuts commented Oct 28, 2025

This extension is required to use OpExtInstWithForwardRefsKHR, which is not used as-is in this PR.
However, if you implement debug instructions for class methods, this will be required as those adds a circular dependency on debug instructions operands (spirv-val should complain if this happens)

@Keenuts
Copy link
Contributor

Keenuts commented Oct 28, 2025

Seems like having a method yields a crash on this PR:
(Compiled in 2 steps, HLSL -> IR, IR -> SPIR-V + debug)

// RUN: %clang --driver-mode=dxc %s -T cs_6_8 -E main -O3 -spirv -g

class A {
  int foo(int value) {
    return value * 2;
  }
};

RWStructuredBuffer<uint> buffer;

[numthreads(1, 1, 1)]
void main() {
  A a;
  buffer[0] = a.foo(buffer[0]);
}
; RUN: %llc --spv-emit-nonsemantic-debug-info --spirv-ext=+SPV_KHR_non_semantic_info -O0 -mtriple=spirv64-unknown-unknown /tmp/a.ll -o -

target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64-G10"
target triple = "spirv1.6-unknown-vulkan1.3-compute"

@.str = private unnamed_addr constant [7 x i8] c"buffer\00", align 1

; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none)
define void @main() local_unnamed_addr #0 {
entry:
    #dbg_value(i32 0, !69, !DIExpression(DW_OP_constu, 0, DW_OP_swap, DW_OP_xderef), !78)
    #dbg_value(i32 0, !72, !DIExpression(DW_OP_constu, 0, DW_OP_swap, DW_OP_xderef), !78)
    #dbg_value(i32 1, !73, !DIExpression(DW_OP_constu, 0, DW_OP_swap, DW_OP_xderef), !78)
    #dbg_value(i32 0, !74, !DIExpression(DW_OP_constu, 0, DW_OP_swap, DW_OP_xderef), !78)
    #dbg_value(ptr @.str, !75, !DIExpression(DW_OP_constu, 0, DW_OP_swap, DW_OP_xderef), !78)
    #dbg_value(i32 1, !76, !DIExpression(DW_OP_constu, 0, DW_OP_swap, DW_OP_xderef), !78)
  %0 = tail call target("spirv.VulkanBuffer", [0 x i32], 12, 1) @llvm.spv.resource.handlefromimplicitbinding.tspirv.VulkanBuffer_a0i32_12_1t(i32 0, i32 0, i32 1, i32 0, ptr nonnull @.str), !dbg !78
    #dbg_value(ptr poison, !87, !DIExpression(DW_OP_constu, 0, DW_OP_swap, DW_OP_xderef), !91)
    #dbg_value(ptr undef, !90, !DIExpression(DW_OP_constu, 0, DW_OP_swap, DW_OP_xderef), !91)
    #dbg_value(ptr poison, !93, !DIExpression(DW_OP_constu, 0, DW_OP_swap, DW_OP_xderef), !97)
    #dbg_value(i32 0, !96, !DIExpression(DW_OP_constu, 0, DW_OP_swap, DW_OP_xderef), !97)
  %1 = tail call noundef align 4 dereferenceable(4) ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.VulkanBuffer_a0i32_12_1t(target("spirv.VulkanBuffer", [0 x i32], 12, 1) %0, i32 0), !dbg !97
  %2 = load i32, ptr addrspace(11) %1, align 4, !dbg !109, !tbaa !65
    #dbg_value(ptr undef, !110, !DIExpression(DW_OP_constu, 0, DW_OP_swap, DW_OP_xderef), !115)
    #dbg_value(i32 %2, !113, !DIExpression(DW_OP_constu, 0, DW_OP_swap, DW_OP_xderef), !115)
  %mul.i = shl nsw i32 %2, 1, !dbg !117
    #dbg_value(ptr poison, !93, !DIExpression(DW_OP_constu, 0, DW_OP_swap, DW_OP_xderef), !118)
    #dbg_value(i32 0, !96, !DIExpression(DW_OP_constu, 0, DW_OP_swap, DW_OP_xderef), !118)
  store i32 %mul.i, ptr addrspace(11) %1, align 4, !dbg !120, !tbaa !65
  ret void
}

; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
declare target("spirv.VulkanBuffer", [0 x i32], 12, 1) @llvm.spv.resource.handlefromimplicitbinding.tspirv.VulkanBuffer_a0i32_12_1t(i32, i32, i32, i32, ptr) #1

; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
declare ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.VulkanBuffer_a0i32_12_1t(target("spirv.VulkanBuffer", [0 x i32], 12, 1), i32) #1

attributes #0 = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none) "frame-pointer"="all" "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }

!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!60, !61, !62, !63}
!llvm.ident = !{!64}
!llvm.errno.tbaa = !{!65}

!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_11, file: !1, producer: "clang version 22.0.0git (/home/user/projects/llvm-project/clang 07b96bbf70c7773e44e31e51b4f1aac63b815a1f)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, globals: !57, splitDebugInlining: false, nameTableKind: None)
!1 = !DIFile(filename: "/home/user/projects/llvm-project/repro.hlsl", directory: "/home/user/projects/llvm-project")
!2 = !{!3}
!3 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "RWStructuredBuffer<unsigned int>", scope: !4, size: 128, flags: DIFlagTypePassByReference | DIFlagNonTrivial, elements: !5, templateParams: !55, identifier: "_ZTSN4hlsl18RWStructuredBufferIjEE")
!4 = !DINamespace(name: "hlsl", scope: null)
!5 = !{!6, !10, !11, !15, !20, !24, !32, !33, !39, !43, !46, !49, !50}
!6 = !DIDerivedType(tag: DW_TAG_member, name: "__handle", scope: !3, file: !7, line: 15, baseType: !8, size: 64)
!7 = !DIFile(filename: "repro.hlsl", directory: "/home/user/projects/llvm-project")
!8 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !9, size: 64)
!9 = !DICompositeType(tag: DW_TAG_structure_type, name: "__hlsl_resource_t", file: !1, flags: DIFlagFwdDecl)
!10 = !DIDerivedType(tag: DW_TAG_member, name: "__counter_handle", scope: !3, file: !7, line: 15, baseType: !8, size: 64, offset: 64)
!11 = !DISubprogram(name: "RWStructuredBuffer", linkageName: "_ZN4hlsl18RWStructuredBufferIjEC4Ev", scope: !3, file: !7, type: !12, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagOptimized)
!12 = !DISubroutineType(types: !13)
!13 = !{null, !14}
!14 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !3, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer, dwarfAddressSpace: 0)
!15 = !DISubprogram(name: "RWStructuredBuffer", linkageName: "_ZN4hlsl18RWStructuredBufferIjEC4ERKS1_", scope: !3, file: !7, type: !16, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagOptimized)
!16 = !DISubroutineType(types: !17)
!17 = !{null, !14, !18}
!18 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !19, size: 64, dwarfAddressSpace: 0)
!19 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !3)
!20 = !DISubprogram(name: "operator=", linkageName: "_ZN4hlsl18RWStructuredBufferIjEaSERKS1_", scope: !3, file: !7, type: !21, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagOptimized)
!21 = !DISubroutineType(types: !22)
!22 = !{!23, !14, !18}
!23 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !3, size: 64, dwarfAddressSpace: 0)
!24 = !DISubprogram(name: "__createFromBindingWithImplicitCounter", linkageName: "_ZN4hlsl18RWStructuredBufferIjE38__createFromBindingWithImplicitCounterEjjijPKcj", scope: !3, file: !7, type: !25, flags: DIFlagPublic | DIFlagPrototyped | DIFlagStaticMember, spFlags: DISPFlagOptimized)
!25 = !DISubroutineType(types: !26)
!26 = !{!3, !27, !27, !28, !27, !29, !27}
!27 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned)
!28 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!29 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !30, size: 64, dwarfAddressSpace: 0)
!30 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !31)
!31 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
!32 = !DISubprogram(name: "__createFromImplicitBindingWithImplicitCounter", linkageName: "_ZN4hlsl18RWStructuredBufferIjE46__createFromImplicitBindingWithImplicitCounterEjjijPKcj", scope: !3, file: !7, type: !25, flags: DIFlagPublic | DIFlagPrototyped | DIFlagStaticMember, spFlags: DISPFlagOptimized)
!33 = !DISubprogram(name: "operator[]", linkageName: "_ZNK4hlsl18RWStructuredBufferIjEixEj", scope: !3, file: !7, type: !34, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagOptimized)
!34 = !DISubroutineType(types: !35)
!35 = !{!36, !38, !27}
!36 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !37, size: 64, dwarfAddressSpace: 11)
!37 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !27)
!38 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !19, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer, dwarfAddressSpace: 0)
!39 = !DISubprogram(name: "operator[]", linkageName: "_ZN4hlsl18RWStructuredBufferIjEixEj", scope: !3, file: !7, type: !40, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagOptimized)
!40 = !DISubroutineType(types: !41)
!41 = !{!42, !14, !27}
!42 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !27, size: 64, dwarfAddressSpace: 11)
!43 = !DISubprogram(name: "Load", linkageName: "_ZN4hlsl18RWStructuredBufferIjE4LoadEj", scope: !3, file: !7, type: !44, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagOptimized)
!44 = !DISubroutineType(types: !45)
!45 = !{!27, !14, !27}
!46 = !DISubprogram(name: "IncrementCounter", linkageName: "_ZN4hlsl18RWStructuredBufferIjE16IncrementCounterEv", scope: !3, file: !7, type: !47, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagOptimized)
!47 = !DISubroutineType(types: !48)
!48 = !{!27, !14}
!49 = !DISubprogram(name: "DecrementCounter", linkageName: "_ZN4hlsl18RWStructuredBufferIjE16DecrementCounterEv", scope: !3, file: !7, type: !47, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagOptimized)
!50 = !DISubprogram(name: "GetDimensions", linkageName: "_ZN4hlsl18RWStructuredBufferIjE13GetDimensionsERjS2_", scope: !3, file: !7, type: !51, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagOptimized)
!51 = !DISubroutineType(types: !52)
!52 = !{null, !14, !53, !53}
!53 = !DIDerivedType(tag: DW_TAG_restrict_type, baseType: !54)
!54 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !27, size: 64, dwarfAddressSpace: 0)
!55 = !{!56}
!56 = !DITemplateTypeParameter(name: "element_type", type: !27)
!57 = !{!58}
!58 = !DIGlobalVariableExpression(var: !59, expr: !DIExpression(DW_OP_constu, 0, DW_OP_swap, DW_OP_xderef))
!59 = distinct !DIGlobalVariable(name: "buffer", linkageName: "_ZL6buffer", scope: !0, file: !7, line: 9, type: !3, isLocal: true, isDefinition: true)
!60 = !{i32 7, !"Dwarf Version", i32 4}
!61 = !{i32 2, !"Debug Info Version", i32 3}
!62 = !{i32 1, !"wchar_size", i32 4}
!63 = !{i32 7, !"frame-pointer", i32 2}
!64 = !{!"clang version 22.0.0git (/home/user/projects/llvm-project/clang 07b96bbf70c7773e44e31e51b4f1aac63b815a1f)"}
!65 = !{!66, !66, i64 0}
!66 = !{!"int", !67, i64 0}
!67 = !{!"omnipotent char", !68, i64 0}
!68 = !{!"Simple C++ TBAA"}
!69 = !DILocalVariable(name: "orderId", arg: 1, scope: !70, file: !7, type: !27)
!70 = distinct !DISubprogram(name: "__createFromImplicitBindingWithImplicitCounter", linkageName: "_ZN4hlsl18RWStructuredBufferIjE46__createFromImplicitBindingWithImplicitCounterEjjijPKcj", scope: !3, file: !7, line: 15, type: !25, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, declaration: !32, retainedNodes: !71)
!71 = !{!69, !72, !73, !74, !75, !76, !77}
!72 = !DILocalVariable(name: "spaceNo", arg: 2, scope: !70, file: !7, type: !27)
!73 = !DILocalVariable(name: "range", arg: 3, scope: !70, file: !7, type: !28)
!74 = !DILocalVariable(name: "index", arg: 4, scope: !70, file: !7, type: !27)
!75 = !DILocalVariable(name: "name", arg: 5, scope: !70, file: !7, type: !29)
!76 = !DILocalVariable(name: "counterOrderId", arg: 6, scope: !70, file: !7, type: !27)
!77 = !DILocalVariable(name: "tmp", scope: !70, file: !7, type: !3)
!78 = !DILocation(line: 0, scope: !70, inlinedAt: !79)
!79 = distinct !DILocation(line: 0, scope: !80, inlinedAt: !83)
!80 = distinct !DISubprogram(name: "__cxx_global_var_init", scope: !7, file: !7, type: !81, flags: DIFlagArtificial | DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0)
!81 = !DISubroutineType(types: !82)
!82 = !{null}
!83 = distinct !DILocation(line: 0, scope: !84)
!84 = distinct !DISubprogram(linkageName: "_GLOBAL__sub_I_repro.hlsl", scope: !7, file: !7, type: !85, flags: DIFlagArtificial | DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0)
!85 = !DISubroutineType(types: !86)
!86 = !{}
!87 = !DILocalVariable(name: "this", arg: 1, scope: !88, type: !23, flags: DIFlagArtificial | DIFlagObjectPointer)
!88 = distinct !DISubprogram(name: "RWStructuredBuffer", linkageName: "_ZN4hlsl18RWStructuredBufferIjEC2ERKS1_", scope: !3, file: !7, line: 15, type: !16, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, declaration: !15, retainedNodes: !89)
!89 = !{!87, !90}
!90 = !DILocalVariable(name: "other", arg: 2, scope: !88, file: !7, type: !18)
!91 = !DILocation(line: 0, scope: !88, inlinedAt: !92)
!92 = distinct !DILocation(line: 0, scope: !70, inlinedAt: !79)
!93 = !DILocalVariable(name: "this", arg: 1, scope: !94, type: !23, flags: DIFlagArtificial | DIFlagObjectPointer)
!94 = distinct !DISubprogram(name: "operator[]", linkageName: "_ZN4hlsl18RWStructuredBufferIjEixEj", scope: !3, file: !7, line: 6, type: !40, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, declaration: !39, retainedNodes: !95)
!95 = !{!93, !96}
!96 = !DILocalVariable(name: "Index", arg: 2, scope: !94, file: !7, type: !27)
!97 = !DILocation(line: 0, scope: !94, inlinedAt: !98)
!98 = distinct !DILocation(line: 14, column: 21, scope: !99)
!99 = distinct !DISubprogram(name: "main", linkageName: "_Z4mainv", scope: !7, file: !7, line: 12, type: !100, scopeLine: 12, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !101)
!100 = !DISubroutineType(cc: DW_CC_LLVM_SpirFunction, types: !82)
!101 = !{!102}
!102 = !DILocalVariable(name: "a", scope: !99, file: !7, line: 13, type: !103)
!103 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "A", file: !7, line: 3, size: 8, flags: DIFlagTypePassByValue, elements: !104, identifier: "_ZTS1A")
!104 = !{!105}
!105 = !DISubprogram(name: "foo", linkageName: "_ZN1A3fooEi", scope: !103, file: !7, line: 4, type: !106, scopeLine: 4, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagOptimized)
!106 = !DISubroutineType(cc: DW_CC_LLVM_SpirFunction, types: !107)
!107 = !{!28, !108, !28}
!108 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !103, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer, dwarfAddressSpace: 0)
!109 = !DILocation(line: 14, column: 21, scope: !99)
!110 = !DILocalVariable(name: "this", arg: 1, scope: !111, type: !114, flags: DIFlagArtificial | DIFlagObjectPointer)
!111 = distinct !DISubprogram(name: "foo", linkageName: "_ZN1A3fooEi", scope: !103, file: !7, line: 4, type: !106, scopeLine: 4, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, declaration: !105, retainedNodes: !112)
!112 = !{!110, !113}
!113 = !DILocalVariable(name: "value", arg: 2, scope: !111, file: !7, line: 4, type: !28)
!114 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !103, size: 64, dwarfAddressSpace: 0)
!115 = !DILocation(line: 0, scope: !111, inlinedAt: !116)
!116 = distinct !DILocation(line: 14, column: 17, scope: !99)
!117 = !DILocation(line: 5, column: 18, scope: !111, inlinedAt: !116)
!118 = !DILocation(line: 0, scope: !94, inlinedAt: !119)
!119 = distinct !DILocation(line: 14, column: 3, scope: !99)
!120 = !DILocation(line: 14, column: 13, scope: !99)

--Modified the SPIRVEmitNonSemanticDI.cpp file for forward referencing
--Modified the test files to reflect the changes made in SPIRVEmitNonSemanticDI.cpp.
@github-actions
Copy link

github-actions bot commented Oct 29, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

--Modified the SPIRVEmitNonSemanticDI.cpp file for forward referencing
--Modified the test files to reflect the changes made in SPIRVEmitNonSemanticDI.cpp.
--Modified the SPIRVEmitNonSemanticDI.cpp file for forward referencing
--Modified the test files to reflect the changes made in SPIRVEmitNonSemanticDI.cpp.
--Modified the SPIRVEmitNonSemanticDI.cpp file for forward referencing
--Modified the test files to reflect the changes made in SPIRVEmitNonSemanticDI.cpp.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants