KhronosGroup / KhronosGroup/glslang

Cannot call InterlockedAdd() method on a RWByteAddressBuffer in HLSL

Open
#2,066 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug HLSL sev:miscompile
Dominant language
C++
Stars
3.6k
Forks
990
Avg merge
1d 2h
Merged PRs (30d)
31

Description

Here's my repro case:
```hlsl
RWByteAddressBuffer MyBuffer;

[numthreads(1, 1, 1)]
void main()
{
uint previous_value;
MyBuffer.InterlockedAdd(0, 1, previous_value);
}
```
This shader compiles to SPIR-V with the following command:
```sh
$ glslangValidator --target-env spirv1.3 -g -e main -V -D test_interlocked.comp.hlsl -o test_interlocked.comp.spv.unoptimized
$ spirv-opt test_interlocked.comp.spv.unoptimized --legalize-hlsl -Os -o test_interlocked.comp.spv
```
```sh
$ glslangValidator --version
Glslang Version: 8.13.3559
ESSL Version: OpenGL ES GLSL 3.20 glslang Khronos. 13.3559
GLSL Version: 4.60 glslang Khronos. 13.3559
SPIR-V Version 0x00010400, Revision 1
GLSL.std.450 Version 100, Revision 1
Khronos Tool ID 8
SPIR-V Generator Version 8
GL_KHR_vulkan_glsl version 100
ARB_GL_gl_spirv version 100
```
The compilation fails when `spirv-opt` is invoked with the following message:
```
error: line 51: AtomicIAdd: expected Value to be of type Result Type
%25 = OpAtomicIAdd %uint %21 %uint_1 %uint_0 %int_1
```
I'm not sure if this problem comes from `glslang` or `spirv-opt`, maybe you guys have more info on this.
As a reference, here is what `dxc` outputs at the atomic instruction for my example:
```spirv
%14 = OpAtomicIAdd %uint %13 %uint_1 %uint_0 %uint_1
```
EDIT: So I slept on it and tried to force constants to the `uint` type. Here's the changed part:
```hlsl
MyBuffer.InterlockedAdd(0, uint(1), previous_value);
```
This successfully compiles with `glslang`. I still think there's a bug here though.

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

Reproduce the issue with test_interlocked.comp.hlsl using the shown glslangValidator and spirv-opt commands, starting at the HLSL InterlockedAdd handling and generated OpAtomicIAdd. Compare the output with the dxc reference and the uint(1) workaround; done means the uncast literal produces valid SPIR-V without the spirv-opt type error.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.