]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/59643 (Predictive commoning unnecessarily punts on scimark2...
authorJakub Jelinek <jakub@redhat.com>
Tue, 7 Jan 2014 07:49:10 +0000 (08:49 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 7 Jan 2014 07:49:10 +0000 (08:49 +0100)
PR tree-optimization/59643
* tree-predcom.c (split_data_refs_to_components): If one dr is
read and one write, determine_offset fails and the write isn't
in the bad component, just put the read into the bad component.

* gcc.dg/pr59643.c: New test.
* gcc.c-torture/execute/pr59643.c: New test.

From-SVN: r206384

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr59643.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr59643.c [new file with mode: 0644]
gcc/tree-predcom.c

index d52cdc3249e3f0b1ec489c7574b125352d051aca..4760b12e0c72023034278babe3e9e31a15a2b506 100644 (file)
@@ -1,3 +1,10 @@
+2014-01-07  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/59643
+       * tree-predcom.c (split_data_refs_to_components): If one dr is
+       read and one write, determine_offset fails and the write isn't
+       in the bad component, just put the read into the bad component.
+
 2014-01-07  Mike Stump  <mikestump@comcast.net>
            Jakub Jelinek  <jakub@redhat.com>
 
index e6576d46e115e071e824d3fb5e0280e05801a7a5..629d42011069a18c0c61ddf4c012dcad9a9696e4 100644 (file)
@@ -1,3 +1,9 @@
+2014-01-07  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/59643
+       * gcc.dg/pr59643.c: New test.
+       * gcc.c-torture/execute/pr59643.c: New test.
+
 2014-01-06  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/59589
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr59643.c b/gcc/testsuite/gcc.c-torture/execute/pr59643.c
new file mode 100644 (file)
index 0000000..e3e8a6a
--- /dev/null
@@ -0,0 +1,39 @@
+/* PR tree-optimization/59643 */
+
+#define N 32
+
+__attribute__((noinline, noclone)) void
+foo (double *a, double *b, double *c, double d, double e, int n)
+{
+  int i;
+  for (i = 1; i < n - 1; i++)
+    a[i] = d * (b[i] + c[i] + a[i - 1] + a[i + 1]) + e * a[i];
+}
+
+double expected[] = {
+  0.0, 10.0, 44.0, 110.0, 232.0, 490.0, 1020.0, 2078.0, 4152.0, 8314.0,
+  16652.0, 33326.0, 66664.0, 133354.0, 266748.0, 533534.0, 1067064.0,
+  2134138.0, 4268300.0, 8536622.0, 17073256.0, 34146538.0, 68293116.0,
+  136586270.0, 273172536.0, 546345082.0, 1092690188.0, 2185380398.0,
+  4370760808.0, 8741521642.0, 17483043324.0, 6.0
+};
+
+int
+main ()
+{
+  int i;
+  double a[N], b[N], c[N];
+  if (__DBL_MANT_DIG__ <= 35)
+    return 0;
+  for (i = 0; i < N; i++)
+    {
+      a[i] = (i & 3) * 2.0;
+      b[i] = (i & 7) - 4;
+      c[i] = i & 7;
+    }
+  foo (a, b, c, 2.0, 3.0, N);
+  for (i = 0; i < N; i++)
+    if (a[i] != expected[i])
+      __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr59643.c b/gcc/testsuite/gcc.dg/pr59643.c
new file mode 100644 (file)
index 0000000..f4df5e5
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR tree-optimization/59643 */
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-pcom-details" } */
+
+void
+foo (double *a, double *b, double *c, double d, double e, int n)
+{
+  int i;
+  for (i = 1; i < n - 1; i++)
+    a[i] = d * (b[i] + c[i] + a[i - 1] + a[i + 1]) + e * a[i];
+}
+
+/* { dg-final { scan-tree-dump-times "Before commoning:" 1 "pcom" } } */
+/* { dg-final { scan-tree-dump-times "Unrolling 2 times" 1 "pcom" } } */
+/* { dg-final { cleanup-tree-dump "pcom" } } */
index 92cecfabec7e37198e9e91e8953c0913736b4db4..7169b2f68f5656560e06fac9ff4e2d22c6853fcf 100644 (file)
@@ -772,10 +772,37 @@ split_data_refs_to_components (struct loop *loop,
       bad = component_of (comp_father, n);
 
       /* If both A and B are reads, we may ignore unsuitable dependences.  */
-      if (DR_IS_READ (dra) && DR_IS_READ (drb)
-         && (ia == bad || ib == bad
-             || !determine_offset (dra, drb, &dummy_off)))
-       continue;
+      if (DR_IS_READ (dra) && DR_IS_READ (drb))
+       {
+         if (ia == bad || ib == bad
+             || !determine_offset (dra, drb, &dummy_off))
+           continue;
+       }
+      /* If A is read and B write or vice versa and there is unsuitable
+        dependence, instead of merging both components into a component
+        that will certainly not pass suitable_component_p, just put the
+        read into bad component, perhaps at least the write together with
+        all the other data refs in it's component will be optimizable.  */
+      else if (DR_IS_READ (dra) && ib != bad)
+       {
+         if (ia == bad)
+           continue;
+         else if (!determine_offset (dra, drb, &dummy_off))
+           {
+             merge_comps (comp_father, comp_size, bad, ia);
+             continue;
+           }
+       }
+      else if (DR_IS_READ (drb) && ia != bad)
+       {
+         if (ib == bad)
+           continue;
+         else if (!determine_offset (dra, drb, &dummy_off))
+           {
+             merge_comps (comp_father, comp_size, bad, ib);
+             continue;
+           }
+       }
 
       merge_comps (comp_father, comp_size, ia, ib);
     }