mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-12 01:17:13 +08:00
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:
parent
078208ebef
commit
b0b324b07f
@ -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.
|
||||
|
33
gcc/expr.c
33
gcc/expr.c
@ -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;
|
||||
}
|
||||
|
||||
|
12
gcc/optabs.c
12
gcc/optabs.c
@ -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 ();
|
||||
|
Loading…
Reference in New Issue
Block a user