-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Description
I discovered this when looking in to #7312. It doesn't matter for that issue as AbstractFloat is f64, which can exactly represent all 32 bit integers. But for conversion from f32 to 32-bit integral types I think we have an issue.
The spec says:
The scalar floating point to integral conversion algorithm is:
To convert a floating point scalar value X to an integer scalar type T:
If X is a NaN, the result is an indeterminate value in T.
If X is exactly representable in the target type T, then the result is that value.
Otherwise, the result is the value in T closest to truncate(X) and also exactly representable in the original floating point type.
The key point is the "also exactly representable in the original floating point type" part. This is explained further in the spec below:
Note: For example:
The wording in the i32 case is slightly off, I assume it's meant to say "the largest float value representable in i32" as it does for u32.
We don't do this part. During const evaluation we just use a rust as cast, which simply clamps to the range of the target type. Since i32::MIN, i32::MAX, and u32::MAX are not representable by f32, this appears to be incorrect.
For our naga backends:
- hlsl does a constructor style cast
- msl does a
static_cast - glsl does a constructor style cast
- spv emits
OpConvertFToU/OpConvertFToSinstructions.
I doubt any of these do the right thing. In fact I would imagine most if not all of them are undefined behaviour when the source value is out of range of the dest type.
Repro steps
fn test() {
var x = i32(2147483648.0f);
}Expected vs observed behavior
The above shader gives this output when translating back to wgsl:
fn test() {
var x: i32 = 2147483647i;
return;
}I would expect it to give:
var x: i32 = 2147483520iNote that tint does the same as us, at least during const evaluation. Their metal output for the above is:
void test() {
int x = 2147483647;
}Metadata
Metadata
Assignees
Labels
Type
Projects
Status