microsoft / microsoft/DirectXShaderCompiler

Incorrect branching surrounding WaveReadLaneAt when shader model cs_6_6

Open
#7,726 11 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug check-in-clang correctness
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

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 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.