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


James E Wilson wrote:
Yes, that is what I was suggesting.

It's corrected and tested on ia64 and x86-64. I've attached new version. Denis.

Index: reload.c
===================================================================
*** reload.c	(revision 111135)
--- 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,6977 ----
    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));
--- 6986,6992 ----
    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 ****
--- 6994,7002 ----
        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));
--- 7005,7011 ----
  	{
  	  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 ****
--- 7013,7020 ----
  	      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,5786 ----
  
  	      if (equiv != 0)
  		{
! 		  if (regno_clobbered_p (regno, insn, rld[r].mode, 2))
  		    switch (rld[r].when_needed)
  		      {
  		      case RELOAD_FOR_OTHER_ADDRESS:
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.

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