aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@gcc.gnu.org>2004-09-28 15:55:04 -0700
committerRichard Henderson <rth@gcc.gnu.org>2004-09-28 15:55:04 -0700
commitb0b324b07fc46746d3eada8cc27d6000a3756bed (patch)
tree657a3287fd0f4515ef8192966bb543603c33c6ab /gcc
parent078208ebefcad46f0fd8e0c559d8c6b411ee4726 (diff)
downloadgcc-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/ChangeLog13
-rw-r--r--gcc/expr.c33
-rw-r--r--gcc/optabs.c12
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.
diff --git a/gcc/expr.c b/gcc/expr.c
index ff8355b..5db2c28 100644
--- a/gcc/expr.c
+++ b/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;
}
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 ();