Fix debug info generation for generic/specialized struct types
- [x] Analyze the failing tests reported by @zangold-nv
- [x] Revert the changes to
slang-ir.cppthat were too broad - [x] Implement a more targeted fix in
slang-ir-insert-debug-value-store.cpp - [x] Run all previously failing tests to confirm they pass
- [x] Run debug-related SPIR-V tests to confirm they pass
- [x] Add test case for generic struct debug info
- [x] Run code review and address feedback
Original prompt
This section details on the original issue you should resolve
<issue_title>DebugInfo isn't properly generated for generic variables/structs</issue_title> <issue_description># Issue Description SPIR-V debuginfo is absent for variables of generic types. Debuginfo for the specialized structs is also missing.
Reproducer Code
__generic<T : __BuiltinArithmeticType> struct GenericStruct { T value; }; RWStructuredBuffer<int> outputBuffer; [numthreads(1, 1, 1)] void main(uint3 dispatchThreadID : SV_DispatchThreadID) { GenericStruct<int> gs_int; gs_int.value = 1; GenericStruct<float> gs_float; gs_float.value = 2.0f; outputBuffer[0] = gs_int.value * gs_float.value; }to compile:
slangc.exe shader.comp -target spirv -g3 -O0 -stage compute -o shader.spv -entry mainExpected Behavior
SPIR-V debuginfo instructions (DebugLocalVariable) should exist for gs_int and gs_float, as well as debug struct definitions for GenericStruct
and GenericStruct . Actual Behavior
Neither DebugLocalVariable nor struct definitions are emitted for the specializations of the generic type.
Environment
- Slang Version (release version number or commit hash): commit 98be4beca46f7a50a1fd9979cc151099ad7375eb
- OS: Windows x64
- GPU/Driver version, if the bug is a runtime result error. N/A
- Any related environment variables. N/A</issue_description>
Comments on the Issue (you are @copilot in this section)
- Fixes shader-slang/slang#9162
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.
It looks like this patch causes several tests to fail:
tests/autodiff/auto-differential-type-generic.slang.2 (vk)
tests/compute/dynamic-dispatch-19.slang (dx12)
tests/compute/dynamic-dispatch-19.slang.1 (dx11)
tests/compute/dynamic-dispatch-19.slang.2 (vk)
tests/compute/generic-list.slang (dx11)
tests/compute/generic-struct-with-constraint.slang (dx11)
tests/compute/generic-list.slang.1 (cpu)
tests/compute/generic-struct-with-constraint.slang.1 (cpu)
tests/compute/generic-list.slang.2 syn (wgpu)
tests/compute/generic-struct-with-constraint.slang.2 syn (wgpu)
tests/compute/generic-list.slang.3 syn (dx12)
tests/compute/generic-struct-with-constraint.slang.3 syn (dx12)
@copilot either fix the patch, or update the test cases - but only if there's a good reason that they're out of date.
It looks like this patch causes several tests to fail:
tests/autodiff/auto-differential-type-generic.slang.2 (vk)
...
Fixed in e87d2a5. The original approach modified emitFieldAddress, emitFieldExtract, and emitElementExtract in slang-ir.cpp globally, which broke tests with complex nested generic types.
The new approach is more targeted:
- Enable specialized types to be debuggable in
isDebuggableType() - Skip debug value stores with non-empty access chains for debug variables with specialized types (because
emitElementAddresscannot handle field accesses onIRSpecializetypes)
This generates DebugLocalVariable and DebugTypeComposite for generic struct types while avoiding the assertion failures. All previously failing tests now pass.
@csyonghe This patch fixes an issue where SPIR-V debuginfo for {structures which are specializations of generic types} and {variables which are instances of those structures} aren't being emitted.
I agree it's not ideal to skip specialized types in the lambda on line 221, but that's not any worse than existing behaviour (which assumes that all IRSpecialize insts aren't debuggable; see the change on line 88). The net change is that we're emitting DebugVar for IRSpecialize insts on line 188, and skipping the emitDebugValue (which was skipped before this patch, anyway).
It looks like we'll still have to figure out how to emit AccessChain/DebugValue for specialized debugVars before they work the way we expect them to in a debugger. My guess is some special handling in (or just after?) the specialization pass that calls back into some shared code in slang-ir-insert-debug-value-store.cpp, but I'm not sure at this point.