[llvm] 06aae40 - [HLSL][SPIRV] Restore support for -g to generate NSDI (#190007)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 1 21:00:41 PDT 2026
Author: Diego Novillo
Date: 2026-04-01T21:00:36-07:00
New Revision: 06aae40c6dee03741f96c1b09ccc57f7fb110dd1
URL: https://github.com/llvm/llvm-project/commit/06aae40c6dee03741f96c1b09ccc57f7fb110dd1
DIFF: https://github.com/llvm/llvm-project/commit/06aae40c6dee03741f96c1b09ccc57f7fb110dd1.diff
LOG: [HLSL][SPIRV] Restore support for -g to generate NSDI (#190007)
The original attempt (#187051) produced a regression for
`intel-sycl-gpu` because `SPIRVEmitNonSemanticDI` will now self-activate
whenever `llvm.dbg.cu` is present. This removed the need for the
explicit `--spv-emit-nonsemantic-debug-info` flag.
The pass is now entered unconditionally for all SPIR-V targets, but
`NonSemantic.Shader.DebugInfo.100` requires the
`SPV_KHR_non_semantic_info`. Targets like `spirv64-intel` do not enable
that extension by default. When `checkSatisfiable()` ran on those
targets, it issued a fatal error rather than silently skipping.
Adds an early-out from `emitGlobalDI()`: if
`SPV_KHR_non_semantic_info` is not available for the current target, the
pass returns without emitting anything.
Added:
clang/test/CodeGenHLSL/debug/source-language.hlsl
llvm/test/CodeGen/SPIRV/debug-info/hlsl-debug-info-auto-activation.ll
llvm/test/CodeGen/SPIRV/debug-info/no-nonsemantic-without-extension.ll
Modified:
clang/lib/CodeGen/CGDebugInfo.cpp
llvm/docs/SPIRVUsage.rst
llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
llvm/test/CodeGen/SPIRV/debug-info/debug-compilation-unit.ll
llvm/test/CodeGen/SPIRV/debug-info/debug-type-basic.ll
llvm/test/CodeGen/SPIRV/debug-info/debug-type-pointer.ll
llvm/test/CodeGen/SPIRV/hlsl-resources/SampleErrorsDebug.ll
llvm/test/CodeGen/SPIRV/llc-pipeline.ll
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index dbd400343d9e1..c5a92a8e7ceb0 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -694,7 +694,9 @@ static llvm::dwarf::SourceLanguage GetSourceLanguage(const CodeGenModule &CGM) {
llvm::dwarf::SourceLanguage LangTag;
if (LO.CPlusPlus) {
- if (LO.HIP)
+ if (LO.HLSL)
+ LangTag = llvm::dwarf::DW_LANG_HLSL;
+ else if (LO.HIP)
LangTag = llvm::dwarf::DW_LANG_HIP;
else if (LO.ObjC)
LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
@@ -732,7 +734,9 @@ GetDISourceLanguageName(const CodeGenModule &CGM) {
uint32_t LangVersion = 0;
llvm::dwarf::SourceLanguageName LangTag;
if (LO.CPlusPlus) {
- if (LO.HIP) {
+ if (LO.HLSL) {
+ LangTag = llvm::dwarf::DW_LNAME_HLSL;
+ } else if (LO.HIP) {
LangTag = llvm::dwarf::DW_LNAME_HIP;
} else if (LO.ObjC) {
LangTag = llvm::dwarf::DW_LNAME_ObjC_plus_plus;
diff --git a/clang/test/CodeGenHLSL/debug/source-language.hlsl b/clang/test/CodeGenHLSL/debug/source-language.hlsl
new file mode 100644
index 0000000000000..f1e63d17724ee
--- /dev/null
+++ b/clang/test/CodeGenHLSL/debug/source-language.hlsl
@@ -0,0 +1,34 @@
+// Verify that HLSL shaders are tagged with DW_LANG_HLSL in the debug compile
+// unit. For DWARFv6, verify the sourceLanguageName field uses DW_LNAME_HLSL.
+
+// DXIL target, DWARFv4
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-compute -x hlsl -emit-llvm \
+// RUN: -disable-llvm-passes -hlsl-entry main \
+// RUN: -debug-info-kind=standalone -dwarf-version=4 -o - %s \
+// RUN: | FileCheck %s --check-prefix=CHECK-V4
+
+// SPIR-V target, DWARFv4
+// RUN: %clang_cc1 -triple spirv-unknown-vulkan-compute -x hlsl -emit-llvm \
+// RUN: -disable-llvm-passes -hlsl-entry main \
+// RUN: -debug-info-kind=standalone -dwarf-version=4 -o - %s \
+// RUN: | FileCheck %s --check-prefix=CHECK-V4
+
+// DXIL target, DWARFv6
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-compute -x hlsl -emit-llvm \
+// RUN: -disable-llvm-passes -hlsl-entry main \
+// RUN: -debug-info-kind=standalone -dwarf-version=6 -o - %s \
+// RUN: | FileCheck %s --check-prefix=CHECK-V6
+
+// SPIR-V target, DWARFv6
+// RUN: %clang_cc1 -triple spirv-unknown-vulkan-compute -x hlsl -emit-llvm \
+// RUN: -disable-llvm-passes -hlsl-entry main \
+// RUN: -debug-info-kind=standalone -dwarf-version=6 -o - %s \
+// RUN: | FileCheck %s --check-prefix=CHECK-V6
+
+// CHECK-V4: !DICompileUnit(language: DW_LANG_HLSL,
+// CHECK-V4-NOT: !DICompileUnit(language: DW_LANG_C_plus_plus
+
+// CHECK-V6: !DICompileUnit(sourceLanguageName: DW_LNAME_HLSL,
+// CHECK-V6-NOT: !DICompileUnit(sourceLanguageName: DW_LNAME_C_plus_plus
+
+[numthreads(1, 1, 1)] void main() {}
diff --git a/llvm/docs/SPIRVUsage.rst b/llvm/docs/SPIRVUsage.rst
index 9a4478f57e802..75a477b86da05 100644
--- a/llvm/docs/SPIRVUsage.rst
+++ b/llvm/docs/SPIRVUsage.rst
@@ -33,9 +33,11 @@ Static Compiler Commands
Command: `llc -O1 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_ALTERA_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_ALTERA_arbitrary_precision_integers extension.
-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.
+3. **Compilation with NonSemantic.Shader.DebugInfo support**
+ Command: `llc -g --spirv-ext=+SPV_KHR_non_semantic_info input.ll -o output.spvt`
+ Description: Compiles an LLVM IL file to SPIR-V with NonSemantic.Shader.DebugInfo.100 instructions. The ``-g`` flag causes the backend to emit NSDI instructions when the module contains debug metadata. The required SPV_KHR_non_semantic_info extension must be enabled explicitly.
+
+ Note: ``--spv-emit-nonsemantic-debug-info`` is a deprecated synonym for ``-g`` and will be removed in a future release.
4. **SPIR-V Binary Generation**
Command: `llc -O0 -mtriple=spirv64-unknown-unknown -filetype=obj input.ll -o output.spvt`
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
index 4e4b9fdffa7f0..f705a0c81db0e 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp
@@ -106,6 +106,13 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF) {
const NamedMDNode *DbgCu = M->getNamedMetadata("llvm.dbg.cu");
if (!DbgCu)
return false;
+ // NonSemantic.Shader.DebugInfo.100 requires SPV_KHR_non_semantic_info.
+ // Bail out if the extension is not available for this target. Targets that
+ // do not enable this extension by default should enable it explicitly with
+ // --spirv-ext=+SPV_KHR_non_semantic_info.
+ if (!TM->getSubtargetImpl()->canUseExtension(
+ SPIRV::Extension::SPV_KHR_non_semantic_info))
+ return false;
for (const auto *Op : DbgCu->operands()) {
if (const auto *CompileUnit = dyn_cast<DICompileUnit>(Op)) {
DIFile *File = CompileUnit->getFile();
diff --git a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
index 9af6879a1c42a..6797722579137 100644
--- a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
@@ -265,14 +265,15 @@ bool SPIRVPassConfig::addRegBankSelect() {
static cl::opt<bool> SPVEnableNonSemanticDI(
"spv-emit-nonsemantic-debug-info",
- cl::desc("Emit SPIR-V NonSemantic.Shader.DebugInfo.100 instructions"),
+ cl::desc("Deprecated. Use -g to emit SPIR-V NonSemantic.Shader.DebugInfo "
+ "instructions"),
cl::Optional, cl::init(false));
void SPIRVPassConfig::addPreEmitPass() {
- if (SPVEnableNonSemanticDI ||
- getSPIRVTargetMachine().getTargetTriple().getVendor() == Triple::AMD) {
- addPass(createSPIRVEmitNonSemanticDIPass(&getTM<SPIRVTargetMachine>()));
- }
+ // The SPIRVEmitNonSemanticDI pass self-activates when the module contains
+ // debug info (llvm.dbg.cu). --spv-emit-nonsemantic-debug-info is a
+ // deprecated synonym for -g.
+ addPass(createSPIRVEmitNonSemanticDIPass(&getTM<SPIRVTargetMachine>()));
}
namespace {
diff --git a/llvm/test/CodeGen/SPIRV/debug-info/debug-compilation-unit.ll b/llvm/test/CodeGen/SPIRV/debug-info/debug-compilation-unit.ll
index 54eb0e45dccee..fd2f46590f103 100644
--- a/llvm/test/CodeGen/SPIRV/debug-info/debug-compilation-unit.ll
+++ b/llvm/test/CodeGen/SPIRV/debug-info/debug-compilation-unit.ll
@@ -30,8 +30,8 @@
; CHECK-SPIRV: [[debug_source_cpp:%[0-9]+]] = OpExtInst [[type_void]] [[ext_inst_non_semantic]] DebugSource [[filename_str_cpp]]
; CHECK-SPIRV: OpExtInst [[type_void]] [[ext_inst_non_semantic]] DebugCompilationUnit [[debug_info_version]] [[dwarf_version]] [[debug_source_cpp]] [[source_language_cpp]]
-; CHECK-OPTION-NOT: OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
-; CHECK-OPTION-NOT: OpString "/AAAAAAAAAA/BBBBBBBB/CCCCCCCCC{{[/\\]}}example.c"
+; CHECK-OPTION: OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
+; CHECK-OPTION: OpString "/AAAAAAAAAA/BBBBBBBB/CCCCCCCCC{{[/\\]}}example.c"
define spir_func void @foo() {
entry:
diff --git a/llvm/test/CodeGen/SPIRV/debug-info/debug-type-basic.ll b/llvm/test/CodeGen/SPIRV/debug-info/debug-type-basic.ll
index c678d9ce350a2..04aa85008d47c 100644
--- a/llvm/test/CodeGen/SPIRV/debug-info/debug-type-basic.ll
+++ b/llvm/test/CodeGen/SPIRV/debug-info/debug-type-basic.ll
@@ -82,7 +82,7 @@
; CHECK-SPIRV-DAG: OpExtInst [[type_void]] [[ext_inst_non_semantic]] DebugTypeBasic [[str_float]] [[size_32bit]] [[encoding_float]] [[flag_zero]]
; CHECK-SPIRV-DAG: OpExtInst [[type_void]] [[ext_inst_non_semantic]] DebugTypeBasic [[str_double]] [[size_64bit]] [[encoding_float]] [[flag_zero]]
-; CHECK-OPTION-NOT: DebugTypeBasic
+; CHECK-OPTION: DebugTypeBasic
define spir_func void @test1() !dbg !9 {
entry:
diff --git a/llvm/test/CodeGen/SPIRV/debug-info/debug-type-pointer.ll b/llvm/test/CodeGen/SPIRV/debug-info/debug-type-pointer.ll
index 9cdcd6db6cde8..f2d7440ae7a65 100644
--- a/llvm/test/CodeGen/SPIRV/debug-info/debug-type-pointer.ll
+++ b/llvm/test/CodeGen/SPIRV/debug-info/debug-type-pointer.ll
@@ -81,7 +81,7 @@
; CHECK-SPIRV-DAG: [[debug_info_none:%[0-9]+]] = OpExtInst {{%[0-9]+ %[0-9]+}} DebugInfoNone
; CHECK-SPIRV-DAG: OpExtInst {{%[0-9]+ %[0-9]+}} DebugTypePointer [[debug_info_none]] [[i32_5]] [[i32_0]]
-; CHECK-OPTION-NOT: DebugTypePointer
+; CHECK-OPTION: DebugTypePointer
@gi0 = dso_local addrspace(1) global ptr addrspace(4) null, align 4, !dbg !0
@gv0 = dso_local addrspace(1) global ptr addrspace(4) null, align 4, !dbg !5
diff --git a/llvm/test/CodeGen/SPIRV/debug-info/hlsl-debug-info-auto-activation.ll b/llvm/test/CodeGen/SPIRV/debug-info/hlsl-debug-info-auto-activation.ll
new file mode 100644
index 0000000000000..1f123dd4b317a
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/debug-info/hlsl-debug-info-auto-activation.ll
@@ -0,0 +1,32 @@
+; Verify that the NSDI pass activates automatically when the module contains
+; debug info (llvm.dbg.cu) without requiring --spv-emit-nonsemantic-debug-info.
+; The language constant in DebugCompilationUnit must be 5 (HLSL).
+
+; RUN: llc --verify-machineinstrs --spirv-ext=+SPV_KHR_non_semantic_info \
+; RUN: -O0 -mtriple=spirv64-unknown-unknown %s -o - \
+; RUN: | FileCheck %s
+; RUN: %if spirv-tools %{ llc --verify-machineinstrs \
+; RUN: --spirv-ext=+SPV_KHR_non_semantic_info \
+; RUN: -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj \
+; RUN: | spirv-val %}
+
+; CHECK: OpExtension "SPV_KHR_non_semantic_info"
+; CHECK: [[ext_inst:%[0-9]+]] = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
+; CHECK-DAG: [[type_void:%[0-9]+]] = OpTypeVoid
+; CHECK-DAG: [[type_i32:%[0-9]+]] = OpTypeInt 32 0
+; CHECK-DAG: [[lang_hlsl:%[0-9]+]] = OpConstant [[type_i32]] 5
+; CHECK: OpExtInst [[type_void]] [[ext_inst]] DebugCompilationUnit
+; CHECK-SAME: [[lang_hlsl]]
+
+define spir_func void @main() {
+entry:
+ ret void
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_HLSL, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "shader.hlsl", directory: "/src")
+!2 = !{i32 7, !"Dwarf Version", i32 5}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
diff --git a/llvm/test/CodeGen/SPIRV/debug-info/no-nonsemantic-without-extension.ll b/llvm/test/CodeGen/SPIRV/debug-info/no-nonsemantic-without-extension.ll
new file mode 100644
index 0000000000000..376a13742dc70
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/debug-info/no-nonsemantic-without-extension.ll
@@ -0,0 +1,22 @@
+; Verify that the NSDI pass does not crash when compiling with debug info for
+; a target that does not have SPV_KHR_non_semantic_info enabled (e.g., OpenCL
+; targets like spirv64-intel). The pass should silently skip emission.
+
+; RUN: llc --verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s -o - \
+; RUN: | FileCheck %s
+
+; CHECK-NOT: OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
+; CHECK-NOT: OpExtension "SPV_KHR_non_semantic_info"
+
+define spir_func void @main() {
+entry:
+ ret void
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_OpenCL, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "test.cl", directory: "/src")
+!2 = !{i32 7, !"Dwarf Version", i32 5}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-resources/SampleErrorsDebug.ll b/llvm/test/CodeGen/SPIRV/hlsl-resources/SampleErrorsDebug.ll
index 26f7194104e18..b443c70e7b17e 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-resources/SampleErrorsDebug.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-resources/SampleErrorsDebug.ll
@@ -1,4 +1,4 @@
-; RUN: not llc -O0 -mtriple=spirv-vulkan-compute %s -o /dev/null 2>&1 | FileCheck %s
+; RUN: not llc -O0 -mtriple=spirv-vulkan-compute --spirv-ext=+SPV_KHR_non_semantic_info %s -o /dev/null 2>&1 | FileCheck %s
; CHECK: error: SampleErrorsDebug.ll:24:10: Non-constant offsets are not supported in sample instructions.
diff --git a/llvm/test/CodeGen/SPIRV/llc-pipeline.ll b/llvm/test/CodeGen/SPIRV/llc-pipeline.ll
index c907ee02f03eb..2877fb871e682 100644
--- a/llvm/test/CodeGen/SPIRV/llc-pipeline.ll
+++ b/llvm/test/CodeGen/SPIRV/llc-pipeline.ll
@@ -81,6 +81,7 @@
; SPIRV-O0-NEXT: Analyze Machine Code For Garbage Collection
; SPIRV-O0-NEXT: Insert fentry calls
; SPIRV-O0-NEXT: Insert XRay ops
+; SPIRV-O0-NEXT: SPIRV NonSemantic.Shader.DebugInfo.100 emitter
; SPIRV-O0-NEXT: Machine Sanitizer Binary Metadata
; SPIRV-O0-NEXT: Lazy Machine Block Frequency Analysis
; SPIRV-O0-NEXT: Machine Optimization Remark Emitter
@@ -225,6 +226,7 @@
; SPIRV-Opt-NEXT: Analyze Machine Code For Garbage Collection
; SPIRV-Opt-NEXT: Insert fentry calls
; SPIRV-Opt-NEXT: Insert XRay ops
+; SPIRV-Opt-NEXT: SPIRV NonSemantic.Shader.DebugInfo.100 emitter
; SPIRV-Opt-NEXT: Machine Sanitizer Binary Metadata
; SPIRV-Opt-NEXT: Lazy Machine Block Frequency Analysis
; SPIRV-Opt-NEXT: Machine Optimization Remark Emitter
More information about the llvm-commits
mailing list