[PATCH] Optimize x*x*x*x*x*x using 3 multiplications.

Roger Sayle roger@eyesopen.com
Thu Jul 31 20:52:00 GMT 2003


On Thu, 31 Jul 2003, Richard Henderson wrote:
> On Wed, Jul 30, 2003 at 09:53:36PM -0600, Roger Sayle wrote:
> > I'm not sure whether reassociation alone could work out that x^23
> > is better calculated as x^13*x^10 instead of x^22*x.
>
> Yields 7 multiplications via bottom-up reassociation.
> Yields a different set of 7 multiplications via top-down reassociation.
> Your power table yields 6 multiplications total.  Hmm...

You might have guessed 23 wasn't chosen at random.  The minimal addition
chain problem is NP-complete, so a lookup table of optimal results really
helps.  I apologise for loading the dice.



> So while reassociation can produce similar results for some inputs,
> (e.g. the x^6 in the subject line) it can't for all inputs.  I can't
> argue with results like that.

Reassociaton!  I now have a name for my pain.  I've just been reading
up on reassociation-based optimization in compilers and several of GCC's
deficiencies on my wish list turn out to be reassociation related.
For example, how "(x & c1) & c2" isn't reduced in simplify_rtx, or
how the following code:

extern int z1, z2;
void foo(int x, int y, int z)
{
  z1 = (x+y)+z;
  z2 = x+(y+z);
}

gets optimized to z2 = z1 with MSVC but not by GCC.  Or for the current
example, x*y*y*x*x*y which could be simplified via pow(x,3)*pow(y,3) into
pow(x*y,3), and so on, etc...  I now have a new life goal to implement
better reassociation in GCC's constant folding and RTL optimizers.



> > I haven't checked but I'd guess GCC also handles "x+x+x+x+x+x" the same
> > way as my patch, i.e. by representing it internally by a multiplication.
>
> Yes, it should.

Arghh!!  I just tried the experiment:

foo:
        fldl    4(%esp)
        fld     %st(0)
        fadd    %st(1), %st
        fadd    %st(1), %st
        fadd    %st(1), %st
        fadd    %st(1), %st
        faddp   %st, %st(1)
        ret


Even with -ffast-math.  Yet another new entry on my TODO list!



> > It's probably not clear from the immediate context of the patch, but
> > the transformation to convert x*x into pow(x,2) is already nested inside
> > an "if (flag_unsafe_math_optimizations)" condition [fold-const.c:5944].
>
> Ah.
>
> > I could repeat the flag_unsafe_math_optimizations check redundantly
> > if you think that would make things clearer?
>
> No, that's ok.


Can I take that as an approval for the current patch?


Roger
--



More information about the Gcc-patches mailing list