Skip to content

[RyuJIT] Div then Mod (or viceversa) executes idiv twice instead of using the value in the register #5213

Description

@redknightlois

Found this trying to optimize a very low level memory addressing algorithm. Suddenly I noticed that we were doing the idiv twice.

Repro on rc2-16551:

  public class Program
    {
        public long Dividend;

        [MethodImpl(MethodImplOptions.NoInlining)]
        public long Run(long parameter)
        {
            long div = parameter / Dividend;
            long mod = parameter % Dividend;

            return div + mod;
        }

        public static void Main(string[] args)
        {
            Random r = new Random();

            var p = new Program();
            p.Dividend = 10;

            long value = p.Run(203);
            Console.WriteLine($"{value}");
            Console.ReadLine();
        }
    }

will output (in x64 but will also happen in x86):

00007FF8E8EC3C83  mov         rcx,qword ptr [rcx+8]  
00007FF8E8EC3C87  mov         rax,r8          // 2 instructions to prepare for idiv. 
00007FF8E8EC3C8A  cqo                    
00007FF8E8EC3C8C  idiv        rax,rcx         // parameter / Dividend
00007FF8E8EC3C8F  mov         r9,rax          // r9:= divResult 
00007FF8E8EC3C92  mov         rax,r8          // 2 instructions to prepare for idiv. 
00007FF8E8EC3C95  cqo  
00007FF8E8EC3C97  idiv        rax,rcx         //  parameter / Dividend
00007FF8E8EC3C9A  lea         rax,[r9+rdx]    // rax := divResult + modulus

this could be written as:

00007FF8E8EC3C83  mov         rcx,qword ptr [rcx+8]  
00007FF8E8EC3C87  mov         rax,r8          // 2 instructions to prepare for idiv. 
00007FF8E8EC3C8A  cqo                    
00007FF8E8EC3C8C  idiv        rax,rcx         //  parameter / Dividend
00007FF8E8EC3C92  add         rax,rdx         //  rax := divResult + modulus

This is pretty common in addressing modes or accessing matrix locations, etc. Everywhere you have a row and a column, you will have such an structure.

category:cq
theme:div-mod-rem
skill-level:expert
cost:large
impact:medium

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIenhancementProduct code improvement that does NOT require public API changes/additionsoptimizationtenet-performancePerformance related issue

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions