Re: [PATCH] match.pd: fold the inequality spelling of divisibility

Andrea Pinski <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <CALvbMcBcSkqOi84vLt7xjyk0JXSkiqA=0aoLbZy9BjucBamX3w@mail.gmail.com>
On Fri, Aug 14, 2026 at 6:23 AM <[email protected]> wrote:
>
> From: Kyrylo Tkachov <[email protected]>
>
> GCC folds:
>
>   x / y * y == x
>
> to:
>
>   x % y == 0
>
> Apply the same simplification to inequality.
>
>   int divisible_by_3 (unsigned int x)
>   {
>     return x / 3 * 3 != x;
>   }
>
> aarch64 -O2:
>
> before:
>
>         divisible_by_3:
>                 mov     w1, 43691
>                 movk    w1, 0xaaaa, lsl 16
>                 umull   x1, w0, w1
>                 lsr     x1, x1, 33
>                 add     w1, w1, w1, lsl 1
>                 cmp     w1, w0
>                 cset    w0, ne
>                 ret
>
> after:
>
>         divisible_by_3:
>                 mov     w1, 43691
>                 movk    w1, 0xaaaa, lsl 16
>                 mul     w0, w0, w1
>                 mov     w1, 1431655765
>                 cmp     w0, w1
>                 cset    w0, hi
>                 ret
>
> Bootstrapped and tested on aarch64-none-linux-gnu.
> Ok for trunk?
> Thanks,
> Kyrill
>
> gcc/ChangeLog:
>
>         * match.pd (x / y * y == x): Extend to inequality.

Ok.

>
> gcc/testsuite/ChangeLog:
>
>         * gcc.dg/tree-ssa/divmul-mod-1.c: New test.
>
> Signed-off-by: Kyrylo Tkachov <[email protected]>
> ---
>  gcc/match.pd                                 |  9 ++---
>  gcc/testsuite/gcc.dg/tree-ssa/divmul-mod-1.c | 38 ++++++++++++++++++++
>  2 files changed, 43 insertions(+), 4 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/divmul-mod-1.c
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 877e449d7d8..33eec29f53a 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -6036,16 +6036,17 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>     (plus:c (mult:c (div @0 @1) @1) (mod @0 @1))
>     @0))
>
> -/* x / y * y == x -> x % y == 0.  */
> -(simplify
> -  (eq:c (mult:c (trunc_div:s @0 @1) @1) @0)
> +/* x / y * y == x -> x % y == 0, and likewise for !=.  */
> +(for cmp (eq ne)
> + (simplify
> +  (cmp:c (mult:c (trunc_div:s @0 @1) @1) @0)
>    (if (TREE_CODE (TREE_TYPE (@0)) != COMPLEX_TYPE
>         && (!VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (@0)))
>            || !target_supports_op_p (TREE_TYPE (@0), TRUNC_DIV_EXPR,
>                                      optab_vector)
>            || target_supports_op_p (TREE_TYPE (@0), TRUNC_MOD_EXPR,
>                                     optab_vector)))
> -   (eq (trunc_mod @0 @1) { build_zero_cst (TREE_TYPE (@0)); })))
> +   (cmp (trunc_mod @0 @1) { build_zero_cst (TREE_TYPE (@0)); }))))
>
>  /* ((X /[ex] C1) +- C2) * (C1 * C3)  -->  (X * C3) +- (C1 * C2 * C3).  */
>  (for op (plus minus)
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/divmul-mod-1.c b/gcc/testsuite/gcc.dg/tree-ssa/divmul-mod-1.c
> new file mode 100644
> index 00000000000..f65a28d2335
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/divmul-mod-1.c
> @@ -0,0 +1,38 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +typedef int v4si __attribute__ ((vector_size (16)));
> +typedef unsigned int v4ui __attribute__ ((vector_size (16)));
> +
> +int
> +eq (unsigned int a, unsigned int b)
> +{
> +  return a / b * b == a;
> +}
> +
> +int
> +ne (unsigned int a, unsigned int b)
> +{
> +  return a / b * b != a;
> +}
> +
> +int
> +nes (int a, int b)
> +{
> +  return a / b * b != a;
> +}
> +
> +v4si
> +veq (v4ui a, v4ui b)
> +{
> +  return a / b * b == a;
> +}
> +
> +v4si
> +vne (v4ui a, v4ui b)
> +{
> +  return a / b * b != a;
> +}
> +
> +/* { dg-final { scan-tree-dump-not " \\* " "optimized" } } */
> +/* { dg-final { scan-tree-dump " % " "optimized" } } */
> --
> 2.50.1 (Apple Git-155)
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.