microsoft / microsoft/DirectXShaderCompiler
Incorrect branching surrounding WaveReadLaneAt when shader model cs_6_6
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 3.7k
- Forks
- 900
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 44
Description
Description
Branching around WaveReadLaneAt has incorrect behavior when compiled with cs_6_6
Steps to Reproduce
cs_6_5 version: https://godbolt.org/z/sbK7hPGbj
cs_6_6 version: https://godbolt.org/z/66nPod54s
(same code, just shader model changed)
So, this code is not as simple as I want, but is as simple as I could get it. The idea is, we have groups of 16 threads that are all one one task, but we don't want them doing duplicate memory loads, so we keep track of the groups, and lane0 does the load, and then shares it with waveReadLaneAt().
Actual Behavior
I'm not perfect at reading dxil, but as far as I can tell, what's happening:
For the cs_6_5 version:
- Lane 0 of each group of 16 threads does a load from a location
- Each thread does a waveReadLaneAt to read their groups lane0 val
- Lane 0 of each group then stores its 0 at it's original location (this isn't important, but we need another "if(laneIndex == 0)" statement that can't be optimized out)
- Each lane stores the value given to it by the waveReadLaneAt, which comes from each laneGroup's lane0
Howeva ☝️
For the cs_6_6 version:
- It BRANCHES based on laneIndex == 0?
- every thread that isn't lane index 0 in the group reads lane 0's value...that hasn't been loaded yet?
- lane 0 threads then do the load. And then do the waveReadAtLane, which just reads their own value, but it's at least loaded this time
- Each lane stores it's "val" but everything but the lane0's in the lane groups have the wrong value (uninitialized?)
Environment
- DXC version - dxc Trunk on godbolt
- Host Operating System - godbolt
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the two linked Godbolt reproductions and compare the generated DXIL for cs_6_5 and cs_6_6 around WaveReadLaneAt and the laneIndex branches. Trace the DXC compiler path responsible for this lowering; done means the cs_6_6 output preserves the expected load-before-read behavior and the reproduction produces matching lane values.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers, computer-graphics
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100