microsoft / microsoft/DirectXShaderCompiler

[Debug info] Base sub-object of a derived variable is described with an empty `!DIExpression()`

Open
#8,751 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug needs-triage
Dominant language
C++
Stars
3.7k
Forks
900
Avg merge
2d 11h
Merged PRs (30d)
44

Description

Version: dxcompiler.dll 1.9(5402-0d3ee6b5)(1.9.0.5402) - 1.9.0.5402 (0d3ee6b55-dirty)
Repro files: inheritance.zip

dxc -T cs_6_0 -Zi -Qembed_debug -Od -Fc inheritance.ll inheritance.hlsl
class Base
{
    int baseValue;
    void SetBase(int v)      { baseValue = v; }
};

class Derived : Base
{
    int derivedValue;
    void SetDerived(int v)   { derivedValue = v; }
    int  GetTotal()          { return baseValue + derivedValue; }
};

[numthreads(1, 1, 1)]
void main()
{
    Derived obj;                 // line 38
    obj.SetBase(input[0]);
    obj.SetDerived(input[1]);
    output[0] = obj.GetTotal();
}

The type metadata is correct. Derived is 64 bits, Base at offset 0 and
derivedValue at offset 32:

!8  = !DICompositeType(tag: DW_TAG_class_type, name: "Base",    file: !1, line: 10, size: 32, align: 32, elements: !9)
!17 = !DICompositeType(tag: DW_TAG_class_type, name: "Derived", file: !1, line: 20, size: 64, align: 32, elements: !18)
!19 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !17, baseType: !8, flags: DIFlagPublic)
!20 = !DIDerivedType(tag: DW_TAG_member, name: "derivedValue", scope: !17, ..., size: 32, align: 32, offset: 32, flags: DIFlagPublic)

!69 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "obj", scope: !4, file: !1, line: 38, type: !17)   ; Derived

Actual

; obj.baseValue: the base sub-object
call void @llvm.dbg.value(metadata i32 %2, i64 0, metadata !69, metadata !62)   ; var:"obj" !DIExpression()

; obj.derivedValue
call void @llvm.dbg.value(metadata i32 %7, i64 0, metadata !69, metadata !78)   ; var:"obj" !DIExpression(DW_OP_bit_piece, 32, 32)

The write to the base part uses an empty !DIExpression(), which claims a
32-bit value is the whole 64-bit variable. The derived part correctly uses
bit_piece 32, 32.

The same shape appears for this in GetTotal, whose DILocalVariable also has
type Derived:

call void @llvm.dbg.value(metadata i32 %2, i64 0, metadata !66, metadata !62)   ; var:"this" !DIExpression()
call void @llvm.dbg.value(metadata i32 %7, i64 0, metadata !66, metadata !78)   ; var:"this" !DIExpression(DW_OP_bit_piece, 32, 32)

Separately, SetBase gets no dbg.value for its this at all. The only
this entries in the module are for SetDerived and GetTotal.

Expected

; Correct DIExpression
call void @llvm.dbg.value(metadata i32 %2, i64 0, metadata !69, metadata !<expr>)   ; var:"obj" !DIExpression(DW_OP_bit_piece, 0, 32)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the supplied inheritance.hlsl and run the documented dxc command to generate inheritance.ll. Inspect the debug-info emission for the Derived base sub-object and for this in SetBase and GetTotal; done means the base writes use a bit-piece expression for offset 0 and SetBase receives the expected this debug value.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.