Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
1 of 3 tasks
khushal1996 opened this issue Mar 27, 2024 · 1 comment · Fixed by #42451
Closed
1 of 3 tasks

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

khushal1996 opened this issue Mar 27, 2024 · 1 comment · Fixed by #42451
Assignees
Labels
breaking-change Indicates a .NET Core breaking change 🏁 Release: .NET 9 Work items for the .NET 9 release doc-idea Indicates issues that are suggestions for new topics [org][type][category] in-pr This issue will be closed (fixed) by an active pull request. Pri1 High priority, do before Pri2 and Pri3 📌 seQUESTered Identifies that an issue has been imported into Quest.

Comments

@khushal1996
Copy link

khushal1996 commented Mar 27, 2024

Description

Behavior of floating point to integer conversions will change following PR dotnet/runtime#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.
  • 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 dotnet/runtime#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)

Associated WorkItem - 307284

@khushal1996 khushal1996 added breaking-change Indicates a .NET Core breaking change doc-idea Indicates issues that are suggestions for new topics [org][type][category] Pri1 High priority, do before Pri2 and Pri3 labels Mar 27, 2024
@dotnet-bot dotnet-bot added the ⌚ Not Triaged Not triaged label Mar 27, 2024
@gewarren gewarren removed the ⌚ Not Triaged Not triaged label Mar 27, 2024
@tannergooding
Copy link
Member

This was discussed in API review as part of dotnet/runtime#61885 and we will (in a follow up PR to dotnet/runtime#97529) be exposing the new helper APIs that do the platform specific conversions for users who require the performance and don't need to care about the different results across platforms.

@gewarren gewarren added the 🏁 Release: .NET 9 Work items for the .NET 9 release label Jun 12, 2024
@dotnet-bot dotnet-bot added the ⌚ Not Triaged Not triaged label Jun 12, 2024
@gewarren gewarren added the 🗺️ reQUEST Triggers an issue to be imported into Quest. label Sep 3, 2024
@dotnet-bot dotnet-bot removed the ⌚ Not Triaged Not triaged label Sep 3, 2024
@dotnet-policy-service dotnet-policy-service bot added the in-pr This issue will be closed (fixed) by an active pull request. label Sep 4, 2024
@sequestor sequestor bot added 📌 seQUESTered Identifies that an issue has been imported into Quest. and removed 🗺️ reQUEST Triggers an issue to be imported into Quest. labels Sep 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking-change Indicates a .NET Core breaking change 🏁 Release: .NET 9 Work items for the .NET 9 release doc-idea Indicates issues that are suggestions for new topics [org][type][category] in-pr This issue will be closed (fixed) by an active pull request. Pri1 High priority, do before Pri2 and Pri3 📌 seQUESTered Identifies that an issue has been imported into Quest.
Projects
Status: ✅ Done
Development

Successfully merging a pull request may close this issue.

4 participants