Commit d0236c3b by Denis Nagorny Committed by H.J. Lu

re PR target/25603 (Miscompiled FORTRAN program)

2006-02-16  Denis Nagorny <denis_nagorny@linux.intel.com>

	PR rtl-optimization/25603
	* reload.c (reg_inc_found_and_valid_p): New. Check REG_INC note.
	(regno_clobbered_p): Use it. Reusing SETS argument for REG_INC case.
	* reload1.c (choose_reload_regs): Added call of regno_clobbered_p 
	with new meaning of SETS.

From-SVN: r111162
parent 464aea98
2006-02-16 Denis Nagorny <denis_nagorny@linux.intel.com>
PR rtl-optimization/25603
* reload.c (reg_inc_found_and_valid_p): New. Check REG_INC note.
(regno_clobbered_p): Use it. Reusing SETS argument for REG_INC case.
* reload1.c (choose_reload_regs): Added call of regno_clobbered_p
with new meaning of SETS.
2006-02-16 Joseph S. Myers <joseph@codesourcery.com> 2006-02-16 Joseph S. Myers <joseph@codesourcery.com>
PR target/20353 PR target/20353
......
...@@ -6941,9 +6941,39 @@ find_inc_amount (rtx x, rtx inced) ...@@ -6941,9 +6941,39 @@ find_inc_amount (rtx x, rtx inced)
return 0; return 0;
} }
/* Return 1 if registers from REGNO to ENDREGNO are the subjects of a
REG_INC note in insn INSN. REGNO must refer to a hard register. */
#ifdef AUTO_INC_DEC
static int
reg_inc_found_and_valid_p (unsigned int regno, unsigned int endregno,
rtx insn)
{
rtx link;
gcc_assert (insn);
if (! INSN_P (insn))
return 0;
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
if (REG_NOTE_KIND (link) == REG_INC)
{
unsigned int test = (int) REGNO (XEXP (link, 0));
if (test >= regno && test < endregno)
return 1;
}
return 0;
}
#else
#define reg_inc_found_and_valid_p(regno,endregno,insn) 0
#endif
/* Return 1 if register REGNO is the subject of a clobber in insn INSN. /* Return 1 if register REGNO is the subject of a clobber in insn INSN.
If SETS is nonzero, also consider SETs. REGNO must refer to a hard If SETS is 1, also consider SETs. If SETS is 2, enable checking
register. */ REG_INC. REGNO must refer to a hard register. */
int int
regno_clobbered_p (unsigned int regno, rtx insn, enum machine_mode mode, regno_clobbered_p (unsigned int regno, rtx insn, enum machine_mode mode,
...@@ -6958,7 +6988,7 @@ regno_clobbered_p (unsigned int regno, rtx insn, enum machine_mode mode, ...@@ -6958,7 +6988,7 @@ regno_clobbered_p (unsigned int regno, rtx insn, enum machine_mode mode,
endregno = regno + nregs; endregno = regno + nregs;
if ((GET_CODE (PATTERN (insn)) == CLOBBER if ((GET_CODE (PATTERN (insn)) == CLOBBER
|| (sets && GET_CODE (PATTERN (insn)) == SET)) || (sets == 1 && GET_CODE (PATTERN (insn)) == SET))
&& REG_P (XEXP (PATTERN (insn), 0))) && REG_P (XEXP (PATTERN (insn), 0)))
{ {
unsigned int test = REGNO (XEXP (PATTERN (insn), 0)); unsigned int test = REGNO (XEXP (PATTERN (insn), 0));
...@@ -6966,6 +6996,9 @@ regno_clobbered_p (unsigned int regno, rtx insn, enum machine_mode mode, ...@@ -6966,6 +6996,9 @@ regno_clobbered_p (unsigned int regno, rtx insn, enum machine_mode mode,
return test >= regno && test < endregno; return test >= regno && test < endregno;
} }
if (sets == 2 && reg_inc_found_and_valid_p (regno, endregno, insn))
return 1;
if (GET_CODE (PATTERN (insn)) == PARALLEL) if (GET_CODE (PATTERN (insn)) == PARALLEL)
{ {
int i = XVECLEN (PATTERN (insn), 0) - 1; int i = XVECLEN (PATTERN (insn), 0) - 1;
...@@ -6974,7 +7007,7 @@ regno_clobbered_p (unsigned int regno, rtx insn, enum machine_mode mode, ...@@ -6974,7 +7007,7 @@ regno_clobbered_p (unsigned int regno, rtx insn, enum machine_mode mode,
{ {
rtx elt = XVECEXP (PATTERN (insn), 0, i); rtx elt = XVECEXP (PATTERN (insn), 0, i);
if ((GET_CODE (elt) == CLOBBER if ((GET_CODE (elt) == CLOBBER
|| (sets && GET_CODE (PATTERN (insn)) == SET)) || (sets == 1 && GET_CODE (PATTERN (insn)) == SET))
&& REG_P (XEXP (elt, 0))) && REG_P (XEXP (elt, 0)))
{ {
unsigned int test = REGNO (XEXP (elt, 0)); unsigned int test = REGNO (XEXP (elt, 0));
...@@ -6982,6 +7015,9 @@ regno_clobbered_p (unsigned int regno, rtx insn, enum machine_mode mode, ...@@ -6982,6 +7015,9 @@ regno_clobbered_p (unsigned int regno, rtx insn, enum machine_mode mode,
if (test >= regno && test < endregno) if (test >= regno && test < endregno)
return 1; return 1;
} }
if (sets == 2
&& reg_inc_found_and_valid_p (regno, endregno, elt))
return 1;
} }
} }
......
...@@ -5780,7 +5780,7 @@ choose_reload_regs (struct insn_chain *chain) ...@@ -5780,7 +5780,7 @@ choose_reload_regs (struct insn_chain *chain)
if (equiv != 0) if (equiv != 0)
{ {
if (regno_clobbered_p (regno, insn, rld[r].mode, 0)) if (regno_clobbered_p (regno, insn, rld[r].mode, 2))
switch (rld[r].when_needed) switch (rld[r].when_needed)
{ {
case RELOAD_FOR_OTHER_ADDRESS: case RELOAD_FOR_OTHER_ADDRESS:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment