[llvm-branch-commits] [llvm] [WIP][SPIRV][Debug Info] Add support for emitting DebugFunction debug info instructions (PR #183122)

Manuel Carrasco via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Mar 10 05:40:17 PDT 2026


https://github.com/mgcarrasco updated https://github.com/llvm/llvm-project/pull/183122

>From 31812060c98d6dcff3eb698533cdb839e40eebc1 Mon Sep 17 00:00:00 2001
From: Manuel Carrasco <Manuel.Carrasco at amd.com>
Date: Tue, 24 Feb 2026 12:00:13 -0600
Subject: [PATCH 1/6] [SPIRV] Add support for emitting DebugFunction debug info
 instructions

This commit adds support for emitting SPIRV DebugFunction and
DebugFunctionDefinition instructions for function definitions.
---
 .../Target/SPIRV/SPIRVEmitNonSemanticDI.cpp   | 218 ++++++++++++++++++
 .../SPIRV/debug-info/debug-function.ll        |  40 ++++
 2 files changed, 258 insertions(+)
 create mode 100644 llvm/test/CodeGen/SPIRV/debug-info/debug-function.ll

diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
index 84c7ae458f49f..6435874e15860 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -64,6 +64,7 @@ struct SPIRVEmitNonSemanticDI : public MachineFunctionPass {
 
 private:
   bool emitGlobalDI(MachineFunction &MF);
+  bool emitFunctionDI(MachineFunction &MF);
   static SourceLanguage
   convertDWARFToSPIRVSourceLanguage(int64_t LLVMSourceLanguage);
   static Register emitOpString(MachineRegisterInfo &MRI,
@@ -75,6 +76,14 @@ struct SPIRVEmitNonSemanticDI : public MachineFunctionPass {
                     const RegisterBankInfo *RBI, MachineFunction &MF,
                     SPIRV::NonSemanticExtInst::NonSemanticExtInst Inst,
                     ArrayRef<Register> Registers);
+  static Register
+  emitDebugTypeFunction(MachineRegisterInfo &MRI, MachineIRBuilder &MIRBuilder,
+                        SPIRVGlobalRegistry *GR, const SPIRVTypeInst &VoidTy,
+                        const SPIRVTypeInst &I32Ty, const SPIRVInstrInfo *TII,
+                        const SPIRVRegisterInfo *TRI,
+                        const RegisterBankInfo *RBI, MachineFunction &MF,
+                        DISubroutineType *FuncType, LLVMContext *Context);
+  static uint64_t getDebugFunctionFlags(const DISubprogram *SP);
 };
 } // anonymous namespace
 
@@ -160,6 +169,63 @@ Register SPIRVEmitNonSemanticDI::emitDIInstruction(
   return InstReg;
 }
 
+// Emit a DebugTypeFunction instruction for the given DISubroutineType.
+// This creates a SPIRV debug type function that represents the function
+// signature, including type flags, return type, and parameter types. Currently
+// only handles void functions with no parameters; type flags are not translated
+// (using 0 as a placeholder), and full parameter and return type support is
+// TODO.
+Register SPIRVEmitNonSemanticDI::emitDebugTypeFunction(
+    MachineRegisterInfo &MRI, MachineIRBuilder &MIRBuilder,
+    SPIRVGlobalRegistry *GR, const SPIRVTypeInst &VoidTy,
+    const SPIRVTypeInst &I32Ty, const SPIRVInstrInfo *TII,
+    const SPIRVRegisterInfo *TRI, const RegisterBankInfo *RBI,
+    MachineFunction &MF, DISubroutineType *FuncType, LLVMContext *Context) {
+  // TODO: Translate flags from the function type. Currently not translating
+  // flags, using 0 as a placeholder.
+  const Register TypeFlagsReg =
+      GR->buildConstantInt(0, MIRBuilder, I32Ty, false);
+
+  SmallVector<Register> TypeRegs;
+  TypeRegs.push_back(TypeFlagsReg);
+
+  // TODO: Handle parameters and return types
+  // void function with no parameters - use OpTypeVoid for return type
+  const SPIRVTypeInst OpTypeVoidInst =
+      GR->getOrCreateSPIRVType(Type::getVoidTy(*Context), MIRBuilder,
+                               SPIRV::AccessQualifier::ReadWrite, false);
+  const Register VoidTypeReg = GR->getSPIRVTypeID(OpTypeVoidInst);
+  TypeRegs.push_back(VoidTypeReg);
+
+  // Emit DebugTypeFunction instruction
+  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(SPIRV::NonSemanticExtInst::DebugTypeFunction);
+  for (auto Reg : TypeRegs) {
+    MIB.addUse(Reg);
+  }
+  MIB.constrainAllUses(*TII, *TRI, *RBI);
+  GR->assignSPIRVTypeToVReg(VoidTy, InstReg, MF);
+  return InstReg;
+}
+
+// TODO: Support additional DebugFunction flags. Currently only FlagIsDefinition
+// is handled.
+uint64_t SPIRVEmitNonSemanticDI::getDebugFunctionFlags(const DISubprogram *SP) {
+  // Map flags - minimal implementation
+  // FlagIsDefinition = 1 << 3
+  uint64_t Flags = 0;
+  if (SP->isDefinition())
+    Flags |= (1 << 3); // FlagIsDefinition
+  return Flags;
+}
+
 bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
   // If this MachineFunction doesn't have any BB repeat procedure
   // for the next
@@ -377,8 +443,160 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
   return true;
 }
 
