aboutsummaryrefslogtreecommitdiff
path: root/gcc/reload.c
diff options
context:
space:
mode:
authorDenis Nagorny <denis_nagorny@linux.intel.com>2006-02-17 00:03:06 +0000
committerH.J. Lu <hjl@gcc.gnu.org>2006-02-16 16:03:06 -0800
commitd0236c3be16b414145be3f4046de2ea6c27a68a7 (patch)
tree21926960298be1c0dcf47707a036cdd3d30e8472 /gcc/reload.c
parent464aea985957cde55ba4c6a3781293441b89119f (diff)
downloadgcc-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.c44
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;
}
}