On Mon, Jul 25, 2022 at 12:37 PM Sam Feifer via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > This patch fixes a missed optimization in match.pd. It takes the pattern, x / > y * y == x, and optimizes it to x % y == 0. This produces fewer instructions. > > There are also tests for the optimizations to be added to the test suite. > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? > > PR tree-optimization/104992 > > gcc/ChangeLog: > > * match.pd x / y * y == x: New simplification. > > gcc/testsuite/ChangeLog: > > * gcc.dg/pr104992-1.c: New test. > * gcc.dg/pr104992.c: New test. > --- > gcc/match.pd | 5 +++++ > gcc/testsuite/gcc.dg/pr104992-1.c | 30 ++++++++++++++++++++++++++ > gcc/testsuite/gcc.dg/pr104992.c | 35 +++++++++++++++++++++++++++++++ > 3 files changed, 70 insertions(+) > create mode 100644 gcc/testsuite/gcc.dg/pr104992-1.c > create mode 100644 gcc/testsuite/gcc.dg/pr104992.c > > diff --git a/gcc/match.pd b/gcc/match.pd > index 9736393061a..f7ab2174b8a 100644 > --- a/gcc/match.pd > +++ b/gcc/match.pd > @@ -8054,3 +8054,8 @@ and, > (if (TYPE_UNSIGNED (TREE_TYPE (@0))) > (bit_and @0 @1) > (cond (le @0 @1) @0 (bit_and @0 @1)))))) > + > +/* x / y * y == x -> x % y == 0. */ > +(simplify > + (eq (mult (trunc_div @0 @1) @1) @0) > + (eq (trunc_mod @0 @1) { build_zero_cst TREE_TYPE(@0); }))
I suspect for eq and mult you might want to add :c to them even though in your testcase you don't need them, you might be able to get it via using different statements and looking at the forwprop gimple dump. Also, did you send the wrong patch as it looks like the function call to build_zero_cst has been eaten ... (or is it just because TREE_TYPE has parentheses inside the macro and it just accidently works :)). You might also want to make sure it does the right thing for vector types and complex types (yes both are valid for trunc_div still). Thanks, Andrew Pinski > diff --git a/gcc/testsuite/gcc.dg/pr104992-1.c > b/gcc/testsuite/gcc.dg/pr104992-1.c > new file mode 100644 > index 00000000000..a80e5e180ce > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/pr104992-1.c > @@ -0,0 +1,30 @@ > +/* PR tree-optimization/104992 */ > +/* { dg-do run } */ > +/* { dg-options "-O2"} */ > + > +#include "pr104992.c" > + > +int main () { > + > + /* Should be true. */ > + if (!foo(6, 3) > + || !bar(12, 2) > + || !baz(34, 17) > + || !qux(50, 10) > + || !fred(16, 8) > + || !baz(-9, 3) > + || !baz(9, -3) > + || !baz(-9, -3) > + ) { > + __builtin_abort(); > + } > + > + /* Should be false. */ > + if (foo(5, 30) > + || bar(72, 27) > + || baz(42, 15)) { > + __builtin_abort(); > + } > + > + return 0; > +} > diff --git a/gcc/testsuite/gcc.dg/pr104992.c b/gcc/testsuite/gcc.dg/pr104992.c > new file mode 100644 > index 00000000000..b4b0ca53118 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/pr104992.c > @@ -0,0 +1,35 @@ > +/* PR tree-optimization/104992 */ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-tree-optimized" } */ > + > +/* Form from PR. */ > +__attribute__((noipa)) unsigned foo(unsigned x, unsigned y) > +{ > + return x / y * y == x; > +} > + > +__attribute__((noipa)) unsigned bar(unsigned x, unsigned y) { > + return x == x / y * y; > +} > + > +/* Signed test case. */ > +__attribute__((noipa)) unsigned baz (int x, int y) { > + return x / y * y == x; > +} > + > +/* Changed order. */ > +__attribute__((noipa)) unsigned qux (unsigned x, unsigned y) { > + return y * (x / y) == x; > +} > + > +/* Wrong order. */ > +__attribute__((noipa)) unsigned fred (unsigned x, unsigned y) { > + return y * x / y == x; > +} > + > +/* Wrong pattern. */ > +__attribute__((noipa)) unsigned waldo (unsigned x, unsigned y, unsigned z) { > + return x / y * z == x; > +} > + > +/* { dg-final {scan-tree-dump-times " % " 4 "optimized" } } */ > > base-commit: 633e9920589ddfaf2d6da1c24ce99b18a2638db4 > -- > 2.31.1 >