microsoft / microsoft/DirectXShaderCompiler

Miscompile when reading matrix from a structure in a ByteAddressBuffer

Open
#8,569 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

Description
A compute shader like this mis-compiles the read. It requires a fairly
particular setup as described in comments below

struct Box { float4x4 m; };   // a struct whose SOLE member is a float4x4

ByteAddressBuffer   src : register(t0);
RWByteAddressBuffer dst : register(u0);

[numthreads(1, 1, 1)]
void csmain()
{
    Box b = src.Load<Box>(0);   // 64-byte struct at offset 0

    // read the first matrix column through the struct member. 
    // DXC loads byte 0 for all four.
    dst.Store(0,  asuint(b.m._m00));
    dst.Store(4,  asuint(b.m._m10));
    dst.Store(8,  asuint(b.m._m20));
    dst.Store(12, asuint(b.m._m30));

    // CORRECT: copy the matrix to a local float4x4 first, then read. Offsets are right.
    float4x4 m = b.m;
    dst.Store(16, asuint(m._m00));
    dst.Store(20, asuint(m._m10));
    dst.Store(24, asuint(m._m20));
    dst.Store(28, asuint(m._m30));
}

Steps to Reproduce
https://godbolt.org/z/bG5reh3rh

Actual Behavior
The DXIL produced by dxc performs the first 4 reads at offset 0

Environment
I reproduced on Mac and Windows. I verified that it reproduces in v1.10.2605.24 and current HEAD.

Please see #8568 for reproducing test and a potential way to address it.

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 Godbolt reproduction to confirm the incorrect DXIL offsets, then read issue #8568 for the reproducing test and potential approach. Run that test and trace the compiler path for loading a matrix member from a struct returned by ByteAddressBuffer.Load. Done means the four direct reads use the correct matrix offsets rather than all reading byte 0.

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
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.