From f3a6a1dff079ce74fcf5d09380fe10c445bf3410 Mon Sep 17 00:00:00 2001 From: Mateusz Chudyk Date: Thu, 4 May 2023 13:32:55 +0200 Subject: [PATCH] [PATCH 30/79] [Backport to 15] Preserve invalid SPIRV source lang literal in module metadata (#1951) (#1980) Some SPIR-V producers generate invalid source language value (invalid = other than the enum values defined in spv::SourceLanguage). While in many cases this is rightly translated to DW_LANG_OpenCL, the original source language value should be preserved in LLVM module metadata for later use by LLVM IR consumers. Co-authored-by: Michal Paszkowski Gbp-Pq: Name 0030-Backport-to-15-Preserve-invalid-SPIRV-source-lang-li.patch --- lib/SPIRV/SPIRVToLLVMDbgTran.cpp | 12 +++++- lib/SPIRV/libSPIRV/SPIRV.debug.h | 17 ++++++++ .../InvalidSourceLanguageSPIRVtoLLVM.spvasm | 40 +++++++++++++++++++ 3 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 test/DebugInfo/InvalidSourceLanguageSPIRVtoLLVM.spvasm diff --git a/lib/SPIRV/SPIRVToLLVMDbgTran.cpp b/lib/SPIRV/SPIRVToLLVMDbgTran.cpp index 152683a..28b2170 100644 --- a/lib/SPIRV/SPIRVToLLVMDbgTran.cpp +++ b/lib/SPIRV/SPIRVToLLVMDbgTran.cpp @@ -159,10 +159,18 @@ SPIRVToLLVMDbgTran::transCompilationUnit(const SPIRVExtInst *DebugInst) { M->addModuleFlag(llvm::Module::Max, "Dwarf Version", DWARFVersion); SPIRVWord SourceLang = getConstantValueOrLiteral(Ops, LanguageIdx, DebugInst->getExtSetKind()); - if (DebugInst->getExtSetKind() == SPIRVEIS_NonSemantic_Shader_DebugInfo_200) + if (DebugInst->getExtSetKind() == SPIRVEIS_NonSemantic_Shader_DebugInfo_200) { SourceLang = convertSPIRVSourceLangToDWARFNonSemanticDbgInfo(SourceLang); - else + } else if (isSPIRVSourceLangValid(SourceLang)) { SourceLang = convertSPIRVSourceLangToDWARF(SourceLang); + } else { + // 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; + } + auto Producer = findModuleProducer(); CU = Builder.createCompileUnit(SourceLang, getFile(Ops[SourceIdx]), Producer, false, "", 0); diff --git a/lib/SPIRV/libSPIRV/SPIRV.debug.h b/lib/SPIRV/libSPIRV/SPIRV.debug.h index 3454d7c..0c17595 100644 --- a/lib/SPIRV/libSPIRV/SPIRV.debug.h +++ b/lib/SPIRV/libSPIRV/SPIRV.debug.h @@ -849,6 +849,23 @@ inline spv::SourceLanguage convertDWARFSourceLangToSPIRV(dwarf::SourceLanguage D } } +inline bool isSPIRVSourceLangValid(unsigned SourceLang) { + switch (SourceLang) { + // When updating this function, make sure to also + // update convertSPIRVSourceLangToDWARF() + case spv::SourceLanguage::SourceLanguageOpenCL_CPP: + case spv::SourceLanguage::SourceLanguageCPP_for_OpenCL: + case spv::SourceLanguage::SourceLanguageOpenCL_C: + case spv::SourceLanguage::SourceLanguageESSL: + case spv::SourceLanguage::SourceLanguageGLSL: + case spv::SourceLanguage::SourceLanguageHLSL: + case spv::SourceLanguage::SourceLanguageUnknown: + return true; + default: + return false; + } +} + inline dwarf::SourceLanguage convertSPIRVSourceLangToDWARF(unsigned SourceLang) { switch (SourceLang) { // When updating this function, make sure to also diff --git a/test/DebugInfo/InvalidSourceLanguageSPIRVtoLLVM.spvasm b/test/DebugInfo/InvalidSourceLanguageSPIRVtoLLVM.spvasm new file mode 100644 index 0000000..82f1f4e --- /dev/null +++ b/test/DebugInfo/InvalidSourceLanguageSPIRVtoLLVM.spvasm @@ -0,0 +1,40 @@ +; This test checks that any invalid source language in the Compilation Unit instruction is mapped to +; DW_LANG_OpenCL and the original literal value is retained in the "Source Lang Literal" LLVM module flag metadata. + +; REQUIRES: spirv-as + +; RUN: spirv-as --target-env spv1.3 %s -o %t.spv +; RUN: llvm-spirv -r -emit-opaque-pointers %t.spv -o - | llvm-dis | FileCheck %s + +; SPIR-V +; Version: 1.1 +; Generator: Khronos LLVM/SPIR-V Translator; 14 +; Bound: 16 +; Schema: 0 + OpCapability Addresses + OpCapability Kernel + %1 = OpExtInstImport "OpenCL.std" + %2 = OpExtInstImport "OpenCL.DebugInfo.100" + OpMemoryModel Physical64 OpenCL + OpEntryPoint Kernel %5 "func" + %7 = OpString "kernel_arg_type.func." + %8 = OpString "/tmp/test.cl" + %9 = OpString "//__CSK_MD5:18aa9ce738eaafc7b7b7181c19092815" + %12 = OpString "func" + %14 = OpString "" + OpSource Unknown 0 + OpName %entry "entry" + OpModuleProcessed "Debug info producer: " + %void = OpTypeVoid + %4 = OpTypeFunction %void + %10 = OpExtInst %void %2 DebugSource %8 %9 + %11 = OpExtInst %void %2 DebugCompilationUnit 65536 5 %10 !0x0000002A + %13 = OpExtInst %void %2 DebugInfoNone + %15 = OpExtInst %void %2 DebugFunction %12 %13 %10 1 0 %11 %14 FlagIsDefinition|FlagPrototyped|FlagIsOptimized 2 %5 %13 + %5 = OpFunction %void None %4 + %entry = OpLabel + OpReturn + OpFunctionEnd + +; CHECK: !{i32 2, !"Source Lang Literal", i32 42} +; CHECK: !DICompileUnit(language: DW_LANG_OpenCL, -- 2.30.2