This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PATCH: [4.1/4.2 Regression]: Miscompiled FORTRAN program
- From: Denis Nagorny <denis_nagorny at linux dot intel dot com>
- To: Jim Wilson <wilson at specifix dot com>
- Cc: "H. J. Lu" <hjl at lucon dot org>, grigory_zagorodnev at linux dot intel dot com, gcc at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Date: Wed, 15 Feb 2006 16:52:36 +0300
- Subject: Re: PATCH: [4.1/4.2 Regression]: Miscompiled FORTRAN program
- References: <43F1A355.6020307@codesourcery.com> <84fc9c000602140210v1a73358ciabc48420c25d4b2e@mail.gmail.com> <43F23414.4090602@codesourcery.com> <20060214200344.GA12578@lucon.org> <43F252B9.1070202@specifix.com>
Jim Wilson wrote:
I don't believe this is safe. If you look at the uses of
regno_clobbered_p in reload.c, the comments clearly indicate that we are
looking for registers used in clobbers. So unconditionally adding code
that handles REG_INC notes will break these uses. You have to add the
REG_INC support the same way that the sets support was added, by adding
another argument (or reusing the sets argument), and then modifying the
one place we know is broken (choose_reload_regs) to use the new argument
(or new sets argument value).
Jim,
Did I understand your idea correctly? Can you comment new patch version.
It isn't fully tested but am I going in right direction?
2006-02-13 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 egno_clobbered_p
with new meaning of SETS.
Index: reload.c
===================================================================
*** reload.c (revision 110905)
--- reload.c (working copy)
*************** static int find_inc_amount (rtx, rtx);
*** 281,286 ****
--- 281,287 ----
static int refers_to_mem_for_reload_p (rtx);
static int refers_to_regno_for_reload_p (unsigned int, unsigned int,
rtx, rtx *);
+ static int reg_inc_found_and_valid_p(unsigned int, unsigned int, rtx);
/* Determine if any secondary reloads are needed for loading (if IN_P is
nonzero) or storing (if IN_P is zero) X to or from a reload register of
*************** find_inc_amount (rtx x, rtx inced)
*** 6941,6949 ****
return 0;
}
/* 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. */
int
regno_clobbered_p (unsigned int regno, rtx insn, enum machine_mode mode,
--- 6942,6978 ----
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. */
+
+ static int
+ reg_inc_found_and_valid_p(unsigned int regno ATTRIBUTE_UNUSED,
+ unsigned int endregno ATTRIBUTE_UNUSED,
+ rtx insn ATTRIBUTE_UNUSED)
+ {
+ #ifdef AUTO_INC_DEC
+ 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;
+ }
+ #endif
+ return 0;
+
+ }
+
/* Return 1 if register REGNO is the subject of a clobber in insn INSN.
! 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,
*************** regno_clobbered_p (unsigned int regno, r
*** 6958,6964 ****
endregno = regno + nregs;
if ((GET_CODE (PATTERN (insn)) == CLOBBER
! || (sets && GET_CODE (PATTERN (insn)) == SET))
&& REG_P (XEXP (PATTERN (insn), 0)))
{
unsigned int test = REGNO (XEXP (PATTERN (insn), 0));
--- 6987,6993 ----
endregno = regno + nregs;
if ((GET_CODE (PATTERN (insn)) == CLOBBER
! || (sets == 1 && GET_CODE (PATTERN (insn)) == SET))
&& REG_P (XEXP (PATTERN (insn), 0)))
{
unsigned int test = REGNO (XEXP (PATTERN (insn), 0));
*************** regno_clobbered_p (unsigned int regno, r
*** 6966,6971 ****
--- 6995,7003 ----
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;
*************** regno_clobbered_p (unsigned int regno, r
*** 6974,6980 ****
{
rtx elt = XVECEXP (PATTERN (insn), 0, i);
if ((GET_CODE (elt) == CLOBBER
! || (sets && GET_CODE (PATTERN (insn)) == SET))
&& REG_P (XEXP (elt, 0)))
{
unsigned int test = REGNO (XEXP (elt, 0));
--- 7006,7012 ----
{
rtx elt = XVECEXP (PATTERN (insn), 0, i);
if ((GET_CODE (elt) == CLOBBER
! || (sets == 1 && GET_CODE (PATTERN (insn)) == SET))
&& REG_P (XEXP (elt, 0)))
{
unsigned int test = REGNO (XEXP (elt, 0));
*************** regno_clobbered_p (unsigned int regno, r
*** 6982,6987 ****
--- 7014,7021 ----
if (test >= regno && test < endregno)
return 1;
}
+ if (sets == 2 && reg_inc_found_and_valid_p(regno, endregno, elt))
+ return 1;
}
}
Index: reload1.c
===================================================================
*** reload1.c (revision 110905)
--- reload1.c (working copy)
*************** choose_reload_regs (struct insn_chain *c
*** 5780,5786 ****
if (equiv != 0)
{
! if (regno_clobbered_p (regno, insn, rld[r].mode, 0))
switch (rld[r].when_needed)
{
case RELOAD_FOR_OTHER_ADDRESS:
--- 5780,5787 ----
if (equiv != 0)
{
! if (regno_clobbered_p (regno, insn, rld[r].mode, 0)
! || regno_clobbered_p (regno, insn, rld[r].mode, 2))
switch (rld[r].when_needed)
{
case RELOAD_FOR_OTHER_ADDRESS: