diff options
author | Denis Nagorny <denis_nagorny@linux.intel.com> | 2006-02-17 00:03:06 +0000 |
---|---|---|
committer | H.J. Lu <hjl@gcc.gnu.org> | 2006-02-16 16:03:06 -0800 |
commit | d0236c3be16b414145be3f4046de2ea6c27a68a7 (patch) | |
tree | 21926960298be1c0dcf47707a036cdd3d30e8472 /gcc/reload.c | |
parent | 464aea985957cde55ba4c6a3781293441b89119f (diff) | |
download | gcc-d0236c3be16b414145be3f4046de2ea6c27a68a7.zip gcc-d0236c3be16b414145be3f4046de2ea6c27a68a7.tar.gz gcc-d0236c3be16b414145be3f4046de2ea6c27a68a7.tar.bz2 |
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
Diffstat (limited to 'gcc/reload.c')
-rw-r--r-- | gcc/reload.c | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/gcc/reload.c b/gcc/reload.c index ceb12ba..31d79ae 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -6941,9 +6941,39 @@ find_inc_amount (rtx x, rtx inced) 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. - If SETS is nonzero, also consider SETs. REGNO must refer to a hard - register. */ + If SETS is 1, also consider SETs. If SETS is 2, enable checking + REG_INC. REGNO must refer to a hard register. */ int 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; 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))) { unsigned int test = REGNO (XEXP (PATTERN (insn), 0)); @@ -6966,6 +6996,9 @@ regno_clobbered_p (unsigned int regno, rtx insn, enum machine_mode mode, 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) { int i = XVECLEN (PATTERN (insn), 0) - 1; @@ -6974,7 +7007,7 @@ regno_clobbered_p (unsigned int regno, rtx insn, enum machine_mode mode, { rtx elt = XVECEXP (PATTERN (insn), 0, i); if ((GET_CODE (elt) == CLOBBER - || (sets && GET_CODE (PATTERN (insn)) == SET)) + || (sets == 1 && GET_CODE (PATTERN (insn)) == SET)) && REG_P (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, if (test >= regno && test < endregno) return 1; } + if (sets == 2 + && reg_inc_found_and_valid_p (regno, endregno, elt)) + return 1; } } |