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

H. J. Lu hjl@lucon.org
Thu Feb 16 22:46:00 GMT 2006


On Thu, Feb 16, 2006 at 12:34:19PM -0800, James E Wilson wrote:
> On Thu, 2006-02-16 at 11:59, Denis Nagorny wrote:
> > It's corrected and tested on ia64 and x86-64. I've attached new version.
> > Denis.
> 
> This look pretty good.  There is still one place where the spacing looks
> funny.
> 
> > +         if (test >= regno && test < endregno)
> > + 	        return 1; 
> 
> Checking this in emacs, I see that the if statement is preceded by 8
> spaces, and the return is preceded by a tab and 8 spaces.  It should be
> only a tab before the if, and a tab and 2 spaces before the return.  Do
> you have tab stops set every 8 characters?  It looks like you might have
> tabs set to 2 characters, otherwise I don't see how you could make this
> mistake and not notice it.
> 
> There are also 3 other lines that start with spaces that should start
> with tabs, though this is only a minor problem.
> 
> Andrew Pinksi made a good suggestion.  The AUTO_INC_DEC ifdefs should be
> placed around the reg_inc_found_and_valid_p function instead of inside
> it.  This lets you get rid of the ATTRIBUTE_UNUSED stuff, and it also is
> more efficient, since it saves the cost of a call for !AUTO_INC_DEC
> targets.

I took the liberty to fix the format issue on behalf of Denis. Is this
OK for mainline?

Thanks.


H.J.
----
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.

--- gcc/reload.c.reg_inc	2006-02-14 09:37:12.000000000 -0800
+++ gcc/reload.c	2006-02-16 14:40:02.000000000 -0800
@@ -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, r
   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, r
       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, r
 	{
 	  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, r
 	      if (test >= regno && test < endregno)
 		return 1;
 	    }
+	  if (sets == 2
+	      && reg_inc_found_and_valid_p (regno, endregno, elt))
+	    return 1; 
 	}
     }
 
--- gcc/reload1.c.reg_inc	2006-02-16 06:47:16.000000000 -0800
+++ gcc/reload1.c	2006-02-16 14:35:37.000000000 -0800
@@ -5780,7 +5780,7 @@ choose_reload_regs (struct insn_chain *c
 
 	      if (equiv != 0)
 		{
-		  if (regno_clobbered_p (regno, insn, rld[r].mode, 0))
+		  if (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