Description
For most basic math intrinsics, HLSL packed types like int8_t4_packed get implicitly cast to float, which is never likely to be intended.
The reason for this behavior:
Most operations use the numeric template in gen_intrin_main.txt, and this template doesn't include the packed component types in the template. However, the packed component type is just defined as another built-in 32-bit unsigned int type, so implicit casting is allowed to other scalar types. Because numeric starts with a float type, that's the first implicit cast checked to see if it's possible. It is, so it inserts an implicit cast to float, even though that's unlikely to make sense for the packed type.
Ideally, we would block implicit casting of the packed type to other scalar types. You could explicitly cast it still, but blocking implicit casts should prevent the auto-cast-to-float behavior when used with many intrinsic functions, raising an error instead. We should probably block the types from ordinary unary and binary math operators that are not equivalent when the packed values are treated as a single scalar. Shifts should be blocked too. Bitwise operators (~, &, |, ^) are fine.
As a much easier alternative, we could add the packed types to numeric, and they would be accepted and treated as uint32 values instead of converting to float. This is less desirable than blocking implicit casting, since for most operations, treating the packed components as a uint32 scalar is not equivalent to performing the operation on each component in isolation. Thus, requiring an explicit cast is clearer.
Description
For most basic math intrinsics, HLSL packed types like
int8_t4_packedget implicitly cast to float, which is never likely to be intended.The reason for this behavior:
Most operations use the
numerictemplate ingen_intrin_main.txt, and this template doesn't include the packed component types in the template. However, the packed component type is just defined as another built-in 32-bit unsigned int type, so implicit casting is allowed to other scalar types. Because numeric starts with a float type, that's the first implicit cast checked to see if it's possible. It is, so it inserts an implicit cast to float, even though that's unlikely to make sense for the packed type.Ideally, we would block implicit casting of the packed type to other scalar types. You could explicitly cast it still, but blocking implicit casts should prevent the auto-cast-to-float behavior when used with many intrinsic functions, raising an error instead. We should probably block the types from ordinary unary and binary math operators that are not equivalent when the packed values are treated as a single scalar. Shifts should be blocked too. Bitwise operators (
~,&,|,^) are fine.As a much easier alternative, we could add the packed types to numeric, and they would be accepted and treated as uint32 values instead of converting to float. This is less desirable than blocking implicit casting, since for most operations, treating the packed components as a uint32 scalar is not equivalent to performing the operation on each component in isolation. Thus, requiring an explicit cast is clearer.