llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-backend-spir-v Author: Manuel Carrasco (mgcarrasco) <details> <summary>Changes</summary> This PR adds support for [DebugLocalVariable](https://registry.khronos.org/SPIR-V/specs/unified1/DebugInfo.html#DebugLocalVariable). --- Patch is 20.88 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/221706.diff 7 Files Affected: - (modified) llvm/lib/Target/SPIRV/SPIRVNonSemanticDebugHandler.cpp (+69-11) - (modified) llvm/lib/Target/SPIRV/SPIRVNonSemanticDebugHandler.h (+20) - (added) llvm/test/CodeGen/SPIRV/debug-info/debug-local-variable-dbg-value.ll (+40) - (added) llvm/test/CodeGen/SPIRV/debug-info/debug-local-variable-records-and-retained.ll (+42) - (added) llvm/test/CodeGen/SPIRV/debug-info/debug-local-variable-retained-nodes.ll (+40) - (added) llvm/test/CodeGen/SPIRV/debug-info/debug-local-variable-skip-type.ll (+32) - (added) llvm/test/CodeGen/SPIRV/debug-info/debug-local-variable.ll (+58) ``````````diff diff --git a/llvm/lib/Target/SPIRV/SPIRVNonSemanticDebugHandler.cpp b/llvm/lib/Target/SPIRV/SPIRVNonSemanticDebugHandler.cpp index bb311d61f59c0..42d40ef4f8c57 100644 --- a/llvm/lib/Target/SPIRV/SPIRVNonSemanticDebugHandler.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVNonSemanticDebugHandler.cpp @@ -257,21 +257,30 @@ unsigned SPIRVNonSemanticDebugHandler::toNSDISrcLang(unsigned DwarfSrcLang) { } } -// Collect distinct DILocations from LLVM IR. DebugLine pre-emission and MIR -// lookups assume every machine-instruction debug location already appeared -// here; a codegen-only location would not be collected and emission will be -// skipped. -static void collectUniqueDebugLocations(const Module &M, - SetVector<const DILocation *> &Out) { +// Collect distinct DILocations and DILocalVariables from LLVM IR. DebugLine +// pre-emission and MIR lookups assume every machine-instruction debug location +// already appeared here; a codegen-only location would not be collected and +// emission will be skipped. +static void collectDebugLocationsAndLocalVariables( + const Module &M, SetVector<const DILocation *> &Locations, + SetVector<const DILocalVariable *> &LVs) { for (const Function &F : M) { - if (!F.getSubprogram()) + const DISubprogram *SP = F.getSubprogram(); + if (!SP) continue; + for (const MDNode *N : SP->getRetainedNodes()) + if (const auto *LV = dyn_cast_or_null<DILocalVariable>(N)) + LVs.insert(LV); for (const Instruction &I : instructions(F)) { if (const DILocation *DL = I.getDebugLoc().get()) - Out.insert(DL); - for (DbgRecord &DR : I.getDbgRecordRange()) + Locations.insert(DL); + for (DbgRecord &DR : I.getDbgRecordRange()) { if (const DILocation *DL = DR.getDebugLoc().get()) - Out.insert(DL); + Locations.insert(DL); + if (const auto *DVR = dyn_cast<DbgVariableRecord>(&DR)) + if (const DILocalVariable *LV = DVR->getVariable()) + LVs.insert(LV); + } } } } @@ -310,6 +319,7 @@ void SPIRVNonSemanticDebugHandler::beginModule(Module *M) { SubprogramDefinitions.clear(); UniqueDebugLocations.clear(); GlobalVariableDebugInfoMap.clear(); + LocalVariables.clear(); LexicalBlocks.clear(); DebugScopeRegs.clear(); DebugInlinedAtRegs.clear(); @@ -393,7 +403,8 @@ void SPIRVNonSemanticDebugHandler::beginModule(Module *M) { GV, GlobalVariableDebugInfo{Expr, DIGVToLLVMGV.lookup(GV)}); } - collectUniqueDebugLocations(*M, UniqueDebugLocations); + collectDebugLocationsAndLocalVariables(*M, UniqueDebugLocations, + LocalVariables); // DILexicalBlock and DINamespace scopes are lowered to DebugLexicalBlock. // Collect them in parent-before-child order so they can be later emitted in a @@ -908,6 +919,43 @@ std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugGlobalVariable( VoidTypeReg, ExtInstSetReg, Ops, MAI); } +std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugLocalVariable( + const DILocalVariable *LV, MCRegister VoidTypeReg, MCRegister I32TypeReg, + MCRegister ExtInstSetReg, SPIRV::ModuleAnalysisInfo &MAI) { + assert(LV && "LV must not be null in emitDebugLocalVariable"); + + auto ParentRegOpt = resolveScope(LV->getScope()); + if (!ParentRegOpt) + return std::nullopt; + + MCRegister TyReg = CachedDebugInfoNoneReg; + if (const DIType *Ty = LV->getType()) { + auto TyRegOpt = lookupOptReg(DebugScopeRegs, Ty); + if (!TyRegOpt) + return std::nullopt; + TyReg = *TyRegOpt; + } + + MCRegister NameReg = getCachedOpStringReg(LV->getName()); + MCRegister FileStrReg = getCachedScopePathOpStringReg( + LV->getFile(), /*UseEmptyPathIfNullScope=*/true); + MCRegister SrcReg = getOrEmitDebugSourceForFileStrReg(FileStrReg, VoidTypeReg, + ExtInstSetReg, MAI); + MCRegister LineReg = + emitOpConstantI32(static_cast<uint32_t>(LV->getLine()), I32TypeReg, MAI); + // DILocalVariable has no column field. Column is hardcoded to 0. + MCRegister ColReg = emitOpConstantI32(0, I32TypeReg, MAI); + MCRegister FlagsReg = emitOpConstantI32(transDebugFlags(LV), I32TypeReg, MAI); + + SmallVector<MCRegister, 8> Ops = {NameReg, TyReg, SrcReg, LineReg, + ColReg, *ParentRegOpt, FlagsReg}; + if (unsigned Arg = LV->getArg()) + Ops.push_back(emitOpConstantI32(Arg, I32TypeReg, MAI)); + + return emitExtInst(SPIRV::NonSemanticExtInst::DebugLocalVariable, VoidTypeReg, + ExtInstSetReg, Ops, MAI); +} + std::optional<MCRegister> SPIRVNonSemanticDebugHandler::emitDebugTypeVector( const DICompositeType *VT, MCRegister ExtInstSetReg, SPIRV::ModuleAnalysisInfo &MAI) { @@ -1141,6 +1189,11 @@ void SPIRVNonSemanticDebugHandler::emitNonSemanticDebugStrings( emitAndCacheScopePathOpStringReg(GV->getFile(), MAI); } + for (const DILocalVariable *LV : LocalVariables) { + emitOpStringIfNew(LV->getName(), MAI); + emitAndCacheScopePathOpStringReg(LV->getFile(), MAI); + } + // Cache the path OpString each DebugLexicalBlock uses (source file), plus // the Name OpString for the DINamespace case. for (const DIScope *S : LexicalBlocks) { @@ -1671,6 +1724,11 @@ void SPIRVNonSemanticDebugHandler::emitNonSemanticGlobalDebugInfo( DebugScopeRegs[S] = *LBReg; } + // Emit DebugLocalVariable after DebugFunction and their lexical blocks so the + // Parent operand can resolve. + for (const DILocalVariable *LV : LocalVariables) + emitDebugLocalVariable(LV, VoidTypeReg, I32TypeReg, ExtInstSetReg, MAI); + // Emit DebugGlobalVariable for each collected DIGlobalVariable. for (const auto &[GV, Info] : GlobalVariableDebugInfoMap) emitDebugGlobalVariable(GV, Info, VoidTypeReg, I32TypeReg, ExtInstSetReg, diff --git a/llvm/lib/Target/SPIRV/SPIRVNonSemanticDebugHandler.h b/llvm/lib/Target/SPIRV/SPIRVNonSemanticDebugHandler.h index ce02b274af75e..b709a37b42da1 100644 --- a/llvm/lib/Target/SPIRV/SPIRVNonSemanticDebugHandler.h +++ b/llvm/lib/Target/SPIRV/SPIRVNonSemanticDebugHandler.h @@ -104,6 +104,10 @@ class SPIRVNonSemanticDebugHandler : public DebugHandlerBase { DenseMap<const DIGlobalVariable *, GlobalVariableDebugInfo> GlobalVariableDebugInfoMap; + // Distinct DILocalVariable nodes collected in beginModule() from dbg + // records, dbg intrinsics, and subprogram retained nodes. + SetVector<const DILocalVariable *> LocalVariables; + // Distinct DILexicalBlock and DINamespace scopes, parent-before-child // order, collected in beginModule() for DebugLexicalBlock emission. SetVector<const DIScope *> LexicalBlocks; @@ -348,6 +352,22 @@ class SPIRVNonSemanticDebugHandler : public DebugHandlerBase { MCRegister ExtInstSetReg, SPIRV::ModuleAnalysisInfo &MAI); + /// Emit \c DebugLocalVariable for the source local variable \p LV: + /// Name, Type, Source, Line, Column, Parent, Flags, and an optional Arg + /// Number. Line, Column, Flags, and Arg Number are emitted as \c OpConstant + /// ids as required for non-semantic debug info. Column is always 0: + /// \c DILocalVariable has no column field. + /// + /// Arg Number is appended when \p LV is a parameter. + /// + /// \returns The result id register on success. Returns \c std::nullopt and + /// emits nothing if \p LV's scope is not an emitted local scope, + /// if a non-null type was not emitted in \c DebugScopeRegs, or if + /// \c resolveScope returns no id for the Parent operand. + std::optional<MCRegister> emitDebugLocalVariable( + const DILocalVariable *LV, MCRegister VoidTypeReg, MCRegister I32TypeReg, + MCRegister ExtInstSetReg, SPIRV::ModuleAnalysisInfo &MAI); + /// Emit \c DebugGlobalVariable for the source global variable \p GV. /// /// (\c SPIRVDebug::Operand::GlobalVariable): Name, Type, Source, Line, diff --git a/llvm/test/CodeGen/SPIRV/debug-info/debug-local-variable-dbg-value.ll b/llvm/test/CodeGen/SPIRV/debug-info/debug-local-variable-dbg-value.ll new file mode 100644 index 0000000000000..9f503153b9317 --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/debug-info/debug-local-variable-dbg-value.ll @@ -0,0 +1,40 @@ +; RUN: llc --verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_KHR_non_semantic_info %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc --verify-machineinstrs --spirv-ext=+SPV_KHR_non_semantic_info -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %} + +; Collect DILocalVariable from a #dbg_value record. No retainedNodes. + +; CHECK-DAG: [[EXT:%[0-9]+]] = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" +; CHECK-DAG: [[VOID:%[0-9]+]] = OpTypeVoid +; CHECK-DAG: [[I32T:%[0-9]+]] = OpTypeInt 32 0 +; CHECK-DAG: [[PATH:%[0-9]+]] = OpString "{{[/\\]}}src{{[/\\]}}debug-local-variable-dbg-value.c" +; CHECK-DAG: [[XNAME:%[0-9]+]] = OpString "x" +; CHECK-DAG: [[INTNAME:%[0-9]+]] = OpString "int" +; CHECK-DAG: [[C0:%[0-9]+]] = OpConstant [[I32T]] 0 +; CHECK-DAG: [[C1:%[0-9]+]] = OpConstant [[I32T]] 1 +; CHECK-DAG: [[C8:%[0-9]+]] = OpConstant [[I32T]] 8 +; CHECK-DAG: [[DS:%[0-9]+]] = OpExtInst [[VOID]] [[EXT]] DebugSource [[PATH]] +; CHECK-DAG: [[INT:%[0-9]+]] = OpExtInst [[VOID]] [[EXT]] DebugTypeBasic [[INTNAME]] {{.*}} [[C0]] +; CHECK-DAG: [[DF:%[0-9]+]] = OpExtInst [[VOID]] [[EXT]] DebugFunction {{.*}} +; CHECK-DAG: OpExtInst [[VOID]] [[EXT]] DebugLocalVariable [[XNAME]] [[INT]] [[DS]] [[C8]] [[C0]] [[DF]] [[C0]] [[C1]] + +target triple = "spirv64-unknown-unknown" + +define spir_func i32 @passthrough(i32 %x) !dbg !5 { +entry: + #dbg_value(i32 %x, !9, !DIExpression(), !10) + ret i32 %x, !dbg !10 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "debug-local-variable-dbg-value.c", directory: "/src") +!2 = !{i32 7, !"Dwarf Version", i32 5} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !DISubroutineType(types: !6) +!6 = !{!7, !7} +!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!5 = distinct !DISubprogram(name: "passthrough", linkageName: "passthrough", scope: !1, file: !1, line: 8, type: !4, scopeLine: 8, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0) +!9 = !DILocalVariable(name: "x", arg: 1, scope: !5, file: !1, line: 8, type: !7) +!10 = !DILocation(line: 8, column: 1, scope: !5) diff --git a/llvm/test/CodeGen/SPIRV/debug-info/debug-local-variable-records-and-retained.ll b/llvm/test/CodeGen/SPIRV/debug-info/debug-local-variable-records-and-retained.ll new file mode 100644 index 0000000000000..81b4ce830eed3 --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/debug-info/debug-local-variable-records-and-retained.ll @@ -0,0 +1,42 @@ +; RUN: llc --verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_KHR_non_semantic_info %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc --verify-machineinstrs --spirv-ext=+SPV_KHR_non_semantic_info -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %} + +; The same DILocalVariable is listed in retainedNodes and referenced by a #dbg_declare. + +; CHECK-DAG: [[EXT:%[0-9]+]] = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" +; CHECK-DAG: [[VOID:%[0-9]+]] = OpTypeVoid +; CHECK-DAG: [[I32T:%[0-9]+]] = OpTypeInt 32 0 +; CHECK-DAG: [[PATH:%[0-9]+]] = OpString "{{[/\\]}}src{{[/\\]}}debug-local-variable-records-and-retained.c" +; CHECK-DAG: [[NAME:%[0-9]+]] = OpString "dup" +; CHECK-DAG: [[INTNAME:%[0-9]+]] = OpString "int" +; CHECK-DAG: [[C0:%[0-9]+]] = OpConstant [[I32T]] 0 +; CHECK-DAG: [[C3:%[0-9]+]] = OpConstant [[I32T]] 3 +; CHECK-DAG: [[DS:%[0-9]+]] = OpExtInst [[VOID]] [[EXT]] DebugSource [[PATH]] +; CHECK-DAG: [[INT:%[0-9]+]] = OpExtInst [[VOID]] [[EXT]] DebugTypeBasic [[INTNAME]] {{.*}} [[C0]] +; CHECK-DAG: [[DF:%[0-9]+]] = OpExtInst [[VOID]] [[EXT]] DebugFunction {{.*}} +; CHECK-DAG: OpExtInst [[VOID]] [[EXT]] DebugLocalVariable [[NAME]] [[INT]] [[DS]] [[C3]] [[C0]] [[DF]] [[C0]] +; CHECK-NOT: DebugLocalVariable + +target triple = "spirv64-unknown-unknown" + +define spir_func void @f() !dbg !5 { +entry: + %dup = alloca i32, align 4 + #dbg_declare(ptr %dup, !9, !DIExpression(), !10) + ret void, !dbg !10 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "debug-local-variable-records-and-retained.c", directory: "/src") +!2 = !{i32 7, !"Dwarf Version", i32 5} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !DISubroutineType(types: !6) +!6 = !{null} +!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!5 = distinct !DISubprogram(name: "f", linkageName: "f", scope: !1, file: !1, line: 1, type: !4, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !8) +!8 = !{!9} +!9 = !DILocalVariable(name: "dup", scope: !5, file: !1, line: 3, type: !7) +!10 = !DILocation(line: 3, column: 1, scope: !5) diff --git a/llvm/test/CodeGen/SPIRV/debug-info/debug-local-variable-retained-nodes.ll b/llvm/test/CodeGen/SPIRV/debug-info/debug-local-variable-retained-nodes.ll new file mode 100644 index 0000000000000..47a2dff9b7015 --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/debug-info/debug-local-variable-retained-nodes.ll @@ -0,0 +1,40 @@ +; RUN: llc --verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_KHR_non_semantic_info %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc --verify-machineinstrs --spirv-ext=+SPV_KHR_non_semantic_info -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %} + +; Collect DILocalVariable only from DISubprogram retainedNodes. There are no +; #dbg_declare / #dbg_value records. + +; CHECK-DAG: [[EXT:%[0-9]+]] = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" +; CHECK-DAG: [[VOID:%[0-9]+]] = OpTypeVoid +; CHECK-DAG: [[I32T:%[0-9]+]] = OpTypeInt 32 0 +; CHECK-DAG: [[PATH:%[0-9]+]] = OpString "{{[/\\]}}src{{[/\\]}}debug-local-variable-retained-nodes.c" +; CHECK-DAG: [[NAME:%[0-9]+]] = OpString "gone" +; CHECK-DAG: [[INTNAME:%[0-9]+]] = OpString "int" +; CHECK-DAG: [[C0:%[0-9]+]] = OpConstant [[I32T]] 0 +; CHECK-DAG: [[C9:%[0-9]+]] = OpConstant [[I32T]] 9 +; CHECK-DAG: [[DS:%[0-9]+]] = OpExtInst [[VOID]] [[EXT]] DebugSource [[PATH]] +; CHECK-DAG: [[INT:%[0-9]+]] = OpExtInst [[VOID]] [[EXT]] DebugTypeBasic [[INTNAME]] {{.*}} [[C0]] +; CHECK-DAG: [[DF:%[0-9]+]] = OpExtInst [[VOID]] [[EXT]] DebugFunction {{.*}} +; CHECK-DAG: OpExtInst [[VOID]] [[EXT]] DebugLocalVariable [[NAME]] [[INT]] [[DS]] [[C9]] [[C0]] [[DF]] [[C0]] + +target triple = "spirv64-unknown-unknown" + +define spir_func void @f() !dbg !5 { +entry: + ret void, !dbg !10 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "debug-local-variable-retained-nodes.c", directory: "/src") +!2 = !{i32 7, !"Dwarf Version", i32 5} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !DISubroutineType(types: !6) +!6 = !{null} +!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!5 = distinct !DISubprogram(name: "f", linkageName: "f", scope: !1, file: !1, line: 1, type: !4, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !8) +!8 = !{!9} +!9 = !DILocalVariable(name: "gone", scope: !5, file: !1, line: 9, type: !7) +!10 = !DILocation(line: 1, column: 1, scope: !5) diff --git a/llvm/test/CodeGen/SPIRV/debug-info/debug-local-variable-skip-type.ll b/llvm/test/CodeGen/SPIRV/debug-info/debug-local-variable-skip-type.ll new file mode 100644 index 0000000000000..ca496aadf4224 --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/debug-info/debug-local-variable-skip-type.ll @@ -0,0 +1,32 @@ +; RUN: llc --verify-machineinstrs --spirv-ext=+SPV_KHR_non_semantic_info -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc --verify-machineinstrs --spirv-ext=+SPV_KHR_non_semantic_info -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %} + +; A DILocalVariable whose type is not yet supported. +; The DebugLocalVariable is skipped. + +; CHECK-DAG: OpExtInst {{.*}} DebugCompilationUnit +; CHECK-NOT: DebugLocalVariable + +target triple = "spirv64-unknown-unknown" + +define spir_func void @f() !dbg !5 { +entry: + %p = alloca ptr, align 8 + #dbg_declare(ptr %p, !9, !DIExpression(), !10) + ret void, !dbg !10 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "t.c", directory: "/tmp") +!2 = !{i32 7, !"Dwarf Version", i32 5} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !DISubroutineType(types: !6) +!6 = !{null} +!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!8 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64) +!5 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !4, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0) +!9 = !DILocalVariable(name: "p", scope: !5, file: !1, line: 2, type: !8) +!10 = !DILocation(line: 2, column: 1, scope: !5) diff --git a/llvm/test/CodeGen/SPIRV/debug-info/debug-local-variable.ll b/llvm/test/CodeGen/SPIRV/debug-info/debug-local-variable.ll new file mode 100644 index 0000000000000..3711c8b6778cd --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/debug-info/debug-local-variable.ll @@ -0,0 +1,58 @@ +; RUN: llc --verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_KHR_non_semantic_info %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc --verify-machineinstrs --spirv-ext=+SPV_KHR_non_semantic_info -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %} + +; A function parameter and a local variable. + +; CHECK-DAG: [[EXT:%[0-9]+]] = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" +; CHECK-DAG: [[VOID:%[0-9]+]] = OpTypeVoid +; CHECK-DAG: [[I32T:%[0-9]+]] = OpTypeInt 32 0 +; CHECK-DAG: [[PATH:%[0-9]+]] = OpString "{{[/\\]}}src{{[/\\]}}debug-local-variable.c" +; CHECK-DAG: [[FNNAME:%[0-9]+]] = OpString "add_one" +; CHECK-DAG: [[INTNAME:%[0-9]+]] = OpString "int" +; CHECK-DAG: [[VALUE:%[0-9]+]] = OpString "value" +; CHECK-DAG: [[RESULT:%[0-9]+]] = OpString "result" +; The trailing anchors keep e.g. [[C1]] from binding to "OpConstant %3 100". +; CHECK-DAG: [[C0:%[0-9]+]] = OpConstant [[I32T]] 0{{ *$}} +; CHECK-DAG: [[C1:%[0-9]+]] = OpConstant [[I32T]] 1{{ *$}} +; CHECK-DAG: [[C7:%[0-9]+]] = OpConstant [[I32T]] 7{{ *$}} +; CHECK-DAG: [[C11:%[0-9]+]] = OpConstant [[I32T]] 11{{ *$}} +; CHECK-DAG: [[DS:%[0-9]+]] = OpExtInst [[VOID]] [[EXT]] DebugSource [[PATH]] +; CHECK-DAG: [[INT:%[0-9]+]] = OpExtInst [[VOID]] [[EXT]] DebugTypeBasic [[INTNAME]] {{.*}} [[C0]] +; CHECK-DAG: [[DF:%[0-9]+]] = OpExtInst [[VOID]] [[EXT]] DebugFunction [[FNNAME]] {{.*}} [[DS]] {{.*}} + +; CHECK-DAG: OpExtInst [[VOID]] [[EXT]] DebugLocalVariable [[VALUE]] [[INT]] [[DS]] [[C7]] [[C0]] [[DF]] [[C0]] [[C1]] +; CHECK-DAG: OpExtInst [[VOID]] [[EXT]] DebugLocalVariable [[RESULT]] [[INT]] [[DS]] [[C11]] [[C0]] [[DF]] [[C0]] + +target triple = "spirv64-unknown-unknown" + +define spir_func i32 @add_one(i32 %value) !dbg !5 { +entry: + %value.addr = alloca i32, align 4 + %result = alloca i32, align 4 + store i32 %value, ptr %value.addr, align 4 + #dbg_declare(ptr %value.addr, !9, !DIExpression(), !11) + %0 = load i32, ptr %value.addr, align 4, !dbg !11 + %add = add nsw i32 %0, %0, !dbg !11 + store i32 %add, ptr %result, align 4, !dbg !11 + #dbg_declare(ptr %result, !10, !DIExpression(), !12) + %1 = load i32, ptr %result, align 4, !dbg !12 + ret i32 %1, !dbg !12 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3} + +!0 = distinct !DICompil... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/221706 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
