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

ARM64 Vector2 multiplication breaks in .NET 8 #98137

Closed
NoelFB opened this issue Feb 7, 2024 · 7 comments
Closed

ARM64 Vector2 multiplication breaks in .NET 8 #98137

NoelFB opened this issue Feb 7, 2024 · 7 comments
Assignees
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
Milestone

Comments

@NoelFB
Copy link

NoelFB commented Feb 7, 2024

Description

On Linux and MacOS, various Vector2 floating point multiplications break after running for a few hundred milliseconds.

Running this code in Release Mode on a dotnet new console application on ARM64 results in the Y component of the vector being zero.

using System.Numerics;

while (true)
{
    Thread.Sleep(10);
    Step(4.0f);
}

static void Step(float number)
{
    var variable = Vector2.One * number;
    if (variable.X != variable.Y)
        throw new Exception("Components don't match");
    Console.WriteLine(variable);
}

This does not occur in Debug Mode. If I don't wrap the code in a function (Step) it doesn't seem to happen. If I hard code the floating value (Vector2.One * 4.0f) it doesn't seem to happen.

Reproduction Steps

Simply create a new console project in .NET 8 and run the above code in Program.cs with dotnet run -c Release. After running for a few hundred milliseconds the application will throw an exception.

Expected behavior

Multiplication should always result in <4,4>

Actual behavior

Multiplication results in <4,0> after several hundred milliseconds

Regression?

Does not occur in .NET 7, only .NET 8

Known Workarounds

No response

Configuration

.NET 8, ARM64, MacOS (have had reports of this same problem on ARM64 Linux)

Other information

This has been an issue found in our open source game Celeste 64 for users running the game on ARM64 for both MacOS and Linux. I personally have only tested on MacOS.

@ghost ghost added the untriaged New issue has not been triaged by the area owner label Feb 7, 2024
@ghost
Copy link

ghost commented Feb 7, 2024

Tagging subscribers to this area: @dotnet/area-system-numerics
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

On Linux and MacOS, various Vector2 floating point multiplications break after running for a few hundred milliseconds.

Running this code in Release Mode on a dotnet new console application on ARM64 results in the Y component of the vector being zero.

using System.Numerics;

while (true)
{
    Thread.Sleep(10);
    Step(4.0f);
}

static void Step(float number)
{
    var variable = Vector2.One * number;
    if (variable.X != variable.Y)
        throw new Exception("Components don't match");
}

This does not occur in Debug Mode. If I don't wrap the code in a function (Step) it doesn't seem to happen. If I hard code the floating value (Vector2.One * 4.0f) it doesn't seem to happen.

Reproduction Steps

Simply create a new console project in .NET 8 and run the above code in Program.cs with dotnet run -c Release. After running for a few hundred milliseconds the application will throw an exception.

Expected behavior

Multiplication should always result in <4,4>

Actual behavior

Multiplication results in <4,0> after several hundred milliseconds

Regression?

Does not occur in .NET 7, only .NET 8

Known Workarounds

No response

Configuration

.NET 8, ARM64, MacOS (have had reports of this same problem on ARM64 Linux)

Other information

This has been an issue found in our open source game Celeste 64 for users running the game on ARM64 for both MacOS and Linux. I personally have only tested on MacOS.

Author: NoelFB
Assignees: -
Labels:

area-System.Numerics, untriaged

Milestone: -

@isadorasophia
Copy link

@tannergooding could you help triaging this?

@EgorBo EgorBo added area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI and removed area-System.Numerics labels Feb 8, 2024
@ghost
Copy link

ghost commented Feb 8, 2024

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

On Linux and MacOS, various Vector2 floating point multiplications break after running for a few hundred milliseconds.

Running this code in Release Mode on a dotnet new console application on ARM64 results in the Y component of the vector being zero.

using System.Numerics;

while (true)
{
    Thread.Sleep(10);
    Step(4.0f);
}

static void Step(float number)
{
    var variable = Vector2.One * number;
    if (variable.X != variable.Y)
        throw new Exception("Components don't match");
    Console.WriteLine(variable);
}

This does not occur in Debug Mode. If I don't wrap the code in a function (Step) it doesn't seem to happen. If I hard code the floating value (Vector2.One * 4.0f) it doesn't seem to happen.

Reproduction Steps

Simply create a new console project in .NET 8 and run the above code in Program.cs with dotnet run -c Release. After running for a few hundred milliseconds the application will throw an exception.

Expected behavior

Multiplication should always result in <4,4>

Actual behavior

Multiplication results in <4,0> after several hundred milliseconds

Regression?

Does not occur in .NET 7, only .NET 8

Known Workarounds

No response

Configuration

.NET 8, ARM64, MacOS (have had reports of this same problem on ARM64 Linux)

Other information

This has been an issue found in our open source game Celeste 64 for users running the game on ARM64 for both MacOS and Linux. I personally have only tested on MacOS.

Author: NoelFB
Assignees: -
Labels:

area-CodeGen-coreclr, untriaged

Milestone: -

@tannergooding
Copy link
Member

This was fixed by @jakobbotsch in .NET 9 via #94413, which was fixing a different issue caused by the types of op1/op2 mismatching for MultiplyByScalar (one is a TYP_SIMD16, the other a TYP_SIMD8).

The simple fix should be backporting this PR to .NET 8.


Independently, we should ensure an issue exists to ensure constant folding does work for this scenario and that the correctly typed operand is selected.

@jakobbotsch
Copy link
Member

This was fixed by @jakobbotsch in .NET 9 via #94413, which was fixing a different issue caused by the types of op1/op2 mismatching for MultiplyByScalar (one is a TYP_SIMD16, the other a TYP_SIMD8).

That PR fixed the type mismatch but also deliberately this particular issue, which I noticed while working on the other one (#94413 (comment)).

@theofficialgman
Copy link

theofficialgman commented Feb 9, 2024

Configuration

.NET 8, ARM64, MacOS (have had reports of this same problem on ARM64 Linux)

can confirm running the testcase results in an exception after 77 iterations on arm64 linux

@BruceForstall BruceForstall removed the untriaged New issue has not been triaged by the area owner label Feb 13, 2024
@BruceForstall BruceForstall added this to the 8.0.x milestone Feb 13, 2024
@jakobbotsch
Copy link
Member

The fix is available in the current .NET 8 release.

@github-actions github-actions bot locked and limited conversation to collaborators Jul 6, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
Projects
None yet
Development

No branches or pull requests

7 participants