RFA: Fix PR 33290 (fallout from Tweak optabs.c's use of constant rtx_costs)

Richard Sandiford richard@codesourcery.com
Mon Sep 3 15:20:00 GMT 2007


This patch caused PR 33290, an ICE for PPC on execute/930921-1.c.
The problem was with the new modes used when forcing constants
into registers:

Richard Sandiford <richard@codesourcery.com> writes:
> +/* X is to be used in mode MODE as an operand to BINOPTAB.  If we're
> +   optimizing, and if the operand is a constant that costs more than
> +   1 instruction, force the constant into a register and return that
> +   register.  Return X otherwise.  UNSIGNEDP says whether X is unsigned.  */
> +
> +static rtx
> +avoid_expensive_constant (enum machine_mode mode, optab binoptab,
> +			  rtx x, bool unsignedp)
> +{
> +  if (optimize
> +      && CONSTANT_P (x)
> +      && rtx_cost (x, binoptab->code) > COSTS_N_INSNS (1))
> +    {
> +      if (GET_MODE (x) != VOIDmode)
> +	x = convert_modes (mode, VOIDmode, x, unsignedp);
> +      x = force_reg (mode, x);
> +    }
> +  return x;
> +}
...
> +  /* If we are optimizing, force expensive constants into a register.  */
> +  xop0 = avoid_expensive_constant (mode0, binoptab, xop0, unsignedp);
> +  if (!shift_optab_p (binoptab))
> +    xop1 = avoid_expensive_constant (mode1, binoptab, xop1, unsignedp);

If an operand is a CONST_INT, it is interpreted in the mode of the
optab result.  That's what happened with the original code, but this
new code (intentionally) uses the mode required by the optab instead.
Thus the mode we pass to avoid_expansive_constant may be different
from the mode of the result, and we need to convert the integer
accordingly.

Patch bootstrapped & regression-tested on x86_64-linux-gnu,
where it introduced no new failures.  Also tested by Andreas
Tobler on PPC Darwin, and in testing by Dominique d'Humieres
(thanks to both).  OK to install?

Richard


gcc/
	PR middle-end/33290
	* optabs.c (avoid_expensive_constant): Canonicalize CONST_INTs
	before forcing them into a register.

Index: gcc/optabs.c
===================================================================
--- gcc/optabs.c	(revision 128038)
+++ gcc/optabs.c	(working copy)
@@ -1290,7 +1290,13 @@ avoid_expensive_constant (enum machine_m
       && CONSTANT_P (x)
       && rtx_cost (x, binoptab->code) > COSTS_N_INSNS (1))
     {
-      if (GET_MODE (x) != VOIDmode)
+      if (GET_CODE (x) == CONST_INT)
+	{
+	  HOST_WIDE_INT intval = trunc_int_for_mode (INTVAL (x), mode);
+	  if (intval != INTVAL (x))
+	    x = GEN_INT (intval);
+	}
+      else
 	x = convert_modes (mode, VOIDmode, x, unsignedp);
       x = force_reg (mode, x);
     }



More information about the Gcc-patches mailing list