From ca42e34adb2e8f796c11d0d2717e7667dc455980 Mon Sep 17 00:00:00 2001 From: uweigand Date: Wed, 14 Dec 2005 23:34:51 +0000 Subject: [PATCH] PR rtl-optimization/25310 * reload1.c (eliminate_regs_in_insn): Handle lowpart SUBREGs of the eliminable register when substituting into a PLUS. PR rtl-optimization/25310 * gcc.c-torture/compile/pr25310.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@108543 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 6 +++++ gcc/reload1.c | 35 +++++++++++++++++++-------- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.c-torture/compile/pr25310.c | 17 +++++++++++++ 4 files changed, 53 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr25310.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 57cdbc3..71260a2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2005-12-14 Ulrich Weigand + + PR rtl-optimization/25310 + * reload1.c (eliminate_regs_in_insn): Handle lowpart SUBREGs + of the eliminable register when substituting into a PLUS. + 2005-12-14 Jakub Jelinek PR debug/25023 diff --git a/gcc/reload1.c b/gcc/reload1.c index 970f5ec..29da121 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -3006,42 +3006,57 @@ eliminate_regs_in_insn (rtx insn, int replace) { if (GET_CODE (SET_SRC (old_set)) == PLUS) plus_src = SET_SRC (old_set); - /* First see if the source is of the form (plus (reg) CST). */ + /* First see if the source is of the form (plus (...) CST). */ if (plus_src - && REG_P (XEXP (plus_src, 0)) - && GET_CODE (XEXP (plus_src, 1)) == CONST_INT - && REGNO (XEXP (plus_src, 0)) < FIRST_PSEUDO_REGISTER) + && GET_CODE (XEXP (plus_src, 1)) == CONST_INT) plus_cst_src = plus_src; else if (REG_P (SET_SRC (old_set)) || plus_src) { /* Otherwise, see if we have a REG_EQUAL note of the form - (plus (reg) CST). */ + (plus (...) CST). */ rtx links; for (links = REG_NOTES (insn); links; links = XEXP (links, 1)) { if (REG_NOTE_KIND (links) == REG_EQUAL && GET_CODE (XEXP (links, 0)) == PLUS - && REG_P (XEXP (XEXP (links, 0), 0)) - && GET_CODE (XEXP (XEXP (links, 0), 1)) == CONST_INT - && REGNO (XEXP (XEXP (links, 0), 0)) < FIRST_PSEUDO_REGISTER) + && GET_CODE (XEXP (XEXP (links, 0), 1)) == CONST_INT) { plus_cst_src = XEXP (links, 0); break; } } } + + /* Check that the first operand of the PLUS is a hard reg or + the lowpart subreg of one. */ + if (plus_cst_src) + { + rtx reg = XEXP (plus_cst_src, 0); + if (GET_CODE (reg) == SUBREG && subreg_lowpart_p (reg)) + reg = SUBREG_REG (reg); + + if (!REG_P (reg) || REGNO (reg) >= FIRST_PSEUDO_REGISTER) + plus_cst_src = 0; + } } if (plus_cst_src) { rtx reg = XEXP (plus_cst_src, 0); HOST_WIDE_INT offset = INTVAL (XEXP (plus_cst_src, 1)); + if (GET_CODE (reg) == SUBREG) + reg = SUBREG_REG (reg); + for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) if (ep->from_rtx == reg && ep->can_eliminate) { + rtx to_rtx = ep->to_rtx; offset += ep->offset; + if (GET_CODE (XEXP (plus_cst_src, 0)) == SUBREG) + to_rtx = gen_lowpart (GET_MODE (XEXP (plus_cst_src, 0)), + to_rtx); if (offset == 0) { int num_clobbers; @@ -3051,7 +3066,7 @@ eliminate_regs_in_insn (rtx insn, int replace) There's not much we can do if that doesn't work. */ PATTERN (insn) = gen_rtx_SET (VOIDmode, SET_DEST (old_set), - ep->to_rtx); + to_rtx); num_clobbers = 0; INSN_CODE (insn) = recog (PATTERN (insn), insn, &num_clobbers); if (num_clobbers) @@ -3081,7 +3096,7 @@ eliminate_regs_in_insn (rtx insn, int replace) PATTERN (insn) = new_body; old_set = single_set (insn); - XEXP (SET_SRC (old_set), 0) = ep->to_rtx; + XEXP (SET_SRC (old_set), 0) = to_rtx; XEXP (SET_SRC (old_set), 1) = GEN_INT (offset); } else diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 15f48b3..85a4828 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-12-14 Ulrich Weigand + + PR rtl-optimization/25310 + * gcc.c-torture/compile/pr25310.c: New test. + 2005-12-14 Jakub Jelinek PR debug/25023 diff --git a/gcc/testsuite/gcc.c-torture/compile/pr25310.c b/gcc/testsuite/gcc.c-torture/compile/pr25310.c new file mode 100644 index 0000000..4cd3087 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr25310.c @@ -0,0 +1,17 @@ + +extern int f (char *, int); + +void test (void) +{ + char buffer[65536]; + char *bufptr; + char *bufend; + int bytes; + + bufptr = buffer; + bufend = buffer + sizeof(buffer) - 1; + + while ((bytes = f (bufptr, bufend - bufptr)) > 0) + bufptr += bytes; +} + -- 2.7.4