Skip to content

Jit can generate pointless movs #10315

@benaadams

Description

@benaadams

e.g.

 mov    r8d,dword ptr [rax]  
 add    rax,4  
 mov    r8d,r8d                 ; pointless mov
 ...
 movzx  eax,byte ptr [rax]  
 mov    eax,eax                 ; pointless mov   

Example

The Checksum routine Magma.Common/Checksum.cs

// Internet Checksum as defined by RFC 791, RFC 793, RFC 1071, RFC 1141, RFC 1624
public static ushort Calcuate(ref byte buffer, int length)
{
    ref var current = ref buffer;
    ulong sum = 0;

    while (length >= sizeof(ulong))
    {
        length -= sizeof(ulong);

        var ulong0 = Unsafe.As<byte, ulong>(ref current);
        current = ref Unsafe.Add(ref current, sizeof(ulong));

        // Add with carry
        sum += ulong0;
        if (sum < ulong0)
        {
            sum++;
        }
    }

    if ((length & sizeof(uint)) != 0)
    {
        var uint0 = Unsafe.As<byte, uint>(ref current);
        current = ref Unsafe.Add(ref current, sizeof(uint));

        // Add with carry
        sum += uint0;
        if (sum < uint0)
        {
            sum++;
        }
    }

    if ((length & sizeof(ushort)) != 0)
    {
        var ushort0 = Unsafe.As<byte, ushort>(ref current);
        current = ref Unsafe.Add(ref current, sizeof(ushort));

        // Add with carry
        sum += ushort0;
        if (sum < ushort0)
        {
            sum++;
        }
    }

    if ((length & sizeof(byte)) != 0)
    {
        var byte0 = current;

        // Add with carry
        sum += byte0;
        if (sum < byte0)
        {
            sum++;
        }
    }

    // Fold down to 16 bits

    var uint1 = (uint)(sum >> 32);
    var uint2 = (uint)sum;

    // Add with carry
    uint1 += uint2;
    if (uint1 < uint2)
    {
        uint1++;
    }

    var ushort2 = (ushort)uint1;
    var ushort1 = (ushort)(uint1 >> 16);

    // Add with carry
    ushort1 = (ushort)(ushort1 + ushort2);
    if (ushort1 < ushort2)
    {
        ushort1++;
    }

    // Invert to get ones-complement result 
    return (ushort)~ushort1;
}

Generates asm with 3 pointless movs

 mov    rax,rcx  
 xor    ecx,ecx  
 cmp    edx,8  
 jl     00007FFB767741B4  
 add    edx,0FFFFFFF8h  
 mov    r8,qword ptr [rax]  
 add    rax,8  
 add    rcx,r8  
 cmp    rcx,r8  
 jae    00007FFB767741AF  
 inc    rcx  
 cmp    edx,8  
 jge    00007FFB7677419A  
 test   dl,4  
 je     00007FFB767741CE  
 mov    r8d,dword ptr [rax]  
 add    rax,4  
 mov    r8d,r8d                 ; pointless mov 
 add    rcx,r8  
 cmp    rcx,r8  
 jae    00007FFB767741CE  
 inc    rcx  
 test   dl,2  
 je     00007FFB767741E9  
 movzx  r8d,word ptr [rax]  
 add    rax,2  
 mov    r8d,r8d                 ; pointless mov   
 add    rcx,r8  
 cmp    rcx,r8  
 jae    00007FFB767741E9  
 inc    rcx  
 test   dl,1  
 je     00007FFB767741FE  
 movzx  eax,byte ptr [rax]  
 mov    eax,eax                 ; pointless mov   
 add    rcx,rax  
 cmp    rcx,rax  
 jae    00007FFB767741FE  
 inc    rcx  
 mov    rax,rcx  
 shr    rax,20h  
 add    eax,ecx  
 cmp    eax,ecx  
 jae    00007FFB7677420D  
 inc    eax  
 movzx  edx,ax  
 shr    eax,10h  
 movzx  eax,ax  
 add    eax,edx  
 movzx  eax,ax  
 cmp    eax,edx  
 jge    00007FFB76774224  
 inc    eax  
 movzx  eax,ax  
 not    eax  
 movzx  eax,ax  
 ret    

category:cq
theme:basic-cq
skill-level:intermediate
cost:medium
impact:medium

Metadata

Metadata

Assignees

Labels

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

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions