-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
Description
In .NET8 RC1, some Vector256 code ill function with AggressiveOptimization flags in Release build.
I tried some repro condition to work fine (the below numbers refer in repro code).
Please see minimal repro code.
- ✅ .NET7 or .NET8 RC1 Debug build ❌ .NET8 RC1 Release build
- ✅ remove
AggressiveOptimization❌ enableAggressiveOptimization - ✅ create Vector256 from literal to
vecTmp❌ create Vector256 with runtime value - ✅ use
Vector256<int>.Zero❌ (3-a)vecTmp ^ vecTmpor (3-b)vec0in this case - ✅ refer
vecTmpanywhere ❌ just usevecTmpto create 0 vector
This problem seems to related with using vec ^ vec.
Use Vector256<int>.Zero to 0 vector, other functions look to work fine in my env.
Reproduction Steps
Run this code with .NET8 RC1.
this code simply compare <0,0,0,0,0,0,0,0> and <0,0,0,0,0,0,0,0>, so result should be <-1,-1,-1,-1,-1,-1,-1,-1>
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
// (1) works fine if `MethodImplOptions.AggressiveOptimization` is disabled
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
void Main()
{
var data = new int[] { 0, 0, 0, 0, 0, 0, 0, 0 };
var span = data.AsSpan();
// (2) works fine if replace Random.Shared.Next() to literal
// var vecTmp = Vector256.Create(0x1234);
var vecTmp = Vector256.Create(Random.Shared.Next());
// xor generates 0, however, `vec0` has wrong values after loop.
// (3-a) works fine if use `Vector256<int>.Zero`
// var vec0 = Vector256<int>.Zero;
var vec0 = vecTmp ^ vecTmp;
for (var elementOffset = 0; elementOffset < span.Length; elementOffset += Vector256<int>.Count)
{
var vec = Vector256.LoadUnsafe(ref MemoryMarshal.GetReference(span), (nuint)elementOffset);
// (3-b) data will be OK if use`Vector256<int>.Zero` directly here
var vecIsZero = Vector256.Equals<int>(vec, vec0);
// var vecIsZero = Vector256.Equals<int>(vec, Vector256<int>.Zero);
vecIsZero.StoreUnsafe(ref MemoryMarshal.GetReference(span), (nuint)elementOffset);
}
// (4) works fine if vecTmp is refered
// Console.WriteLine($"{vecTmp}");
// expected: True
// actual : False
Console.WriteLine(vec0.Equals(Vector256<int>.Zero));
// expected: <0, 0, 0, 0, 0, 0, 0, 0>
// actual: <same random value> ... has random values it might be `vecTmp`
Console.WriteLine(vec0);
// expected: <-1, -1, -1, -1, -1, -1, -1, -1>
// actual : <0, 0, 0, 0, 0, 0, 0, 0>
Console.WriteLine(Vector256.Create(data));
}
Main();Expected behavior
vec0becomes<0, 0, 0, 0, 0, 0, 0, 0>databecomes<-1, -1, -1, -1, -1, -1, -1, -1>
Actual behavior
vec0becomes<same random value>databecomes<0, 0, 0, 0, 0, 0, 0, 0>
vec0 seems to be the same to vecTmp, however if observe vecTmp, result becomes expected values
Regression?
yes.
in .NET 7.0.401 or Debug build, it works fine.
(in .csproj <TargetFramework>net7.0</TargetFramework> or <TargetFramework>net8.0</TargetFramework> changes result)
Known Workarounds
No response
Configuration
dotnet --info
.NET SDK:
Version: 8.0.100-rc.1.23455.8
Commit: e14caf947f
OS Name: Windows
OS Version: 10.0.19045
OS Platform: Windows
RID: win-x64
Other information
No response