This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: rs6000 fused multiply-add patch [+ patchlet]
Sorry for the delay...
First, a trivial extra patch that's needed to get fma's in all
fastmath cases:
2002-12-21 Segher Boessenkool <segher@koffie.nl>
* combine.c (combine_simplify_rtx): Add a simplification
for the multiplication of two negations.
*** gcc/combine.c.orig Sat Dec 21 01:22:18 2002
--- gcc/combine.c Sat Dec 21 01:49:03 2002
*************** combine_simplify_rtx (x, op0_mode, last,
*** 4417,4422 ****
--- 4417,4427 ----
if (tem)
return gen_binary (DIV, mode, tem, XEXP (XEXP (x, 0), 1));
}
+
+ /* Simplify (mult (neg A) (neg B)) to (mult A B). */
+ if (GET_CODE (XEXP (x, 0)) == NEG && GET_CODE (XEXP (x, 1)) == NEG)
+ return gen_binary (MULT, mode, XEXP (XEXP (x, 0), 0),
+ XEXP (XEXP (x, 1), 0));
break;
case UDIV:
---end of patch
This is needed because of the pushing-inwards of NEG's, when there's
already a NEG inside, like in -(b * -c) - a . With this, it passes
all my 96 cases for a single fma insn expression. Great!
Geoff Keating wrote:
> > Geoffrey Keating wrote:
> > > +@item
> > > +In combinations of @code{neg}, @code{mult}, @code{plus}, and
> > > +@code{minus}, the @code{neg} operations (if any) will be moved inside
> > > +the operations as far as possible. For instance,
> > > +@code{(neg (mult A B))} is canonicalized as @code{(mult (neg A) B)}, but
> > > +@code{(plus (mult (neg A) B) C)} is canonicalized as
> > > +@code{(minus A (mult B C))}.
[Typo: this last example is in error (it mixes up the ABC).]
This exact example is the only case where ieee-math doesn't use an
fma instruction where it could [as you yourself already mentioned, btw]
(it uses an fmul/fsub sequence instead of an fneg/fmadd sequence); it might
be nice to get the extra precision the fma provides. Slightly worse though,
for -(a - b * c), it generates fmul/fsub/fneg instead of fneg/fnmadd.
I'll try to write a splitter for this, like you suggest.
> I'd have used your testcases, but they didn't seem to be in your patch.
I don't know how to write a testsuite thingy yet; maybe tomorrow, if I can
find myself a working version of dejagnu. I'll send my testcases, promise :)
Oh btw, for a function like
float bla(float a, float b, float c)
{
return a + b * c;
}
gcc generates something like
fmadds 2,2,3,1
fmr 1,2
blr
any idea what needs to be fixed to get rid of the fmr insn?
Segher