{"action":"created","issue":{"url":"https://api.github.com/repos/dotnet/coreclr/issues/3439","repository_url":"https://api.github.com/repos/dotnet/coreclr","labels_url":"https://api.github.com/repos/dotnet/coreclr/issues/3439/labels{/name}","comments_url":"https://api.github.com/repos/dotnet/coreclr/issues/3439/comments","events_url":"https://api.github.com/repos/dotnet/coreclr/issues/3439/events","html_url":"https://github.com/dotnet/coreclr/issues/3439","id":137459391,"number":3439,"title":"[RyuJIT] Div then Mod (or viceversa) executes idiv twice instead of using the value in the register","user":{"login":"redknightlois","id":1045411,"avatar_url":"https://avatars.githubusercontent.com/u/1045411?v=3","gravatar_id":"","url":"https://api.github.com/users/redknightlois","html_url":"https://github.com/redknightlois","followers_url":"https://api.github.com/users/redknightlois/followers","following_url":"https://api.github.com/users/redknightlois/following{/other_user}","gists_url":"https://api.github.com/users/redknightlois/gists{/gist_id}","starred_url":"https://api.github.com/users/redknightlois/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/redknightlois/subscriptions","organizations_url":"https://api.github.com/users/redknightlois/orgs","repos_url":"https://api.github.com/users/redknightlois/repos","events_url":"https://api.github.com/users/redknightlois/events{/privacy}","received_events_url":"https://api.github.com/users/redknightlois/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/dotnet/coreclr/labels/CodeGen","name":"CodeGen","color":"d4c5f9"},{"url":"https://api.github.com/repos/dotnet/coreclr/labels/optimization","name":"optimization","color":"0052cc"}],"state":"open","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/dotnet/coreclr/milestones/5","html_url":"https://github.com/dotnet/coreclr/milestones/Future","labels_url":"https://api.github.com/repos/dotnet/coreclr/milestones/5/labels","id":1328081,"number":5,"title":"Future","description":"Milestone tracking the issues that have been triaged for after 1.0.0-rtm","creator":{"login":"joshfree","id":1302850,"avatar_url":"https://avatars.githubusercontent.com/u/1302850?v=3","gravatar_id":"","url":"https://api.github.com/users/joshfree","html_url":"https://github.com/joshfree","followers_url":"https://api.github.com/users/joshfree/followers","following_url":"https://api.github.com/users/joshfree/following{/other_user}","gists_url":"https://api.github.com/users/joshfree/gists{/gist_id}","starred_url":"https://api.github.com/users/joshfree/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/joshfree/subscriptions","organizations_url":"https://api.github.com/users/joshfree/orgs","repos_url":"https://api.github.com/users/joshfree/repos","events_url":"https://api.github.com/users/joshfree/events{/privacy}","received_events_url":"https://api.github.com/users/joshfree/received_events","type":"User","site_admin":false},"open_issues":318,"closed_issues":36,"state":"open","created_at":"2015-09-29T00:26:07Z","updated_at":"2016-03-01T04:03:11Z","due_on":null,"closed_at":null},"comments":8,"created_at":"2016-03-01T03:43:03Z","updated_at":"2016-03-01T16:49:28Z","closed_at":null,"body":"Found this trying to optimize a very low level memory addressing algorithm. Suddenly I noticed that we were doing the idiv twice. \r\n\r\nRepro on rc2-16551:\r\n\r\n```csharp  \r\n  public class Program\r\n    {\r\n        public long Dividend;\r\n\r\n        [MethodImpl(MethodImplOptions.NoInlining)]\r\n        public long Run(long parameter)\r\n        {\r\n            long div = parameter / Dividend;\r\n            long mod = parameter % Dividend;\r\n\r\n            return div + mod;\r\n        }\r\n\r\n        public static void Main(string[] args)\r\n        {\r\n            Random r = new Random();\r\n\r\n            var p = new Program();\r\n            p.Dividend = 10;\r\n\r\n            long value = p.Run(203);\r\n            Console.WriteLine($\"{value}\");\r\n            Console.ReadLine();\r\n        }\r\n    }\r\n```\r\n\r\nwill output (in x64 but will also happen in x86):\r\n\r\n``` asm\r\n00007FF8E8EC3C83  mov         rcx,qword ptr [rcx+8]  \r\n00007FF8E8EC3C87  mov         rax,r8          // 2 instructions to prepare for idiv. \r\n00007FF8E8EC3C8A  cqo                    \r\n00007FF8E8EC3C8C  idiv        rax,rcx         // parameter / Dividend\r\n00007FF8E8EC3C8F  mov         r9,rax          // r9:= divResult \r\n00007FF8E8EC3C92  mov         rax,r8          // 2 instructions to prepare for idiv. \r\n00007FF8E8EC3C95  cqo  \r\n00007FF8E8EC3C97  idiv        rax,rcx         //  parameter / Dividend\r\n00007FF8E8EC3C9A  lea         rax,[r9+rdx]    // rax := divResult + modulus\r\n```\r\n\r\nthis could be written as:\r\n\r\n``` asm\r\n00007FF8E8EC3C83  mov         rcx,qword ptr [rcx+8]  \r\n00007FF8E8EC3C87  mov         rax,r8          // 2 instructions to prepare for idiv. \r\n00007FF8E8EC3C8A  cqo                    \r\n00007FF8E8EC3C8C  idiv        rax,rcx         //  parameter / Dividend\r\n00007FF8E8EC3C92  add         rax,rdx         //  rax := divResult + modulus\r\n```\r\n\r\nThis 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."},"comment":{"url":"https://api.github.com/repos/dotnet/coreclr/issues/comments/190806928","html_url":"https://github.com/dotnet/coreclr/issues/3439#issuecomment-190806928","issue_url":"https://api.github.com/repos/dotnet/coreclr/issues/3439","id":190806928,"user":{"login":"redknightlois","id":1045411,"avatar_url":"https://avatars.githubusercontent.com/u/1045411?v=3","gravatar_id":"","url":"https://api.github.com/users/redknightlois","html_url":"https://github.com/redknightlois","followers_url":"https://api.github.com/users/redknightlois/followers","following_url":"https://api.github.com/users/redknightlois/following{/other_user}","gists_url":"https://api.github.com/users/redknightlois/gists{/gist_id}","starred_url":"https://api.github.com/users/redknightlois/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/redknightlois/subscriptions","organizations_url":"https://api.github.com/users/redknightlois/orgs","repos_url":"https://api.github.com/users/redknightlois/repos","events_url":"https://api.github.com/users/redknightlois/events{/privacy}","received_events_url":"https://api.github.com/users/redknightlois/received_events","type":"User","site_admin":false},"created_at":"2016-03-01T16:49:28Z","updated_at":"2016-03-01T16:49:28Z","body":"@mikedn They are just two sides of the same coin. \r\n\r\n```\r\nAbsolutePosition := row * stride + column\r\n```\r\nand\r\n```\r\nrow := AbsolutePosition / TotalColumns\r\ncolumn = AbsolutePosition % TotalColumns\r\n```\r\n\r\nPutting all in the context of the assembly/compiler use is why you are seeing it as special/unusual, where it is not. This pattern is usually hidden in plain sight, it is so common and used, that is very easy to overlook. Only in certain places you will see both together because that means you are trying to retrieve both values at the same time instead of accessing it using a for loop. "}}