Issue 138996
Summary [DirectX] DXILCBufferAccess gets tripped up by arrays that are exactly 64 bits long
Labels backend:DirectX
Assignees
Reporter bogner
    If an array fits in exactly 64 bits (for example, if it's 2 32 bit integers or 4 16 bit integers), DXILCBufferAccess gets a bit confused. Consider:

https://hlsl.godbolt.org/z/j3aqnEcdx
```hlsl
cbuffer CBArrays : register(b0) {
  uint32_t c1[2];
}

struct Arrays {
  uint32_t c1[2];
};
RWStructuredBuffer<Arrays> Out : register(u1);

[numthreads(1,1,1)]
void main() {
  Out[0].c1 = c1;
}
```

The array copy is turned into a memcpy by clang, which is then simplified into just loading and copying an `i64`. Then, we feed something like the following into DXILCBufferAccess:

```llvm
define void @main() local_unnamed_addr #1 {
entry:
  %CBArrays.cb_h.i.i = tail call target("dx.CBuffer", target("dx.Layout", %__cblayout_CBArrays, 20, 0)) @llvm.dx.resource.handlefrombinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBArrayss_20_0tt(i32 0, i32 0, i32 1, i32 0, i1 false)
  store target("dx.CBuffer", target("dx.Layout", %__cblayout_CBArrays, 20, 0)) %CBArrays.cb_h.i.i, ptr @CBArrays.cb, align 4
  %0 = tail call target("dx.RawBuffer", %struct.Arrays, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_s_struct.Arrayss_1_0t(i32 0, i32 1, i32 1, i32 0, i1 false)
  %1 = tail call noundef nonnull align 1 dereferenceable(8) ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_s_struct.Arrayss_1_0t(target("dx.RawBuffer", %struct.Arrays, 1, 0) %0, i32 0)
  %2 = load i64, ptr addrspace(2) @c1, align 4, !tbaa !6
  store i64 %2, ptr %1, align 1, !tbaa !6
  ret void
}
```

Seeing the `i64` load, the pass assumes that the type it should use for the access is a 64 bit type, and things go wrong from there.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to