From c18fe5e21da034dba7ce6d971919c0fe6c016ab2 Mon Sep 17 00:00:00 2001 From: LU-JOHN <111294400+LU-JOHN@users.noreply.github.com> Date: Wed, 31 Jan 2024 07:08:38 -0600 Subject: [PATCH] [PATCH 75/79] Preserve DIExpression in DIGlobalVariableExpression (#2324) Ensure that SPIR-V that uses a DebugGlobalVariable's Variable field to hold an Expression can be reverse translated. A Variable field can be used to hold an Expression in order to preserve a DIExpression in a DIGlobalVariableExpression in LLVM IR. Signed-off-by: Lu, John Gbp-Pq: Name 0075-Preserve-DIExpression-in-DIGlobalVariableExpression-.patch --- lib/SPIRV/SPIRVToLLVMDbgTran.cpp | 34 +++++++++++----- test/DebugInfo/DebugInfo-GV-with-DIE.spt | 51 ++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 10 deletions(-) create mode 100644 test/DebugInfo/DebugInfo-GV-with-DIE.spt diff --git a/lib/SPIRV/SPIRVToLLVMDbgTran.cpp b/lib/SPIRV/SPIRVToLLVMDbgTran.cpp index 180b91e..e6f2e81 100644 --- a/lib/SPIRV/SPIRVToLLVMDbgTran.cpp +++ b/lib/SPIRV/SPIRVToLLVMDbgTran.cpp @@ -1120,6 +1120,15 @@ MDNode *SPIRVToLLVMDbgTran::transGlobalVariable(const SPIRVExtInst *DebugInst) { StaticMemberDecl = transDebugInst( BM->get(Ops[StaticMemberDeclarationIdx])); } + + DIExpression *DIExpr = nullptr; + // Check if Ops[VariableIdx] is not being used to hold a variable operand. + // Instead it is being used to hold an Expression that holds the initial + // value of the GlobalVariable. + if (getDbgInst(Ops[VariableIdx])) + DIExpr = + transDebugInst(BM->get(Ops[VariableIdx])); + SPIRVWord Flags = getConstantValueOrLiteral(Ops, FlagsIdx, DebugInst->getExtSetKind()); bool IsLocal = Flags & SPIRVDebug::FlagIsLocal; @@ -1128,7 +1137,7 @@ MDNode *SPIRVToLLVMDbgTran::transGlobalVariable(const SPIRVExtInst *DebugInst) { if (IsDefinition) { VarDecl = getDIBuilder(DebugInst).createGlobalVariableExpression( Parent, Name, LinkageName, File, LineNo, Ty, IsLocal, IsDefinition, - nullptr, StaticMemberDecl); + DIExpr, StaticMemberDecl); } else { VarDecl = getDIBuilder(DebugInst).createTempGlobalVariableFwdDecl( Parent, Name, LinkageName, File, LineNo, Ty, IsLocal, StaticMemberDecl); @@ -1137,15 +1146,20 @@ MDNode *SPIRVToLLVMDbgTran::transGlobalVariable(const SPIRVExtInst *DebugInst) { llvm::TempMDNode TMP(VarDecl); VarDecl = getDIBuilder(DebugInst).replaceTemporary(std::move(TMP), VarDecl); } - // If the variable has no initializer Ops[VariableIdx] is OpDebugInfoNone. - // Otherwise Ops[VariableIdx] may be a global variable or a constant(C++ - // static const). - if (VarDecl && !getDbgInst(Ops[VariableIdx])) { - SPIRVValue *V = BM->get(Ops[VariableIdx]); - Value *Var = SPIRVReader->transValue(V, nullptr, nullptr); - llvm::GlobalVariable *GV = dyn_cast_or_null(Var); - if (GV && !GV->hasMetadata("dbg")) - GV->addMetadata("dbg", *VarDecl); + + // Ops[VariableIdx] was not used to hold an Expression with the initial value + // for the GlobalVariable + if (!DIExpr) { + // If the variable has no initializer Ops[VariableIdx] is OpDebugInfoNone. + // Otherwise Ops[VariableIdx] may be a global variable or a constant(C++ + // static const). + if (VarDecl && !getDbgInst(Ops[VariableIdx])) { + SPIRVValue *V = BM->get(Ops[VariableIdx]); + Value *Var = SPIRVReader->transValue(V, nullptr, nullptr); + llvm::GlobalVariable *GV = dyn_cast_or_null(Var); + if (GV && !GV->hasMetadata("dbg")) + GV->addMetadata("dbg", *VarDecl); + } } return VarDecl; } diff --git a/test/DebugInfo/DebugInfo-GV-with-DIE.spt b/test/DebugInfo/DebugInfo-GV-with-DIE.spt new file mode 100644 index 0000000..a3d615f --- /dev/null +++ b/test/DebugInfo/DebugInfo-GV-with-DIE.spt @@ -0,0 +1,51 @@ +;; Ensure that reverse translation can handle an Expression in +;; a DebugGlobalVariable's Variable field. +;; This is used to preserve a DIExpressions in a DIGlobalVariableExpression. + +; RUN: llvm-spirv -to-binary %s -o %t.spv +; RUN: llvm-spirv -r -o %t.rev.bc %t.spv +; RUN: llvm-dis %t.rev.bc -o %t.rev.ll +; RUN: FileCheck %s --input-file %t.rev.ll + +; CHECK: ![[#]] = !DIGlobalVariableExpression(var: ![[#GV:]], expr: !DIExpression(DW_OP_constu, 1, DW_OP_stack_value)) +; CHECK: ![[#GV]] = distinct !DIGlobalVariable(name: "true", scope: ![[#]], file: ![[#]], line: 3777, type: ![[#]], isLocal: true, isDefinition: true) + +119734787 65536 393230 31 0 +2 Capability Addresses +2 Capability Linkage +2 Capability Kernel +8 Extension "SPV_KHR_non_semantic_info" +5 ExtInstImport 1 "OpenCL.std" +11 ExtInstImport 2 "NonSemantic.Shader.DebugInfo.100" +3 MemoryModel 2 2 +7 String 3 "/path/to/test.cpp" +3 String 6 "0" +3 String 10 "" +4 String 16 "bool" +4 String 23 "true" +3 Source 0 0 +4 TypeInt 7 32 0 +4 Constant 7 8 1 +4 Constant 7 12 65536 +4 Constant 7 13 4 +4 Constant 7 14 6 +4 Constant 7 17 8 +4 Constant 7 18 2 +4 Constant 7 21 0 +4 Constant 7 25 7 +4 Constant 7 28 3777 +4 Constant 7 29 12 +2 TypeVoid 4 + +6 ExtInst 4 5 2 DebugSource 3 +7 ExtInst 4 9 2 DebugBuildIdentifier 6 8 +6 ExtInst 4 11 2 DebugStoragePath 10 +9 ExtInst 4 15 2 DebugCompilationUnit 12 13 5 14 +5 ExtInst 4 19 2 DebugInfoNone +9 ExtInst 4 20 2 DebugTypeBasic 16 17 18 19 +7 ExtInst 4 22 2 DebugTypeQualifier 20 21 +7 ExtInst 4 24 2 DebugOperation 17 8 +6 ExtInst 4 26 2 DebugOperation 25 +7 ExtInst 4 27 2 DebugExpression 24 26 +14 ExtInst 4 30 2 DebugGlobalVariable 23 22 5 28 21 15 10 27 29 + -- 2.30.2