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

Reply via email to