https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64308

--- Comment #3 from Tavian Barnes <tavianator at gmail dot com> ---
@Richard Biener: Yes the range for _16 could be [0, 4294967294].  Why can't VRP
can't assume division by zero doesn't occur?  If it can then it could say
anything mod [a, b] fits in [0, b - 1].

That's a reasonable improvement by itself but it's not enough to optimize this
PR, because to use divl for (ret * b % m), you need (ret * b / m) to fit in [0,
4294967295] as well.  And to know that that, as Marc Glisse suggests, you'd
need symbolic ranges.

@Marc Glisse: Is there currently no support at all for symbolic ranges?  If you
can infer that b < m is an invariant then that's all you need.  Formally it's
something like this:

If x, y, and z are 32-bit unsigned integers, and x <= z || y <= z, then

    (uint64_t)x * (uint64_t)y % z

can be computed with mull and divl because x * y / z is always <= max(x, y)
which fits in 32 bits.

Reply via email to