[PATCH 30/79] [Backport to 15] Preserve invalid SPIRV source lang literal in module...
authorMateusz Chudyk <mateuszchudyk@gmail.com>
Thu, 4 May 2023 11:32:55 +0000 (13:32 +0200)
committerAndreas Beckmann <anbe@debian.org>
Thu, 14 Mar 2024 19:01:08 +0000 (20:01 +0100)
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 <michal@paszkowski.org>
Gbp-Pq: Name 0030-Backport-to-15-Preserve-invalid-SPIRV-source-lang-li.patch

lib/SPIRV/SPIRVToLLVMDbgTran.cpp
lib/SPIRV/libSPIRV/SPIRV.debug.h
test/DebugInfo/InvalidSourceLanguageSPIRVtoLLVM.spvasm [new file with mode: 0644]

index 152683a507a86608afe40484d7d10a79c02d6399..28b2170ebf65df0472670e159e64d32191a3a638 100644 (file)
@@ -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);
index 3454d7c7554770cbdf3fe209f6e994a8d6b6ad7e..0c17595e4cfcfb713bf9adb2096c27dcf088f9a7 100644 (file)
@@ -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 (file)
index 0000000..82f1f4e
--- /dev/null
@@ -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,