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: Fix PR rtl-optimization/27761 (miscompilation)


Hi!

On Fri, May 26, 2006 at 04:07:30PM -0700, Ian Lance Taylor wrote:
> Michael Matz <matz@suse.de> writes:
> 
> > 	* combine.c (try_combine): Protect i1src and i2src from becoming
> > 	shared through subst().
> 
> This patch is going to generate a lot of garbage.
> 
> Suppose we instead eliminate the UNIQUE_COPY parameter to subst, and
> always copy TO if we are going to substitute it?  That would at least
> cut down on the garbage a bit.
> 
> Anybody else have any thoughts on this?

Jim apparently outlined a fix for this in bugzilla many months ago.
I have tested that this fixes the bug (on ia64 on both trunk and on
gcc-4_1-branch) and bootstrapped/regtested it on 7 linux arches.
I have also tried to add a temporary assertion to see when
i1pat RTL changed and it hits already several times in libgcc.a, though
in that case the RTL changes did not cause miscompilation.

Ok for trunk/4.2/4.1?

2006-12-08  Jim Wilson  <wilson@specifix.com>
	    Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/27761
	* combine.c (try_combine): Don't create a useless garbage SET
	if PATTERN (i2) is a PARALLEL.  If added_sets_1, save
	PATTERN (i1) resp. SET from i1src to i1dest in i1pat
	and use it to prevent accidental modification of i1src.

--- gcc/combine.c.jj	2006-11-17 09:55:14.000000000 +0100
+++ gcc/combine.c	2006-12-07 15:33:37.000000000 +0100
@@ -1819,8 +1819,8 @@ try_combine (rtx i3, rtx i2, rtx i1, int
   rtx i3dest_killed = 0;
   /* SET_DEST and SET_SRC of I2 and I1.  */
   rtx i2dest, i2src, i1dest = 0, i1src = 0;
-  /* PATTERN (I2), or a copy of it in certain cases.  */
-  rtx i2pat;
+  /* PATTERN (I1) and PATTERN (I2), or a copy of it in certain cases.  */
+  rtx i1pat = 0, i2pat = 0;
   /* Indicates if I2DEST or I1DEST is in I2SRC or I1_SRC.  */
   int i2dest_in_i2src = 0, i1dest_in_i1src = 0, i2dest_in_i1src = 0;
   int i2dest_killed = 0, i1dest_killed = 0;
@@ -2218,12 +2218,21 @@ try_combine (rtx i3, rtx i2, rtx i1, int
      rtx.  If I2 is a PARALLEL, we just need the piece that assigns I2SRC to
      I2DEST.  */
 
-  i2pat = (GET_CODE (PATTERN (i2)) == PARALLEL
-	   ? gen_rtx_SET (VOIDmode, i2dest, i2src)
-	   : PATTERN (i2));
-
   if (added_sets_2)
-    i2pat = copy_rtx (i2pat);
+    {
+      if (GET_CODE (PATTERN (i2)) == PARALLEL)
+	i2pat = gen_rtx_SET (VOIDmode, i2dest, copy_rtx (i2src));
+      else
+	i2pat = copy_rtx (PATTERN (i2));
+    }
+
+  if (added_sets_1)
+    {
+      if (GET_CODE (PATTERN (i1)) == PARALLEL)
+	i1pat = gen_rtx_SET (VOIDmode, i1dest, copy_rtx (i1src));
+      else
+	i1pat = copy_rtx (PATTERN (i1));
+    }
 
   combine_merges++;
 
@@ -2418,9 +2427,7 @@ try_combine (rtx i3, rtx i2, rtx i1, int
 	}
 
       if (added_sets_1)
-	XVECEXP (newpat, 0, --total_sets)
-	  = (GET_CODE (PATTERN (i1)) == PARALLEL
-	     ? gen_rtx_SET (VOIDmode, i1dest, i1src) : PATTERN (i1));
+	XVECEXP (newpat, 0, --total_sets) = i1pat;
 
       if (added_sets_2)
 	{


	Jakub


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