diff --git a/llvm/docs/SPIRVUsage.rst b/llvm/docs/SPIRVUsage.rst index 70865b95cb393..0f0b21fb23770 100644 --- a/llvm/docs/SPIRVUsage.rst +++ b/llvm/docs/SPIRVUsage.rst @@ -33,7 +33,11 @@ Static Compiler Commands Command: `llc -O1 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_arbitrary_precision_integers input.ll -o output.spvt` Description: Compiles an LLVM IL file to SPIR-V with (`-O1`) optimizations, targeting a 64-bit architecture. It enables the SPV_INTEL_arbitrary_precision_integers extension. -3. **SPIR-V Binary Generation** +3. **Compilation with experimental NonSemantic.Shader.DebugInfo.100 support** + Command: `llc --spv-emit-nonsemantic-debug-info --spirv-ext=+SPV_KHR_non_semantic_info input.ll -o output.spvt` + Description: Compiles an LLVM IL file to SPIR-V with additional NonSemantic.Shader.DebugInfo.100 instructions. It enables the required SPV_KHR_non_semantic_info extension. + +4. **SPIR-V Binary Generation** Command: `llc -O0 -mtriple=spirv64-unknown-unknown -filetype=obj input.ll -o output.spvt` Description: Generates a SPIR-V object file (`output.spvt`) from an LLVM module, targeting a 64-bit SPIR-V architecture with no optimizations. @@ -181,6 +185,8 @@ list of supported SPIR-V extensions, sorted alphabetically by their extension na - Adds a new instruction that enables rotating values across invocations within a subgroup. * - ``SPV_KHR_uniform_group_instructions`` - Allows support for additional group operations within uniform control flow. + * - ``SPV_KHR_non_semantic_info`` + - Adds the ability to declare extended instruction sets that have no semantic impact and can be safely removed from a module. To enable multiple extensions, list them separated by spaces. For example, to enable support for atomic operations on floating-point numbers and arbitrary precision integers, use: diff --git a/llvm/lib/Target/SPIRV/CMakeLists.txt b/llvm/lib/Target/SPIRV/CMakeLists.txt index 14647e92f5d08..5f8aea5fc8d84 100644 --- a/llvm/lib/Target/SPIRV/CMakeLists.txt +++ b/llvm/lib/Target/SPIRV/CMakeLists.txt @@ -40,6 +40,7 @@ add_llvm_target(SPIRVCodeGen SPIRVSubtarget.cpp SPIRVTargetMachine.cpp SPIRVUtils.cpp + SPIRVEmitNonSemanticDI.cpp LINK_COMPONENTS Analysis diff --git a/llvm/lib/Target/SPIRV/SPIRV.h b/llvm/lib/Target/SPIRV/SPIRV.h index e597a1dc8dc06..6c35a467f53be 100644 --- a/llvm/lib/Target/SPIRV/SPIRV.h +++ b/llvm/lib/Target/SPIRV/SPIRV.h @@ -26,6 +26,7 @@ FunctionPass *createSPIRVRegularizerPass(); FunctionPass *createSPIRVPreLegalizerPass(); FunctionPass *createSPIRVPostLegalizerPass(); ModulePass *createSPIRVEmitIntrinsicsPass(SPIRVTargetMachine *TM); +MachineFunctionPass *createSPIRVEmitNonSemanticDIPass(SPIRVTargetMachine *TM); InstructionSelector * createSPIRVInstructionSelector(const SPIRVTargetMachine &TM, const SPIRVSubtarget &Subtarget, @@ -36,6 +37,7 @@ void initializeSPIRVConvergenceRegionAnalysisWrapperPassPass(PassRegistry &); void initializeSPIRVPreLegalizerPass(PassRegistry &); void initializeSPIRVPostLegalizerPass(PassRegistry &); void initializeSPIRVEmitIntrinsicsPass(PassRegistry &); +void initializeSPIRVEmitNonSemanticDIPass(PassRegistry &); } // namespace llvm #endif // LLVM_LIB_TARGET_SPIRV_SPIRV_H diff --git a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp index 7fe8e11aaa420..55b4162780209 100644 --- a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp @@ -274,6 +274,8 @@ void SPIRVAsmPrinter::outputDebugSourceAndStrings(const Module &M) { addStringImm(Str.first(), Inst); outputMCInst(Inst); } + // Output OpString. + outputModuleSection(SPIRV::MB_DebugStrings); // Output OpSource. MCInst Inst; Inst.setOpcode(SPIRV::OpSource); @@ -589,9 +591,11 @@ void SPIRVAsmPrinter::outputModuleSections() { // the first section to allow use of: OpLine and OpNoLine debug information; // non-semantic instructions with OpExtInst. outputModuleSection(SPIRV::MB_TypeConstVars); - // 10. All function declarations (functions without a body). + // 10. All global NonSemantic.Shader.DebugInfo.100 instructions. + outputModuleSection(SPIRV::MB_NonSemanticGlobalDI); + // 11. All function declarations (functions without a body). outputExtFuncDecls(); - // 11. All function definitions (functions with a body). + // 12. All function definitions (functions with a body). // This is done in regular function output. } diff --git a/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp b/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp index c7c244cfa8977..90a9ab1d33ced 100644 --- a/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp @@ -68,7 +68,8 @@ static const std::map SPIRV::Extension::Extension::SPV_KHR_shader_clock}, {"SPV_KHR_cooperative_matrix", SPIRV::Extension::Extension::SPV_KHR_cooperative_matrix}, -}; + {"SPV_KHR_non_semantic_info", + SPIRV::Extension::Extension::SPV_KHR_non_semantic_info}}; bool SPIRVExtensionsParser::parse(cl::Option &O, llvm::StringRef ArgName, llvm::StringRef ArgValue, diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp new file mode 100644 index 0000000000000..cc506356e3904 --- /dev/null +++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp @@ -0,0 +1,188 @@ +#include "MCTargetDesc/SPIRVBaseInfo.h" +#include "MCTargetDesc/SPIRVMCTargetDesc.h" +#include "SPIRVGlobalRegistry.h" +#include "SPIRVRegisterInfo.h" +#include "SPIRVTargetMachine.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/MachineOperand.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/Metadata.h" +#include "llvm/PassRegistry.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/Path.h" + +#define DEBUG_TYPE "spirv-nonsemantic-debug-info" + +namespace llvm { +struct SPIRVEmitNonSemanticDI : public MachineFunctionPass { + static char ID; + SPIRVTargetMachine *TM; + SPIRVEmitNonSemanticDI(SPIRVTargetMachine *TM); + SPIRVEmitNonSemanticDI(); + + bool runOnMachineFunction(MachineFunction &MF) override; + +private: + bool IsGlobalDIEmitted = false; + bool emitGlobalDI(MachineFunction &MF); +}; + +void initializeSPIRVEmitNonSemanticDIPass(PassRegistry &); + +FunctionPass *createSPIRVEmitNonSemanticDIPass(SPIRVTargetMachine *TM) { + return new SPIRVEmitNonSemanticDI(TM); +} +} // namespace llvm + +using namespace llvm; + +INITIALIZE_PASS(SPIRVEmitNonSemanticDI, DEBUG_TYPE, + "SPIRV NonSemantic.Shader.DebugInfo.100 emitter", false, false) + +char SPIRVEmitNonSemanticDI::ID = 0; + +SPIRVEmitNonSemanticDI::SPIRVEmitNonSemanticDI(SPIRVTargetMachine *TM) + : MachineFunctionPass(ID), TM(TM) { + initializeSPIRVEmitNonSemanticDIPass(*PassRegistry::getPassRegistry()); +} + +SPIRVEmitNonSemanticDI::SPIRVEmitNonSemanticDI() : MachineFunctionPass(ID) { + initializeSPIRVEmitNonSemanticDIPass(*PassRegistry::getPassRegistry()); +} + +bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) { + // If this MachineFunction doesn't have any BB repeat procedure + // for the next + if (MF.begin() == MF.end()) { + IsGlobalDIEmitted = false; + return false; + } + + // Required variables to get from metadata search + LLVMContext *Context; + SmallString<128> FilePath; + unsigned SourceLanguage = 0; + int64_t DwarfVersion = 0; + int64_t DebugInfoVersion = 0; + + // Searching through the Module metadata to find nescessary + // information like DwarfVersion or SourceLanguage + { + const MachineModuleInfo &MMI = + getAnalysis().getMMI(); + const Module *M = MMI.getModule(); + Context = &M->getContext(); + const NamedMDNode *DbgCu = M->getNamedMetadata("llvm.dbg.cu"); + if (!DbgCu) + return false; + for (const auto *Op : DbgCu->operands()) { + if (const auto *CompileUnit = dyn_cast(Op)) { + DIFile *File = CompileUnit->getFile(); + sys::path::append(FilePath, File->getDirectory(), File->getFilename()); + SourceLanguage = CompileUnit->getSourceLanguage(); + break; + } + } + const NamedMDNode *ModuleFlags = M->getNamedMetadata("llvm.module.flags"); + for (const auto *Op : ModuleFlags->operands()) { + const MDOperand &MaybeStrOp = Op->getOperand(1); + if (MaybeStrOp.equalsStr("Dwarf Version")) + DwarfVersion = + cast( + cast(Op->getOperand(2))->getValue()) + ->getSExtValue(); + else if (MaybeStrOp.equalsStr("Debug Info Version")) + DebugInfoVersion = + cast( + cast(Op->getOperand(2))->getValue()) + ->getSExtValue(); + } + } + // NonSemantic.Shader.DebugInfo.100 global DI instruction emitting + { + // Required LLVM variables for emitting logic + const SPIRVInstrInfo *TII = TM->getSubtargetImpl()->getInstrInfo(); + const SPIRVRegisterInfo *TRI = TM->getSubtargetImpl()->getRegisterInfo(); + const RegisterBankInfo *RBI = TM->getSubtargetImpl()->getRegBankInfo(); + SPIRVGlobalRegistry *GR = TM->getSubtargetImpl()->getSPIRVGlobalRegistry(); + MachineRegisterInfo &MRI = MF.getRegInfo(); + MachineBasicBlock &MBB = *MF.begin(); + + // To correct placement of a OpLabel instruction during SPIRVAsmPrinter + // emission all new instructions needs to be placed after OpFunction + // and before first terminator + MachineIRBuilder MIRBuilder(MBB, MBB.getFirstTerminator()); + + // Emit OpString with FilePath which is required by DebugSource + const Register StrReg = MRI.createVirtualRegister(&SPIRV::IDRegClass); + MRI.setType(StrReg, LLT::scalar(32)); + MachineInstrBuilder MIB = MIRBuilder.buildInstr(SPIRV::OpString); + MIB.addDef(StrReg); + addStringImm(FilePath, MIB); + + const SPIRVType *VoidTy = + GR->getOrCreateSPIRVType(Type::getVoidTy(*Context), MIRBuilder); + + // Emit DebugSource which is required by DebugCompilationUnit + const Register DebugSourceResIdReg = + MRI.createVirtualRegister(&SPIRV::IDRegClass); + MRI.setType(DebugSourceResIdReg, LLT::scalar(32)); + MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst) + .addDef(DebugSourceResIdReg) + .addUse(GR->getSPIRVTypeID(VoidTy)) + .addImm(static_cast( + SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100)) + .addImm(SPIRV::NonSemanticExtInst::DebugSource) + .addUse(StrReg); + MIB.constrainAllUses(*TII, *TRI, *RBI); + GR->assignSPIRVTypeToVReg(VoidTy, DebugSourceResIdReg, MF); + + const SPIRVType *I32Ty = + GR->getOrCreateSPIRVType(Type::getInt32Ty(*Context), MIRBuilder); + + // Convert DwarfVersion, DebugInfo and SourceLanguage integers to OpConstant + // instructions required by DebugCompilationUnit + const Register DwarfVersionReg = + GR->buildConstantInt(DwarfVersion, MIRBuilder, I32Ty, false); + const Register DebugInfoVersionReg = + GR->buildConstantInt(DebugInfoVersion, MIRBuilder, I32Ty, false); + const Register SourceLanguageReg = + GR->buildConstantInt(SourceLanguage, MIRBuilder, I32Ty, false); + + // Emit DebugCompilationUnit + const Register DebugCompUnitResIdReg = + MRI.createVirtualRegister(&SPIRV::IDRegClass); + MRI.setType(DebugCompUnitResIdReg, LLT::scalar(32)); + MIB = MIRBuilder.buildInstr(SPIRV::OpExtInst) + .addDef(DebugCompUnitResIdReg) + .addUse(GR->getSPIRVTypeID(VoidTy)) + .addImm(static_cast( + SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100)) + .addImm(SPIRV::NonSemanticExtInst::DebugCompilationUnit) + .addUse(DebugInfoVersionReg) + .addUse(DwarfVersionReg) + .addUse(DebugSourceResIdReg) + .addUse(SourceLanguageReg); + MIB.constrainAllUses(*TII, *TRI, *RBI); + GR->assignSPIRVTypeToVReg(VoidTy, DebugCompUnitResIdReg, MF); + } + return true; +} + +bool SPIRVEmitNonSemanticDI::runOnMachineFunction(MachineFunction &MF) { + bool Res = false; + // emitGlobalDI needs to be executed only once to avoid + // emitting duplicates + if (!IsGlobalDIEmitted) { + IsGlobalDIEmitted = true; + Res = emitGlobalDI(MF); + } + return Res; +} diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp index ac0aa682ea4be..a2fcfc636e368 100644 --- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp @@ -21,7 +21,6 @@ #include "SPIRVSubtarget.h" #include "SPIRVTargetMachine.h" #include "SPIRVUtils.h" -#include "TargetInfo/SPIRVTargetInfo.h" #include "llvm/ADT/STLExtras.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/TargetPassConfig.h" @@ -427,7 +426,19 @@ void SPIRVModuleAnalysis::processOtherInstrs(const Module &M) { if (MAI.getSkipEmission(&MI)) continue; const unsigned OpCode = MI.getOpcode(); - if (OpCode == SPIRV::OpName || OpCode == SPIRV::OpMemberName) { + if (OpCode == SPIRV::OpString) { + collectOtherInstr(MI, MAI, SPIRV::MB_DebugStrings, IS); + } else if (OpCode == SPIRV::OpExtInst) { + MachineOperand Ins = MI.getOperand(3); + namespace NS = SPIRV::NonSemanticExtInst; + static constexpr int64_t GlobalNonSemanticDITy[] = { + NS::DebugSource, NS::DebugCompilationUnit}; + bool IsGlobalDI = false; + for (unsigned Idx = 0; Idx < std::size(GlobalNonSemanticDITy); ++Idx) + IsGlobalDI |= Ins.getImm() == GlobalNonSemanticDITy[Idx]; + if (IsGlobalDI) + collectOtherInstr(MI, MAI, SPIRV::MB_NonSemanticGlobalDI, IS); + } else if (OpCode == SPIRV::OpName || OpCode == SPIRV::OpMemberName) { collectOtherInstr(MI, MAI, SPIRV::MB_DebugNames, IS); } else if (OpCode == SPIRV::OpEntryPoint) { collectOtherInstr(MI, MAI, SPIRV::MB_EntryPoints, IS); @@ -899,6 +910,14 @@ void addInstrRequirements(const MachineInstr &MI, Reqs.addCapability(SPIRV::Capability::Float16Buffer); break; } + case SPIRV::OpExtInst: { + if (MI.getOperand(2).getImm() == + static_cast( + SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100)) { + Reqs.addExtension(SPIRV::Extension::SPV_KHR_non_semantic_info); + } + break; + } case SPIRV::OpBitReverse: case SPIRV::OpBitFieldInsert: case SPIRV::OpBitFieldSExtract: diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h index 79226d6d93efb..024728c347e8a 100644 --- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h +++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h @@ -20,7 +20,6 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringMap.h" namespace llvm { class SPIRVSubtarget; @@ -34,9 +33,11 @@ enum ModuleSectionType { MB_EntryPoints, // All OpEntryPoint instructions (if any). // MB_ExecutionModes, MB_DebugSourceAndStrings, MB_DebugNames, // All OpName and OpMemberName intrs. + MB_DebugStrings, // All OpString intrs. MB_DebugModuleProcessed, // All OpModuleProcessed instructions. MB_Annotations, // OpDecorate, OpMemberDecorate etc. MB_TypeConstVars, // OpTypeXXX, OpConstantXXX, and global OpVariables. + MB_NonSemanticGlobalDI, // OpExtInst with e.g. DebugSource, DebugTypeBasic. MB_ExtFuncDecls, // OpFunction etc. to declare for external funcs. NUM_MODULE_SECTIONS // Total number of sections requiring basic blocks. }; diff --git a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp index 52fc6f33b4ef1..48a2ce89bad39 100644 --- a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp @@ -115,6 +115,7 @@ class SPIRVPassConfig : public TargetPassConfig { void addOptimizedRegAlloc() override {} void addPostRegAlloc() override; + void addPreEmitPass() override; private: const SPIRVTargetMachine &TM; @@ -208,6 +209,17 @@ bool SPIRVPassConfig::addRegBankSelect() { return false; } +static cl::opt SPVEnableNonSemanticDI( + "spv-emit-nonsemantic-debug-info", + cl::desc("Emit SPIR-V NonSemantic.Shader.DebugInfo.100 instructions"), + cl::Optional, cl::init(false)); + +void SPIRVPassConfig::addPreEmitPass() { + if (SPVEnableNonSemanticDI) { + addPass(createSPIRVEmitNonSemanticDIPass(&getTM())); + } +} + namespace { // A custom subclass of InstructionSelect, which is mostly the same except from // not requiring RegBankSelect to occur previously. diff --git a/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll b/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll new file mode 100644 index 0000000000000..336b7db324c3d --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/debug-info/basic-global-di.ll @@ -0,0 +1,46 @@ +; RUN: llc --verify-machineinstrs --spv-emit-nonsemantic-debug-info --spirv-ext=+SPV_KHR_non_semantic_info --print-after=spirv-nonsemantic-debug-info -O0 -mtriple=spirv64-unknown-unknown %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-MIR +; RUN: llc --verify-machineinstrs --spv-emit-nonsemantic-debug-info --spirv-ext=+SPV_KHR_non_semantic_info -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV +; RUN: llc --verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_KHR_non_semantic_info %s -o - | FileCheck %s --check-prefix=CHECK-OPTION +; RUN: %if spirv-tools %{ llc --spirv-ext=+SPV_KHR_non_semantic_info -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %} + +; CHECK-MIR-DAG: [[type_void:%[0-9]+\:type]] = OpTypeVoid +; CHECK-MIR-DAG: [[type_i64:%[0-9]+\:type\(s64\)]] = OpTypeInt 32, 0 +; CHECK-MIR-DAG: [[dwarf_version:%[0-9]+\:iid\(s32\)]] = OpConstantI [[type_i64]], 5 +; CHECK-MIR-DAG: [[source_language:%[0-9]+\:iid\(s32\)]] = OpConstantI [[type_i64]], 3 +; CHECK-MIR-DAG: [[debug_info_version:%[0-9]+\:iid\(s32\)]] = OpConstantI [[type_i64]], 21 +; CHECK-MIR-DAG: [[filename_str:%[0-9]+\:id\(s32\)]] = OpString 1094795567, 1094795585, 792805697, 1111638594, 1111638594, 1128481583, 1128481603, 1697596227, 1886216568, 1663985004, 0 +; CHECK-MIR-DAG: [[debug_source:%[0-9]+\:id\(s32\)]] = OpExtInst [[type_void]], 3, 35, [[filename_str]] +; CHECK-MIR-DAG: [[debug_compilation_unit:%[0-9]+\:id\(s32\)]] = OpExtInst [[type_void]], 3, 1, [[source_language]], [[dwarf_version]], [[debug_source]], [[debug_info_version]] + +; CHECK-SPIRV: [[ext_inst_non_semantic:%[0-9]+]] = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" +; CHECK-SPIRV: [[filename_str:%[0-9]+]] = OpString "/AAAAAAAAAA/BBBBBBBB/CCCCCCCCC/example.c" +; CHECK-SPIRV-DAG: [[type_void:%[0-9]+]] = OpTypeVoid +; CHECK-SPIRV-DAG: [[type_i32:%[0-9]+]] = OpTypeInt 32 0 +; CHECK-SPIRV-DAG: [[dwarf_version:%[0-9]+]] = OpConstant [[type_i32]] 5 +; CHECK-SPIRV-DAG: [[debug_info_version:%[0-9]+]] = OpConstant [[type_i32]] 21 +; CHECK-SPIRV-DAG: [[source_language:%[0-9]+]] = OpConstant [[type_i32]] 3 +; CHECK-SPIRV: [[debug_source:%[0-9]+]] = OpExtInst [[type_void]] [[ext_inst_non_semantic]] DebugSource [[filename_str]] +; CHECK-SPIRV: [[debug_compiation_unit:%[0-9]+]] = OpExtInst [[type_void]] [[ext_inst_non_semantic]] DebugCompilationUnit [[source_language]] [[dwarf_version]] [[debug_source]] [[debug_info_version]] + +; CHECK-OPTION-NOT: OpExtInstImport "NonSemantic.Shader.DebugInfo.100" +; CHECK-OPTION-NOT: OpString "/AAAAAAAAAA/BBBBBBBB/CCCCCCCCC/example.c" + +define spir_func void @foo() { +entry: + ret void +} + +define spir_func void @bar() { +entry: + ret void +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3, !4, !5} + +!0 = distinct !DICompileUnit(language: DW_LANG_OpenCL, file: !1, producer: "clang version XX.X.XXXX (FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "example.c", directory: "/AAAAAAAAAA/BBBBBBBB/CCCCCCCCC", checksumkind: CSK_MD5, checksum: "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF") +!2 = !{i32 7, !"Dwarf Version", i32 5} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !{i32 1, !"wchar_size", i32 4} +!5 = !{i32 7, !"frame-pointer", i32 2}