Skip to content

Redundant mov instructions generated #49535

@jamescourtney

Description

@jamescourtney

Description

I maintain a tool that generates performance-critical code, so I spend some time looking at JIT dumps to make sure the code that I'm generating is JIT-friendly (bounds-check eliding, etc).

I am by no means an authority in assembly, but I've come across something that mystifies me and makes me think there may be a bug with some redundant instructions.

My configuration is:

  • .NET 5.0 x64 on Win10 x64, fully updated
  • AMD Ryzen 5950x (Zen 3, AVX2 supported)

I'm unable to get a succinct reproduction of the issue (it may only happen when the method uses more variables than there are registers), so I'll share high-level details and add a link to a gist later. The code is basically trying to write an aligned integer at a 4-byte boundary:

checked
{
  int offset;
   ...
   // align to 4 byte boundary
   offset += (-offset) & (sizeof(int) - 1);
   int location = offset;
   offset += sizeof(int);

   // write the value at location.
   ...
}
G_M47529_IG13:
       8BC3                 mov      eax, ebx
       F7D8                 neg      eax
       83E003               and      eax, 3
       03C3                 add      eax, ebx
       0F80A3000000         jo       G_M47529_IG25
       8BD8                 mov      ebx, eax

       // These two mov's appear entirely redundant.
       8BC3                 mov      eax, ebx
       8BD8                 mov      ebx, eax

       83C304               add      ebx, 4
       0F8094000000         jo       G_M47529_IG25
       8B5708               mov      edx, dword ptr [rdi+8]
       3BC2                 cmp      eax, edx
       0F878E000000         ja       G_M47529_IG26

Unless I'm very mistaken (always possible 🙂), My question is that after the first mov, we know for sure that the eax and ebx registers carry the same value, which should mean that the next two instructions could be eliminated with no adverse side effects, right?

The full repro is available here. I've tried to remove all of the code that isn't essential to view the issue: https://gist.github.com/jamescourtney/5000bec600493d7dc08633a07ba2dd06

Metadata

Metadata

Assignees

No one assigned

    Labels

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

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions