-
Notifications
You must be signed in to change notification settings - Fork 6k
Closed
Labels
🏁 Release: .NET 8Work items for the .NET 8 releaseWork items for the .NET 8 release📌 seQUESTeredIdentifies that an issue has been imported into Quest.Identifies that an issue has been imported into Quest.breaking-changeIndicates a .NET Core breaking changeIndicates a .NET Core breaking change
Description
Description
.NET 8 adds support for vectorization in the Enumerable.Sum methods where applicable. As a side-effect of that change, the vectorized implementation can change the order in which the different elements are added. While this should not change the final result in successful runs, it can result in unexpected OverflowException for certain sets of pathological inputs.
Version
.NET 8 Preview 7
Previous behavior
The code
Test(GetEnumerable1()); // Non-vectorizable
Test(GetEnumerable1().ToArray()); // Vectorizable
Test(GetEnumerable2()); // Non-vectorizable
Test(GetEnumerable2().ToArray()); // Vectorizable
static IEnumerable<int> GetEnumerable1()
{
for (int i = 0; i < 32; ++i)
{
yield return 1_000_000_000;
yield return -1_000_000_000;
}
}
static IEnumerable<int> GetEnumerable2()
{
for (int i = 0; i < 32; ++i)
{
yield return 100_000_000;
}
for (int i = 0; i < 32; ++i)
{
yield return -100_000_000;
}
}
static void Test(IEnumerable<int> input)
{
try
{
Console.WriteLine(input.Sum());
}
catch (Exception ex)
{
Console.WriteLine(ex.GetType().Name);
}
}Prints
0
0
OverflowException
OverflowException
New behavior
The same code prints
0
OverflowException
OverflowException
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
Taking advantage of vectorization in LINQ APIs.
Recommended action
Assuming your code is impacted by the change, you could either
- Disabling vectorization altogether in your application by setting the
DOTNET_EnableHWIntrinsicenvironment variable to0or - Writing a custom
Summethod that doesn't use vectorization:static int Sum(IEnumerable<int> values) { int acc = 0; foreach (int value in values) { checked { acc += value; } } return acc; }
Feature area
LINQ
Affected APIs
The Enumerable.Sum method group.
Metadata
Metadata
Assignees
Labels
🏁 Release: .NET 8Work items for the .NET 8 releaseWork items for the .NET 8 release📌 seQUESTeredIdentifies that an issue has been imported into Quest.Identifies that an issue has been imported into Quest.breaking-changeIndicates a .NET Core breaking changeIndicates a .NET Core breaking change