+// Emits the SPIRV DebugFunction instruction for a given MachineFunction.
+bool SPIRVEmitNonSemanticDI::emitFunctionDI(MachineFunction &MF) {
+  const Function &F = MF.getFunction();
+
+  DISubprogram *SP = F.getSubprogram();
+  // DISubProgram is not available, don't translate
+  if (!SP) {
+    return false;
+  }
+
+  // TODO: Support declarations
+  // Only process function definitions, skip declarations.
+  // Function declarations require an optional operand in the DebugFunction
+  // instruction that is not yet supported.
+  if (!SP->isDefinition()) {
+    return false;
+  }
+
+  // We insert at the first basic block available
+  if (MF.begin() == MF.end()) {
+    return false;
+  }
+
+  // Get the scope from DISubProgram
+  DIScope *Scope = SP->getScope();
+  if (!Scope) {
+    return false;
+  }
+
+  // TODO: Support additional DIScope types beyond DIFile.
+  // Only translate when scope is DIFile
+  const DIFile *FileScope = dyn_cast<DIFile>(Scope);
+  if (!FileScope) {
+    return false;
+  }
+
+  // Use SP->getUnit() as the scope for DebugSource.
+  // In SPIRV, the DebugSource scope cannot be a File, so we use the
+  // CompilationUnit instead. This matches what the translator does when
+  // handling DIFile scopes.
+  const DICompileUnit *CU = SP->getUnit();
+  if (!CU) {
+    return false;
+  }
+
+  // Check for function type - required for DebugTypeFunction
+  DISubroutineType *FuncType = SP->getType();
+  if (!FuncType) {
+    return false;
+  }
+
+  // TODO: Support functions with return types and parameters.
+  // Check that the function type array has exactly one element and it is null.
+  // This corresponds to void functions with no parameters.
+  DITypeArray TypeArray = FuncType->getTypeArray();
+  if (TypeArray.size() != 1 || TypeArray[0] != nullptr) {
+    return false;
+  }
+
+  const Module *M = getModule(MF);
+  LLVMContext *Context = &M->getContext();
+
+  // Emit DebugCompilationUnit and DebugFunction
+  {
+    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.getFirstTerminator());
+
+    const SPIRVTypeInst VoidTy =
+        GR->getOrCreateSPIRVType(Type::getVoidTy(*Context), MIRBuilder,
+                                 SPIRV::AccessQualifier::ReadWrite, false);
+
+    const SPIRVTypeInst I32Ty =
+        GR->getOrCreateSPIRVType(Type::getInt32Ty(*Context), MIRBuilder,
+                                 SPIRV::AccessQualifier::ReadWrite, false);
+
+    // Get file path from DICompileUnit for DebugSource (needed for
+    // DebugFunction)
+    DIFile *File = CU->getFile();
+    SmallString<128> FilePath;
+    sys::path::append(FilePath, File->getDirectory(), File->getFilename());
+
+    // Emit DebugSource (needed for DebugFunction)
+    const Register FilePathStrReg = emitOpString(MRI, MIRBuilder, FilePath);
+    const Register DebugSourceReg = emitDIInstruction(
+        MRI, MIRBuilder, GR, VoidTy, TII, TRI, RBI, MF,
+        SPIRV::NonSemanticExtInst::DebugSource, {FilePathStrReg});
+
+    // Look up the DebugCompilationUnit register from emitGlobalDI
+    auto It = CompileUnitRegMap.find(CU);
+    assert(It != CompileUnitRegMap.end() &&
+           "DebugCompilationUnit register should have been created in "
+           "emitGlobalDI");
+    const Register DebugCompUnitReg = It->second;
+
+    // Emit DebugFunction
+    // Get function metadata
+    StringRef FuncName = SP->getName();
+    StringRef LinkageName = SP->getLinkageName();
+    unsigned Line = SP->getLine();
+    unsigned ScopeLine = SP->getScopeLine();
+
+    uint64_t Flags = getDebugFunctionFlags(SP);
+
+    const Register NameStrReg = emitOpString(MRI, MIRBuilder, FuncName);
+    const Register LinkageNameStrReg =
+        emitOpString(MRI, MIRBuilder, LinkageName);
+
+    // Emit DebugTypeFunction
+    const Register DebugTypeFunctionReg =
+        emitDebugTypeFunction(MRI, MIRBuilder, GR, VoidTy, I32Ty, TII, TRI, RBI,
+                              MF, FuncType, Context);
+
+    const Register LineReg =
+        GR->buildConstantInt(Line, MIRBuilder, I32Ty, false);
+    const Register ColumnReg =
+        GR->buildConstantInt(0, MIRBuilder, I32Ty, false);
+    const Register FlagsReg =
+        GR->buildConstantInt(Flags, MIRBuilder, I32Ty, false);
+    const Register ScopeLineReg =
+        GR->buildConstantInt(ScopeLine, MIRBuilder, I32Ty, false);
+
+    // TODO: Handle function declarations. Declarations require an optional
+    // operand in the DebugFunction instruction that specifies the declaration's
+    // location.
+    const Register DebugFuncReg = emitDIInstruction(
+        MRI, MIRBuilder, GR, VoidTy, TII, TRI, RBI, MF,
+        SPIRV::NonSemanticExtInst::DebugFunction,
+        {NameStrReg, DebugTypeFunctionReg, DebugSourceReg, LineReg, ColumnReg,
+         DebugCompUnitReg, LinkageNameStrReg, FlagsReg, ScopeLineReg});
+
+    // Emit DebugFunctionDefinition to link the DebugFunction to the actual
+    // OpFunction.
+    const MachineInstr *OpFunctionMI = GR->getFunctionDefinition(&F);
+    if (OpFunctionMI && OpFunctionMI->getOpcode() == SPIRV::OpFunction) {
+      Register FuncReg = OpFunctionMI->getOperand(0).getReg();
+      emitDIInstruction(MRI, MIRBuilder, GR, VoidTy, TII, TRI, RBI, MF,
+                        SPIRV::NonSemanticExtInst::DebugFunctionDefinition,
+                        {DebugFuncReg, FuncReg});
+    }
+
+    return true;
+  }
+}
+
+// TODO: Deduplicate instructions
 bool SPIRVEmitNonSemanticDI::runOnMachineFunction(MachineFunction &MF) {
   CompileUnitRegMap.clear();
   bool Res = emitGlobalDI(MF);
+  Res |= emitFunctionDI(MF);
   return Res;
 }
