Skip to content

ISimdVector issue (GVM resolution doesn't report [Intrinsic]?) #93174

@EgorBo

Description

@EgorBo
[MethodImpl(MethodImplOptions.NoInlining)]
private static bool Foo1<TVector>(ref int t1, ref int t2)
    where TVector : struct, ISimdVector<TVector, int>
{
    TVector vec1 = TVector.LoadUnsafe(ref t1);
    TVector vec2 = TVector.LoadUnsafe(ref t2);
    return vec1 == vec2;
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static bool Foo2<TVector>(ref int t1, ref int t2)
    where TVector : struct, ISimdVector<TVector, int>
{
    TVector vec1 = TVector.LoadUnsafe(ref t1);
    TVector vec2 = TVector.LoadUnsafe(ref t2);
    return vec1.Equals(vec2);
}

Current codegen for FooX<Vector128<int>>(...):

; Assembly listing for method Foo1
G_M44695_IG01:  ;; offset=0x0000
       sub      rsp, 72
       vzeroupper 
G_M44695_IG02:  ;; offset=0x0007
       vmovups  xmm0, xmmword ptr [rcx]
       vmovaps  xmmword ptr [rsp+0x30], xmm0
       vmovups  xmm0, xmmword ptr [rdx]
       vmovaps  xmmword ptr [rsp+0x20], xmm0
       mov      rax, qword ptr [rsp+0x30]
       mov      qword ptr [rsp+0x18], rax
       mov      rax, qword ptr [rsp+0x20]
       mov      qword ptr [rsp+0x10], rax
       mov      eax, dword ptr [rsp+0x18]
       cmp      dword ptr [rsp+0x10], eax
       jne      SHORT G_M44695_IG08
G_M44695_IG03:  ;; offset=0x0039
       mov      eax, dword ptr [rsp+0x1C]
       cmp      dword ptr [rsp+0x14], eax
       jne      SHORT G_M44695_IG08
G_M44695_IG04:  ;; offset=0x0043
       mov      rax, qword ptr [rsp+0x38]
       mov      qword ptr [rsp+0x08], rax
       mov      rax, qword ptr [rsp+0x28]
       mov      qword ptr [rsp], rax
       mov      eax, dword ptr [rsp+0x08]
       cmp      dword ptr [rsp], eax
       jne      SHORT G_M44695_IG06
G_M44695_IG05:  ;; offset=0x005F
       mov      eax, dword ptr [rsp+0x0C]
       cmp      dword ptr [rsp+0x04], eax
       jne      SHORT G_M44695_IG06
       mov      eax, 1
       jmp      SHORT G_M44695_IG07
G_M44695_IG06:  ;; offset=0x0070
       xor      eax, eax
G_M44695_IG07:  ;; offset=0x0072
       jmp      SHORT G_M44695_IG09
G_M44695_IG08:  ;; offset=0x0074
       xor      eax, eax
G_M44695_IG09:  ;; offset=0x0076
       add      rsp, 72
       ret      
; Total bytes of code 123


; Assembly listing for method Foo2
G_M34100_IG01:  ;; offset=0x0000
       vzeroupper 
G_M34100_IG02:  ;; offset=0x0003
       vmovups  xmm0, xmmword ptr [rcx]
       vpcmpd   k1, xmm0, xmmword ptr [rdx], 4
       kortestb k1, k1
       sete     al
       movzx    rax, al
G_M34100_IG03:  ;; offset=0x0018
       ret      
; Total bytes of code 25

Both Foo1 and Foo2 are expected to produce the same codegen. It looks like vec1 == vec2; was inlined into slow path of Vector128.op_Equality as if [Intrinsic] didn't exist on it. Equals works fine because it's a non-Intrinsic wrapper around intrinsic ==.

cc @tannergooding @dotnet/jit-contrib

We need to fix this issue before we start adopting ISimdVector

Metadata

Metadata

Assignees

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions