re PR rtl-optimization/25310 (ICE in reload_cse_simplify_operands, at postreload.c:393)

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.

From-SVN: r108543
This commit is contained in:
Ulrich Weigand 2005-12-14 23:34:51 +00:00 committed by Ulrich Weigand
parent 6f93378c69
commit 7efd40b52a
4 changed files with 53 additions and 10 deletions

View File

@ -1,3 +1,9 @@
2005-12-14 Ulrich Weigand <uweigand@de.ibm.com>
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 <jakub@redhat.com>
PR debug/25023

View File

@ -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 < &reg_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

View File

@ -1,3 +1,8 @@
2005-12-14 Ulrich Weigand <uweigand@de.ibm.com>
PR rtl-optimization/25310
* gcc.c-torture/compile/pr25310.c: New test.
2005-12-14 Jakub Jelinek <jakub@redhat.com>
PR debug/25023

View File

@ -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;
}