Skip to content

[HLSL] [DirectX] Clang emits struct alloca instructions for structs with one or more array-typed fields, or any struct when compiling with -O0 #147109

Open
@Icohedron

Description

@Icohedron

After resolving #146974, validation errors of the form Pointer type bitcast must be have same size and Bitcast on struct types is not allowed appear.
There are 16 occurrences of both errors in total, and they all originate from two DML shaders: OneHot_256_uint16_native_int64_emulated_4 and OneHot_256_uint16_native_int32_native_4

The issue is that Clang is emitting an alloca for structs that contain one or more array-typed fields.

For example, take this shader: https://godbolt.org/z/641qM9T8z

// compile args: -E CSMain -T cs_6_2 -enable-16bit-types -Xclang -emit-llvm
RWStructuredBuffer<uint> output;
struct MyStruct {
  uint arr[2];
};
[numthreads(1, 1, 1)]
void CSMain(uint3 Tid: SV_DispatchThreadID) {
  MyStruct s = {Tid.x, 0};
  uint d = s.arr[Tid.y];
  output[0] = d ;
}

A struct definition and an alloca of the struct appear in the IR that is to be fed to the DirectX backend.

%struct.MyStruct = type { [2 x i32] }
define void @CSMain() local_unnamed_addr #0 {
  %1 = alloca %struct.MyStruct, align 4, !DIAssignID !56
...

This is causing issues because the DirectX backend does not handle allocas for structs and thus causes a cascade of validation errors.

Function: CSMain: error: Pointer type bitcast must be have same size.
note: at '%3 = bitcast %struct.MyStruct* %s.i to i32*' in block 'entry' of function 'CSMain'.
Function: CSMain: error: Bitcast on struct types is not allowed.
note: at '%4 = bitcast %struct.MyStruct* %s.i to [1 x %struct.MyStruct]*' in block 'entry' of function 'CSMain'.
Function: CSMain: error: Pointer type bitcast must be have same size.
note: at '%5 = bitcast %struct.MyStruct* %arrayinit.element.i1 to i32*' in block 'entry' of function 'CSMain'.
Function: CSMain: error: Bitcast on struct types is not allowed.
note: at '%6 = bitcast %struct.MyStruct* %s.i to [2 x i32]*' in block 'entry' of function 'CSMain'.
Validation failed.

Additionally, if you compile with -O0, structs and struct allocas will be emitted regardless of whether or not the struct contains an array-typed field.

The issue is that the SROA pass is responsible for eliminating the structs, but fails to do so when the struct contains an array-typed field. Furthermore, the SROA pass does not run when the flag -O0 is specified.

How do we want to correctly handle structs?

Metadata

Metadata

Assignees

Type

Projects

Status

Planning

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions