This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
RFA: Fix PR 33290 (fallout from Tweak optabs.c's use of constant rtx_costs)
- From: Richard Sandiford <richard at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 03 Sep 2007 16:20:02 +0100
- Subject: RFA: Fix PR 33290 (fallout from Tweak optabs.c's use of constant rtx_costs)
- References: <87y7gaji3x.fsf@firetop.home>
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);
}