[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
Fri Mar 6 06:39:36 PST 2026
https://github.com/mgcarrasco updated https://github.com/llvm/llvm-project/pull/183122
>From 3ac724d898c7e250989a8f270b9588f16cecb54d 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 6cbe15f5fa429..3dbff31b26644 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -62,6 +62,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,
@@ -73,6 +74,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
@@ -156,6 +165,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
@@ -373,8 +439,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 8427a8a7537e0caf0f6907ce1472d252f5fa37c6 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 3dbff31b26644..43aab9f6494dc 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -444,7 +444,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;
}
@@ -457,19 +457,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;
@@ -484,7 +484,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;
@@ -501,7 +501,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();
@@ -521,7 +521,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());
@@ -532,15 +532,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();
@@ -552,7 +552,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 e0358763a507f3b681bcfb0d7a5fa27b1724e899 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 65f2890f283d3cc82a2ae946f4ad5807dd83ceda 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 43aab9f6494dc..54bf384039db6 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -444,51 +444,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 a395edbd015045908cc71e47efaf10a6a34ab65e 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 54bf384039db6..9718d8108954f 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -581,7 +581,7 @@ bool SPIRVEmitNonSemanticDI::emitFunctionDI(MachineFunction &MF) {
}
}
-// TODO: Deduplicate instructions
+// TODO: Deduplicate instructions.
bool SPIRVEmitNonSemanticDI::runOnMachineFunction(MachineFunction &MF) {
CompileUnitRegMap.clear();
bool Res = emitGlobalDI(MF);
>From 835e5d9e42c92c0ae6baea905c90e361db173561 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