-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
Description
After several calls function argument gets corrupted: it's value gets overwritten by the first field of the first argument.
Reproduction Steps
Compile and run next code in release (the 'scale' parameter of the CreateInclineOrIdentity will swap to 0 at some point):
using System.Numerics;
namespace JitBugReproduce;
internal class Program
{
static void Main()
{
for (int j = 0; j < 10000; j++)
{
CreateInclineOrIdentity(new(), new(), new(), 42);
}
}
public static void CreateInclineOrIdentity(Point2D fixedStart, Point2D fixedEnd, Point2D scalingDirection, float scale)
{
Foo();
PrintSuspiciousArgument(scale); // just print the scale's value
}
internal static void PrintSuspiciousArgument(float probe)
{
Console.Out.Write(probe);
Console.Out.Write(' ');
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
public static void Foo() { }
public readonly struct Point2D
{
private readonly Vector2 _host;
}
}
The project configuration:
[JitFailure.zip](https://github.com/dotnet/runtime/files/13764096/JitFailure.zip)
I've attached the whole project.
Expected behavior
The console full of 42 value.
Actual behavior
A span of zeroes in the console.
Regression?
No response
Known Workarounds
Mark corrupted parameter with the 'in' keyword.
Configuration
Windows 10 (10.0.19045.3803/22H2/2022Update)
AMD Ryzen 7 5800H with Radeon Graphics, 1 CPU, 16 logical and 8 physical cores
.NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
Other information
The problem could be seen in the assembly. This is the function call site:
mov rcx,[rsp+30] ; 1-st argument (Point2D struct)
mov rdx,[rsp+28]; 2-nd argument (Point2D struct)
mov r8,[rsp+20]; 3-nd argument (Point2D struct)
vmovss xmm3,dword ptr [rax+4]; 4-th argument, a float
add rsp,38
jmp qword ptr [7FF8390FE910]; JitBugReproduce.AlongAxisScaling.CreateInclineOrIdentity(JitBugReproduce.Point2D, JitBugReproduce.Point2D, JitBugReproduce.Vector2D, Single)
And here is the function code being JITtered serveral times:
; JitBugReproduce.AlongAxisScaling.CreateInclineOrIdentity(JitBugReproduce.Point2D, JitBugReproduce.Point2D, JitBugReproduce.Vector2D, Single)
; var fixedLine = new Line2D(fixedStart, fixedEnd - fixedStart, FloatExtensions.DefaultEpsilon);
; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
; PrintSuspiciousArgument(scale); // just print the scale's value
; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
; return Identity;
; ^^^^^^^^^^^^^^^^
sub rsp,48
vzeroupper
vmovq xmm3,rcx; here the float value is overwritten by the first argument data
vmovq xmm1,rdx
vmovq xmm2,r8
vmovss dword ptr [rsp+68],xmm3