Hello!

> $ 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?

Because "div" insn generates "division by zero" on the overflow and
that's not what we expect from truncate. VRP information is not passed
into RTL generation, so we avoid generation of this insn.

Please see the comment in gcc/config/i386.md and Intel instruction set
reference document.

Uros.

Reply via email to