On Wed, Nov 15, 2017 at 3:39 PM, Wilco Dijkstra <wilco.dijks...@arm.com> wrote: > Richard Biener wrote: >> On Tue, Oct 17, 2017 at 6:32 PM, Wilco Dijkstra <wilco.dijks...@arm.com> >> wrote: > >>> (if (flag_reciprocal_math) >>> - /* Convert (A/B)/C to A/(B*C) */ >>> + /* Convert (A/B)/C to A/(B*C). */ >>> (simplify >>> (rdiv (rdiv:s @0 @1) @2) >>> - (rdiv @0 (mult @1 @2))) >>> + (rdiv @0 (mult @1 @2))) >>> + >>> + /* Canonicalize x / (C1 * y) to (x * C2) / y. */ >>> + (if (optimize) >> >> why if (optimize) here? The pattern you removed has no >> such check. As discussed this may undo CSE of C1 * y >> so please check for a single-use on the mult with :s > > I think that came from an earlier version of this patch. I've removed it > and added a single use check. > >>> + (simplify >>> + (rdiv @0 (mult @1 REAL_CST@2)) >>> + (if (!real_zerop (@1)) >> >> why this check? The pattern below didn't have it. > > Presumably to avoid the change when dividing by zero. I've removed it, here is > the updated version. This passes bootstrap and regress:
Ok. Richard. > > ChangeLog > 2017-11-15 Wilco Dijkstra <wdijk...@arm.com> > Jackson Woodruff <jackson.woodr...@arm.com> > > gcc/ > PR 71026/tree-optimization > * match.pd: Canonicalize constant multiplies in division. > > gcc/testsuite/ > PR 71026/tree-optimization > * gcc.dg/cse_recip.c: New test. > -- > > diff --git a/gcc/match.pd b/gcc/match.pd > index > b5042b783c0830a2da08c44bed39842a17911844..ea7d90ed977cfff991d74bee54e91ecb209b6030 > 100644 > --- a/gcc/match.pd > +++ b/gcc/match.pd > @@ -344,10 +344,18 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > (negate @0))) > > (if (flag_reciprocal_math) > - /* Convert (A/B)/C to A/(B*C) */ > + /* Convert (A/B)/C to A/(B*C). */ > (simplify > (rdiv (rdiv:s @0 @1) @2) > - (rdiv @0 (mult @1 @2))) > + (rdiv @0 (mult @1 @2))) > + > + /* Canonicalize x / (C1 * y) to (x * C2) / y. */ > + (simplify > + (rdiv @0 (mult:s @1 REAL_CST@2)) > + (with > + { tree tem = const_binop (RDIV_EXPR, type, build_one_cst (type), @2); } > + (if (tem) > + (rdiv (mult @0 { tem; } ) @1)))) > > /* Convert A/(B/C) to (A/B)*C */ > (simplify > @@ -646,15 +654,6 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > (if (tem) > (rdiv { tem; } @1))))) > > -/* Convert C1/(X*C2) into (C1/C2)/X */ > -(simplify > - (rdiv REAL_CST@0 (mult @1 REAL_CST@2)) > - (if (flag_reciprocal_math) > - (with > - { tree tem = const_binop (RDIV_EXPR, type, @0, @2); } > - (if (tem) > - (rdiv { tem; } @1))))) > - > /* Simplify ~X & X as zero. */ > (simplify > (bit_and:c (convert? @0) (convert? (bit_not @0))) > diff --git a/gcc/testsuite/gcc.dg/cse_recip.c > b/gcc/testsuite/gcc.dg/cse_recip.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..88cba9930c0eb1fdee22a797eff110cd9a14fcda > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/cse_recip.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-options "-Ofast -fdump-tree-optimized-raw" } */ > + > +void > +cse_recip (float x, float y, float *a) > +{ > + a[0] = y / (5 * x); > + a[1] = y / (3 * x); > + a[2] = y / x; > +} > + > +/* { dg-final { scan-tree-dump-times "rdiv_expr" 1 "optimized" } } */ > > > >