Fix ppc-fmadd-1.c for 603

Joseph S. Myers joseph@codesourcery.com
Thu Jan 4 12:56:00 GMT 2007


This patch fixes the test failure
FAIL: gcc.target/powerpc/ppc-fmadd-1.c scan-assembler-not f(add|sub|mul|neg)
for -mcpu=603.

The problem is miscalculation of costs for certain multiply-add and
multiply-subtract combinations, leading to the test

  a[3] = -b[3] - c[3] * d[3];           // fnmadd with fast-math

generating an fneg instruction because combine decides the costs are
against the required combination.  There are two problems here: the
MULT may appear as either the first or second operand of MINUS, and
the handling in the MULT cast

      /* FMA accounted in outer PLUS/MINUS.  */
      else if ((mode == DFmode || mode == SFmode)
               && (outer_code == PLUS || outer_code == MINUS))
        *total = 0;

does not distinguish, so the MINUS handling should also not
distinguish, and whereas PLUS uses an adjustment

              /* FNMA accounted in outer NEG.  */
              if (outer_code == NEG)
                *total = rs6000_cost->dmul - rs6000_cost->fp;

MINUS wrongly uses 0 there - and 603 is a processor where the costs
are different:

  COSTS_N_INSNS (3),    /* fp */
  COSTS_N_INSNS (4),    /* dmul */

so rs6000_cost->dmul - rs6000_cost->fp is correct for MINUS as well as
PLUS.

Tested with no regressions with cross to powerpc-none-linux-gnu.  OK
to commit?

2007-01-04  Joseph Myers  <joseph@codesourcery.com>

	* config/rs6000/rs6000.c (rs6000_rtx_costs): Make adjustment for
	MULT inside MINUS as either argument.  Use rs6000_cost->dmul -
	rs6000_cost->fp not 0 as adjustment for outer NEG.

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 120402)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -19738,11 +19738,12 @@
     case MINUS:
       if (mode == DFmode)
 	{
-	  if (GET_CODE (XEXP (x, 0)) == MULT)
+	  if (GET_CODE (XEXP (x, 0)) == MULT
+	      || GET_CODE (XEXP (x, 1)) == MULT)
 	    {
 	      /* FNMA accounted in outer NEG.  */
 	      if (outer_code == NEG)
-		*total = 0;
+		*total = rs6000_cost->dmul - rs6000_cost->fp;
 	      else
 		*total = rs6000_cost->dmul;
 	    }

-- 
Joseph S. Myers
joseph@codesourcery.com



More information about the Gcc-patches mailing list