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