]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization/112281 - loop distribution and zero dependence distances
authorRichard Biener <rguenther@suse.de>
Mon, 20 Nov 2023 12:39:52 +0000 (13:39 +0100)
committerRichard Biener <rguenther@suse.de>
Mon, 20 Nov 2023 13:58:10 +0000 (14:58 +0100)
The following fixes an omission in dependence testing for loop
distribution.  When the overall dependence distance is not zero but
the dependence direction in the innermost common loop is = there is
a conflict between the partitions and we have to merge them.

PR tree-optimization/112281
* tree-loop-distribution.cc
(loop_distribution::pg_add_dependence_edges): For = in the
innermost common loop record a partition conflict.

* gcc.dg/torture/pr112281-1.c: New testcase.
* gcc.dg/torture/pr112281-2.c: Likewise.

gcc/testsuite/gcc.dg/torture/pr112281-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr112281-2.c [new file with mode: 0644]
gcc/tree-loop-distribution.cc

diff --git a/gcc/testsuite/gcc.dg/torture/pr112281-1.c b/gcc/testsuite/gcc.dg/torture/pr112281-1.c
new file mode 100644 (file)
index 0000000..711f566
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do run } */
+/* { dg-additional-options "-ftree-loop-distribution" } */
+
+struct {
+  int : 8;
+  int a;
+} b, d[4] = {{0}, {0}, {0}, {5}};
+int c, e;
+int main() {
+  for (c = 2; c; c--)
+    for (e = 0; e < 2; e++) {
+      d[c] = b = d[c + 1];
+      d[c + 1].a = 0;
+    }
+  if (b.a != 0)
+    __builtin_abort();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr112281-2.c b/gcc/testsuite/gcc.dg/torture/pr112281-2.c
new file mode 100644 (file)
index 0000000..d7671e3
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do run } */
+/* { dg-additional-options "-ftree-loop-distribution" } */
+
+struct {
+  int : 8;
+  int a;
+} b, d[4] = {{5}, {0}, {0}, {0}};
+int c, e;
+int main() {
+  for (c = 0; c < 2; c++)
+    for (e = 0; e < 2; e++) {
+      d[c + 1] = b = d[c];
+      d[c].a = 0;
+    }
+  if (b.a != 0)
+    __builtin_abort();
+  return 0;
+}
index ffca535064bee1c080c13285ae96463f9951c7f5..95c1eea65beeb80aff6ee1457c911b186a712e03 100644 (file)
@@ -2155,9 +2155,6 @@ loop_distribution::pg_add_dependence_edges (struct graph *rdg, int dir,
            }
          else if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE)
            {
-             if (DDR_REVERSED_P (ddr))
-               this_dir = -this_dir;
-
              /* Known dependences can still be unordered througout the
                 iteration space, see gcc.dg/tree-ssa/ldist-16.c and
                 gcc.dg/tree-ssa/pr94969.c.  */
@@ -2170,7 +2167,20 @@ loop_distribution::pg_add_dependence_edges (struct graph *rdg, int dir,
              /* Else as the distance vector is lexicographic positive swap
                 the dependence direction.  */
              else
-               this_dir = -this_dir;
+               {
+                 if (DDR_REVERSED_P (ddr))
+                   this_dir = -this_dir;
+                 this_dir = -this_dir;
+
+                 /* When then dependence distance of the innermost common
+                    loop of the DRs is zero we have a conflict.  */
+                 auto l1 = gimple_bb (DR_STMT (dr1))->loop_father;
+                 auto l2 = gimple_bb (DR_STMT (dr2))->loop_father;
+                 int idx = index_in_loop_nest (find_common_loop (l1, l2)->num,
+                                               DDR_LOOP_NEST (ddr));
+                 if (DDR_DIST_VECT (ddr, 0)[idx] == 0)
+                   this_dir = 2;
+               }
            }
          else
            this_dir = 0;