gnu/gcc/7ebe4eb29d8fc0167f98705b53b4fddb28f0cffb match: fold a remainder compared with its dividend
A remainder of non-negative operands equals its dividend exactly when the
dividend is smaller than the divisor. Comparing the two therefore does
not need the division at all. This sits next to the (X / Y) == 0 rule,
which has the same shape and the same non-negativity requirement.
int f (unsigned x, unsigned y) { return x % y == x; }
aarch64 -O2:
before after
udiv w2, w0, w1 cmp w0, w1
msub w2, w2, w1, w0 cset w0, cc
cmp w2, w0
cset w0, eq
A zero divisor can raise a non-call exception. Keep the division or
remainder when the divisor might be zero and non-call exceptions are
enabled. Also keep an explicit zero divisor for diagnostics.
Bootstrapped and tested on aarch64-none-linux-gnu.
gcc/ChangeLog:
* match.pd ((X / Y) ==/!= 0): Preserve a possible zero-divisor
exception.
((X % Y) ==/!= X): New simplification. Preserve a possible
zero-divisor exception.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/modcmp-1.c: New test.
* gcc.dg/tree-ssa/modcmp-noncall-1.c: Likewise.
Signed-off-by: Kyrylo Tkachov <ktkachov@nvidia.com>
3 files changed