dotnet / dotnet/runtime

JIT: (bug) Vector128/256<uint> division produces wrong lanes without AVX-512 (blendvpd used for 32-bit correction)

Open
#133,752 1 comment 0 reactions 1 assignee Claimed by @tannergooding View on GitHub
area-CodeGen-coreclr
Dominant language
C#
Stars
18.3k
Forks
5.6k
PR merge metrics
PR metrics pending

Description

### Minimal repro

```csharp
using System;
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;

public static class Program
{
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
public static Vector128 Test(Vector128 l, Vector128 r) => l / r;

public static void Main()
{
Console.WriteLine(Test(Vector128.Create(uint.MaxValue, 9u, 1u, 1u), Vector128.Create(1u, 3u, 1u, 1u)));
}
}
```

### Expected

`<4294967295, 3, 1, 1>`

### Actual

`<2147483648, 3, 1, 1>`

### Notes

Repros on any AVX/AVX2 CPU without AVX-512; on an AVX-512 host set `DOTNET_EnableAVX512=0`. Correct when AVX-512 is available.
The `cvttpd2dq` overflow fixup blends with `blendvpd` (64-bit lanes) over packed 32-bit quotients, so one dword's sign bit controls its neighbour too.
`Vector256` is also wrong and additionally corrupts a correctly-computed neighbour lane: ` / <1,3,1,1,7,1,1,2>` gives `<2147483648,3,1,1,7,4294967295,2147483648,4>` instead of `<4294967295,3,1,1,1,4294967295,3000000000,4>`.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.