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

Reply via email to