docs icon indicating copy to clipboard operation
docs copied to clipboard

[Breaking change]: Scalar and packed floating point to integer conversions

Open khushal1996 opened this issue 3 months ago • 1 comments

Description

Behavior of floating point to integer conversions will change following PR https://github.com/dotnet/runtime/pull/97529. The change moves existing non-saturating conversion on x86/x64 arch to saturating behavior. Hence, following this PR, floating point to integer conversion in .NET will have saturating behavior.

Version

.NET 9 RC 1

Previous behavior

Previous behavior --

Case - float/double to long scalar and packed

long.MinValue <= x <= long.MaxValue ---> (long)x otherwise ---> long.MinValue

Case - float/double to int scalar and packed

int.MinValue <= x <= int.MaxValue ---> (int)x otherwise ---> int.MinValue

Case - float/double to uint scalar and packed

---> (((long)x << 32) >> 32)

Case - float/double to ulong scalar and packed

x <= 2^63 ---> (long)x otherwise ---> (long)(x - 2^63) + 2^63

New behavior

Previous behavior --

Case - float/double to long scalar and packed

long.MinValue <= x <= long.MaxValue ---> (long)x x < long.MinValue ---> long.MinValue x = NaN ---> 0 x > long.MaxValue ---> long.MaxValue

Case - float/double to int scalar and packed

int.MinValue <= x <= int.MaxValue ---> (int)x x < int.MinValue ---> int.MinValue x = NaN ---> 0 x > int.MaxValue ---> int.MaxValue

Case - float/double to uint scalar and packed

0 <= x <= uint.MaxValue ---> (uint)x x > uint.MaxValue ---> uint.MaxValue otherwise ---> 0

Case - float/double to ulong scalar and packed

0 <= x <= ulong.MaxValue ---> (ulong)x x > ulong.MaxValue ---> ulong.MaxValue otherwise ---> 0

Type of breaking change

  • [ ] Binary incompatible: Existing binaries may encounter a breaking change in behavior, such as failure to load or execute, and if so, require recompilation.
  • [ ] Source incompatible: When recompiled using the new SDK or component or to target the new runtime, existing source code may require source changes to compile successfully.
  • [X] Behavioral change: Existing binaries may behave differently at run time.

Reason for change

.NET wants to standardize all floating point to integer conversions to have saturating behavior. The PR https://github.com/dotnet/runtime/pull/97529 changes behavior of x86/x64 to support saturating behavior.

Recommended action

  1. Change impacts only users of arch x86/x64
  2. This change affects those who were relying .NET returning any value (correct or incorrect) irrespective of the input for floating point to integer conversions.
  3. The change effect all overflow scalar and packed conversions from float/double to int/uint/long/ulong

Feature area

JIT

Affected APIs

all explicit and implicit casts from floating point to integer.

  1. (long)val; where type(val) = float/double
  2. Vector.ConvertToInt64(Vector<double> val)
  3. (int)val; where type(val) = float/double
  4. Vector.ConvertToInt32(Vector<float> val)
  5. (uint)val; where type(val) = float/double
  6. Vector.ConvertToUInt32(Vector<float> val)
  7. (ulong)val; where type(val) = float/double
  8. Vector.ConvertToUInt64(Vector<double> val)

khushal1996 avatar Mar 27 '24 23:03 khushal1996