Jay Foad <jay.f...@gmail.com> writes:

> This source code:
>
> $ cat rand.c
> #include <stdint.h>
> uint32_t rand(uint32_t x) { return (uint64_t)x * 16807 % 0x7FFFFFFF; }
>
> compiles to this optimised x86 code:
>
> $ gcc -S -O3 -m32 -fomit-frame-pointer -o - rand.c
> ...
> rand:
>       subl    $28, %esp
>       movl    $16807, %eax
>       mull    32(%esp)
>       movl    $2147483647, 8(%esp)
>       movl    $0, 12(%esp)
>       movl    %eax, (%esp)
>       movl    %edx, 4(%esp)
>       call    __umoddi3
>       addl    $28, %esp
>       ret
>
> Why does the compiler generate a call to __umoddi3, rather than a
> single 64- to 32-bit divide/remainder instruction, "div"? Is it
> lacking the necessary VRP to determine that the high part of the
> dividend is strictly less than the divisor?

This question would be better directed to the mailing list
gcc-h...@gcc.gnu.org.  Please take any followups to gcc-help.  Thanks.

The div instruction is difficult for gcc to use for 64->32 division
because it generates an exception if the quotient is too large.  For
code like the above gcc would have to insert runtime checks to make sure
that the division did not overflow, even though the code only cares
about the remainder.  That might still be better than calling
__umoddi3--I'm not sure--in which case this would be a missed
optimization.  Please consider filing a missed optimization bug report.

Ian

Reply via email to