Problem
ByteAddressBuffer::Store<min16int>() (and other min precision scalar/vector template stores) crashes during compilation with llvm::cast<X>() argument of incompatible type!.
The crash occurs in TranslateMinPrecisionRawBuffer (DxilGenerationPass.cpp), specifically in ReplaceMinPrecisionRawBufferStoreByType. The code does cast<StructType>(STy->getElementType(0)) to look up struct type annotations for signedness. For ByteAddressBuffer, the resource type is { i32 }, so getElementType(0) returns i32 (not a StructType), and the cast asserts.
This is a pre-existing bug — these template stores have never worked for min precision types on ByteAddressBuffer.
Why this can't be fixed in DxilGen
The TranslateMinPrecisionRawBuffer pass needs signedness information to choose between sext (signed) and zext (unsigned) when widening from 16-bit to 32-bit. For StructuredBuffers, this comes from struct type annotations. For ByteAddressBuffer, there are no struct annotations — it's a raw buffer.
An incomplete fix was attempted in PR #8274 (falling back to sext when no annotation exists), but this is wrong for min16uint and was reverted in PR #8321.
Proposed fix: widen during Clang CodeGen
At CodeGen time, signedness information is still available from the HLSL type system. For scalar/vector (non-struct) template stores on ByteAddressBuffer, the widening from 16-bit to 32-bit min precision types should be performed during CodeGen, before the information is lost.
This is simpler than the StructuredBuffer case, where embedded 16-bit types in structs would require recreating storage struct types, replacing subscript calls, and recursing through all GEP and instruction users. For scalar/vector types, the widening can be applied directly.
Open question
For templated Load/Store, is the struct type annotation captured? There has been prior work to prevent loss of type annotation information for similar cases, but it's unclear if this path is currently covered. If annotations are available, the existing TranslateMinPrecisionRawBuffer logic could potentially be extended instead.
Repro
RWByteAddressBuffer g_buf : register(u0);
[numthreads(1,1,1)]
void main() {
min16int si = (min16int)1;
g_buf.Store<min16int>(0, si); // crashes
}
Compile with: dxc -E main -T cs_6_2 repro.hlsl
Related
Problem
ByteAddressBuffer::Store<min16int>()(and other min precision scalar/vector template stores) crashes during compilation withllvm::cast<X>() argument of incompatible type!.The crash occurs in
TranslateMinPrecisionRawBuffer(DxilGenerationPass.cpp), specifically inReplaceMinPrecisionRawBufferStoreByType. The code doescast<StructType>(STy->getElementType(0))to look up struct type annotations for signedness. For ByteAddressBuffer, the resource type is{ i32 }, sogetElementType(0)returnsi32(not aStructType), and the cast asserts.This is a pre-existing bug — these template stores have never worked for min precision types on ByteAddressBuffer.
Why this can't be fixed in DxilGen
The
TranslateMinPrecisionRawBufferpass needs signedness information to choose betweensext(signed) andzext(unsigned) when widening from 16-bit to 32-bit. For StructuredBuffers, this comes from struct type annotations. For ByteAddressBuffer, there are no struct annotations — it's a raw buffer.An incomplete fix was attempted in PR #8274 (falling back to
sextwhen no annotation exists), but this is wrong formin16uintand was reverted in PR #8321.Proposed fix: widen during Clang CodeGen
At CodeGen time, signedness information is still available from the HLSL type system. For scalar/vector (non-struct) template stores on ByteAddressBuffer, the widening from 16-bit to 32-bit min precision types should be performed during CodeGen, before the information is lost.
This is simpler than the StructuredBuffer case, where embedded 16-bit types in structs would require recreating storage struct types, replacing subscript calls, and recursing through all GEP and instruction users. For scalar/vector types, the widening can be applied directly.
Open question
For templated
Load/Store, is the struct type annotation captured? There has been prior work to prevent loss of type annotation information for similar cases, but it's unclear if this path is currently covered. If annotations are available, the existingTranslateMinPrecisionRawBufferlogic could potentially be extended instead.Repro
Compile with:
dxc -E main -T cs_6_2 repro.hlslRelated
sextvszextsignedness issue for min precision vector stores (same root cause — signedness lost by DxilGen time)