diff options
author | Richard Henderson <rth@gcc.gnu.org> | 2004-09-28 15:55:04 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2004-09-28 15:55:04 -0700 |
commit | b0b324b07fc46746d3eada8cc27d6000a3756bed (patch) | |
tree | 657a3287fd0f4515ef8192966bb543603c33c6ab /gcc | |
parent | 078208ebefcad46f0fd8e0c559d8c6b411ee4726 (diff) | |
download | gcc-b0b324b07fc46746d3eada8cc27d6000a3756bed.zip gcc-b0b324b07fc46746d3eada8cc27d6000a3756bed.tar.gz gcc-b0b324b07fc46746d3eada8cc27d6000a3756bed.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/expr.c | 33 | ||||
-rw-r--r-- | gcc/optabs.c | 12 |
3 files changed, 42 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 11e0ce2..69229c2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. @@ -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; } diff --git a/gcc/optabs.c b/gcc/optabs.c index fc3ef00..cc0627b 100644 --- a/gcc/optabs.c +++ b/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 (); |