This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PATCH: [4.1/4.2 Regression]: Miscompiled FORTRAN program


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:


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]