https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69556
--- Comment #4 from rguenther at suse dot de <rguenther at suse dot de> --- On January 29, 2016 6:39:07 PM GMT+01:00, "jgreenhalgh at gcc dot gnu.org" <gcc-bugzi...@gcc.gnu.org> wrote: >https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69556 > >James Greenhalgh <jgreenhalgh at gcc dot gnu.org> changed: > > What |Removed |Added >---------------------------------------------------------------------------- > CC| |jgreenhalgh at gcc dot gnu.org, > | |rguenth at gcc dot gnu.org > >--- Comment #3 from James Greenhalgh <jgreenhalgh at gcc dot gnu.org> >--- >(In reply to Andrew Pinski from comment #2) >> (In reply to Andrew Pinski from comment #1) >> > I suspect we should disable "Fold (C1/X)*C2 into (C1*C2)/X" for >gimple then >> > and have it only for generic. >> >> Or check for single use of the divide. > >I had thought that was what the :s in the first line of pattern was >trying to >do: > > (simplify > (mult (rdiv:s REAL_CST@0 @1) REAL_CST@2) > (if (flag_associative_math) > (with > { tree tem = const_binop (MULT_EXPR, type, @0, @2); } > (if (tem) > (rdiv { tem; } @1))))) > >If I capture the rdiv, and explicitly check it for single_use (as in >the >untested patch below), then the rule fails. So there's either a >misunderstanding/disagreement here about what :s implies, or the >match.pd >machinery has a bug. I think there is a misunderstanding. A replacement is still allowed if it is a single operation as that replaces at least one other (the one we are simplifying). This assumes equal cost of course which for divide vs. Mult is not the case. So an explicit && single_use as in the patch below is needed. Note that this will disable CSE of the two cases as well then. Richard. >diff --git a/gcc/match.pd b/gcc/match.pd >index 5f28215..9460a9b 100644 >--- a/gcc/match.pd >+++ b/gcc/match.pd >@@ -445,11 +445,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > > /* Fold (C1/X)*C2 into (C1*C2)/X. */ > (simplify >- (mult (rdiv:s REAL_CST@0 @1) REAL_CST@2) >+ (mult (rdiv:s@3 REAL_CST@0 @1) REAL_CST@2) > (if (flag_associative_math) > (with > { tree tem = const_binop (MULT_EXPR, type, @0, @2); } >- (if (tem) >+ (if (tem && single_use (@3)) > (rdiv { tem; } @1))))) > > /* Convert C1/(X*C2) into (C1/C2)/X */