re PR tree-optimization/17531 ([ivopts] ICE compiling gzip deflate.c)

PR 17531
        * expr.c (expand_expr_addr_expr_1): Only assemble_external for decls.
        Don't check VOIDmode here.  Force PLUS operands to common type.
        (expand_expr_addr_expr): Do VOIDmode check earlier.  Force use of
        Pmode if given a non pointer type.

        PR 17531
        * optabs.c (expand_binop): Force constants to the correct mode.

From-SVN: r88257
This commit is contained in:
Richard Henderson 2004-09-28 15:55:04 -07:00
parent 078208ebef
commit b0b324b07f
3 changed files with 42 additions and 16 deletions

View File

@ -1,3 +1,16 @@
2004-09-28 Richard Henderson <rth@redhat.com>
PR 17531
* expr.c (expand_expr_addr_expr_1): Only assemble_external for decls.
Don't check VOIDmode here. Force PLUS operands to common type.
(expand_expr_addr_expr): Do VOIDmode check earlier. Force use of
Pmode if given a non pointer type.
2004-09-28 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
PR 17531
* optabs.c (expand_binop): Force constants to the correct mode.
2004-09-28 Ulrich Weigand <uweigand@de.ibm.com>
* config/s390/s390.c (s390_adjust_cost): Remove.

View File

@ -6088,7 +6088,7 @@ expand_expr_addr_expr_1 (tree exp, rtx target, enum machine_mode tmode,
case CONST_DECL:
/* Recurse and make the output_constant_def clause above handle this. */
return expand_expr_addr_expr_1 (DECL_INITIAL (exp), target,
tmode, modifier);
tmode, modifier);
case REALPART_EXPR:
/* The real part of the complex number is always first, therefore
@ -6126,7 +6126,7 @@ expand_expr_addr_expr_1 (tree exp, rtx target, enum machine_mode tmode,
result = XEXP (result, 0);
/* ??? Is this needed anymore? */
if (!TREE_USED (exp) == 0)
if (DECL_P (exp) && !TREE_USED (exp) == 0)
{
assemble_external (exp);
TREE_USED (exp) = 1;
@ -6149,13 +6149,6 @@ expand_expr_addr_expr_1 (tree exp, rtx target, enum machine_mode tmode,
subtarget = offset || bitpos ? NULL_RTX : target;
result = expand_expr_addr_expr_1 (inner, subtarget, tmode, modifier);
if (tmode == VOIDmode)
{
tmode = GET_MODE (result);
if (tmode == VOIDmode)
tmode = Pmode;
}
if (offset)
{
rtx tmp;
@ -6164,6 +6157,9 @@ expand_expr_addr_expr_1 (tree exp, rtx target, enum machine_mode tmode,
result = force_operand (result, NULL);
tmp = expand_expr (offset, NULL, tmode, EXPAND_NORMAL);
result = convert_memory_address (tmode, result);
tmp = convert_memory_address (tmode, tmp);
if (modifier == EXPAND_SUM)
result = gen_rtx_PLUS (tmode, result, tmp);
else
@ -6178,7 +6174,7 @@ expand_expr_addr_expr_1 (tree exp, rtx target, enum machine_mode tmode,
{
/* Someone beforehand should have rejected taking the address
of such an object. */
gcc_assert (!(bitpos % BITS_PER_UNIT));
gcc_assert ((bitpos % BITS_PER_UNIT) == 0);
result = plus_constant (result, bitpos / BITS_PER_UNIT);
if (modifier < EXPAND_SUM)
@ -6198,19 +6194,28 @@ expand_expr_addr_expr (tree exp, rtx target, enum machine_mode tmode,
enum machine_mode rmode;
rtx result;
/* Target mode of VOIDmode says "whatever's natural". */
if (tmode == VOIDmode)
tmode = TYPE_MODE (TREE_TYPE (exp));
/* We can get called with some Weird Things if the user does silliness
like "(short) &a". In that case, convert_memory_address won't do
the right thing, so ignore the given target mode. */
if (!targetm.valid_pointer_mode (tmode))
tmode = Pmode;
result = expand_expr_addr_expr_1 (TREE_OPERAND (exp, 0), target,
tmode, modifier);
/* Despite expand_expr claims concerning ignoring TMODE when not
strictly convenient, stuff breaks if we don't honor it. */
if (tmode == VOIDmode)
tmode = TYPE_MODE (TREE_TYPE (exp));
strictly convenient, stuff breaks if we don't honor it. Note
that combined with the above, we only do this for pointer modes. */
rmode = GET_MODE (result);
if (rmode == VOIDmode)
rmode = tmode;
if (rmode != tmode)
result = convert_memory_address (tmode, result);
return result;
}

View File

@ -834,11 +834,19 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
force expensive constants into a register. */
if (CONSTANT_P (op0) && optimize
&& rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
op0 = force_reg (mode, op0);
{
if (GET_MODE (op0) != VOIDmode)
op0 = convert_modes (mode, VOIDmode, op0, unsignedp);
op0 = force_reg (mode, op0);
}
if (CONSTANT_P (op1) && optimize
&& ! shift_op && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
op1 = force_reg (mode, op1);
{
if (GET_MODE (op1) != VOIDmode)
op1 = convert_modes (mode, VOIDmode, op1, unsignedp);
op1 = force_reg (mode, op1);
}
/* Record where to delete back to if we backtrack. */
last = get_last_insn ();