diff --git a/llvm/test/CodeGen/SPIRV/debug-info/debug-function.ll b/llvm/test/CodeGen/SPIRV/debug-info/debug-function.ll
new file mode 100644
index 0000000000000..d9bbbe950515f
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/debug-info/debug-function.ll
@@ -0,0 +1,40 @@
+; RUN: llc --verify-machineinstrs --spv-emit-nonsemantic-debug-info --spirv-ext=+SPV_KHR_non_semantic_info -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc --verify-machineinstrs --spv-emit-nonsemantic-debug-info --spirv-ext=+SPV_KHR_non_semantic_info -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; The path separator may be '/' on Unix or '\' on Windows, so we use a flexible pattern
+; CHECK: OpString "{{[/\]}}A{{[/\]}}B{{[/\]}}C{{[/\]}}example.cpp"
+; CHECK: [[FILE_STRING:%[0-9]+]] = OpString "{{[/\]}}A{{[/\]}}B{{[/\]}}C{{[/\]}}example.cpp"
+; CHECK: [[NAME:%[0-9]+]] = OpString "test1"
+; CHECK: [[LINKAGE:%[0-9]+]] = OpString "XXXX"
+; CHECK: [[VOID_TYPE:%[0-9]+]] = OpTypeVoid
+; CHECK: [[ZERO:%[0-9]+]] = OpConstant {{.*}} 0
+; CHECK: [[LINE:%[0-9]+]] = OpConstant {{.*}} 1
+; CHECK: [[FLAGS:%[0-9]+]] = OpConstant {{.*}} 8
+; CHECK: OpExtInst {{.*}} DebugSource {{.*}}
+; CHECK: [[PARENT:%[0-9]+]] = OpExtInst {{.*}} DebugCompilationUnit {{.*}}
+; CHECK: [[SOURCE:%[0-9]+]] = OpExtInst {{.*}} DebugSource [[FILE_STRING]]
+; CHECK: [[TYPE:%[0-9]+]] = OpExtInst {{.*}} DebugTypeFunction [[ZERO]] [[VOID_TYPE]]
+; CHECK: [[DEBUG_FUNC:%[0-9]+]] = OpExtInst {{.*}} DebugFunction [[NAME]] [[TYPE]] [[SOURCE]] [[LINE]] [[ZERO]] [[PARENT]] [[LINKAGE]] [[FLAGS]] [[LINE]]
+; CHECK: [[FUNC:%[0-9]+]] = OpFunction {{.*}}
+; DebugFunctionDefinition must be after OpFunction
+; CHECK: OpExtInst {{.*}} DebugFunctionDefinition [[DEBUG_FUNC]] [[FUNC]]
+
+target triple = "spirv64-unknown-unknown"
+
+define spir_func void  @test1() !dbg !9 {
+entry:
+  ret void
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3, !4, !5}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_Zig, file: !1, producer: "clang version XX.X.XXXX (F F)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "example.cpp", directory: "/A/B/C")
+!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}
+!9 = distinct !DISubprogram(name: "test1", linkageName: "XXXX", scope: !1, file: !1, line: 1, type: !10, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0)
+!10 = !DISubroutineType(types: !11)
+!11 = !{null}

