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) >