[PATCH 75/79] Preserve DIExpression in DIGlobalVariableExpression (#2324)
authorLU-JOHN <111294400+LU-JOHN@users.noreply.github.com>
Wed, 31 Jan 2024 13:08:38 +0000 (07:08 -0600)
committerAndreas Beckmann <anbe@debian.org>
Thu, 8 Feb 2024 21:48:18 +0000 (22:48 +0100)
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 <john.lu@intel.com>
Gbp-Pq: Name 0075-Preserve-DIExpression-in-DIGlobalVariableExpression-.patch

lib/SPIRV/SPIRVToLLVMDbgTran.cpp
test/DebugInfo/DebugInfo-GV-with-DIE.spt [new file with mode: 0644]

index 180b91e0d81b9a440371796d42bea3d4fcb4d8c0..e6f2e8131c35528028b9a0947ebe424d7d0abe8c 100644 (file)
@@ -1120,6 +1120,15 @@ MDNode *SPIRVToLLVMDbgTran::transGlobalVariable(const SPIRVExtInst *DebugInst) {
     StaticMemberDecl = transDebugInst<DIDerivedType>(
         BM->get<SPIRVExtInst>(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<SPIRVDebug::Expression>(Ops[VariableIdx]))
+    DIExpr =
+        transDebugInst<DIExpression>(BM->get<SPIRVExtInst>(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<SPIRVDebug::DebugInfoNone>(Ops[VariableIdx])) {
-    SPIRVValue *V = BM->get<SPIRVValue>(Ops[VariableIdx]);
-    Value *Var = SPIRVReader->transValue(V, nullptr, nullptr);
-    llvm::GlobalVariable *GV = dyn_cast_or_null<llvm::GlobalVariable>(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<SPIRVDebug::DebugInfoNone>(Ops[VariableIdx])) {
+      SPIRVValue *V = BM->get<SPIRVValue>(Ops[VariableIdx]);
+      Value *Var = SPIRVReader->transValue(V, nullptr, nullptr);
+      llvm::GlobalVariable *GV = dyn_cast_or_null<llvm::GlobalVariable>(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 (file)
index 0000000..a3d615f
--- /dev/null
@@ -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 
+