Description
The Problem
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
Reproducing the problem
Validate one of the problematic DML shaders mentioned.
dxv validation/OneHot_256_uint16_native_int32_native_4.dat
This minimal shader also reproduces the validation error when validated after being compiled https://godbolt.org/z/GexqvYc1d
// compile args: -E CSMain -T cs_6_2 -enable-16bit-types
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 ;
}
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.
Observations
Adding -Xclang -emit-llvm
to the compile args, we can see the following loads, stores, and GEPs being emitted:
%struct.MyStruct = type { [2 x i32] }
%1 = alloca %struct.MyStruct, align 4, !DIAssignID !56
store i32 %3, ptr %1, align 4, !dbg !99, !tbaa !100, !DIAssignID !104
%5 = getelementptr inbounds nuw i8, ptr %1, i32 4, !dbg !99
store i32 0, ptr %5, align 4, !dbg !99, !tbaa !100, !DIAssignID !105
%6 = getelementptr inbounds nuw [2 x i32], ptr %1, i32 0, i32 %4, !dbg !106
%7 = load i32, ptr %6, align 4, !dbg !106, !tbaa !100
Case 1: Direct store of an i32
into a struct
This is similar to issue #147114 but it's a direct store into a struct alloca as opposed to an array alloca.
The store instruction
%1 = alloca %struct.MyStruct, align 4, !DIAssignID !56
store i32 %3, ptr %1, align 4, !dbg !99, !tbaa !100, !DIAssignID !104
causes the dxil-prepare pass to emit the bitcast
%1 = alloca %struct.MyStruct, align 4, !DIAssignID !56
%5 = bitcast ptr %1 to ptr, !dbg !108
store i32 %3, ptr %5, align 4, !dbg !108
which triggers the validation error
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'.
Case 2: i8
GEP improperly legalized for structs
The i8
GEP emitted by Clang
%1 = alloca %struct.MyStruct, align 4, !DIAssignID !56
%5 = getelementptr inbounds nuw i8, ptr %1, i32 4, !dbg !99
store i32 0, ptr %5, align 4, !dbg !99, !tbaa !100, !DIAssignID !105
gets transformed by the dxil-legalize pass to
%1 = alloca %struct.MyStruct, align 4, !DIAssignID !56
%5 = getelementptr inbounds nuw [1 x %struct.MyStruct], ptr %1, i32 0, i32 0, !dbg !99
store i32 0, ptr %5, align 4, !dbg !99, !tbaa !100, !DIAssignID !105
which causes the dxil-prepare pass to emit bitcasts
%1 = alloca %struct.MyStruct, align 4, !DIAssignID !56
%6 = bitcast ptr %1 to ptr, !dbg !108
%7 = getelementptr inbounds nuw [1 x %struct.MyStruct], ptr %6, i32 0, i32 0, !dbg !108
%8 = bitcast ptr %7 to ptr, !dbg !108
store i32 0, ptr %8, align 4, !dbg !108
causing the validation errors
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'.
Case 3: Clang emits a [2 x i32]
GEP for the struct access
The following GEP is emitted by Clang
%1 = alloca %struct.MyStruct, align 4, !DIAssignID !56
%6 = getelementptr inbounds nuw [2 x i32], ptr %1, i32 0, i32 %4, !dbg !106
for which dxil-prepare inserts a bitcast
%1 = alloca %struct.MyStruct, align 4, !DIAssignID !56
%9 = bitcast ptr %1 to ptr, !dbg !111
%10 = getelementptr inbounds nuw [2 x i32], ptr %9, i32 0, i32 %4, !dbg !111
and triggers the validation error
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'.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status