From b0b324b07fc46746d3eada8cc27d6000a3756bed Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 28 Sep 2004 15:55:04 -0700 Subject: [PATCH] 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 --- gcc/ChangeLog | 13 +++++++++++++ gcc/expr.c | 33 +++++++++++++++++++-------------- gcc/optabs.c | 12 ++++++++++-- 3 files changed, 42 insertions(+), 16 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 11e0ce2325b..69229c2d13c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2004-09-28 Richard Henderson + + 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 + + PR 17531 + * optabs.c (expand_binop): Force constants to the correct mode. + 2004-09-28 Ulrich Weigand * config/s390/s390.c (s390_adjust_cost): Remove. diff --git a/gcc/expr.c b/gcc/expr.c index ff8355bc738..5db2c280038 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 fc3ef00ba43..cc0627b1240 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 (); -- 2.30.2