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

Denis Nagorny denis_nagorny@linux.intel.com
Wed Feb 15 13:52:00 GMT 2006


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:



More information about the Gcc mailing list