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 ^ vecTmp
or (3-b)vec0
in this case - ✅ refer
vecTmp
anywhere ❌ just usevecTmp
to 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
vec0
becomes<0, 0, 0, 0, 0, 0, 0, 0>
data
becomes<-1, -1, -1, -1, -1, -1, -1, -1>
Actual behavior
vec0
becomes<same random value>
data
becomes<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