>From 3e15e617089fb22e4b50ab1ad0cde717dfda66ee Mon Sep 17 00:00:00 2001
From: Manuel Carrasco <Manuel.Carrasco at amd.com>
Date: Fri, 6 Mar 2026 07:57:45 -0600
Subject: [PATCH 2/6] [review] improve comments.

---
 .../Target/SPIRV/SPIRVEmitNonSemanticDI.cpp   | 22 +++++++++----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
index 6435874e15860..0d0089df7cdde 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -448,7 +448,7 @@ bool SPIRVEmitNonSemanticDI::emitFunctionDI(MachineFunction &MF) {
   const Function &F = MF.getFunction();
 
   DISubprogram *SP = F.getSubprogram();
-  // DISubProgram is not available, don't translate
+  // DISubProgram is not available, don't translate.
   if (!SP) {
     return false;
   }
@@ -461,19 +461,19 @@ bool SPIRVEmitNonSemanticDI::emitFunctionDI(MachineFunction &MF) {
     return false;
   }
 
-  // We insert at the first basic block available
+  // We insert at the first basic block available.
   if (MF.begin() == MF.end()) {
     return false;
   }
 
-  // Get the scope from DISubProgram
+  // Get the scope from DISubProgram.
   DIScope *Scope = SP->getScope();
   if (!Scope) {
     return false;
   }
 
   // TODO: Support additional DIScope types beyond DIFile.
-  // Only translate when scope is DIFile
+  // Only translate when scope is DIFile.
   const DIFile *FileScope = dyn_cast<DIFile>(Scope);
   if (!FileScope) {
     return false;
@@ -488,7 +488,7 @@ bool SPIRVEmitNonSemanticDI::emitFunctionDI(MachineFunction &MF) {
     return false;
   }
 
-  // Check for function type - required for DebugTypeFunction
+  // Check for function type - required for DebugTypeFunction.
   DISubroutineType *FuncType = SP->getType();
   if (!FuncType) {
     return false;
@@ -505,7 +505,7 @@ bool SPIRVEmitNonSemanticDI::emitFunctionDI(MachineFunction &MF) {
   const Module *M = getModule(MF);
   LLVMContext *Context = &M->getContext();
 
-  // Emit DebugCompilationUnit and DebugFunction
+  // Emit DebugCompilationUnit and DebugFunction.
   {
     const SPIRVInstrInfo *TII = TM->getSubtargetImpl()->getInstrInfo();
     const SPIRVRegisterInfo *TRI = TM->getSubtargetImpl()->getRegisterInfo();
@@ -525,7 +525,7 @@ bool SPIRVEmitNonSemanticDI::emitFunctionDI(MachineFunction &MF) {
                                  SPIRV::AccessQualifier::ReadWrite, false);
 
     // Get file path from DICompileUnit for DebugSource (needed for
-    // DebugFunction)
+    // DebugFunction).
     DIFile *File = CU->getFile();
     SmallString<128> FilePath;
     sys::path::append(FilePath, File->getDirectory(), File->getFilename());
@@ -536,15 +536,15 @@ bool SPIRVEmitNonSemanticDI::emitFunctionDI(MachineFunction &MF) {
         MRI, MIRBuilder, GR, VoidTy, TII, TRI, RBI, MF,
         SPIRV::NonSemanticExtInst::DebugSource, {FilePathStrReg});
 
-    // Look up the DebugCompilationUnit register from emitGlobalDI
+    // Look up the DebugCompilationUnit register from emitGlobalDI.
     auto It = CompileUnitRegMap.find(CU);
     assert(It != CompileUnitRegMap.end() &&
            "DebugCompilationUnit register should have been created in "
            "emitGlobalDI");
     const Register DebugCompUnitReg = It->second;
 
-    // Emit DebugFunction
-    // Get function metadata
+    // Emit DebugFunction.
+    // Get function metadata.
     StringRef FuncName = SP->getName();
     StringRef LinkageName = SP->getLinkageName();
     unsigned Line = SP->getLine();
@@ -556,7 +556,7 @@ bool SPIRVEmitNonSemanticDI::emitFunctionDI(MachineFunction &MF) {
     const Register LinkageNameStrReg =
         emitOpString(MRI, MIRBuilder, LinkageName);
 
-    // Emit DebugTypeFunction
+    // Emit DebugTypeFunction.
     const Register DebugTypeFunctionReg =
         emitDebugTypeFunction(MRI, MIRBuilder, GR, VoidTy, I32Ty, TII, TRI, RBI,
                               MF, FuncType, Context);

>From 32e7bc945371867ebf8ec00fdf3cc3a13a9a4921 Mon Sep 17 00:00:00 2001
From: Manuel Carrasco <Manuel.Carrasco at amd.com>
Date: Fri, 6 Mar 2026 08:00:31 -0600
Subject: [PATCH 3/6] [review] fix comment.

---
 llvm/test/CodeGen/SPIRV/debug-info/debug-function.ll | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/test/CodeGen/SPIRV/debug-info/debug-function.ll b/llvm/test/CodeGen/SPIRV/debug-info/debug-function.ll
index d9bbbe950515f..e88df5ba6ee3e 100644
--- a/llvm/test/CodeGen/SPIRV/debug-info/debug-function.ll
+++ b/llvm/test/CodeGen/SPIRV/debug-info/debug-function.ll
@@ -1,7 +1,7 @@
 ; RUN: llc --verify-machineinstrs --spv-emit-nonsemantic-debug-info --spirv-ext=+SPV_KHR_non_semantic_info -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
 ; RUN: %if spirv-tools %{ llc --verify-machineinstrs --spv-emit-nonsemantic-debug-info --spirv-ext=+SPV_KHR_non_semantic_info -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
 
-; The path separator may be '/' on Unix or '\' on Windows, so we use a flexible pattern
+; The path separator may be '/' on Unix or '\' on Windows, so we use a flexible pattern.
 ; CHECK: OpString "{{[/\]}}A{{[/\]}}B{{[/\]}}C{{[/\]}}example.cpp"
 ; CHECK: [[FILE_STRING:%[0-9]+]] = OpString "{{[/\]}}A{{[/\]}}B{{[/\]}}C{{[/\]}}example.cpp"
 ; CHECK: [[NAME:%[0-9]+]] = OpString "test1"

>From 734ec217e033ff5c6af8ff0a49e18f04c4ba3b8b Mon Sep 17 00:00:00 2001
From: Manuel Carrasco <Manuel.Carrasco at amd.com>
Date: Fri, 6 Mar 2026 08:03:08 -0600
Subject: [PATCH 4/6] [reviews] simplify code.

---
 .../Target/SPIRV/SPIRVEmitNonSemanticDI.cpp   | 24 +++++++------------
 1 file changed, 8 insertions(+), 16 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
index 0d0089df7cdde..fadee1991658b 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -448,51 +448,43 @@ bool SPIRVEmitNonSemanticDI::emitFunctionDI(MachineFunction &MF) {
   const Function &F = MF.getFunction();
 
   DISubprogram *SP = F.getSubprogram();
-  // DISubProgram is not available, don't translate.
-  if (!SP) {
+  if (!SP)
     return false;
-  }
 
   // TODO: Support declarations
   // Only process function definitions, skip declarations.
   // Function declarations require an optional operand in the DebugFunction
   // instruction that is not yet supported.
-  if (!SP->isDefinition()) {
+  if (!SP->isDefinition())
     return false;
-  }
 
   // We insert at the first basic block available.
-  if (MF.begin() == MF.end()) {
+  if (MF.begin() == MF.end())
     return false;
-  }
 
   // Get the scope from DISubProgram.
   DIScope *Scope = SP->getScope();
-  if (!Scope) {
+  if (!Scope)
     return false;
-  }
 
   // TODO: Support additional DIScope types beyond DIFile.
   // Only translate when scope is DIFile.
   const DIFile *FileScope = dyn_cast<DIFile>(Scope);
-  if (!FileScope) {
+  if (!FileScope)
     return false;
-  }
 
   // Use SP->getUnit() as the scope for DebugSource.
   // In SPIRV, the DebugSource scope cannot be a File, so we use the
   // CompilationUnit instead. This matches what the translator does when
   // handling DIFile scopes.
   const DICompileUnit *CU = SP->getUnit();
-  if (!CU) {
+  if (!CU)
     return false;
-  }
 
-  // Check for function type - required for DebugTypeFunction.
+  // Check for function type (required for emitting DebugTypeFunction).
   DISubroutineType *FuncType = SP->getType();
-  if (!FuncType) {
+  if (!FuncType)
     return false;
-  }
 
   // TODO: Support functions with return types and parameters.
   // Check that the function type array has exactly one element and it is null.

>From ffe1380633e3a501de6e877391af09893d94cd05 Mon Sep 17 00:00:00 2001
From: Manuel Carrasco <Manuel.Carrasco at amd.com>
Date: Fri, 6 Mar 2026 08:38:37 -0600
Subject: [PATCH 5/6] [reviews] minor edit.

---
 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 fadee1991658b..c2d14bad80b94 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -585,7 +585,7 @@ bool SPIRVEmitNonSemanticDI::emitFunctionDI(MachineFunction &MF) {
   }
 }
 
-// TODO: Deduplicate instructions
+// TODO: Deduplicate instructions.
 bool SPIRVEmitNonSemanticDI::runOnMachineFunction(MachineFunction &MF) {
   CompileUnitRegMap.clear();
   bool Res = emitGlobalDI(MF);

>From be5d7e3fa9cdfe6f003e8ce58f6d6ed4cde821f8 Mon Sep 17 00:00:00 2001
From: Manuel Carrasco <Manuel.Carrasco at amd.com>
Date: Fri, 6 Mar 2026 08:39:14 -0600
Subject: [PATCH 6/6] [reviews] Update comment.

---
 llvm/test/CodeGen/SPIRV/debug-info/debug-function.ll | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/test/CodeGen/SPIRV/debug-info/debug-function.ll b/llvm/test/CodeGen/SPIRV/debug-info/debug-function.ll
index e88df5ba6ee3e..674823c27bcb7 100644
--- a/llvm/test/CodeGen/SPIRV/debug-info/debug-function.ll
+++ b/llvm/test/CodeGen/SPIRV/debug-info/debug-function.ll
@@ -16,7 +16,7 @@
 ; CHECK: [[TYPE:%[0-9]+]] = OpExtInst {{.*}} DebugTypeFunction [[ZERO]] [[VOID_TYPE]]
 ; CHECK: [[DEBUG_FUNC:%[0-9]+]] = OpExtInst {{.*}} DebugFunction [[NAME]] [[TYPE]] [[SOURCE]] [[LINE]] [[ZERO]] [[PARENT]] [[LINKAGE]] [[FLAGS]] [[LINE]]
 ; CHECK: [[FUNC:%[0-9]+]] = OpFunction {{.*}}
-; DebugFunctionDefinition must be after OpFunction
+; DebugFunctionDefinition must be after OpFunction.
 ; CHECK: OpExtInst {{.*}} DebugFunctionDefinition [[DEBUG_FUNC]] [[FUNC]]
 
 target triple = "spirv64-unknown-unknown"



More information about the llvm-branch-commits mailing list