Blame SOURCES/gcc34-rh172117.patch

6fdc0f
2005-12-18  Alexandre Oliva  <aoliva@redhat.com>
6fdc0f
6fdc0f
	* optabs.c (expand_vector_binop): Do not use a SUBREG to modify
6fdc0f
	a subword in the output if it matches any of the inputs.
6fdc0f
6fdc0f
2006-04-20  Jakub Jelinek  <jakub@redhat.com>
6fdc0f
6fdc0f
	* gcc.c-torture/execute/20060420-1.c: New test.
6fdc0f
6fdc0f
--- gcc/optabs.c.orig	2005-11-21 11:43:20.000000000 -0200
6fdc0f
+++ gcc/optabs.c	2005-12-18 18:35:14.000000000 -0200
6fdc0f
@@ -1933,16 +1933,19 @@
6fdc0f
 
6fdc0f
       for (i = 0; i < elts; ++i)
6fdc0f
 	{
6fdc0f
-	  /* If this is part of a register, and not the first item in the
6fdc0f
-	     word, we can't store using a SUBREG - that would clobber
6fdc0f
-	     previous results.
6fdc0f
+	  /* If this is part of a register, and not the first item in
6fdc0f
+	     the word, we can't store using a SUBREG - that would
6fdc0f
+	     clobber previous results, or even the input operands, if
6fdc0f
+	     target matches any of them.
6fdc0f
 	     And storing with a SUBREG is only possible for the least
6fdc0f
 	     significant part, hence we can't do it for big endian
6fdc0f
 	     (unless we want to permute the evaluation order.  */
6fdc0f
 	  if (GET_CODE (target) == REG
6fdc0f
 	      && (BYTES_BIG_ENDIAN
6fdc0f
 		  ? subsize < UNITS_PER_WORD
6fdc0f
-		  : ((i * subsize) % UNITS_PER_WORD) != 0))
6fdc0f
+		  : (((i * subsize) % UNITS_PER_WORD) != 0
6fdc0f
+		     || (subsize < UNITS_PER_WORD
6fdc0f
+			 && (target == op0 || target == op1)))))
6fdc0f
 	    t = NULL_RTX;
6fdc0f
 	  else
6fdc0f
 	    t = simplify_gen_subreg (submode, target, mode, i * subsize);
6fdc0f
--- gcc/testsuite/gcc.c-torture/execute/20060420-1.c.jj	2006-04-20 18:47:19.000000000 +0200
6fdc0f
+++ gcc/testsuite/gcc.c-torture/execute/20060420-1.c	2006-04-20 19:07:20.000000000 +0200
6fdc0f
@@ -0,0 +1,71 @@
6fdc0f
+extern void abort (void);
6fdc0f
+
6fdc0f
+typedef float v4flt __attribute__ ((vector_size (16)));
6fdc0f
+
6fdc0f
+void __attribute__ ((noinline)) foo (float *dst, float **src, int a, int n)
6fdc0f
+{
6fdc0f
+  int i, j;
6fdc0f
+  int z = sizeof (v4flt) / sizeof (float);
6fdc0f
+  unsigned m = sizeof (v4flt) - 1;
6fdc0f
+
6fdc0f
+  for (j = 0; j < n && (((unsigned long) dst + j) & m); ++j)
6fdc0f
+    {
6fdc0f
+      float t = src[0][j];
6fdc0f
+      for (i = 1; i < a; ++i)
6fdc0f
+	t += src[i][j];
6fdc0f
+      dst[j] = t;
6fdc0f
+    }
6fdc0f
+
6fdc0f
+  for (; j < (n - (4 * z - 1)); j += 4 * z)
6fdc0f
+    {
6fdc0f
+      v4flt t0 = *(v4flt *) (src[0] + j + 0 * z);
6fdc0f
+      v4flt t1 = *(v4flt *) (src[0] + j + 1 * z);
6fdc0f
+      v4flt t2 = *(v4flt *) (src[0] + j + 2 * z);
6fdc0f
+      v4flt t3 = *(v4flt *) (src[0] + j + 3 * z);
6fdc0f
+      for (i = 1; i < a; ++i)
6fdc0f
+	{
6fdc0f
+	  t0 += *(v4flt *) (src[i] + j + 0 * z);
6fdc0f
+	  t1 += *(v4flt *) (src[i] + j + 1 * z);
6fdc0f
+	  t2 += *(v4flt *) (src[i] + j + 2 * z);
6fdc0f
+	  t3 += *(v4flt *) (src[i] + j + 3 * z);
6fdc0f
+	}
6fdc0f
+      *(v4flt *) (dst + j + 0 * z) = t0;
6fdc0f
+      *(v4flt *) (dst + j + 1 * z) = t1;
6fdc0f
+      *(v4flt *) (dst + j + 2 * z) = t2;
6fdc0f
+      *(v4flt *) (dst + j + 3 * z) = t3;
6fdc0f
+    }
6fdc0f
+  for (; j < n; ++j)
6fdc0f
+    {
6fdc0f
+      float t = src[0][j];
6fdc0f
+      for (i = 1; i < a; ++i)
6fdc0f
+	t += src[i][j];
6fdc0f
+      dst[j] = t;
6fdc0f
+    }
6fdc0f
+}
6fdc0f
+
6fdc0f
+float buffer[64];
6fdc0f
+
6fdc0f
+int
6fdc0f
+main (void)
6fdc0f
+{
6fdc0f
+  int i;
6fdc0f
+  float *dst, *src[2];
6fdc0f
+
6fdc0f
+  dst = buffer;
6fdc0f
+  dst += (-(long int) buffer & (16 * sizeof (float) - 1)) / sizeof (float);
6fdc0f
+  src[0] = dst + 16;
6fdc0f
+  src[1] = dst + 32;
6fdc0f
+  for (i = 0; i < 16; ++i)
6fdc0f
+    {
6fdc0f
+      src[0][i] = (float) i + 11 * (float) i;
6fdc0f
+      src[1][i] = (float) i + 12 * (float) i;
6fdc0f
+    }
6fdc0f
+  foo (dst, src, 2, 16);
6fdc0f
+  for (i = 0; i < 16; ++i)
6fdc0f
+    {
6fdc0f
+      float e = (float) i + 11 * (float) i + (float) i + 12 * (float) i;
6fdc0f
+      if (dst[i] != e)
6fdc0f
+	abort ();
6fdc0f
+    }
6fdc0f
+  return 0;
6fdc0f
+}