Home
Reading
Searching
Subscribe
Sponsors
Statistics
Posting
Contact
Spam
Lists
Links
About
Hosting
Filtering
Features Download
Marketing
Archives
FAQ
Blog
 
Gmane
From: Jasper Neumann <jn <at> sirrida.de>
Subject: Idea for optimization (test for remainder)
Newsgroups: gmane.comp.compilers.llvm.devel
Date: Thursday 27th February 2014 16:07:26 UTC (over 3 years ago)
Hello folks!

Consider the expression (x % d) == c where d and c are constants.
For simplicity let us assume that x is unsigned and 0 <= c < d.
Let us further assume that d = a * (1 << b) and a is odd.
Then our expression can be transformed to
rotate_right(x-c, b) * inverse_mul(a) <= (high_value(x) - c) / d .
Example [(x % 250) == 3]:
   sub eax,3
   ror eax,1
   imul eax,eax,0x26e978d5  // multiplicative inverse of 125
   cmp eax,17179869  // 0xffffffff / 250
   jbe OK

A range check for x can be embedded as well with no additional code.
For signed values a similar transformation is possible.

For more details see my comment on Hacker's Delight 
(http://hackersdelight.org/corres.txt)
and/or our paper about hashing 
(http://programming.sirrida.de/hashsuper.pdf).

The current version of Clang / LLVM (clang -O3 -S) translates it to the 
following (GCC produces similar code):
   movl  %edi, %eax
   imulq $274877907, %rax, %rax  # imm = 0x10624DD3
   shrq $36, %rax
   imull $250, %eax, %eax
   movl  %edi, %ecx
   subl  %eax, %ecx
   cmpl  $3, %ecx
   je    OK
Please note that there are 2 multiply operations and one of them 
produces a double width result (multiply high).

Best regards
Jasper
 
CD: 47ms