Skip to content

[DirectX] DXILCBufferAccess gets tripped up by arrays that are exactly 64 bits long #138996

Open
@bogner

Description

@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

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:

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions