Skip to content

Translation of NonSemantic.Shader.DebugInfo DebugLocalVariable ArgNumber does not correctly wrap/unwrap in OpConstant #3768

Description

@AdamBrouwersHarries

Both directions of translation (i.e. LLVM -> SPIRV and SPIRV -> LLVM) of the NonSemantic.Shader.DebugInfo DebugLocalVariable op incorrectly translate the (optional) ArgNumber argument. As per the spec, the ArgNumber operand is the id of a 32-bit integer OpConstant.

However, neither "side" of the translator respect this. From the LLVM -> SPIRV side, the ArgNumber is written as a literal:

  if (SPIRVWord ArgNumber = Var->getArg())
    Ops.push_back(ArgNumber);

while on the SPIRV -> LLVM side, the ArgNumber (which should be an id) is read as a literal:

  if (Ops.size() > ArgNumberIdx)
    return getDIBuilder(DebugInst).createParameterVariable(
        Scope, Name, Ops[ArgNumberIdx], File, LineNo, Ty, true, Flags);

This "works" to a certain extent, as the same bug exists on both sides of the translator (even if the debug information ends up being incorrect). However, issues occur when working with very large kernels which contain more than UINT64_MAX ids. This will overflow LLVM's internal16-bit integer that stores the arg number, or cause an assertion in debug builds.


Attached is a test for the SPIRV -> LLVM pipeline: big_kernel.spvasm.txt. The test consists of more than 65535 IDs, followed by a DebugLocalVariable call that uses an ID that is beyond that range. This triggers the assertion in LLVM. Full disclosure, it was created with the assistance of AI (specifically Claude Sonnet 4.6).

Writing a test for the LLVM -> SPIRV case is more difficult, as LLVM inherently cannot produce a value of greater than 65535 from its internal debug information. I have however observed this behaviour in the wild, in SPIRV generated by SYCL kernels, so it is somehow possible. If necessary, I can keep working on this until I have a test.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions