Skip to content

Commit ec02380

Browse files
authored
[DebugInfo] Fix SPIR-V consumption of DebugInfoNone for debug types (#2341)
OpenCL and NonSemantic DebugInfo specifications are flexible in terms of allowing any debug information be replaced with DebugInfoNone, so various of SPIR-V producers follow that and generate it for base types of several debug instructions, leaving SPIR-V consumers to handle this. By default the translator replaces missing debug info with tag: null, which is in most cases correct. Yet, there are situations, where it's not allowed by both LLVM and DWARF, for example for DW_TAG_array_type DWARF spec sets, that DW_AT_type attribute is mandatory. For such cases new transNonNullDebugType wrapper function was added to the translator, generating "DIBasicType(tag: DW_TAG_unspecified_type, name: "SPIRV unknown type")" where DebugInfoNone was used as the type. This function doesn't replace all calls to transDebugInst<DIType> as there are cases, where we can generate null type, for example DWARF doesn't require it for DW_TAG_typedef, hence I'm not changing translation flow in this case. Additionally to this, while DWARF requires type attribute for DW_TAG_pointer_type, LLVM does not, hence I'm not changing translation flow in this case as well. Signed-off-by: Sidorov, Dmitry <[email protected]>
1 parent 95d70a9 commit ec02380

8 files changed

+472
-12
lines changed

lib/SPIRV/SPIRVToLLVMDbgTran.cpp

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ SPIRVToLLVMDbgTran::transTypeArrayOpenCL(const SPIRVExtInst *DebugInst) {
352352
const SPIRVWordVec &Ops = DebugInst->getArguments();
353353
assert(Ops.size() >= MinOperandCount && "Invalid number of operands");
354354
DIType *BaseTy =
355-
transDebugInst<DIType>(BM->get<SPIRVExtInst>(Ops[BaseTypeIdx]));
355+
transNonNullDebugType(BM->get<SPIRVExtInst>(Ops[BaseTypeIdx]));
356356
size_t TotalCount = 1;
357357
SmallVector<llvm::Metadata *, 8> Subscripts;
358358
// Ops looks like: { BaseType, count1|upperBound1, count2|upperBound2, ...,
@@ -412,7 +412,7 @@ SPIRVToLLVMDbgTran::transTypeArrayNonSemantic(const SPIRVExtInst *DebugInst) {
412412
const SPIRVWordVec &Ops = DebugInst->getArguments();
413413
assert(Ops.size() >= MinOperandCount && "Invalid number of operands");
414414
DIType *BaseTy =
415-
transDebugInst<DIType>(BM->get<SPIRVExtInst>(Ops[BaseTypeIdx]));
415+
transNonNullDebugType(BM->get<SPIRVExtInst>(Ops[BaseTypeIdx]));
416416
size_t TotalCount = 1;
417417
SmallVector<llvm::Metadata *, 8> Subscripts;
418418
if (DebugInst->getExtOp() == SPIRVDebug::TypeArray) {
@@ -436,7 +436,7 @@ SPIRVToLLVMDbgTran::transTypeArrayDynamic(const SPIRVExtInst *DebugInst) {
436436
const SPIRVWordVec &Ops = DebugInst->getArguments();
437437
assert(Ops.size() >= MinOperandCount && "Invalid number of operands");
438438
DIType *BaseTy =
439-
transDebugInst<DIType>(BM->get<SPIRVExtInst>(Ops[BaseTypeIdx]));
439+
transNonNullDebugType(BM->get<SPIRVExtInst>(Ops[BaseTypeIdx]));
440440
size_t TotalCount = 1;
441441
SmallVector<llvm::Metadata *, 8> Subscripts;
442442
for (size_t I = SubrangesIdx; I < Ops.size(); ++I) {
@@ -479,7 +479,7 @@ SPIRVToLLVMDbgTran::transTypeVector(const SPIRVExtInst *DebugInst) {
479479
const SPIRVWordVec &Ops = DebugInst->getArguments();
480480
assert(Ops.size() >= MinOperandCount && "Invalid number of operands");
481481
DIType *BaseTy =
482-
transDebugInst<DIType>(BM->get<SPIRVExtInst>(Ops[BaseTypeIdx]));
482+
transNonNullDebugType(BM->get<SPIRVExtInst>(Ops[BaseTypeIdx]));
483483
SPIRVWord Count = getConstantValueOrLiteral(Ops, ComponentCountIdx,
484484
DebugInst->getExtSetKind());
485485
// FIXME: The current design of SPIR-V Debug Info doesn't provide a field
@@ -686,8 +686,7 @@ SPIRVToLLVMDbgTran::transTypeMemberOpenCL(const SPIRVExtInst *DebugInst) {
686686
getConstantValueOrLiteral(Ops, LineIdx, DebugInst->getExtSetKind());
687687
StringRef Name = getString(Ops[NameIdx]);
688688
DIScope *Scope = getScope(BM->getEntry(Ops[ParentIdx]));
689-
DIType *BaseType =
690-
transDebugInst<DIType>(BM->get<SPIRVExtInst>(Ops[TypeIdx]));
689+
DIType *BaseType = transNonNullDebugType(BM->get<SPIRVExtInst>(Ops[TypeIdx]));
691690
uint64_t OffsetInBits =
692691
BM->get<SPIRVConstant>(Ops[OffsetIdx])->getZExtIntValue();
693692
SPIRVWord SPIRVFlags =
@@ -739,8 +738,7 @@ SPIRVToLLVMDbgTran::transTypeMemberNonSemantic(const SPIRVExtInst *DebugInst,
739738
SPIRVWord LineNo =
740739
getConstantValueOrLiteral(Ops, LineIdx, DebugInst->getExtSetKind());
741740
StringRef Name = getString(Ops[NameIdx]);
742-
DIType *BaseType =
743-
transDebugInst<DIType>(BM->get<SPIRVExtInst>(Ops[TypeIdx]));
741+
DIType *BaseType = transNonNullDebugType(BM->get<SPIRVExtInst>(Ops[TypeIdx]));
744742
uint64_t OffsetInBits =
745743
BM->get<SPIRVConstant>(Ops[OffsetIdx])->getZExtIntValue();
746744
SPIRVWord SPIRVFlags =
@@ -853,9 +851,9 @@ SPIRVToLLVMDbgTran::transTypePtrToMember(const SPIRVExtInst *DebugInst) {
853851
const SPIRVWordVec &Ops = DebugInst->getArguments();
854852
assert(Ops.size() >= OperandCount && "Invalid number of operands");
855853
SPIRVExtInst *Member = BM->get<SPIRVExtInst>(Ops[MemberTypeIdx]);
856-
DIType *PointeeTy = transDebugInst<DIType>(Member);
854+
DIType *PointeeTy = transNonNullDebugType(Member);
857855
SPIRVExtInst *ContainingTy = BM->get<SPIRVExtInst>(Ops[ParentIdx]);
858-
DIType *BaseTy = transDebugInst<DIType>(ContainingTy);
856+
DIType *BaseTy = transNonNullDebugType(ContainingTy);
859857
return getDIBuilder(DebugInst).createMemberPointerType(PointeeTy, BaseTy, 0);
860858
}
861859

@@ -1116,7 +1114,7 @@ MDNode *SPIRVToLLVMDbgTran::transGlobalVariable(const SPIRVExtInst *DebugInst) {
11161114
assert(Ops.size() >= MinOperandCount && "Invalid number of operands");
11171115

11181116
StringRef Name = getString(Ops[NameIdx]);
1119-
DIType *Ty = transDebugInst<DIType>(BM->get<SPIRVExtInst>(Ops[TypeIdx]));
1117+
DIType *Ty = transNonNullDebugType(BM->get<SPIRVExtInst>(Ops[TypeIdx]));
11201118
DIFile *File = getFile(Ops[SourceIdx]);
11211119
SPIRVWord LineNo =
11221120
getConstantValueOrLiteral(Ops, LineIdx, DebugInst->getExtSetKind());
@@ -1182,7 +1180,7 @@ DINode *SPIRVToLLVMDbgTran::transLocalVariable(const SPIRVExtInst *DebugInst) {
11821180
DIFile *File = getFile(Ops[SourceIdx]);
11831181
SPIRVWord LineNo =
11841182
getConstantValueOrLiteral(Ops, LineIdx, DebugInst->getExtSetKind());
1185-
DIType *Ty = transDebugInst<DIType>(BM->get<SPIRVExtInst>(Ops[TypeIdx]));
1183+
DIType *Ty = transNonNullDebugType(BM->get<SPIRVExtInst>(Ops[TypeIdx]));
11861184
DINode::DIFlags Flags = DINode::FlagZero;
11871185
SPIRVWord SPIRVFlags =
11881186
getConstantValueOrLiteral(Ops, FlagsIdx, DebugInst->getExtSetKind());
@@ -1412,6 +1410,13 @@ MDNode *SPIRVToLLVMDbgTran::transExpression(const SPIRVExtInst *DebugInst) {
14121410
return getDIBuilder(DebugInst).createExpression(Addr);
14131411
}
14141412

1413+
DIType *
1414+
SPIRVToLLVMDbgTran::transNonNullDebugType(const SPIRVExtInst *DebugInst) {
1415+
if (DebugInst->getExtOp() != SPIRVDebug::DebugInfoNone)
1416+
return transDebugInst<DIType>(DebugInst);
1417+
return getDIBuilder(DebugInst).createUnspecifiedType("SPIRV unknown type");
1418+
}
1419+
14151420
MDNode *SPIRVToLLVMDbgTran::transDebugInstImpl(const SPIRVExtInst *DebugInst) {
14161421
switch (DebugInst->getExtOp()) {
14171422
case SPIRVDebug::DebugInfoNone:

lib/SPIRV/SPIRVToLLVMDbgTran.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ class SPIRVToLLVMDbgTran {
8383
DebugInstCache[DebugInst] = Res;
8484
return static_cast<T *>(Res);
8585
}
86+
8687
Instruction *transDebugIntrinsic(const SPIRVExtInst *DebugInst,
8788
BasicBlock *BB);
8889
void finalize();
@@ -99,6 +100,8 @@ class SPIRVToLLVMDbgTran {
99100

100101
MDNode *transDebugInstImpl(const SPIRVExtInst *DebugInst);
101102

103+
DIType *transNonNullDebugType(const SPIRVExtInst *DebugInst);
104+
102105
llvm::DebugLoc transDebugLocation(const SPIRVExtInst *DebugInst);
103106

104107
llvm::DebugLoc transDebugScope(const SPIRVInstruction *Inst);
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
; Tests translation of GlobalVariable with DebugInfoNone type
2+
3+
; REQUIRES: spirv-as
4+
5+
; RUN: spirv-as %s --target-env spv1.1 -o %t.spv
6+
; RUN: llvm-spirv -r -o %t.rev.bc %t.spv
7+
; RUN: llvm-dis %t.rev.bc -o %t.rev.ll
8+
; RUN: FileCheck %s --input-file %t.rev.ll --check-prefix CHECK-LLVM
9+
10+
; CHECK-LLVM: distinct !DIGlobalVariable(name: "i", linkageName: "_ZL1i", scope: ![[#]], file: ![[#]], line: 1, type: ![[#Type:]], isLocal: true, isDefinition: true)
11+
; CHECK-LLVM: ![[#Type]] = !DIBasicType(tag: DW_TAG_unspecified_type, name: "SPIRV unknown type")
12+
13+
; SPIR-V
14+
; Version: 1.1
15+
; Generator: Khronos LLVM/SPIR-V Translator; 14
16+
; Bound: 24
17+
; Schema: 0
18+
OpCapability Addresses
19+
OpCapability Linkage
20+
OpCapability Kernel
21+
%1 = OpExtInstImport "OpenCL.std"
22+
%2 = OpExtInstImport "OpenCL.DebugInfo.100"
23+
OpMemoryModel Physical64 OpenCL
24+
%8 = OpString "/tmp/global.cpp"
25+
%13 = OpString "int"
26+
%17 = OpString "main"
27+
%18 = OpString ""
28+
%21 = OpString "i"
29+
%22 = OpString "_ZL1i"
30+
OpSource Unknown 0
31+
OpName %main "main"
32+
OpName %entry "entry"
33+
OpModuleProcessed "Debuginfoproducer:clangversion3.4"
34+
OpDecorate %main LinkageAttributes "main" Export
35+
%uint = OpTypeInt 32 0
36+
%uint_0 = OpConstant %uint 0
37+
%uint_32 = OpConstant %uint 32
38+
%4 = OpTypeFunction %uint
39+
%void = OpTypeVoid
40+
%10 = OpExtInst %void %2 DebugInfoNone
41+
%11 = OpExtInst %void %2 DebugSource %8
42+
%12 = OpExtInst %void %2 DebugCompilationUnit 65536 3 %11 CPP_for_OpenCL
43+
%15 = OpExtInst %void %2 DebugTypeBasic %13 %uint_32 Signed
44+
%16 = OpExtInst %void %2 DebugTypeFunction None %15
45+
%19 = OpExtInst %void %2 DebugInfoNone
46+
%20 = OpExtInst %void %2 DebugFunction %17 %16 %11 2 0 %12 %18 FlagIsDefinition|FlagPrototyped|FlagIsOptimized 2 %main %19
47+
%23 = OpExtInst %void %2 DebugGlobalVariable %21 %10 %11 1 0 %12 %22 %19 FlagIsLocal|FlagIsDefinition
48+
%main = OpFunction %uint None %4
49+
%entry = OpLabel
50+
%24 = OpExtInst %void %2 DebugScope %20
51+
OpLine %8 4 0
52+
OpReturnValue %uint_0
53+
OpFunctionEnd
54+
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
; Tests translation of DebugTypeInheritance and DebugLocalVariable with
2+
; DebugInfoNone type
3+
4+
; REQUIRES: spirv-as
5+
6+
; RUN: spirv-as %s --target-env spv1.1 -o %t.spv
7+
; RUN: llvm-spirv -r -o %t.rev.bc %t.spv
8+
; RUN: llvm-dis %t.rev.bc -o %t.rev.ll
9+
; RUN: FileCheck %s --input-file %t.rev.ll --check-prefix CHECK-LLVM
10+
11+
; CHECK-LLVM: DILocalVariable(name: "c", scope: !9, file: !3, line: 7, type: ![[#Type:]])
12+
; CHECK-LLVM: ![[#Type]] = !DIBasicType(tag: DW_TAG_unspecified_type, name: "SPIRV unknown type")
13+
; CHECK-LLVM-NOT: DW_TAG_inheritance
14+
15+
; SPIR-V
16+
; Version: 1.0
17+
; Generator: Khronos LLVM/SPIR-V Translator; 14
18+
; Bound: 62
19+
; Schema: 0
20+
OpCapability Addresses
21+
OpCapability Linkage
22+
OpCapability Kernel
23+
OpCapability Int8
24+
OpExtension "SPV_KHR_non_semantic_info"
25+
%1 = OpExtInstImport "OpenCL.std"
26+
%2 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
27+
OpMemoryModel Physical64 OpenCL
28+
%15 = OpString "/app/example.cpp"
29+
%17 = OpString "0"
30+
%20 = OpString ""
31+
%26 = OpString "int"
32+
%31 = OpString "_ZTS1C"
33+
%32 = OpString "C"
34+
%35 = OpString "_ZTS1B"
35+
%36 = OpString "B"
36+
%38 = OpString "_ZTS1A"
37+
%39 = OpString "A"
38+
%48 = OpString "foo"
39+
%49 = OpString "_Z3foov"
40+
%53 = OpString "c"
41+
OpSource Unknown 0
42+
OpName %_Z3foov "_Z3foov"
43+
OpName %class_C "class.C"
44+
OpDecorate %_Z3foov LinkageAttributes "_Z3foov" Export
45+
OpDecorate %10 Alignment 1
46+
%uint = OpTypeInt 32 0
47+
%uchar = OpTypeInt 8 0
48+
%uint_0 = OpConstant %uint 0
49+
%uint_1 = OpConstant %uint 1
50+
%uint_65536 = OpConstant %uint 65536
51+
%uint_4 = OpConstant %uint 4
52+
%uint_6 = OpConstant %uint 6
53+
%uint_32 = OpConstant %uint 32
54+
%uint_8 = OpConstant %uint 8
55+
%uint_32768 = OpConstant %uint 32768
56+
%uint_3 = OpConstant %uint 3
57+
%uint_2 = OpConstant %uint 2
58+
%uint_136 = OpConstant %uint 136
59+
%uint_7 = OpConstant %uint 7
60+
%uint_11 = OpConstant %uint 11
61+
%uint_12 = OpConstant %uint 12
62+
%4 = OpTypeFunction %uint
63+
%class_C = OpTypeStruct %uchar
64+
%_ptr_Function_class_C = OpTypePointer Function %class_C
65+
%void = OpTypeVoid
66+
%12 = OpExtInst %void %2 DebugInfoNone
67+
%16 = OpExtInst %void %2 DebugSource %15
68+
%19 = OpExtInst %void %2 DebugBuildIdentifier %17 %uint_1
69+
%21 = OpExtInst %void %2 DebugStoragePath %20
70+
%25 = OpExtInst %void %2 DebugCompilationUnit %uint_65536 %uint_4 %16 %uint_6
71+
%28 = OpExtInst %void %2 DebugTypeBasic %26 %uint_32 %uint_4 %12
72+
%29 = OpExtInst %void %2 DebugTypeFunction %uint_0 %28
73+
%37 = OpExtInst %void %2 DebugTypeComposite %39 %uint_0 %16 %uint_1 %uint_0 %25 %38 %uint_8 %uint_32768
74+
%43 = OpExtInst %void %2 DebugTypeInheritance %37 %uint_0 %uint_0 %uint_3
75+
%34 = OpExtInst %void %2 DebugTypeComposite %36 %uint_0 %16 %uint_2 %uint_0 %25 %35 %uint_8 %uint_32768 %43
76+
%46 = OpExtInst %void %2 DebugTypeInheritance %34 %uint_0 %uint_0 %uint_3
77+
%30 = OpExtInst %void %2 DebugTypeComposite %32 %uint_0 %16 %uint_3 %uint_0 %25 %31 %uint_8 %uint_32768 %46
78+
%51 = OpExtInst %void %2 DebugFunction %48 %29 %16 %uint_4 %uint_0 %25 %49 %uint_136 %uint_4 %12
79+
%55 = OpExtInst %void %2 DebugLocalVariable %53 %12 %16 %uint_7 %uint_0 %51 %uint_0
80+
%56 = OpExtInst %void %2 DebugExpression
81+
%_Z3foov = OpFunction %uint DontInline %4
82+
%6 = OpLabel
83+
%52 = OpExtInst %void %2 DebugFunctionDefinition %51 %_Z3foov
84+
%10 = OpVariable %_ptr_Function_class_C Function
85+
%57 = OpExtInst %void %2 DebugScope %51
86+
%60 = OpExtInst %void %2 DebugLine %15 %uint_7 %uint_7 %uint_11 %uint_12
87+
%13 = OpExtInst %void %2 DebugDeclare %55 %10 %56
88+
%61 = OpExtInst %void %2 DebugLine %15 %uint_8 %uint_8 %uint_3 %uint_4
89+
OpReturnValue %uint_0
90+
OpFunctionEnd
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
; Tests translation of DebugTypePtrToMember DebugInfoNone type
2+
3+
; REQUIRES: spirv-as
4+
5+
; RUN: spirv-as %s --target-env spv1.1 -o %t.spv
6+
; RUN: llvm-spirv -r -o %t.rev.bc %t.spv
7+
; RUN: llvm-dis %t.rev.bc -o %t.rev.ll
8+
; RUN: FileCheck %s --input-file %t.rev.ll --check-prefix CHECK-LLVM
9+
10+
; CHECK-LLVM: !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: ![[#Type:]]
11+
; CHECK-LLVM: ![[#Type]] = !DIBasicType(tag: DW_TAG_unspecified_type, name: "SPIRV unknown type")
12+
13+
; SPIR-V
14+
; Version: 1.0
15+
; Generator: Khronos LLVM/SPIR-V Translator; 14
16+
; Bound: 35
17+
; Schema: 0
18+
OpCapability Addresses
19+
OpCapability Linkage
20+
OpCapability Kernel
21+
OpCapability Int64
22+
OpExtension "SPV_KHR_non_semantic_info"
23+
%1 = OpExtInstImport "OpenCL.std"
24+
%2 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
25+
OpMemoryModel Physical64 OpenCL
26+
%7 = OpString "./foo.cpp"
27+
%10 = OpString "0"
28+
%14 = OpString ""
29+
%20 = OpString "int"
30+
%26 = OpString "_ZTS3Foo"
31+
%27 = OpString "Foo"
32+
%32 = OpString "x"
33+
OpSource Unknown 0
34+
OpName %x "x"
35+
OpDecorate %x LinkageAttributes "x" Export
36+
OpDecorate %x Alignment 8
37+
%ulong = OpTypeInt 64 0
38+
%uint = OpTypeInt 32 0
39+
%ulong_18446744073709551615 = OpConstant %ulong 18446744073709551615
40+
%uint_1 = OpConstant %uint 1
41+
%uint_65536 = OpConstant %uint 65536
42+
%uint_2 = OpConstant %uint 2
43+
%uint_6 = OpConstant %uint 6
44+
%uint_32 = OpConstant %uint 32
45+
%uint_4 = OpConstant %uint 4
46+
%uint_0 = OpConstant %uint 0
47+
%uint_16 = OpConstant %uint 16
48+
%uint_8 = OpConstant %uint 8
49+
%_ptr_CrossWorkgroup_ulong = OpTypePointer CrossWorkgroup %ulong
50+
%void = OpTypeVoid
51+
%x = OpVariable %_ptr_CrossWorkgroup_ulong CrossWorkgroup %ulong_18446744073709551615
52+
%9 = OpExtInst %void %2 DebugSource %7
53+
%13 = OpExtInst %void %2 DebugBuildIdentifier %10 %uint_1
54+
%15 = OpExtInst %void %2 DebugStoragePath %14
55+
%19 = OpExtInst %void %2 DebugCompilationUnit %uint_65536 %uint_2 %9 %uint_6
56+
%23 = OpExtInst %void %2 DebugInfoNone
57+
%24 = OpExtInst %void %2 DebugTypeBasic %20 %uint_32 %uint_4 %23
58+
%25 = OpExtInst %void %2 DebugTypeComposite %27 %uint_1 %9 %uint_1 %uint_0 %19 %26 %uint_0 %uint_16
59+
%31 = OpExtInst %void %2 DebugTypePtrToMember %23 %25
60+
%34 = OpExtInst %void %2 DebugGlobalVariable %32 %31 %9 %uint_4 %uint_0 %19 %14 %x %uint_8

0 commit comments

Comments
 (0)