llvm / llvm/llvm-project

[HLSL][SPIR-V] WavePrefix* HLSL operations in control flow generates invalid SPIR-V

Open
#217,826 1 comment 0 reactions 0 assignees View on GitHub
backend:SPIR-V clang:HLSL:SPIRV
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

Clang-vk tests are failing due to failing spirv-val.
This is the output below:

```
D:\llvm-project\build>python3 D:\llvm-project\build\bin\llvm-lit.py --show-all "D:\llvm-project\build\tools\OffloadTest\test\clang-vk\WaveOps\WavePrefixProduct.fp64.test"
llvm-lit.py: D:\llvm-project\llvm\utils\lit\lit\llvm\config.py:64: note: using lit tools: C:\Program Files\Git\usr\bin
-- Testing: 1 tests, 1 workers --
XFAIL: OffloadTest-clang-vk :: WaveOps/WavePrefixProduct.fp64.test (1 of 1)
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 183
d:\llvm-project\build\bin\split-file.exe D:\OffloadTest\test\WaveOps\WavePrefixProduct.fp64.test D:\llvm-project\build\tools\OffloadTest\test\clang-vk\WaveOps\Output\WavePrefixProduct.fp64.test.tmp
# executed command: 'd:\llvm-project\build\bin\split-file.exe' 'D:\OffloadTest\test\WaveOps\WavePrefixProduct.fp64.test' 'D:\llvm-project\build\tools\OffloadTest\test\clang-vk\WaveOps\Output\WavePrefixProduct.fp64.test.tmp'
# RUN: at line 184
d:\llvm-project\build\bin\clang-dxc.exe -spirv -fspv-target-env=vulkan1.3 -fspv-extension=DXC --dxv-path=D:/hlsl.bin/Debug/bin -T cs_6_5 -Fo D:\llvm-project\build\tools\OffloadTest\test\clang-vk\WaveOps\Output\WavePrefixProduct.fp64.test.tmp.o D:\llvm-project\build\tools\OffloadTest\test\clang-vk\WaveOps\Output\WavePrefixProduct.fp64.test.tmp/source.hlsl
# executed command: 'd:\llvm-project\build\bin\clang-dxc.exe' -spirv -fspv-target-env=vulkan1.3 -fspv-extension=DXC --dxv-path=D:/hlsl.bin/Debug/bin -T cs_6_5 -Fo 'D:\llvm-project\build\tools\OffloadTest\test\clang-vk\WaveOps\Output\WavePrefixProduct.fp64.test.tmp.o' 'D:\llvm-project\build\tools\OffloadTest\test\clang-vk\WaveOps\Output\WavePrefixProduct.fp64.test.tmp/source.hlsl'
# .---command stderr------------
# | error: line 309: block 16 branches to the selection construct, but not to the selection header 7
# | %new_header623_new_exit = OpLabel
# |
# | clang-dxc: error: spirv-val command failed with exit code 1 (use -v to see invocation)
# `-----------------------------
# error: command failed with exit status: 1

--

********************

Testing Time: 2.43s

Total Discovered Tests: 1
Expectedly Failed: 1 (100.00%)
```

Here is some HLSL that causes this assertion to be hit after running spirv-val on the compiled output:

```hlsl
StructuredBuffer In : register(t0);
RWStructuredBuffer Out1 : register(u1); // test scalar
RWStructuredBuffer Out2 : register(u2); // test double2
RWStructuredBuffer Out3 : register(u3); // test double3
RWStructuredBuffer Out4 : register(u4); // test double4
RWStructuredBuffer Out5 : register(u5); // constant folding

[numthreads(4,1,1)]
void main(uint3 tid : SV_GroupThreadID)
{
double4 v = In[0];

// Mask per "active lane set": only <=N lanes contribute
double s1 = tid.x <= 0 ? WavePrefixProduct( v.x ) : 0;
double s2 = tid.x <= 1 ? WavePrefixProduct( v.x ) : 0;
double s3 = tid.x <= 2 ? WavePrefixProduct( v.x ) : 0;
double s4 = tid.x <= 3 ? WavePrefixProduct( v.x ) : 0;

double2 v2_1 = tid.x <= 0 ? WavePrefixProduct( v.xy ) : double2(0,0);
double2 v2_2 = tid.x <= 1 ? WavePrefixProduct( v.xy ) : double2(0,0);
double2 v2_3 = tid.x <= 2 ? WavePrefixProduct( v.xy ) : double2(0,0);
double2 v2_4 = tid.x <= 3 ? WavePrefixProduct( v.xy ) : double2(0,0);

double3 v3_1 = tid.x <= 0 ? WavePrefixProduct( v.xyz ) : double3(0,0,0);
double3 v3_2 = tid.x <= 1 ? WavePrefixProduct( v.xyz ) : double3(0,0,0);
double3 v3_3 = tid.x <= 2 ? WavePrefixProduct( v.xyz ) : double3(0,0,0);
double3 v3_4 = tid.x <= 3 ? WavePrefixProduct( v.xyz ) : double3(0,0,0);

double4 v4_1 = tid.x <= 0 ? WavePrefixProduct( v ) : double4(0,0,0,0);
double4 v4_2 = tid.x <= 1 ? WavePrefixProduct( v ) : double4(0,0,0,0);
double4 v4_3 = tid.x <= 2 ? WavePrefixProduct( v ) : double4(0,0,0,0);
double4 v4_4 = tid.x <= 3 ? WavePrefixProduct( v ) : double4(0,0,0,0);

double scalars[4] = { s1, s2, s3, s4 };
double2 vec2s [4] = { v2_1, v2_2, v2_3, v2_4 };
double3 vec3s [4] = { v3_1, v3_2, v3_3, v3_4 };
double4 vec4s [4] = { v4_1, v4_2, v4_3, v4_4 };

Out1[tid.x].x = scalars[tid.x];
Out2[tid.x].xy = vec2s[tid.x];
Out3[tid.x].xyz = vec3s[tid.x];
Out4[tid.x] = vec4s[tid.x];
Out5[tid.x] = WavePrefixProduct(double4(2,3,5,7));
}
```

And the godbolt link that generates the validation error:
https://godbolt.org/z/qr3q64Thn

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.