Skip to content

Inconsistent and counterintuitive codegen behavior of + operator for Vector512<T> depending on the number and order of operands generated by compare instructions, unlike for Vector256<T> #92261

Description

@MineCake147E

Description

When I was playing with the Vector512<T>, I found some inconsistent behavior of + operator for Vector512<byte>, depending on one or more arguments being generated by Vector512.Equals or not.

Both the .NET 7 and .NET 8 RC 1 are doing the right thing for Vector256<byte>:

[MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector256<byte>Test1(Vector256<byte>ymm0,Vector256<byte>ymm1,Vector256<byte>ymm2,Vector256<byte>ymm3)=>Avx2.BlendVariable(ymm0,ymm2,Vector256.Equals(ymm0,ymm1)+Vector256.Equals(ymm2,ymm3));

In .NET 7, it generates:

vzerouppermovrax,qword ptr [rsp+28h]vmovupdymm0,ymmword ptr [rdx]vmovupdymm1,ymmword ptr [r9]vpcmpeqb ymm2,ymm0,ymmword ptr [r8]vpcmpeqb ymm3,ymm1,ymmword ptr [rax]vpaddbymm2,ymm2,ymm3vpblendvbymm0,ymm0,ymm1,ymm2vmovupd ymmword ptr [rcx],ymm0movrax,rcxvzeroupperret

In .NET 8 RC 1, it generates:

vzerouppermovrax,qword ptr [rsp+28h]vmovupsymm0,ymmword ptr [rdx]vmovupsymm1,ymmword ptr [r9]vpcmpeqb ymm2,ymm0,ymmword ptr [r8]vpcmpeqb ymm3,ymm1,ymmword ptr [rax]vpaddbymm2,ymm2,ymm3vpblendvbymm0,ymm0,ymm1,ymm2vmovups ymmword ptr [rcx],ymm0movrax,rcxvzeroupperret

But when it comes to Vector512<byte>, it somehow goes wrong.

[MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));

In .NET 8 RC 1, it generates:

vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpcmpeqb k2,zmm1,zmmword ptr [rax]kaddq k1,k1,k2 ; WRONG INSTRUCTION!vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

While what I expect it to generate looks like:

vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

And even weirder, if I add Vector512<byte>.Zero in advance of adding second operand, like:

[MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

It generates what I expect it to generate from Test512Blend:

vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

Adding the Vector512<T>.Zero MUST NOT alter the result of the whole integer + operation.

Reproduction Steps

  1. Obtain a JIT assembly for the codes below with .NET 8 RC 1:
[MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector256<byte>Test1(Vector256<byte>ymm0,Vector256<byte>ymm1,Vector256<byte>ymm2,Vector256<byte>ymm3)=>Avx2.BlendVariable(ymm0,ymm2,Vector256.Equals(ymm0,ymm1)+Vector256.Equals(ymm2,ymm3));
[MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));
[MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

Expected behavior

The code:

[MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));

and

[MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

For both functions, it should generate something like:

vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

Actual behavior

For the code:

[MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));

It instead generates something like:

vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpcmpeqb k2,zmm1,zmmword ptr [rax]kaddq k1,k1,k2 vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

Regression?

Unknown

Known Workarounds

By adding Vector512<T>.Zero in advance of adding second operand, like:

[MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

It generates:

vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

Configuration

  • .NET version: 8.0.100-rc.1.23455.8
  • PC: Custom built PC
    • OS: Windows 11 Home 22H2 (22621.2283)
    • CPU: Intel(R) Xeon(R) w5-2455X 3.19 GHz
    • RAM: 32 GB DDR5 ECC RDIMM
    • Graphics: NVIDIA GeForce GTX1060(6 GB)
    • Storage:
      • OS(C:) : WD_BLACK SN770 1TB PCIe 4.0 NVMe M.2 SSD
      • DATA (D:) : Western Digital WDC WD10EZEX-22MFCA0 1000.2 GB 7200RPM SATA HDD
      • WORKSPACE (E:) : Seagate ST1000DM003-1ER162 1000.2 GB 7200RPM SATA HDD
Visual Studio 2022 installation

Microsoft Visual Studio Community 2022
Version 17.8.0 Preview 2.0
VisualStudio.17.Preview/17.8.0-pre.2.0+34112.27
Microsoft .NET Framework
Version 4.8.09032

インストールされているバージョン:Community

Visual C++ 2022 00482-90000-00000-AA248
Microsoft Visual C++ 2022

ASP.NET and Web Tools 17.8.226.21692
ASP.NET and Web Tools

AvaloniaPackage Extension 1.0
AvaloniaPackage Visual Studio Extension Detailed Info

Azure App Service Tools v3.0.0 17.8.226.21692
Azure App Service Tools v3.0.0

Azure Functions and Web Jobs Tools 17.8.226.21692
Azure Functions and Web Jobs Tools

C# ツール 4.8.0-2.23429.7+44555193fd1135b5d53a2099f76fec91e0d1ebde
IDE で使用する C# コンポーネント。プロジェクトの種類や設定に応じて、異なるバージョンのコンパイラを使用できます。

Code Cleanup On Save 1.0.12
Automatically run one of the Code Clean profiles when saving the document. This ensures your code is always formatted correctly and follows your coding style conventions.

Common Azure Tools 1.10
Provides common services for use by Azure Mobile Services and Microsoft Azure Tools.

Extensibility Message Bus 1.4.39 (main@e8108eb)
Provides common messaging-based MEF services for loosely coupled Visual Studio extension components communication and integration.

File Icons 2.7
Adds icons for files that are not recognized by Solution Explorer

Microsoft JVM Debugger 1.0
Provides support for connecting the Visual Studio debugger to JDWP compatible Java Virtual Machines

Mono Debugging for Visual Studio 17.8.14 (0c9914e)
Support for debugging Mono processes with Visual Studio.

NuGet パッケージ マネージャー 6.8.0
Visual Studio 内の NuGet パッケージ マネージャー。NuGet の詳細については、https://docs.nuget.org/ にアクセスしてください

Razor (ASP.NET Core) 17.8.2.2345506+ade90399d42c1a7bf92191b1c067816c0ae1c311
ASP.NET Core Razor の言語サービスを提供します。

SonarLint for Visual Studio 7.3.0.77872
SonarLint is an extension to your favorite IDE that provides on-the-fly feedback to developers on new bugs and quality issues injected into their code.

SQL Server Data Tools 17.8.64.0
Microsoft SQL Server Data Tools

Tweaks 2022 1.1.143
A collection of minor fixes and tweaks for Visual Studio to reduce the paper cuts and make you a happier developer

TypeScript Tools 17.0.20830.2001
TypeScript Tools for Microsoft Visual Studio

Visual Basic ツール 4.8.0-2.23429.7+44555193fd1135b5d53a2099f76fec91e0d1ebde
IDE で使用する Visual Basic コンポーネント。プロジェクトの種類や設定に応じて、異なるバージョンのコンパイラを使用できます。

Visual F# Tools 17.8.0-beta.23425.10+0d3549fa5b8b6387ade191d76768405cefed8229
Microsoft Visual F# Tools

Visual Studio IntelliCode 2.2
Visual Studio 向けの AI 支援付き開発。

VisualStudio.DeviceLog 1.0
パッケージに関する情報

VisualStudio.Mac 1.0
Mac Extension for Visual Studio

Xamarin 17.8.0.118 (main@35c256f)
Xamarin.iOS と Xamarin.Android の開発を有効にする Visual Studio 拡張機能

Xamarin Designer 17.8.1.11 (remotes/origin/d17-8@13ef934098)
Visual Studio で Xamarin Designer ツールを有効にするための Visual Studio 拡張機能。

Xamarin Templates 17.8.16 (830b56a)
Templates for building iOS, Android, and Windows apps with Xamarin and Xamarin.Forms.

Xamarin.Android SDK 13.2.1.2 (d17-5/a8a26c7)
Xamarin.Android Reference Assemblies and MSBuild support.
Mono: d9a6e87
Java.Interop: xamarin/java.interop/d17-5@149d70fe
SQLite: xamarin/sqlite@68c69d8
Xamarin.Android Tools: xamarin/xamarin-android-tools/d17-5@ca1552d

Xamarin.iOS and Xamarin.Mac SDK 16.4.0.16 (b5972410d)
Xamarin.iOS and Xamarin.Mac Reference Assemblies and MSBuild support.

Other information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIavx512Related to the AVX-512 architecture

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      , 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
       blocks
      (function() {
      function addCopyButtons() {
      document.querySelectorAll('pre code').forEach(function(codeBlock) {
      if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
      codeBlock.parentElement.setAttribute('data-copy-added', 'true');
      var btn = document.createElement('button');
      btn.textContent = 'Copy';
      btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
      btn.onmouseover = function() { this.style.opacity = '1'; };
      btn.onmouseout = function() { this.style.opacity = '0.7'; };
      btn.onclick = function() {
      navigator.clipboard.writeText(codeBlock.textContent).then(function() {
      btn.textContent = 'Copied!';
      setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
      });
      };
      codeBlock.parentElement.style.position = 'relative';
      codeBlock.parentElement.appendChild(btn);
      });
      }
      addCopyButtons();
      // Re-run on dynamic content
      var observer = new MutationObserver(addCopyButtons);
      observer.observe(document.body, { childList: true, subtree: true });
      })();
      }
      } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
      })();
      (function(){
      try {
      var __m = "github.com";
      var __re = new RegExp('^' + "github\\.com" + '
      Inconsistent and counterintuitive codegen behavior of `+` operator for `Vector512<T>` depending on the number and order of operands generated by compare instructions, unlike for `Vector256<T>` · Issue #92261 · dotnet/runtime · GitHub
      Skip to content

      Inconsistent and counterintuitive codegen behavior of + operator for Vector512<T> depending on the number and order of operands generated by compare instructions, unlike for Vector256<T> #92261

      Description

      @MineCake147E

      Description

      When I was playing with the Vector512<T>, I found some inconsistent behavior of + operator for Vector512<byte>, depending on one or more arguments being generated by Vector512.Equals or not.

      Both the .NET 7 and .NET 8 RC 1 are doing the right thing for Vector256<byte>:

      [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector256<byte>Test1(Vector256<byte>ymm0,Vector256<byte>ymm1,Vector256<byte>ymm2,Vector256<byte>ymm3)=>Avx2.BlendVariable(ymm0,ymm2,Vector256.Equals(ymm0,ymm1)+Vector256.Equals(ymm2,ymm3));

      In .NET 7, it generates:

      vzerouppermovrax,qword ptr [rsp+28h]vmovupdymm0,ymmword ptr [rdx]vmovupdymm1,ymmword ptr [r9]vpcmpeqb ymm2,ymm0,ymmword ptr [r8]vpcmpeqb ymm3,ymm1,ymmword ptr [rax]vpaddbymm2,ymm2,ymm3vpblendvbymm0,ymm0,ymm1,ymm2vmovupd ymmword ptr [rcx],ymm0movrax,rcxvzeroupperret

      In .NET 8 RC 1, it generates:

      vzerouppermovrax,qword ptr [rsp+28h]vmovupsymm0,ymmword ptr [rdx]vmovupsymm1,ymmword ptr [r9]vpcmpeqb ymm2,ymm0,ymmword ptr [r8]vpcmpeqb ymm3,ymm1,ymmword ptr [rax]vpaddbymm2,ymm2,ymm3vpblendvbymm0,ymm0,ymm1,ymm2vmovups ymmword ptr [rcx],ymm0movrax,rcxvzeroupperret

      But when it comes to Vector512<byte>, it somehow goes wrong.

      [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));

      In .NET 8 RC 1, it generates:

      vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpcmpeqb k2,zmm1,zmmword ptr [rax]kaddq k1,k1,k2 ; WRONG INSTRUCTION!vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

      While what I expect it to generate looks like:

      vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

      And even weirder, if I add Vector512<byte>.Zero in advance of adding second operand, like:

      [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

      It generates what I expect it to generate from Test512Blend:

      vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

      Adding the Vector512<T>.Zero MUST NOT alter the result of the whole integer + operation.

      Reproduction Steps

      1. Obtain a JIT assembly for the codes below with .NET 8 RC 1:
      [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector256<byte>Test1(Vector256<byte>ymm0,Vector256<byte>ymm1,Vector256<byte>ymm2,Vector256<byte>ymm3)=>Avx2.BlendVariable(ymm0,ymm2,Vector256.Equals(ymm0,ymm1)+Vector256.Equals(ymm2,ymm3));
      [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));
      [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

      Expected behavior

      The code:

      [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));

      and

      [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

      For both functions, it should generate something like:

      vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

      Actual behavior

      For the code:

      [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));

      It instead generates something like:

      vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpcmpeqb k2,zmm1,zmmword ptr [rax]kaddq k1,k1,k2 vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

      Regression?

      Unknown

      Known Workarounds

      By adding Vector512<T>.Zero in advance of adding second operand, like:

      [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

      It generates:

      vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

      Configuration

      • .NET version: 8.0.100-rc.1.23455.8
      • PC: Custom built PC
        • OS: Windows 11 Home 22H2 (22621.2283)
        • CPU: Intel(R) Xeon(R) w5-2455X 3.19 GHz
        • RAM: 32 GB DDR5 ECC RDIMM
        • Graphics: NVIDIA GeForce GTX1060(6 GB)
        • Storage:
          • OS(C:) : WD_BLACK SN770 1TB PCIe 4.0 NVMe M.2 SSD
          • DATA (D:) : Western Digital WDC WD10EZEX-22MFCA0 1000.2 GB 7200RPM SATA HDD
          • WORKSPACE (E:) : Seagate ST1000DM003-1ER162 1000.2 GB 7200RPM SATA HDD
      Visual Studio 2022 installation

      Microsoft Visual Studio Community 2022
      Version 17.8.0 Preview 2.0
      VisualStudio.17.Preview/17.8.0-pre.2.0+34112.27
      Microsoft .NET Framework
      Version 4.8.09032

      インストールされているバージョン:Community

      Visual C++ 2022 00482-90000-00000-AA248
      Microsoft Visual C++ 2022

      ASP.NET and Web Tools 17.8.226.21692
      ASP.NET and Web Tools

      AvaloniaPackage Extension 1.0
      AvaloniaPackage Visual Studio Extension Detailed Info

      Azure App Service Tools v3.0.0 17.8.226.21692
      Azure App Service Tools v3.0.0

      Azure Functions and Web Jobs Tools 17.8.226.21692
      Azure Functions and Web Jobs Tools

      C# ツール 4.8.0-2.23429.7+44555193fd1135b5d53a2099f76fec91e0d1ebde
      IDE で使用する C# コンポーネント。プロジェクトの種類や設定に応じて、異なるバージョンのコンパイラを使用できます。

      Code Cleanup On Save 1.0.12
      Automatically run one of the Code Clean profiles when saving the document. This ensures your code is always formatted correctly and follows your coding style conventions.

      Common Azure Tools 1.10
      Provides common services for use by Azure Mobile Services and Microsoft Azure Tools.

      Extensibility Message Bus 1.4.39 (main@e8108eb)
      Provides common messaging-based MEF services for loosely coupled Visual Studio extension components communication and integration.

      File Icons 2.7
      Adds icons for files that are not recognized by Solution Explorer

      Microsoft JVM Debugger 1.0
      Provides support for connecting the Visual Studio debugger to JDWP compatible Java Virtual Machines

      Mono Debugging for Visual Studio 17.8.14 (0c9914e)
      Support for debugging Mono processes with Visual Studio.

      NuGet パッケージ マネージャー 6.8.0
      Visual Studio 内の NuGet パッケージ マネージャー。NuGet の詳細については、https://docs.nuget.org/ にアクセスしてください

      Razor (ASP.NET Core) 17.8.2.2345506+ade90399d42c1a7bf92191b1c067816c0ae1c311
      ASP.NET Core Razor の言語サービスを提供します。

      SonarLint for Visual Studio 7.3.0.77872
      SonarLint is an extension to your favorite IDE that provides on-the-fly feedback to developers on new bugs and quality issues injected into their code.

      SQL Server Data Tools 17.8.64.0
      Microsoft SQL Server Data Tools

      Tweaks 2022 1.1.143
      A collection of minor fixes and tweaks for Visual Studio to reduce the paper cuts and make you a happier developer

      TypeScript Tools 17.0.20830.2001
      TypeScript Tools for Microsoft Visual Studio

      Visual Basic ツール 4.8.0-2.23429.7+44555193fd1135b5d53a2099f76fec91e0d1ebde
      IDE で使用する Visual Basic コンポーネント。プロジェクトの種類や設定に応じて、異なるバージョンのコンパイラを使用できます。

      Visual F# Tools 17.8.0-beta.23425.10+0d3549fa5b8b6387ade191d76768405cefed8229
      Microsoft Visual F# Tools

      Visual Studio IntelliCode 2.2
      Visual Studio 向けの AI 支援付き開発。

      VisualStudio.DeviceLog 1.0
      パッケージに関する情報

      VisualStudio.Mac 1.0
      Mac Extension for Visual Studio

      Xamarin 17.8.0.118 (main@35c256f)
      Xamarin.iOS と Xamarin.Android の開発を有効にする Visual Studio 拡張機能

      Xamarin Designer 17.8.1.11 (remotes/origin/d17-8@13ef934098)
      Visual Studio で Xamarin Designer ツールを有効にするための Visual Studio 拡張機能。

      Xamarin Templates 17.8.16 (830b56a)
      Templates for building iOS, Android, and Windows apps with Xamarin and Xamarin.Forms.

      Xamarin.Android SDK 13.2.1.2 (d17-5/a8a26c7)
      Xamarin.Android Reference Assemblies and MSBuild support.
      Mono: d9a6e87
      Java.Interop: xamarin/java.interop/d17-5@149d70fe
      SQLite: xamarin/sqlite@68c69d8
      Xamarin.Android Tools: xamarin/xamarin-android-tools/d17-5@ca1552d

      Xamarin.iOS and Xamarin.Mac SDK 16.4.0.16 (b5972410d)
      Xamarin.iOS and Xamarin.Mac Reference Assemblies and MSBuild support.

      Other information

      No response

      Metadata

      Metadata

      Assignees

      No one assigned

        Labels

        area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIavx512Related to the AVX-512 architecture

        Type

        No type

        Projects

        No projects

          Milestone

          No milestone

          Relationships

          None yet

          Development

          No branches or pull requests

          Issue actions

          , 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Inconsistent and counterintuitive codegen behavior of `+` operator for `Vector512<T>` depending on the number and order of operands generated by compare instructions, unlike for `Vector256<T>` · Issue #92261 · dotnet/runtime · GitHub
          Skip to content

          Inconsistent and counterintuitive codegen behavior of + operator for Vector512<T> depending on the number and order of operands generated by compare instructions, unlike for Vector256<T> #92261

          Description

          @MineCake147E

          Description

          When I was playing with the Vector512<T>, I found some inconsistent behavior of + operator for Vector512<byte>, depending on one or more arguments being generated by Vector512.Equals or not.

          Both the .NET 7 and .NET 8 RC 1 are doing the right thing for Vector256<byte>:

          [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector256<byte>Test1(Vector256<byte>ymm0,Vector256<byte>ymm1,Vector256<byte>ymm2,Vector256<byte>ymm3)=>Avx2.BlendVariable(ymm0,ymm2,Vector256.Equals(ymm0,ymm1)+Vector256.Equals(ymm2,ymm3));

          In .NET 7, it generates:

          vzerouppermovrax,qword ptr [rsp+28h]vmovupdymm0,ymmword ptr [rdx]vmovupdymm1,ymmword ptr [r9]vpcmpeqb ymm2,ymm0,ymmword ptr [r8]vpcmpeqb ymm3,ymm1,ymmword ptr [rax]vpaddbymm2,ymm2,ymm3vpblendvbymm0,ymm0,ymm1,ymm2vmovupd ymmword ptr [rcx],ymm0movrax,rcxvzeroupperret

          In .NET 8 RC 1, it generates:

          vzerouppermovrax,qword ptr [rsp+28h]vmovupsymm0,ymmword ptr [rdx]vmovupsymm1,ymmword ptr [r9]vpcmpeqb ymm2,ymm0,ymmword ptr [r8]vpcmpeqb ymm3,ymm1,ymmword ptr [rax]vpaddbymm2,ymm2,ymm3vpblendvbymm0,ymm0,ymm1,ymm2vmovups ymmword ptr [rcx],ymm0movrax,rcxvzeroupperret

          But when it comes to Vector512<byte>, it somehow goes wrong.

          [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));

          In .NET 8 RC 1, it generates:

          vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpcmpeqb k2,zmm1,zmmword ptr [rax]kaddq k1,k1,k2 ; WRONG INSTRUCTION!vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

          While what I expect it to generate looks like:

          vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

          And even weirder, if I add Vector512<byte>.Zero in advance of adding second operand, like:

          [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

          It generates what I expect it to generate from Test512Blend:

          vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

          Adding the Vector512<T>.Zero MUST NOT alter the result of the whole integer + operation.

          Reproduction Steps

          1. Obtain a JIT assembly for the codes below with .NET 8 RC 1:
          [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector256<byte>Test1(Vector256<byte>ymm0,Vector256<byte>ymm1,Vector256<byte>ymm2,Vector256<byte>ymm3)=>Avx2.BlendVariable(ymm0,ymm2,Vector256.Equals(ymm0,ymm1)+Vector256.Equals(ymm2,ymm3));
          [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));
          [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

          Expected behavior

          The code:

          [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));

          and

          [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

          For both functions, it should generate something like:

          vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

          Actual behavior

          For the code:

          [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));

          It instead generates something like:

          vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpcmpeqb k2,zmm1,zmmword ptr [rax]kaddq k1,k1,k2 vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

          Regression?

          Unknown

          Known Workarounds

          By adding Vector512<T>.Zero in advance of adding second operand, like:

          [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

          It generates:

          vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

          Configuration

          • .NET version: 8.0.100-rc.1.23455.8
          • PC: Custom built PC
            • OS: Windows 11 Home 22H2 (22621.2283)
            • CPU: Intel(R) Xeon(R) w5-2455X 3.19 GHz
            • RAM: 32 GB DDR5 ECC RDIMM
            • Graphics: NVIDIA GeForce GTX1060(6 GB)
            • Storage:
              • OS(C:) : WD_BLACK SN770 1TB PCIe 4.0 NVMe M.2 SSD
              • DATA (D:) : Western Digital WDC WD10EZEX-22MFCA0 1000.2 GB 7200RPM SATA HDD
              • WORKSPACE (E:) : Seagate ST1000DM003-1ER162 1000.2 GB 7200RPM SATA HDD
          Visual Studio 2022 installation

          Microsoft Visual Studio Community 2022
          Version 17.8.0 Preview 2.0
          VisualStudio.17.Preview/17.8.0-pre.2.0+34112.27
          Microsoft .NET Framework
          Version 4.8.09032

          インストールされているバージョン:Community

          Visual C++ 2022 00482-90000-00000-AA248
          Microsoft Visual C++ 2022

          ASP.NET and Web Tools 17.8.226.21692
          ASP.NET and Web Tools

          AvaloniaPackage Extension 1.0
          AvaloniaPackage Visual Studio Extension Detailed Info

          Azure App Service Tools v3.0.0 17.8.226.21692
          Azure App Service Tools v3.0.0

          Azure Functions and Web Jobs Tools 17.8.226.21692
          Azure Functions and Web Jobs Tools

          C# ツール 4.8.0-2.23429.7+44555193fd1135b5d53a2099f76fec91e0d1ebde
          IDE で使用する C# コンポーネント。プロジェクトの種類や設定に応じて、異なるバージョンのコンパイラを使用できます。

          Code Cleanup On Save 1.0.12
          Automatically run one of the Code Clean profiles when saving the document. This ensures your code is always formatted correctly and follows your coding style conventions.

          Common Azure Tools 1.10
          Provides common services for use by Azure Mobile Services and Microsoft Azure Tools.

          Extensibility Message Bus 1.4.39 (main@e8108eb)
          Provides common messaging-based MEF services for loosely coupled Visual Studio extension components communication and integration.

          File Icons 2.7
          Adds icons for files that are not recognized by Solution Explorer

          Microsoft JVM Debugger 1.0
          Provides support for connecting the Visual Studio debugger to JDWP compatible Java Virtual Machines

          Mono Debugging for Visual Studio 17.8.14 (0c9914e)
          Support for debugging Mono processes with Visual Studio.

          NuGet パッケージ マネージャー 6.8.0
          Visual Studio 内の NuGet パッケージ マネージャー。NuGet の詳細については、https://docs.nuget.org/ にアクセスしてください

          Razor (ASP.NET Core) 17.8.2.2345506+ade90399d42c1a7bf92191b1c067816c0ae1c311
          ASP.NET Core Razor の言語サービスを提供します。

          SonarLint for Visual Studio 7.3.0.77872
          SonarLint is an extension to your favorite IDE that provides on-the-fly feedback to developers on new bugs and quality issues injected into their code.

          SQL Server Data Tools 17.8.64.0
          Microsoft SQL Server Data Tools

          Tweaks 2022 1.1.143
          A collection of minor fixes and tweaks for Visual Studio to reduce the paper cuts and make you a happier developer

          TypeScript Tools 17.0.20830.2001
          TypeScript Tools for Microsoft Visual Studio

          Visual Basic ツール 4.8.0-2.23429.7+44555193fd1135b5d53a2099f76fec91e0d1ebde
          IDE で使用する Visual Basic コンポーネント。プロジェクトの種類や設定に応じて、異なるバージョンのコンパイラを使用できます。

          Visual F# Tools 17.8.0-beta.23425.10+0d3549fa5b8b6387ade191d76768405cefed8229
          Microsoft Visual F# Tools

          Visual Studio IntelliCode 2.2
          Visual Studio 向けの AI 支援付き開発。

          VisualStudio.DeviceLog 1.0
          パッケージに関する情報

          VisualStudio.Mac 1.0
          Mac Extension for Visual Studio

          Xamarin 17.8.0.118 (main@35c256f)
          Xamarin.iOS と Xamarin.Android の開発を有効にする Visual Studio 拡張機能

          Xamarin Designer 17.8.1.11 (remotes/origin/d17-8@13ef934098)
          Visual Studio で Xamarin Designer ツールを有効にするための Visual Studio 拡張機能。

          Xamarin Templates 17.8.16 (830b56a)
          Templates for building iOS, Android, and Windows apps with Xamarin and Xamarin.Forms.

          Xamarin.Android SDK 13.2.1.2 (d17-5/a8a26c7)
          Xamarin.Android Reference Assemblies and MSBuild support.
          Mono: d9a6e87
          Java.Interop: xamarin/java.interop/d17-5@149d70fe
          SQLite: xamarin/sqlite@68c69d8
          Xamarin.Android Tools: xamarin/xamarin-android-tools/d17-5@ca1552d

          Xamarin.iOS and Xamarin.Mac SDK 16.4.0.16 (b5972410d)
          Xamarin.iOS and Xamarin.Mac Reference Assemblies and MSBuild support.

          Other information

          No response

          Metadata

          Metadata

          Assignees

          No one assigned

            Labels

            area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIavx512Related to the AVX-512 architecture

            Type

            No type

            Projects

            No projects

              Milestone

              No milestone

              Relationships

              None yet

              Development

              No branches or pull requests

              Issue actions

              , 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Inconsistent and counterintuitive codegen behavior of `+` operator for `Vector512<T>` depending on the number and order of operands generated by compare instructions, unlike for `Vector256<T>` · Issue #92261 · dotnet/runtime · GitHub
              Skip to content

              Inconsistent and counterintuitive codegen behavior of + operator for Vector512<T> depending on the number and order of operands generated by compare instructions, unlike for Vector256<T> #92261

              Description

              @MineCake147E

              Description

              When I was playing with the Vector512<T>, I found some inconsistent behavior of + operator for Vector512<byte>, depending on one or more arguments being generated by Vector512.Equals or not.

              Both the .NET 7 and .NET 8 RC 1 are doing the right thing for Vector256<byte>:

              [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector256<byte>Test1(Vector256<byte>ymm0,Vector256<byte>ymm1,Vector256<byte>ymm2,Vector256<byte>ymm3)=>Avx2.BlendVariable(ymm0,ymm2,Vector256.Equals(ymm0,ymm1)+Vector256.Equals(ymm2,ymm3));

              In .NET 7, it generates:

              vzerouppermovrax,qword ptr [rsp+28h]vmovupdymm0,ymmword ptr [rdx]vmovupdymm1,ymmword ptr [r9]vpcmpeqb ymm2,ymm0,ymmword ptr [r8]vpcmpeqb ymm3,ymm1,ymmword ptr [rax]vpaddbymm2,ymm2,ymm3vpblendvbymm0,ymm0,ymm1,ymm2vmovupd ymmword ptr [rcx],ymm0movrax,rcxvzeroupperret

              In .NET 8 RC 1, it generates:

              vzerouppermovrax,qword ptr [rsp+28h]vmovupsymm0,ymmword ptr [rdx]vmovupsymm1,ymmword ptr [r9]vpcmpeqb ymm2,ymm0,ymmword ptr [r8]vpcmpeqb ymm3,ymm1,ymmword ptr [rax]vpaddbymm2,ymm2,ymm3vpblendvbymm0,ymm0,ymm1,ymm2vmovups ymmword ptr [rcx],ymm0movrax,rcxvzeroupperret

              But when it comes to Vector512<byte>, it somehow goes wrong.

              [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));

              In .NET 8 RC 1, it generates:

              vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpcmpeqb k2,zmm1,zmmword ptr [rax]kaddq k1,k1,k2 ; WRONG INSTRUCTION!vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

              While what I expect it to generate looks like:

              vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

              And even weirder, if I add Vector512<byte>.Zero in advance of adding second operand, like:

              [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

              It generates what I expect it to generate from Test512Blend:

              vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

              Adding the Vector512<T>.Zero MUST NOT alter the result of the whole integer + operation.

              Reproduction Steps

              1. Obtain a JIT assembly for the codes below with .NET 8 RC 1:
              [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector256<byte>Test1(Vector256<byte>ymm0,Vector256<byte>ymm1,Vector256<byte>ymm2,Vector256<byte>ymm3)=>Avx2.BlendVariable(ymm0,ymm2,Vector256.Equals(ymm0,ymm1)+Vector256.Equals(ymm2,ymm3));
              [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));
              [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

              Expected behavior

              The code:

              [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));

              and

              [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

              For both functions, it should generate something like:

              vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

              Actual behavior

              For the code:

              [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));

              It instead generates something like:

              vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpcmpeqb k2,zmm1,zmmword ptr [rax]kaddq k1,k1,k2 vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

              Regression?

              Unknown

              Known Workarounds

              By adding Vector512<T>.Zero in advance of adding second operand, like:

              [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

              It generates:

              vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

              Configuration

              • .NET version: 8.0.100-rc.1.23455.8
              • PC: Custom built PC
                • OS: Windows 11 Home 22H2 (22621.2283)
                • CPU: Intel(R) Xeon(R) w5-2455X 3.19 GHz
                • RAM: 32 GB DDR5 ECC RDIMM
                • Graphics: NVIDIA GeForce GTX1060(6 GB)
                • Storage:
                  • OS(C:) : WD_BLACK SN770 1TB PCIe 4.0 NVMe M.2 SSD
                  • DATA (D:) : Western Digital WDC WD10EZEX-22MFCA0 1000.2 GB 7200RPM SATA HDD
                  • WORKSPACE (E:) : Seagate ST1000DM003-1ER162 1000.2 GB 7200RPM SATA HDD
              Visual Studio 2022 installation

              Microsoft Visual Studio Community 2022
              Version 17.8.0 Preview 2.0
              VisualStudio.17.Preview/17.8.0-pre.2.0+34112.27
              Microsoft .NET Framework
              Version 4.8.09032

              インストールされているバージョン:Community

              Visual C++ 2022 00482-90000-00000-AA248
              Microsoft Visual C++ 2022

              ASP.NET and Web Tools 17.8.226.21692
              ASP.NET and Web Tools

              AvaloniaPackage Extension 1.0
              AvaloniaPackage Visual Studio Extension Detailed Info

              Azure App Service Tools v3.0.0 17.8.226.21692
              Azure App Service Tools v3.0.0

              Azure Functions and Web Jobs Tools 17.8.226.21692
              Azure Functions and Web Jobs Tools

              C# ツール 4.8.0-2.23429.7+44555193fd1135b5d53a2099f76fec91e0d1ebde
              IDE で使用する C# コンポーネント。プロジェクトの種類や設定に応じて、異なるバージョンのコンパイラを使用できます。

              Code Cleanup On Save 1.0.12
              Automatically run one of the Code Clean profiles when saving the document. This ensures your code is always formatted correctly and follows your coding style conventions.

              Common Azure Tools 1.10
              Provides common services for use by Azure Mobile Services and Microsoft Azure Tools.

              Extensibility Message Bus 1.4.39 (main@e8108eb)
              Provides common messaging-based MEF services for loosely coupled Visual Studio extension components communication and integration.

              File Icons 2.7
              Adds icons for files that are not recognized by Solution Explorer

              Microsoft JVM Debugger 1.0
              Provides support for connecting the Visual Studio debugger to JDWP compatible Java Virtual Machines

              Mono Debugging for Visual Studio 17.8.14 (0c9914e)
              Support for debugging Mono processes with Visual Studio.

              NuGet パッケージ マネージャー 6.8.0
              Visual Studio 内の NuGet パッケージ マネージャー。NuGet の詳細については、https://docs.nuget.org/ にアクセスしてください

              Razor (ASP.NET Core) 17.8.2.2345506+ade90399d42c1a7bf92191b1c067816c0ae1c311
              ASP.NET Core Razor の言語サービスを提供します。

              SonarLint for Visual Studio 7.3.0.77872
              SonarLint is an extension to your favorite IDE that provides on-the-fly feedback to developers on new bugs and quality issues injected into their code.

              SQL Server Data Tools 17.8.64.0
              Microsoft SQL Server Data Tools

              Tweaks 2022 1.1.143
              A collection of minor fixes and tweaks for Visual Studio to reduce the paper cuts and make you a happier developer

              TypeScript Tools 17.0.20830.2001
              TypeScript Tools for Microsoft Visual Studio

              Visual Basic ツール 4.8.0-2.23429.7+44555193fd1135b5d53a2099f76fec91e0d1ebde
              IDE で使用する Visual Basic コンポーネント。プロジェクトの種類や設定に応じて、異なるバージョンのコンパイラを使用できます。

              Visual F# Tools 17.8.0-beta.23425.10+0d3549fa5b8b6387ade191d76768405cefed8229
              Microsoft Visual F# Tools

              Visual Studio IntelliCode 2.2
              Visual Studio 向けの AI 支援付き開発。

              VisualStudio.DeviceLog 1.0
              パッケージに関する情報

              VisualStudio.Mac 1.0
              Mac Extension for Visual Studio

              Xamarin 17.8.0.118 (main@35c256f)
              Xamarin.iOS と Xamarin.Android の開発を有効にする Visual Studio 拡張機能

              Xamarin Designer 17.8.1.11 (remotes/origin/d17-8@13ef934098)
              Visual Studio で Xamarin Designer ツールを有効にするための Visual Studio 拡張機能。

              Xamarin Templates 17.8.16 (830b56a)
              Templates for building iOS, Android, and Windows apps with Xamarin and Xamarin.Forms.

              Xamarin.Android SDK 13.2.1.2 (d17-5/a8a26c7)
              Xamarin.Android Reference Assemblies and MSBuild support.
              Mono: d9a6e87
              Java.Interop: xamarin/java.interop/d17-5@149d70fe
              SQLite: xamarin/sqlite@68c69d8
              Xamarin.Android Tools: xamarin/xamarin-android-tools/d17-5@ca1552d

              Xamarin.iOS and Xamarin.Mac SDK 16.4.0.16 (b5972410d)
              Xamarin.iOS and Xamarin.Mac Reference Assemblies and MSBuild support.

              Other information

              No response

              Metadata

              Metadata

              Assignees

              No one assigned

                Labels

                area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIavx512Related to the AVX-512 architecture

                Type

                No type

                Projects

                No projects

                  Milestone

                  No milestone

                  Relationships

                  None yet

                  Development

                  No branches or pull requests

                  Issue actions

                  , 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Inconsistent and counterintuitive codegen behavior of `+` operator for `Vector512<T>` depending on the number and order of operands generated by compare instructions, unlike for `Vector256<T>` · Issue #92261 · dotnet/runtime · GitHub
                  Skip to content

                  Inconsistent and counterintuitive codegen behavior of + operator for Vector512<T> depending on the number and order of operands generated by compare instructions, unlike for Vector256<T> #92261

                  Description

                  @MineCake147E

                  Description

                  When I was playing with the Vector512<T>, I found some inconsistent behavior of + operator for Vector512<byte>, depending on one or more arguments being generated by Vector512.Equals or not.

                  Both the .NET 7 and .NET 8 RC 1 are doing the right thing for Vector256<byte>:

                  [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector256<byte>Test1(Vector256<byte>ymm0,Vector256<byte>ymm1,Vector256<byte>ymm2,Vector256<byte>ymm3)=>Avx2.BlendVariable(ymm0,ymm2,Vector256.Equals(ymm0,ymm1)+Vector256.Equals(ymm2,ymm3));

                  In .NET 7, it generates:

                  vzerouppermovrax,qword ptr [rsp+28h]vmovupdymm0,ymmword ptr [rdx]vmovupdymm1,ymmword ptr [r9]vpcmpeqb ymm2,ymm0,ymmword ptr [r8]vpcmpeqb ymm3,ymm1,ymmword ptr [rax]vpaddbymm2,ymm2,ymm3vpblendvbymm0,ymm0,ymm1,ymm2vmovupd ymmword ptr [rcx],ymm0movrax,rcxvzeroupperret

                  In .NET 8 RC 1, it generates:

                  vzerouppermovrax,qword ptr [rsp+28h]vmovupsymm0,ymmword ptr [rdx]vmovupsymm1,ymmword ptr [r9]vpcmpeqb ymm2,ymm0,ymmword ptr [r8]vpcmpeqb ymm3,ymm1,ymmword ptr [rax]vpaddbymm2,ymm2,ymm3vpblendvbymm0,ymm0,ymm1,ymm2vmovups ymmword ptr [rcx],ymm0movrax,rcxvzeroupperret

                  But when it comes to Vector512<byte>, it somehow goes wrong.

                  [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));

                  In .NET 8 RC 1, it generates:

                  vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpcmpeqb k2,zmm1,zmmword ptr [rax]kaddq k1,k1,k2 ; WRONG INSTRUCTION!vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

                  While what I expect it to generate looks like:

                  vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

                  And even weirder, if I add Vector512<byte>.Zero in advance of adding second operand, like:

                  [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

                  It generates what I expect it to generate from Test512Blend:

                  vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

                  Adding the Vector512<T>.Zero MUST NOT alter the result of the whole integer + operation.

                  Reproduction Steps

                  1. Obtain a JIT assembly for the codes below with .NET 8 RC 1:
                  [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector256<byte>Test1(Vector256<byte>ymm0,Vector256<byte>ymm1,Vector256<byte>ymm2,Vector256<byte>ymm3)=>Avx2.BlendVariable(ymm0,ymm2,Vector256.Equals(ymm0,ymm1)+Vector256.Equals(ymm2,ymm3));
                  [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));
                  [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

                  Expected behavior

                  The code:

                  [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));

                  and

                  [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

                  For both functions, it should generate something like:

                  vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

                  Actual behavior

                  For the code:

                  [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));

                  It instead generates something like:

                  vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpcmpeqb k2,zmm1,zmmword ptr [rax]kaddq k1,k1,k2 vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

                  Regression?

                  Unknown

                  Known Workarounds

                  By adding Vector512<T>.Zero in advance of adding second operand, like:

                  [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

                  It generates:

                  vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

                  Configuration

                  • .NET version: 8.0.100-rc.1.23455.8
                  • PC: Custom built PC
                    • OS: Windows 11 Home 22H2 (22621.2283)
                    • CPU: Intel(R) Xeon(R) w5-2455X 3.19 GHz
                    • RAM: 32 GB DDR5 ECC RDIMM
                    • Graphics: NVIDIA GeForce GTX1060(6 GB)
                    • Storage:
                      • OS(C:) : WD_BLACK SN770 1TB PCIe 4.0 NVMe M.2 SSD
                      • DATA (D:) : Western Digital WDC WD10EZEX-22MFCA0 1000.2 GB 7200RPM SATA HDD
                      • WORKSPACE (E:) : Seagate ST1000DM003-1ER162 1000.2 GB 7200RPM SATA HDD
                  Visual Studio 2022 installation

                  Microsoft Visual Studio Community 2022
                  Version 17.8.0 Preview 2.0
                  VisualStudio.17.Preview/17.8.0-pre.2.0+34112.27
                  Microsoft .NET Framework
                  Version 4.8.09032

                  インストールされているバージョン:Community

                  Visual C++ 2022 00482-90000-00000-AA248
                  Microsoft Visual C++ 2022

                  ASP.NET and Web Tools 17.8.226.21692
                  ASP.NET and Web Tools

                  AvaloniaPackage Extension 1.0
                  AvaloniaPackage Visual Studio Extension Detailed Info

                  Azure App Service Tools v3.0.0 17.8.226.21692
                  Azure App Service Tools v3.0.0

                  Azure Functions and Web Jobs Tools 17.8.226.21692
                  Azure Functions and Web Jobs Tools

                  C# ツール 4.8.0-2.23429.7+44555193fd1135b5d53a2099f76fec91e0d1ebde
                  IDE で使用する C# コンポーネント。プロジェクトの種類や設定に応じて、異なるバージョンのコンパイラを使用できます。

                  Code Cleanup On Save 1.0.12
                  Automatically run one of the Code Clean profiles when saving the document. This ensures your code is always formatted correctly and follows your coding style conventions.

                  Common Azure Tools 1.10
                  Provides common services for use by Azure Mobile Services and Microsoft Azure Tools.

                  Extensibility Message Bus 1.4.39 (main@e8108eb)
                  Provides common messaging-based MEF services for loosely coupled Visual Studio extension components communication and integration.

                  File Icons 2.7
                  Adds icons for files that are not recognized by Solution Explorer

                  Microsoft JVM Debugger 1.0
                  Provides support for connecting the Visual Studio debugger to JDWP compatible Java Virtual Machines

                  Mono Debugging for Visual Studio 17.8.14 (0c9914e)
                  Support for debugging Mono processes with Visual Studio.

                  NuGet パッケージ マネージャー 6.8.0
                  Visual Studio 内の NuGet パッケージ マネージャー。NuGet の詳細については、https://docs.nuget.org/ にアクセスしてください

                  Razor (ASP.NET Core) 17.8.2.2345506+ade90399d42c1a7bf92191b1c067816c0ae1c311
                  ASP.NET Core Razor の言語サービスを提供します。

                  SonarLint for Visual Studio 7.3.0.77872
                  SonarLint is an extension to your favorite IDE that provides on-the-fly feedback to developers on new bugs and quality issues injected into their code.

                  SQL Server Data Tools 17.8.64.0
                  Microsoft SQL Server Data Tools

                  Tweaks 2022 1.1.143
                  A collection of minor fixes and tweaks for Visual Studio to reduce the paper cuts and make you a happier developer

                  TypeScript Tools 17.0.20830.2001
                  TypeScript Tools for Microsoft Visual Studio

                  Visual Basic ツール 4.8.0-2.23429.7+44555193fd1135b5d53a2099f76fec91e0d1ebde
                  IDE で使用する Visual Basic コンポーネント。プロジェクトの種類や設定に応じて、異なるバージョンのコンパイラを使用できます。

                  Visual F# Tools 17.8.0-beta.23425.10+0d3549fa5b8b6387ade191d76768405cefed8229
                  Microsoft Visual F# Tools

                  Visual Studio IntelliCode 2.2
                  Visual Studio 向けの AI 支援付き開発。

                  VisualStudio.DeviceLog 1.0
                  パッケージに関する情報

                  VisualStudio.Mac 1.0
                  Mac Extension for Visual Studio

                  Xamarin 17.8.0.118 (main@35c256f)
                  Xamarin.iOS と Xamarin.Android の開発を有効にする Visual Studio 拡張機能

                  Xamarin Designer 17.8.1.11 (remotes/origin/d17-8@13ef934098)
                  Visual Studio で Xamarin Designer ツールを有効にするための Visual Studio 拡張機能。

                  Xamarin Templates 17.8.16 (830b56a)
                  Templates for building iOS, Android, and Windows apps with Xamarin and Xamarin.Forms.

                  Xamarin.Android SDK 13.2.1.2 (d17-5/a8a26c7)
                  Xamarin.Android Reference Assemblies and MSBuild support.
                  Mono: d9a6e87
                  Java.Interop: xamarin/java.interop/d17-5@149d70fe
                  SQLite: xamarin/sqlite@68c69d8
                  Xamarin.Android Tools: xamarin/xamarin-android-tools/d17-5@ca1552d

                  Xamarin.iOS and Xamarin.Mac SDK 16.4.0.16 (b5972410d)
                  Xamarin.iOS and Xamarin.Mac Reference Assemblies and MSBuild support.

                  Other information

                  No response

                  Metadata

                  Metadata

                  Assignees

                  No one assigned

                    Labels

                    area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIavx512Related to the AVX-512 architecture

                    Type

                    No type

                    Projects

                    No projects

                      Milestone

                      No milestone

                      Relationships

                      None yet

                      Development

                      No branches or pull requests

                      Issue actions

                      , 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Inconsistent and counterintuitive codegen behavior of `+` operator for `Vector512<T>` depending on the number and order of operands generated by compare instructions, unlike for `Vector256<T>` · Issue #92261 · dotnet/runtime · GitHub
                      Skip to content

                      Inconsistent and counterintuitive codegen behavior of + operator for Vector512<T> depending on the number and order of operands generated by compare instructions, unlike for Vector256<T> #92261

                      Description

                      @MineCake147E

                      Description

                      When I was playing with the Vector512<T>, I found some inconsistent behavior of + operator for Vector512<byte>, depending on one or more arguments being generated by Vector512.Equals or not.

                      Both the .NET 7 and .NET 8 RC 1 are doing the right thing for Vector256<byte>:

                      [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector256<byte>Test1(Vector256<byte>ymm0,Vector256<byte>ymm1,Vector256<byte>ymm2,Vector256<byte>ymm3)=>Avx2.BlendVariable(ymm0,ymm2,Vector256.Equals(ymm0,ymm1)+Vector256.Equals(ymm2,ymm3));

                      In .NET 7, it generates:

                      vzerouppermovrax,qword ptr [rsp+28h]vmovupdymm0,ymmword ptr [rdx]vmovupdymm1,ymmword ptr [r9]vpcmpeqb ymm2,ymm0,ymmword ptr [r8]vpcmpeqb ymm3,ymm1,ymmword ptr [rax]vpaddbymm2,ymm2,ymm3vpblendvbymm0,ymm0,ymm1,ymm2vmovupd ymmword ptr [rcx],ymm0movrax,rcxvzeroupperret

                      In .NET 8 RC 1, it generates:

                      vzerouppermovrax,qword ptr [rsp+28h]vmovupsymm0,ymmword ptr [rdx]vmovupsymm1,ymmword ptr [r9]vpcmpeqb ymm2,ymm0,ymmword ptr [r8]vpcmpeqb ymm3,ymm1,ymmword ptr [rax]vpaddbymm2,ymm2,ymm3vpblendvbymm0,ymm0,ymm1,ymm2vmovups ymmword ptr [rcx],ymm0movrax,rcxvzeroupperret

                      But when it comes to Vector512<byte>, it somehow goes wrong.

                      [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));

                      In .NET 8 RC 1, it generates:

                      vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpcmpeqb k2,zmm1,zmmword ptr [rax]kaddq k1,k1,k2 ; WRONG INSTRUCTION!vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

                      While what I expect it to generate looks like:

                      vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

                      And even weirder, if I add Vector512<byte>.Zero in advance of adding second operand, like:

                      [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

                      It generates what I expect it to generate from Test512Blend:

                      vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

                      Adding the Vector512<T>.Zero MUST NOT alter the result of the whole integer + operation.

                      Reproduction Steps

                      1. Obtain a JIT assembly for the codes below with .NET 8 RC 1:
                      [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector256<byte>Test1(Vector256<byte>ymm0,Vector256<byte>ymm1,Vector256<byte>ymm2,Vector256<byte>ymm3)=>Avx2.BlendVariable(ymm0,ymm2,Vector256.Equals(ymm0,ymm1)+Vector256.Equals(ymm2,ymm3));
                      [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));
                      [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

                      Expected behavior

                      The code:

                      [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));

                      and

                      [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

                      For both functions, it should generate something like:

                      vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

                      Actual behavior

                      For the code:

                      [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));

                      It instead generates something like:

                      vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpcmpeqb k2,zmm1,zmmword ptr [rax]kaddq k1,k1,k2 vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

                      Regression?

                      Unknown

                      Known Workarounds

                      By adding Vector512<T>.Zero in advance of adding second operand, like:

                      [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

                      It generates:

                      vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

                      Configuration

                      • .NET version: 8.0.100-rc.1.23455.8
                      • PC: Custom built PC
                        • OS: Windows 11 Home 22H2 (22621.2283)
                        • CPU: Intel(R) Xeon(R) w5-2455X 3.19 GHz
                        • RAM: 32 GB DDR5 ECC RDIMM
                        • Graphics: NVIDIA GeForce GTX1060(6 GB)
                        • Storage:
                          • OS(C:) : WD_BLACK SN770 1TB PCIe 4.0 NVMe M.2 SSD
                          • DATA (D:) : Western Digital WDC WD10EZEX-22MFCA0 1000.2 GB 7200RPM SATA HDD
                          • WORKSPACE (E:) : Seagate ST1000DM003-1ER162 1000.2 GB 7200RPM SATA HDD
                      Visual Studio 2022 installation

                      Microsoft Visual Studio Community 2022
                      Version 17.8.0 Preview 2.0
                      VisualStudio.17.Preview/17.8.0-pre.2.0+34112.27
                      Microsoft .NET Framework
                      Version 4.8.09032

                      インストールされているバージョン:Community

                      Visual C++ 2022 00482-90000-00000-AA248
                      Microsoft Visual C++ 2022

                      ASP.NET and Web Tools 17.8.226.21692
                      ASP.NET and Web Tools

                      AvaloniaPackage Extension 1.0
                      AvaloniaPackage Visual Studio Extension Detailed Info

                      Azure App Service Tools v3.0.0 17.8.226.21692
                      Azure App Service Tools v3.0.0

                      Azure Functions and Web Jobs Tools 17.8.226.21692
                      Azure Functions and Web Jobs Tools

                      C# ツール 4.8.0-2.23429.7+44555193fd1135b5d53a2099f76fec91e0d1ebde
                      IDE で使用する C# コンポーネント。プロジェクトの種類や設定に応じて、異なるバージョンのコンパイラを使用できます。

                      Code Cleanup On Save 1.0.12
                      Automatically run one of the Code Clean profiles when saving the document. This ensures your code is always formatted correctly and follows your coding style conventions.

                      Common Azure Tools 1.10
                      Provides common services for use by Azure Mobile Services and Microsoft Azure Tools.

                      Extensibility Message Bus 1.4.39 (main@e8108eb)
                      Provides common messaging-based MEF services for loosely coupled Visual Studio extension components communication and integration.

                      File Icons 2.7
                      Adds icons for files that are not recognized by Solution Explorer

                      Microsoft JVM Debugger 1.0
                      Provides support for connecting the Visual Studio debugger to JDWP compatible Java Virtual Machines

                      Mono Debugging for Visual Studio 17.8.14 (0c9914e)
                      Support for debugging Mono processes with Visual Studio.

                      NuGet パッケージ マネージャー 6.8.0
                      Visual Studio 内の NuGet パッケージ マネージャー。NuGet の詳細については、https://docs.nuget.org/ にアクセスしてください

                      Razor (ASP.NET Core) 17.8.2.2345506+ade90399d42c1a7bf92191b1c067816c0ae1c311
                      ASP.NET Core Razor の言語サービスを提供します。

                      SonarLint for Visual Studio 7.3.0.77872
                      SonarLint is an extension to your favorite IDE that provides on-the-fly feedback to developers on new bugs and quality issues injected into their code.

                      SQL Server Data Tools 17.8.64.0
                      Microsoft SQL Server Data Tools

                      Tweaks 2022 1.1.143
                      A collection of minor fixes and tweaks for Visual Studio to reduce the paper cuts and make you a happier developer

                      TypeScript Tools 17.0.20830.2001
                      TypeScript Tools for Microsoft Visual Studio

                      Visual Basic ツール 4.8.0-2.23429.7+44555193fd1135b5d53a2099f76fec91e0d1ebde
                      IDE で使用する Visual Basic コンポーネント。プロジェクトの種類や設定に応じて、異なるバージョンのコンパイラを使用できます。

                      Visual F# Tools 17.8.0-beta.23425.10+0d3549fa5b8b6387ade191d76768405cefed8229
                      Microsoft Visual F# Tools

                      Visual Studio IntelliCode 2.2
                      Visual Studio 向けの AI 支援付き開発。

                      VisualStudio.DeviceLog 1.0
                      パッケージに関する情報

                      VisualStudio.Mac 1.0
                      Mac Extension for Visual Studio

                      Xamarin 17.8.0.118 (main@35c256f)
                      Xamarin.iOS と Xamarin.Android の開発を有効にする Visual Studio 拡張機能

                      Xamarin Designer 17.8.1.11 (remotes/origin/d17-8@13ef934098)
                      Visual Studio で Xamarin Designer ツールを有効にするための Visual Studio 拡張機能。

                      Xamarin Templates 17.8.16 (830b56a)
                      Templates for building iOS, Android, and Windows apps with Xamarin and Xamarin.Forms.

                      Xamarin.Android SDK 13.2.1.2 (d17-5/a8a26c7)
                      Xamarin.Android Reference Assemblies and MSBuild support.
                      Mono: d9a6e87
                      Java.Interop: xamarin/java.interop/d17-5@149d70fe
                      SQLite: xamarin/sqlite@68c69d8
                      Xamarin.Android Tools: xamarin/xamarin-android-tools/d17-5@ca1552d

                      Xamarin.iOS and Xamarin.Mac SDK 16.4.0.16 (b5972410d)
                      Xamarin.iOS and Xamarin.Mac Reference Assemblies and MSBuild support.

                      Other information

                      No response

                      Metadata

                      Metadata

                      Assignees

                      No one assigned

                        Labels

                        area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIavx512Related to the AVX-512 architecture

                        Type

                        No type

                        Projects

                        No projects

                          Milestone

                          No milestone

                          Relationships

                          None yet

                          Development

                          No branches or pull requests

                          Issue actions

                          , 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Inconsistent and counterintuitive codegen behavior of `+` operator for `Vector512<T>` depending on the number and order of operands generated by compare instructions, unlike for `Vector256<T>` · Issue #92261 · dotnet/runtime · GitHub
                          Skip to content

                          Inconsistent and counterintuitive codegen behavior of + operator for Vector512<T> depending on the number and order of operands generated by compare instructions, unlike for Vector256<T> #92261

                          Description

                          @MineCake147E

                          Description

                          When I was playing with the Vector512<T>, I found some inconsistent behavior of + operator for Vector512<byte>, depending on one or more arguments being generated by Vector512.Equals or not.

                          Both the .NET 7 and .NET 8 RC 1 are doing the right thing for Vector256<byte>:

                          [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector256<byte>Test1(Vector256<byte>ymm0,Vector256<byte>ymm1,Vector256<byte>ymm2,Vector256<byte>ymm3)=>Avx2.BlendVariable(ymm0,ymm2,Vector256.Equals(ymm0,ymm1)+Vector256.Equals(ymm2,ymm3));

                          In .NET 7, it generates:

                          vzerouppermovrax,qword ptr [rsp+28h]vmovupdymm0,ymmword ptr [rdx]vmovupdymm1,ymmword ptr [r9]vpcmpeqb ymm2,ymm0,ymmword ptr [r8]vpcmpeqb ymm3,ymm1,ymmword ptr [rax]vpaddbymm2,ymm2,ymm3vpblendvbymm0,ymm0,ymm1,ymm2vmovupd ymmword ptr [rcx],ymm0movrax,rcxvzeroupperret

                          In .NET 8 RC 1, it generates:

                          vzerouppermovrax,qword ptr [rsp+28h]vmovupsymm0,ymmword ptr [rdx]vmovupsymm1,ymmword ptr [r9]vpcmpeqb ymm2,ymm0,ymmword ptr [r8]vpcmpeqb ymm3,ymm1,ymmword ptr [rax]vpaddbymm2,ymm2,ymm3vpblendvbymm0,ymm0,ymm1,ymm2vmovups ymmword ptr [rcx],ymm0movrax,rcxvzeroupperret

                          But when it comes to Vector512<byte>, it somehow goes wrong.

                          [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));

                          In .NET 8 RC 1, it generates:

                          vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpcmpeqb k2,zmm1,zmmword ptr [rax]kaddq k1,k1,k2 ; WRONG INSTRUCTION!vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

                          While what I expect it to generate looks like:

                          vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

                          And even weirder, if I add Vector512<byte>.Zero in advance of adding second operand, like:

                          [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

                          It generates what I expect it to generate from Test512Blend:

                          vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

                          Adding the Vector512<T>.Zero MUST NOT alter the result of the whole integer + operation.

                          Reproduction Steps

                          1. Obtain a JIT assembly for the codes below with .NET 8 RC 1:
                          [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector256<byte>Test1(Vector256<byte>ymm0,Vector256<byte>ymm1,Vector256<byte>ymm2,Vector256<byte>ymm3)=>Avx2.BlendVariable(ymm0,ymm2,Vector256.Equals(ymm0,ymm1)+Vector256.Equals(ymm2,ymm3));
                          [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));
                          [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

                          Expected behavior

                          The code:

                          [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));

                          and

                          [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

                          For both functions, it should generate something like:

                          vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

                          Actual behavior

                          For the code:

                          [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));

                          It instead generates something like:

                          vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpcmpeqb k2,zmm1,zmmword ptr [rax]kaddq k1,k1,k2 vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

                          Regression?

                          Unknown

                          Known Workarounds

                          By adding Vector512<T>.Zero in advance of adding second operand, like:

                          [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

                          It generates:

                          vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

                          Configuration

                          • .NET version: 8.0.100-rc.1.23455.8
                          • PC: Custom built PC
                            • OS: Windows 11 Home 22H2 (22621.2283)
                            • CPU: Intel(R) Xeon(R) w5-2455X 3.19 GHz
                            • RAM: 32 GB DDR5 ECC RDIMM
                            • Graphics: NVIDIA GeForce GTX1060(6 GB)
                            • Storage:
                              • OS(C:) : WD_BLACK SN770 1TB PCIe 4.0 NVMe M.2 SSD
                              • DATA (D:) : Western Digital WDC WD10EZEX-22MFCA0 1000.2 GB 7200RPM SATA HDD
                              • WORKSPACE (E:) : Seagate ST1000DM003-1ER162 1000.2 GB 7200RPM SATA HDD
                          Visual Studio 2022 installation

                          Microsoft Visual Studio Community 2022
                          Version 17.8.0 Preview 2.0
                          VisualStudio.17.Preview/17.8.0-pre.2.0+34112.27
                          Microsoft .NET Framework
                          Version 4.8.09032

                          インストールされているバージョン:Community

                          Visual C++ 2022 00482-90000-00000-AA248
                          Microsoft Visual C++ 2022

                          ASP.NET and Web Tools 17.8.226.21692
                          ASP.NET and Web Tools

                          AvaloniaPackage Extension 1.0
                          AvaloniaPackage Visual Studio Extension Detailed Info

                          Azure App Service Tools v3.0.0 17.8.226.21692
                          Azure App Service Tools v3.0.0

                          Azure Functions and Web Jobs Tools 17.8.226.21692
                          Azure Functions and Web Jobs Tools

                          C# ツール 4.8.0-2.23429.7+44555193fd1135b5d53a2099f76fec91e0d1ebde
                          IDE で使用する C# コンポーネント。プロジェクトの種類や設定に応じて、異なるバージョンのコンパイラを使用できます。

                          Code Cleanup On Save 1.0.12
                          Automatically run one of the Code Clean profiles when saving the document. This ensures your code is always formatted correctly and follows your coding style conventions.

                          Common Azure Tools 1.10
                          Provides common services for use by Azure Mobile Services and Microsoft Azure Tools.

                          Extensibility Message Bus 1.4.39 (main@e8108eb)
                          Provides common messaging-based MEF services for loosely coupled Visual Studio extension components communication and integration.

                          File Icons 2.7
                          Adds icons for files that are not recognized by Solution Explorer

                          Microsoft JVM Debugger 1.0
                          Provides support for connecting the Visual Studio debugger to JDWP compatible Java Virtual Machines

                          Mono Debugging for Visual Studio 17.8.14 (0c9914e)
                          Support for debugging Mono processes with Visual Studio.

                          NuGet パッケージ マネージャー 6.8.0
                          Visual Studio 内の NuGet パッケージ マネージャー。NuGet の詳細については、https://docs.nuget.org/ にアクセスしてください

                          Razor (ASP.NET Core) 17.8.2.2345506+ade90399d42c1a7bf92191b1c067816c0ae1c311
                          ASP.NET Core Razor の言語サービスを提供します。

                          SonarLint for Visual Studio 7.3.0.77872
                          SonarLint is an extension to your favorite IDE that provides on-the-fly feedback to developers on new bugs and quality issues injected into their code.

                          SQL Server Data Tools 17.8.64.0
                          Microsoft SQL Server Data Tools

                          Tweaks 2022 1.1.143
                          A collection of minor fixes and tweaks for Visual Studio to reduce the paper cuts and make you a happier developer

                          TypeScript Tools 17.0.20830.2001
                          TypeScript Tools for Microsoft Visual Studio

                          Visual Basic ツール 4.8.0-2.23429.7+44555193fd1135b5d53a2099f76fec91e0d1ebde
                          IDE で使用する Visual Basic コンポーネント。プロジェクトの種類や設定に応じて、異なるバージョンのコンパイラを使用できます。

                          Visual F# Tools 17.8.0-beta.23425.10+0d3549fa5b8b6387ade191d76768405cefed8229
                          Microsoft Visual F# Tools

                          Visual Studio IntelliCode 2.2
                          Visual Studio 向けの AI 支援付き開発。

                          VisualStudio.DeviceLog 1.0
                          パッケージに関する情報

                          VisualStudio.Mac 1.0
                          Mac Extension for Visual Studio

                          Xamarin 17.8.0.118 (main@35c256f)
                          Xamarin.iOS と Xamarin.Android の開発を有効にする Visual Studio 拡張機能

                          Xamarin Designer 17.8.1.11 (remotes/origin/d17-8@13ef934098)
                          Visual Studio で Xamarin Designer ツールを有効にするための Visual Studio 拡張機能。

                          Xamarin Templates 17.8.16 (830b56a)
                          Templates for building iOS, Android, and Windows apps with Xamarin and Xamarin.Forms.

                          Xamarin.Android SDK 13.2.1.2 (d17-5/a8a26c7)
                          Xamarin.Android Reference Assemblies and MSBuild support.
                          Mono: d9a6e87
                          Java.Interop: xamarin/java.interop/d17-5@149d70fe
                          SQLite: xamarin/sqlite@68c69d8
                          Xamarin.Android Tools: xamarin/xamarin-android-tools/d17-5@ca1552d

                          Xamarin.iOS and Xamarin.Mac SDK 16.4.0.16 (b5972410d)
                          Xamarin.iOS and Xamarin.Mac Reference Assemblies and MSBuild support.

                          Other information

                          No response

                          Metadata

                          Metadata

                          Assignees

                          No one assigned

                            Labels

                            area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIavx512Related to the AVX-512 architecture

                            Type

                            No type

                            Projects

                            No projects

                              Milestone

                              No milestone

                              Relationships

                              None yet

                              Development

                              No branches or pull requests

                              Issue actions

                              , 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); Inconsistent and counterintuitive codegen behavior of `+` operator for `Vector512<T>` depending on the number and order of operands generated by compare instructions, unlike for `Vector256<T>` · Issue #92261 · dotnet/runtime · GitHub
                              Skip to content

                              Inconsistent and counterintuitive codegen behavior of + operator for Vector512<T> depending on the number and order of operands generated by compare instructions, unlike for Vector256<T> #92261

                              Description

                              @MineCake147E

                              Description

                              When I was playing with the Vector512<T>, I found some inconsistent behavior of + operator for Vector512<byte>, depending on one or more arguments being generated by Vector512.Equals or not.

                              Both the .NET 7 and .NET 8 RC 1 are doing the right thing for Vector256<byte>:

                              [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector256<byte>Test1(Vector256<byte>ymm0,Vector256<byte>ymm1,Vector256<byte>ymm2,Vector256<byte>ymm3)=>Avx2.BlendVariable(ymm0,ymm2,Vector256.Equals(ymm0,ymm1)+Vector256.Equals(ymm2,ymm3));

                              In .NET 7, it generates:

                              vzerouppermovrax,qword ptr [rsp+28h]vmovupdymm0,ymmword ptr [rdx]vmovupdymm1,ymmword ptr [r9]vpcmpeqb ymm2,ymm0,ymmword ptr [r8]vpcmpeqb ymm3,ymm1,ymmword ptr [rax]vpaddbymm2,ymm2,ymm3vpblendvbymm0,ymm0,ymm1,ymm2vmovupd ymmword ptr [rcx],ymm0movrax,rcxvzeroupperret

                              In .NET 8 RC 1, it generates:

                              vzerouppermovrax,qword ptr [rsp+28h]vmovupsymm0,ymmword ptr [rdx]vmovupsymm1,ymmword ptr [r9]vpcmpeqb ymm2,ymm0,ymmword ptr [r8]vpcmpeqb ymm3,ymm1,ymmword ptr [rax]vpaddbymm2,ymm2,ymm3vpblendvbymm0,ymm0,ymm1,ymm2vmovups ymmword ptr [rcx],ymm0movrax,rcxvzeroupperret

                              But when it comes to Vector512<byte>, it somehow goes wrong.

                              [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));

                              In .NET 8 RC 1, it generates:

                              vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpcmpeqb k2,zmm1,zmmword ptr [rax]kaddq k1,k1,k2 ; WRONG INSTRUCTION!vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

                              While what I expect it to generate looks like:

                              vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

                              And even weirder, if I add Vector512<byte>.Zero in advance of adding second operand, like:

                              [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

                              It generates what I expect it to generate from Test512Blend:

                              vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

                              Adding the Vector512<T>.Zero MUST NOT alter the result of the whole integer + operation.

                              Reproduction Steps

                              1. Obtain a JIT assembly for the codes below with .NET 8 RC 1:
                              [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector256<byte>Test1(Vector256<byte>ymm0,Vector256<byte>ymm1,Vector256<byte>ymm2,Vector256<byte>ymm3)=>Avx2.BlendVariable(ymm0,ymm2,Vector256.Equals(ymm0,ymm1)+Vector256.Equals(ymm2,ymm3));
                              [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));
                              [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

                              Expected behavior

                              The code:

                              [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));

                              and

                              [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

                              For both functions, it should generate something like:

                              vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

                              Actual behavior

                              For the code:

                              [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512.Equals(zmm2,zmm3));

                              It instead generates something like:

                              vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpcmpeqb k2,zmm1,zmmword ptr [rax]kaddq k1,k1,k2 vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

                              Regression?

                              Unknown

                              Known Workarounds

                              By adding Vector512<T>.Zero in advance of adding second operand, like:

                              [MethodImpl(MethodImplOptions.AggressiveOptimization)]privatestaticVector512<byte>Test512Blend3(Vector512<byte>zmm0,Vector512<byte>zmm1,Vector512<byte>zmm2,Vector512<byte>zmm3)=>Avx512BW.BlendVariable(zmm0,zmm2,Vector512.Equals(zmm0,zmm1)+Vector512<byte>.Zero+Vector512.Equals(zmm2,zmm3));

                              It generates:

                              vzerouppermovrax,qword ptr [rsp+28h]vmovupszmm0,zmmword ptr [rdx]vmovupszmm1,zmmword ptr [r9]vpcmpeqb k1,zmm0,zmmword ptr [r8]vpmovm2bzmm2,k1 vpcmpeqb k1,zmm1,zmmword ptr [rax]vpmovm2bzmm3,k1 vpaddbzmm2,zmm2,zmm3vpmovb2m k1,zmm2vpblendmbzmm0{k1},zmm0,zmm1vmovups zmmword ptr [rcx],zmm0movrax,rcxvzeroupperret

                              Configuration

                              • .NET version: 8.0.100-rc.1.23455.8
                              • PC: Custom built PC
                                • OS: Windows 11 Home 22H2 (22621.2283)
                                • CPU: Intel(R) Xeon(R) w5-2455X 3.19 GHz
                                • RAM: 32 GB DDR5 ECC RDIMM
                                • Graphics: NVIDIA GeForce GTX1060(6 GB)
                                • Storage:
                                  • OS(C:) : WD_BLACK SN770 1TB PCIe 4.0 NVMe M.2 SSD
                                  • DATA (D:) : Western Digital WDC WD10EZEX-22MFCA0 1000.2 GB 7200RPM SATA HDD
                                  • WORKSPACE (E:) : Seagate ST1000DM003-1ER162 1000.2 GB 7200RPM SATA HDD
                              Visual Studio 2022 installation

                              Microsoft Visual Studio Community 2022
                              Version 17.8.0 Preview 2.0
                              VisualStudio.17.Preview/17.8.0-pre.2.0+34112.27
                              Microsoft .NET Framework
                              Version 4.8.09032

                              インストールされているバージョン:Community

                              Visual C++ 2022 00482-90000-00000-AA248
                              Microsoft Visual C++ 2022

                              ASP.NET and Web Tools 17.8.226.21692
                              ASP.NET and Web Tools

                              AvaloniaPackage Extension 1.0
                              AvaloniaPackage Visual Studio Extension Detailed Info

                              Azure App Service Tools v3.0.0 17.8.226.21692
                              Azure App Service Tools v3.0.0

                              Azure Functions and Web Jobs Tools 17.8.226.21692
                              Azure Functions and Web Jobs Tools

                              C# ツール 4.8.0-2.23429.7+44555193fd1135b5d53a2099f76fec91e0d1ebde
                              IDE で使用する C# コンポーネント。プロジェクトの種類や設定に応じて、異なるバージョンのコンパイラを使用できます。

                              Code Cleanup On Save 1.0.12
                              Automatically run one of the Code Clean profiles when saving the document. This ensures your code is always formatted correctly and follows your coding style conventions.

                              Common Azure Tools 1.10
                              Provides common services for use by Azure Mobile Services and Microsoft Azure Tools.

                              Extensibility Message Bus 1.4.39 (main@e8108eb)
                              Provides common messaging-based MEF services for loosely coupled Visual Studio extension components communication and integration.

                              File Icons 2.7
                              Adds icons for files that are not recognized by Solution Explorer

                              Microsoft JVM Debugger 1.0
                              Provides support for connecting the Visual Studio debugger to JDWP compatible Java Virtual Machines

                              Mono Debugging for Visual Studio 17.8.14 (0c9914e)
                              Support for debugging Mono processes with Visual Studio.

                              NuGet パッケージ マネージャー 6.8.0
                              Visual Studio 内の NuGet パッケージ マネージャー。NuGet の詳細については、https://docs.nuget.org/ にアクセスしてください

                              Razor (ASP.NET Core) 17.8.2.2345506+ade90399d42c1a7bf92191b1c067816c0ae1c311
                              ASP.NET Core Razor の言語サービスを提供します。

                              SonarLint for Visual Studio 7.3.0.77872
                              SonarLint is an extension to your favorite IDE that provides on-the-fly feedback to developers on new bugs and quality issues injected into their code.

                              SQL Server Data Tools 17.8.64.0
                              Microsoft SQL Server Data Tools

                              Tweaks 2022 1.1.143
                              A collection of minor fixes and tweaks for Visual Studio to reduce the paper cuts and make you a happier developer

                              TypeScript Tools 17.0.20830.2001
                              TypeScript Tools for Microsoft Visual Studio

                              Visual Basic ツール 4.8.0-2.23429.7+44555193fd1135b5d53a2099f76fec91e0d1ebde
                              IDE で使用する Visual Basic コンポーネント。プロジェクトの種類や設定に応じて、異なるバージョンのコンパイラを使用できます。

                              Visual F# Tools 17.8.0-beta.23425.10+0d3549fa5b8b6387ade191d76768405cefed8229
                              Microsoft Visual F# Tools

                              Visual Studio IntelliCode 2.2
                              Visual Studio 向けの AI 支援付き開発。

                              VisualStudio.DeviceLog 1.0
                              パッケージに関する情報

                              VisualStudio.Mac 1.0
                              Mac Extension for Visual Studio

                              Xamarin 17.8.0.118 (main@35c256f)
                              Xamarin.iOS と Xamarin.Android の開発を有効にする Visual Studio 拡張機能

                              Xamarin Designer 17.8.1.11 (remotes/origin/d17-8@13ef934098)
                              Visual Studio で Xamarin Designer ツールを有効にするための Visual Studio 拡張機能。

                              Xamarin Templates 17.8.16 (830b56a)
                              Templates for building iOS, Android, and Windows apps with Xamarin and Xamarin.Forms.

                              Xamarin.Android SDK 13.2.1.2 (d17-5/a8a26c7)
                              Xamarin.Android Reference Assemblies and MSBuild support.
                              Mono: d9a6e87
                              Java.Interop: xamarin/java.interop/d17-5@149d70fe
                              SQLite: xamarin/sqlite@68c69d8
                              Xamarin.Android Tools: xamarin/xamarin-android-tools/d17-5@ca1552d

                              Xamarin.iOS and Xamarin.Mac SDK 16.4.0.16 (b5972410d)
                              Xamarin.iOS and Xamarin.Mac Reference Assemblies and MSBuild support.

                              Other information

                              No response

                              Metadata

                              Metadata

                              Assignees

                              No one assigned

                                Labels

                                area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIavx512Related to the AVX-512 architecture

                                Type

                                No type

                                Projects

                                No projects

                                  Milestone

                                  No milestone

                                  Relationships

                                  None yet

                                  Development

                                  No branches or pull requests

                                  Issue actions