| Issue |
204427
|
| Summary |
[HLSL] Copies between two `inout`/`out` array parameters are dropped if there is a GroupMemoryBarrierWithGroupSync present
|
| Labels |
HLSL
|
| Assignees |
|
| Reporter |
Icohedron
|
Repro: https://hlsl.godbolt.org/z/d5bq4TKso
The following compute shader initializes a 2D source array of integers and copies it to a destination array via a `Copy` function taking the two array parameters as `inout` and `out`. An element of the destination array is written to the output UAV.
Compiled with: `clang-dxc -T cs_6_0 -E CSMain`
```hlsl
RWStructuredBuffer<int> output : register(u0);
void Copy(inout int src[2][2], out int dst[2][2])
{
[unroll]
for (uint i = 0; i < 2; i++)
{
[unroll]
for (uint j = 0; j < 2; j++)
{
dst[i][j] = src[i][j];
GroupMemoryBarrierWithGroupSync(); // no-op barrier
}
}
}
[numthreads(1, 1, 1)]
void CSMain()
{
int src[2][2];
[unroll] for (uint a = 0; a < 2; a++)
[unroll] for (uint b = 0; b < 2; b++)
src[a][b] = 4;
int dst[2][2];
Copy(src, dst);
output[0] = dst[1][1];
}
```
However, Clang emits the following IR, dropping the loads and stores entirely.
```llvm
define void @CSMain() local_unnamed_addr #0 {
entry:
br label %for.cond.i.i
for.cond.i.i:
br label %for.cond.cleanup3.i.i
for.cond.cleanup3.i.i:
call void @dx.op.barrier(i32 80, i32 9)
call void @dx.op.barrier(i32 80, i32 9)
br label %for.cond.cleanup3.i.i.1
for.cond.cleanup3.i.i.1:
call void @dx.op.barrier(i32 80, i32 9)
call void @dx.op.barrier(i32 80, i32 9)
ret void
}
...
```
Removing the `GroupMemoryBarrierWithGroupSync` or changing the `inout` src parameter to an `in` parameter makes the loads and stores appear as expected.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs