On 8/4/2026 4:06 AM, [email protected] wrote:
From: Kyrylo Tkachov <[email protected]>
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
The :s marker cannot reject this flat replacement. Remove the inactive
marker.
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.
Ok for trunk?
Thanks,
Kyrill
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.
Like most of these, I'm curious where this showed up :-)
It looks correct to me. OK for the trunk. Note that your cover
indicates you removed a :s tag, but I don't see that in the patch.
Probably best to resolve that one way or another before committing.
Thanks,
jeff