From e0a17959335723628c929e5feefbe964249f4fb6 Mon Sep 17 00:00:00 2001 From: Andreas Krebbel Date: Wed, 6 Aug 2008 06:51:11 +0000 Subject: [PATCH] reload.c (find_reloads): Force constants into literal pool also if they are wrapped in a SUBREG. 2008-08-06 Andreas Krebbel * reload.c (find_reloads): Force constants into literal pool also if they are wrapped in a SUBREG. 2008-08-06 Andreas Krebbel * gcc.c-torture/compile/20080806-1.c: New testcase. From-SVN: r138763 --- gcc/ChangeLog | 5 ++ gcc/reload.c | 90 +++++++++++-------- gcc/testsuite/ChangeLog | 4 + .../gcc.c-torture/compile/20080806-1.c | 33 +++++++ 4 files changed, 93 insertions(+), 39 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/20080806-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7b50bdf77ad..5ec9a6e1ad4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2008-08-06 Andreas Krebbel + + * reload.c (find_reloads): Force constants into literal pool + also if they are wrapped in a SUBREG. + 2008-08-06 Maxim Kuvyrkov PR target/35659 diff --git a/gcc/reload.c b/gcc/reload.c index a6ea4ff4e5a..93fff404569 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -3843,49 +3843,61 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, /* Any constants that aren't allowed and can't be reloaded into registers are here changed into memory references. */ for (i = 0; i < noperands; i++) - if (! goal_alternative_win[i] - && CONST_POOL_OK_P (recog_data.operand[i]) - && ((PREFERRED_RELOAD_CLASS (recog_data.operand[i], - (enum reg_class) goal_alternative[i]) - == NO_REGS) - || no_input_reloads) - && operand_mode[i] != VOIDmode) + if (! goal_alternative_win[i]) { - int this_address_reloaded; + rtx op = recog_data.operand[i]; + rtx subreg = NULL_RTX; + rtx plus = NULL_RTX; + enum machine_mode mode = operand_mode[i]; - this_address_reloaded = 0; - substed_operand[i] = recog_data.operand[i] - = find_reloads_toplev (force_const_mem (operand_mode[i], - recog_data.operand[i]), - i, address_type[i], ind_levels, 0, insn, - &this_address_reloaded); - if (alternative_allows_const_pool_ref (this_address_reloaded == 0 - ? substed_operand[i] - : NULL, - recog_data.constraints[i], - goal_alternative_number)) - goal_alternative_win[i] = 1; - } + /* Reloads of SUBREGs of CONSTANT RTXs are handled later in + push_reload so we have to let them pass here. */ + if (GET_CODE (op) == SUBREG) + { + subreg = op; + op = SUBREG_REG (op); + mode = GET_MODE (op); + } - /* Likewise any invalid constants appearing as operand of a PLUS - that is to be reloaded. */ - for (i = 0; i < noperands; i++) - if (! goal_alternative_win[i] - && GET_CODE (recog_data.operand[i]) == PLUS - && CONST_POOL_OK_P (XEXP (recog_data.operand[i], 1)) - && (PREFERRED_RELOAD_CLASS (XEXP (recog_data.operand[i], 1), - (enum reg_class) goal_alternative[i]) - == NO_REGS) - && operand_mode[i] != VOIDmode) - { - rtx tem = force_const_mem (operand_mode[i], - XEXP (recog_data.operand[i], 1)); - tem = gen_rtx_PLUS (operand_mode[i], - XEXP (recog_data.operand[i], 0), tem); + if (GET_CODE (op) == PLUS) + { + plus = op; + op = XEXP (op, 1); + } - substed_operand[i] = recog_data.operand[i] - = find_reloads_toplev (tem, i, address_type[i], - ind_levels, 0, insn, NULL); + if (CONST_POOL_OK_P (op) + && ((PREFERRED_RELOAD_CLASS (op, + (enum reg_class) goal_alternative[i]) + == NO_REGS) + || no_input_reloads) + && mode != VOIDmode) + { + int this_address_reloaded; + rtx tem = force_const_mem (mode, op); + + /* If we stripped a SUBREG or a PLUS above add it back. */ + if (plus != NULL_RTX) + tem = gen_rtx_PLUS (mode, XEXP (plus, 0), tem); + + if (subreg != NULL_RTX) + tem = gen_rtx_SUBREG (operand_mode[i], tem, SUBREG_BYTE (subreg)); + + this_address_reloaded = 0; + substed_operand[i] = recog_data.operand[i] + = find_reloads_toplev (tem, i, address_type[i], ind_levels, + 0, insn, &this_address_reloaded); + + /* If the alternative accepts constant pool refs directly + there will be no reload needed at all. */ + if (plus == NULL_RTX + && subreg == NULL_RTX + && alternative_allows_const_pool_ref (this_address_reloaded == 0 + ? substed_operand[i] + : NULL, + recog_data.constraints[i], + goal_alternative_number)) + goal_alternative_win[i] = 1; + } } /* Record the values of the earlyclobber operands for the caller. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0a3088ba8cc..92c95cc547b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2008-08-06 Andreas Krebbel + + * gcc.c-torture/compile/20080806-1.c: New testcase. + 2008-08-06 Maxim Kuvyrkov * gcc.target/ia64/20080802-1.c: New test. diff --git a/gcc/testsuite/gcc.c-torture/compile/20080806-1.c b/gcc/testsuite/gcc.c-torture/compile/20080806-1.c new file mode 100644 index 00000000000..33f0857d5c2 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/20080806-1.c @@ -0,0 +1,33 @@ +int gl2; +typedef __SIZE_TYPE__ size_t; + +extern void *memcpy (void *dest, const void *src, size_t n); + +void +f1 () +{ + int i2; + unsigned char bf[64 * 1024 + 4]; + + for (i2 = 0; i2 < 3; i2++) + { + unsigned char *p2 = bf; + unsigned char *p3 = ((void *) 0); + unsigned short ctf2; + + p2 += sizeof (short); + + for (ctf2 = 0; ctf2 < 3; ctf2++) + { + if (ctf2 == 1) + { + unsigned short of = p2 - bf - 6; + unsigned short *ofp = (unsigned short *) &of; + memcpy (p3, ofp, sizeof (short)); + } + + if (gl2 == 1) + p2 += 3; + } + } +}