Pewarta Proxy

📋 Server Request & Proxy Logs

Loading active proxy settings...
Developed by Khairul Adha (adhexa.id)
Mengambil log server...

⚙️ Pengaturan Proxy Target

Skip to content

[SPIR-V] We cannot debug our shaders because -fspv-debug=vulkan asserts “isa<> used on a null pointer” on void template arguments and vk::SpirvType variables #9082

Open

Description

@Erfan-Ahmadi

Description

Compiling either of the two shaders below with -fspv-debug=vulkan-with-source (or plain -fspv-debug=vulkan) makes dxc exit without producing any output or diagnostic. Release builds terminate with exit code 0xE0000001 (STATUS_LLVM_ASSERT) and print nothing. -Od makes no difference. Without the -fspv-debug option both shaders compile and validate fine.

Steps to Reproduce

Compiler arguments for both files:

-T cs_6_8 -E main -spirv -fspv-target-env=vulkan1.3 -HV 202x -fspv-debug=vulkan-with-source

Repro A: struct template with a void type argument

https://godbolt.org/z/WEMWje6rP

template<typename T, typename Unused = void>
struct Plus
{
    static const T identity = T(0);
    T operator()(const in T a, const in T b) { return a + b; }
};
[[vk::binding(0,0)]] RWStructuredBuffer<uint> buff;
[numthreads(64,1,1)]
void main(uint3 ID : SV_DispatchThreadID) { Plus<uint> op; buff[ID.x] = op(buff[ID.x], Plus<uint>::identity); }

Repro B: vk::SpirvType as a struct member

https://godbolt.org/z/E8jGnxKGK

using bda_ptr_t = vk::SpirvType</*OpTypePointer*/32, 8, 8, vk::Literal<vk::integral_constant<uint, /*PhysicalStorageBuffer*/5349> >, uint>;

[[vk::ext_capability(/*PhysicalStorageBufferAddresses*/5347)]]
[[vk::ext_instruction(/*OpBitcast*/124)]]
bda_ptr_t toPtr(uint64_t addr);

[[vk::ext_instruction(/*OpLoad*/61)]]
uint loadPtr(bda_ptr_t p, [[vk::ext_literal]] uint aligned, [[vk::ext_literal]] uint alignment);

struct Ref { bda_ptr_t ptr; uint load() { return loadPtr(ptr, 2, 4); } };

struct PC { uint64_t addr; };
[[vk::push_constant]] PC pc;
[[vk::binding(0,0)]] RWStructuredBuffer<uint> buff;

[numthreads(64,1,1)]
void main(uint3 ID : SV_DispatchThreadID)
{
    Ref r; r.ptr = toPtr(pc.addr + ID.x * 4);
    buff[ID.x] = r.load();
}

The same bda_ptr_t as a local variable or as a parameter of a non-intrinsic function crashes too.

Actual Behavior

dxc exits with code 0xE0000001 and no output. Running it under a debugger shows this assertion, which is otherwise only sent to OutputDebugString:

Error: assert(Val && "isa<> used on a null pointer")
File: include/llvm/Support/Casting.h(96)
Func: llvm::isa_impl_cl<clang::spirv::SpirvDebugType, const clang::spirv::SpirvDebugType*>::doit

Expected Behavior

Valid SPIR-V with debug info. Both patterns are common and used a lot in Nabla: the void default argument is the usual SFINAE idiom, and vk::SpirvType members are how buffer-device-address pointers get wrapped in user code.

Environment

  • DXC version godbolt trunk

Possible cause

I have not debugged this properly, but from reading tools/clang/lib/SPIRV/DebugTypeVisitor.cpp it looks like DebugTypeVisitor::lowerToDebugType has no case for SpirvType::TK_Void or SpirvType::TK_SpirvIntrinsicType, so it returns nullptr (after queueing a "Fail to lower SpirvType" diagnostic that never gets printed). The callers seem to use that result unchecked: the template-parameter path in lowerDebugTypeTemplate, the member path in lowerToDebugTypeComposite, and the function-type case. If that is right, lowering those kinds to a DebugTypeBasic with the Unspecified encoding (or DebugInfoNone, which NonSemantic.Shader.DebugInfo.100 allows wherever a type is expected) and skipping members or template parameters

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugBug, regression, crashneeds-triageAwaiting triagespirvWork related to SPIR-V

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions