Issue 180600
Summary [SPIRV] Reconstituted arrays in structs can end up with extra padding.
Labels HLSL, backend:SPIR-V
Assignees
Reporter bogner
    Given the following HLSL, I'm seeing an "Unimplemented implicit down-cast from load." assertion. This assert is happening because we end with a load of cbuffer padding in `SPIRVLegalizePointerCast::transformLoad`, but the problem occurred earlier.

```hlsl
struct X {
  int a1;
};
struct Y : X {
 int a2;
  int a3;
};
struct Z {
  X xs[2];
  Y y;
};

cbuffer cb0 : register(b0) {
  Z zs[2];
};

RWStructuredBuffer<int> Out : register(u1);

[numthreads(1,1,1)]
void main() {
  Out[0] = zs[1].y.a2;
}
```
Compiler explorer: https://hlsl.godbolt.org/z/4xv3T9nTK

The problem here is that SPIRVUtils's `reconstitutePeeledArrayType` function isn't handling padding after the array correctly. Taking a look at the before/after of the SPIRVEmitIntrinsics pass, we see the issue,

`clang-dxc -spirv -T cs_6_5 -fvk-use-dx-layout x.hlsl -mllvm -stop-before=emit-intrinsics`
```llvm
  %Z = type <{ <{ [1 x <{ %X, target("spirv.Padding", 12) }>], %X }>, target("spirv.Padding", 12), %Y }>
  %X = type <{ i32 }>
  %Y = type <{ i32, i32, i32 }>
```

clang-dxc -spirv -T cs_6_5 -fvk-use-dx-layout x.hlsl -mllvm -stop-after=emit-intrinsics
```llvm
  %Z = type <{ <{ [1 x <{ %X, target("spirv.Padding", 12) }>], %X }>, target("spirv.Padding", 12), %Y }>
  %X = type <{ i32 }>
  %Y = type <{ i32, i32, i32 }>
  %Z.0 = type <{ [2 x <{ %X, target("spirv.Padding", 12) }>], target("spirv.Padding", 12), %Y }>
```

The reconstituted type, `%Z.0`, has padding within the `2 x %X` array and also after it, but this doesn't match the physical layout of the original `%Z`, which should have `%Y` directly following the `%X` array. The correct reconstituted type should be:

```llvm
  %Z.0 = type <{ [2 x <{ %X, target("spirv.Padding", 12) }>], %Y }>
```

_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to