diff --git a/lib/SPIRV/SPIRVToLLVMDbgTran.cpp b/lib/SPIRV/SPIRVToLLVMDbgTran.cpp index a1102cf093..180b91e0d8 100644 --- a/lib/SPIRV/SPIRVToLLVMDbgTran.cpp +++ b/lib/SPIRV/SPIRVToLLVMDbgTran.cpp @@ -173,6 +173,34 @@ DIScope *SPIRVToLLVMDbgTran::getScope(const SPIRVEntry *ScopeInst) { return transDebugInst(static_cast(ScopeInst)); } +void SPIRVToLLVMDbgTran::appendToSourceLangLiteral(DICompileUnit *CompileUnit, + SPIRVWord SourceLang) { + if (!M->getModuleFlag("Source Lang Literal")) { + M->addModuleFlag(llvm::Module::Warning, "Source Lang Literal", + MDTuple::get(M->getContext(), {})); + } + auto *SourceLangLiteral = + dyn_cast(M->getModuleFlag("Source Lang Literal")); + + // Copy old content + SmallVector Nodes; + for (auto &Node : SourceLangLiteral->operands()) { + Nodes.push_back(Node); + } + + // Add new entry + Nodes.push_back(MDTuple::get( + M->getContext(), SmallVector{ + CompileUnit, + ConstantAsMetadata::get(ConstantInt::get( + Type::getInt32Ty(M->getContext()), SourceLang)), + })); + + // Update + M->setModuleFlag(llvm::Module::Warning, "Source Lang Literal", + MDTuple::get(M->getContext(), Nodes)); +} + DICompileUnit * SPIRVToLLVMDbgTran::transCompilationUnit(const SPIRVExtInst *DebugInst, const std::string CompilerVersion, @@ -197,6 +225,8 @@ SPIRVToLLVMDbgTran::transCompilationUnit(const SPIRVExtInst *DebugInst, } SPIRVWord SourceLang = getConstantValueOrLiteral(Ops, LanguageIdx, DebugInst->getExtSetKind()); + SPIRVWord OriginalSourceLang = SourceLang; + bool InvalidSourceLang = false; if (DebugInst->getExtSetKind() == SPIRVEIS_NonSemantic_Shader_DebugInfo_200) { SourceLang = convertSPIRVSourceLangToDWARFNonSemanticDbgInfo(SourceLang); } else if (isSPIRVSourceLangValid(SourceLang)) { @@ -205,8 +235,8 @@ SPIRVToLLVMDbgTran::transCompilationUnit(const SPIRVExtInst *DebugInst, // Some SPIR-V producers generate invalid source language value. In such // case the original value should be preserved in "Source Lang Literal" // module flag for later use by LLVM IR consumers. - M->addModuleFlag(llvm::Module::Warning, "Source Lang Literal", SourceLang); SourceLang = dwarf::DW_LANG_OpenCL; + InvalidSourceLang = true; } BuilderMap[DebugInst->getId()] = std::make_unique(*M); @@ -224,20 +254,28 @@ SPIRVToLLVMDbgTran::transCompilationUnit(const SPIRVExtInst *DebugInst, DebugInst->getExtSetKind() == SPIRVEIS_NonSemantic_Shader_DebugInfo_200); - return BuilderMap[DebugInst->getId()]->createCompileUnit( + auto *CompileUnit = BuilderMap[DebugInst->getId()]->createCompileUnit( SourceLang, getFile(Ops[SourceIdx]), DebugInst->getExtSetKind() == SPIRVEIS_NonSemantic_Shader_DebugInfo_100 ? CompilerVersion : getString(Ops[ProducerIdx]), false, Flags, 0, StoragePath, DICompileUnit::DebugEmissionKind::FullDebug, BuildIdentifier); + if (InvalidSourceLang) { + appendToSourceLangLiteral(CompileUnit, OriginalSourceLang); + } + return CompileUnit; } // TODO: Remove this workaround once we switch to NonSemantic.Shader.* debug // info by default auto Producer = findModuleProducer(); - return BuilderMap[DebugInst->getId()]->createCompileUnit( + auto *CompileUnit = BuilderMap[DebugInst->getId()]->createCompileUnit( SourceLang, getFile(Ops[SourceIdx]), Producer, false, Flags, 0); + if (InvalidSourceLang) { + appendToSourceLangLiteral(CompileUnit, OriginalSourceLang); + } + return CompileUnit; } DIBasicType *SPIRVToLLVMDbgTran::transTypeBasic(const SPIRVExtInst *DebugInst) { diff --git a/lib/SPIRV/SPIRVToLLVMDbgTran.h b/lib/SPIRV/SPIRVToLLVMDbgTran.h index 86cf6da791..e32b9b40ae 100644 --- a/lib/SPIRV/SPIRVToLLVMDbgTran.h +++ b/lib/SPIRV/SPIRVToLLVMDbgTran.h @@ -105,6 +105,9 @@ class SPIRVToLLVMDbgTran { MDNode *transDebugInlined(const SPIRVExtInst *Inst); MDNode *transDebugInlinedNonSemanticShader200(const SPIRVExtInst *Inst); + void appendToSourceLangLiteral(DICompileUnit *CompileUnit, + SPIRVWord SourceLang); + DICompileUnit *transCompilationUnit(const SPIRVExtInst *DebugInst, const std::string CompilerVersion = "", const std::string Flags = ""); diff --git a/test/DebugInfo/InvalidSourceLanguageSPIRVtoLLVM.spvasm b/test/DebugInfo/InvalidSourceLanguageSPIRVtoLLVM.spvasm index 82f1f4e504..7005573ecf 100644 --- a/test/DebugInfo/InvalidSourceLanguageSPIRVtoLLVM.spvasm +++ b/test/DebugInfo/InvalidSourceLanguageSPIRVtoLLVM.spvasm @@ -36,5 +36,7 @@ OpReturn OpFunctionEnd -; CHECK: !{i32 2, !"Source Lang Literal", i32 42} -; CHECK: !DICompileUnit(language: DW_LANG_OpenCL, +; CHECK: {{![0-9]+}} = !{i32 2, !"Source Lang Literal", [[LIST:![0-9]+]]} +; CHECK: [[LIST]] = !{[[ENTRY:![0-9]+]]} +; CHECK: [[ENTRY]] = !{[[CU:![0-9]+]], i32 42} +; CHECK: [[CU]] = distinct !DICompileUnit(language: DW_LANG_OpenCL