Closed
Description
Description
The following code miscompiles in tier1, only if SSE4.1 is not available (DOTNET_EnableSSE41=0
):
[MethodImpl(MethodImplOptions.NoInlining)]
static Vector2 Asdf2(Vector2 totalForce)
{
return Vector2.Dot(totalForce, totalForce) * new Vector2(1, 1);
}
Reproduction Steps
Run this code in release with DOTNET_EnableSSE41=0
:
using System.Numerics;
using System.Runtime.CompilerServices;
public static class Program
{
public static void Main()
{
Vector2? result = null;
while (true)
{
var got = Asdf2(new Vector2(2, 3));
result ??= got;
Console.WriteLine(got);
if (got != result)
throw new InvalidOperationException();
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
static Vector2 Asdf2(Vector2 totalForce)
{
return Vector2.Dot(totalForce, totalForce) * new Vector2(1, 1);
}
}
Expected behavior
Program spins forever printing <13, 13>
Actual behavior
Tiered compilation kicks in and the result changes to <13, 0>
, tripping the exception.
Generated code:
; Assembly listing for method Program:Asdf2(System.Numerics.Vector2):System.Numerics.Vector2 (Tier1)
; Emitting BLENDED_CODE for generic X64 - Windows
; Tier1 code
; optimized code
; rsp based frame
; partially interruptible
; No PGO data
G_M000_IG01: ;; offset=0x0000
movd xmm0, rcx
G_M000_IG02: ;; offset=0x0005
mulps xmm0, xmm0
haddps xmm0, xmm0
movd rax, xmm0
G_M000_IG03: ;; offset=0x0011
ret
; Total bytes of code 18
Regression?
Worked in .NET 7
Known Workarounds
Wrap the Vector2.Dot
call itself in NoInlining
.
Configuration
.NET 8: 8.0.1
OS: Windows 11 and Linux
Architecture: x64
Other information
Discovered through space-wizards/space-station-14#24008