Patchwork Fix combiner i3/i2 pattern splitting (PR rtl-optimization/45695, take 2)

login
register
mail settings
Submitter Jakub Jelinek
Date Sept. 20, 2010, 1:42 p.m.
Message ID <20100920134250.GN1269@tyan-ft48-01.lab.bos.redhat.com>
Download mbox | patch
Permalink /patch/65209/
State New
Headers show

Comments

Jakub Jelinek - Sept. 20, 2010, 1:42 p.m.
On Mon, Sep 20, 2010 at 01:20:01PM +0200, Eric Botcazou wrote:
> > The following patch just fixes the HAVE_cc0 case then and does the removal.
> 
> It will enable more combining for all targets though, won't it?  If so, I 
> think that it isn't appropriate for the branch.  Just replace the 'break' 
> with 'undo_all + return' there (and add the missing call to use_crosses_set_p 
> for cc0 targets if you want).

So this for 4.5 branch instead?

2010-09-20  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/45695
	* combine.c (try_combine): Don't try to swap the two patterns, if the
	chosen order is not possible, just give up.  For HAVE_cc0 targets,
	check if XVECEXP (newpat, 0, 0) doesn't use REGs or MEMs set by insns
	in between i2 and i3.

	* gcc.c-torture/execute/pr45695.c: New test.



	Jakub
Eric Botcazou - Sept. 20, 2010, 8:22 p.m.
> 2010-09-20  Jakub Jelinek  <jakub@redhat.com>
>
> 	PR rtl-optimization/45695
> 	* combine.c (try_combine): Don't try to swap the two patterns, if the
> 	chosen order is not possible, just give up.  For HAVE_cc0 targets,
> 	check if XVECEXP (newpat, 0, 0) doesn't use REGs or MEMs set by insns
> 	in between i2 and i3.
>
> 	* gcc.c-torture/execute/pr45695.c: New test.

Yes, thanks.

Patch

--- gcc/combine.c.jj	2010-09-20 15:26:42.420457795 +0200
+++ gcc/combine.c	2010-09-20 15:35:17.249646756 +0200
@@ -3531,6 +3531,12 @@  try_combine (rtx i3, rtx i2, rtx i1, int
 #ifdef HAVE_cc0
       if (reg_referenced_p (cc0_rtx, XVECEXP (newpat, 0, 0)))
 	{
+	  if (use_crosses_set_p (SET_SRC (XVECEXP (newpat, 0, 0)),
+				 DF_INSN_LUID (i2)))
+	    {
+	      undo_all ();
+	      return 0;
+	    }
 	  newi2pat = XVECEXP (newpat, 0, 0);
 	  newpat = XVECEXP (newpat, 0, 1);
 	}
@@ -3554,44 +3560,11 @@  try_combine (rtx i3, rtx i2, rtx i1, int
 		  {
 		    rtx reg = XEXP (XVECEXP (newi2pat, 0, i), 0);
 		    if (reg_overlap_mentioned_p (reg, newpat))
-		      break;
+		      {
+			undo_all ();
+			return 0;
+		      }
 		  }
-
-	      if (i >= 0)
-		{
-		  /* CLOBBERs on newi2pat prevent it going first.
-		     Try the other order of the insns if possible.  */
-		  temp = newpat;
-		  newpat = XVECEXP (newi2pat, 0, 0);
-		  newi2pat = temp;
-#ifdef HAVE_cc0
-		  if (reg_referenced_p (cc0_rtx, newpat))
-		    {
-		      undo_all ();
-		      return 0;
-		    }
-#endif
-
-		  i2_code_number = recog_for_combine (&newi2pat, i2,
-						      &new_i2_notes);
-		  if (i2_code_number < 0)
-		    {
-		      undo_all ();
-		      return 0;
-		    }
-
-		  if (GET_CODE (newi2pat) == PARALLEL)
-		    for (i = XVECLEN (newi2pat, 0) - 1; i >= 0; i--)
-		      if (GET_CODE (XVECEXP (newi2pat, 0, i)) == CLOBBER)
-			{
-			  rtx reg = XEXP (XVECEXP (newi2pat, 0, i), 0);
-			  if (reg_overlap_mentioned_p (reg, newpat))
-			    {
-			      undo_all ();
-			      return 0;
-			    }
-			}
-		}
 	    }
 
 	  insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
--- gcc/testsuite/gcc.c-torture/execute/pr45695.c.jj	2010-09-20 15:33:11.081489086 +0200
+++ gcc/testsuite/gcc.c-torture/execute/pr45695.c	2010-09-20 15:33:11.082656001 +0200
@@ -0,0 +1,32 @@ 
+/* PR rtl-optimization/45695 */
+
+extern void abort (void);
+
+__attribute__((noinline)) void
+g (int x)
+{
+  asm volatile ("" : "+r" (x));
+}
+
+__attribute__((noinline)) int
+f (int a, int b, int d)
+{
+  int r = -1;
+  b += d;
+  if (d == a)
+    r = b - d;
+  g (b);
+  return r;
+}
+
+int
+main (void)
+{
+  int l;
+  asm ("" : "=r" (l) : "0" (0));
+  if (f (l + 0, l + 1, l + 4) != -1)
+    abort ();
+  if (f (l + 4, l + 1, l + 4) != 1)
+    abort ();
+  return 0;
+}