This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: how to generate x86 "narrowing" divide instruction
- From: Uros Bizjak <ubizjak at gmail dot com>
- To: GCC Development <gcc at gcc dot gnu dot org>
- Cc: Jay Foad <jay dot foad at gmail dot com>
- Date: Mon, 7 Mar 2011 19:12:48 +0100
- Subject: Re: how to generate x86 "narrowing" divide instruction
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.