aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2025-01-23 13:10:17 +0100
committerRichard Biener <rguenth@gcc.gnu.org>2025-01-27 13:31:35 +0100
commit04ba1300407f106a6dd10d346f58a51d87e6d43e (patch)
tree6a7f8caf63aa61a084933ed89c755ad4f89f58be
parent3600b1ff14a459e84bb40bdfea7cd8d2ffd73d8d (diff)
downloadgcc-04ba1300407f106a6dd10d346f58a51d87e6d43e.zip
gcc-04ba1300407f106a6dd10d346f58a51d87e6d43e.tar.gz
gcc-04ba1300407f106a6dd10d346f58a51d87e6d43e.tar.bz2
tree-optimization/112859 - bogus loop distribution
When we get a zero distance vector we still have to check for the situation of a common inner loop with zero distance. But we can still allow a zero distance for the loop we distribute (gcc.dg/tree-ssa/ldist-33.c is such a case). This is because zero distances in non-outermost loops are a misrepresentation of dependence by dependence analysis. Note that test coverage of loop distribution of loop nests is very low. PR tree-optimization/112859 PR tree-optimization/115347 * tree-loop-distribution.cc (loop_distribution::pg_add_dependence_edges): For a zero distance vector still make sure to not have an inner loop with zero distance. * gcc.dg/torture/pr112859.c: New testcase. * gcc.dg/torture/pr115347.c: Likewise.
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr112859.c24
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr115347.c21
-rw-r--r--gcc/tree-loop-distribution.cc27
3 files changed, 61 insertions, 11 deletions
diff --git a/gcc/testsuite/gcc.dg/torture/pr112859.c b/gcc/testsuite/gcc.dg/torture/pr112859.c
new file mode 100644
index 0000000..18f5bf4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr112859.c
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-additional-options "-ftree-loop-distribution" } */
+
+struct a {
+ char b;
+ int c;
+} f, *i = &f;
+static struct a e[4];
+int *d, **g = &d;
+static int h, j;
+int main()
+{
+ for (; h < 1; h++) {
+ struct a k = {1, 1};
+ for (j = 0; j < 2; j++) {
+ *i = e[h];
+ e[h] = k;
+ }
+ *g = 0;
+ }
+ if (f.c != 1)
+ __builtin_abort();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr115347.c b/gcc/testsuite/gcc.dg/torture/pr115347.c
new file mode 100644
index 0000000..2299495
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr115347.c
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+/* { dg-additional-options "-ftree-loop-distribution" } */
+
+struct a {
+ int b;
+ int c;
+} d, e[2];
+int f, g, h;
+int main()
+{
+ for (; f < 1; f++) {
+ for (h = 0; h < 2; h++) {
+ d = e[f];
+ g = e[1].c;
+ e[f].c = 1;
+ }
+ }
+ if (d.c != 1)
+ __builtin_abort();
+ return 0;
+}
diff --git a/gcc/tree-loop-distribution.cc b/gcc/tree-loop-distribution.cc
index 7c0e4a8..9d9d2ae 100644
--- a/gcc/tree-loop-distribution.cc
+++ b/gcc/tree-loop-distribution.cc
@@ -2178,25 +2178,30 @@ loop_distribution::pg_add_dependence_edges (struct graph *rdg, int dir,
gcc.dg/tree-ssa/pr94969.c. */
if (DDR_NUM_DIST_VECTS (ddr) != 1)
this_dir = 2;
- /* If the overlap is exact preserve stmt order. */
- else if (lambda_vector_zerop (DDR_DIST_VECT (ddr, 0),
- DDR_NB_LOOPS (ddr)))
- ;
- /* Else as the distance vector is lexicographic positive swap
- the dependence direction. */
else
{
- if (DDR_REVERSED_P (ddr))
- this_dir = -this_dir;
- this_dir = -this_dir;
-
+ /* If the overlap is exact preserve stmt order. */
+ if (lambda_vector_zerop (DDR_DIST_VECT (ddr, 0),
+ DDR_NB_LOOPS (ddr)))
+ ;
+ /* Else as the distance vector is lexicographic positive swap
+ the dependence direction. */
+ else
+ {
+ 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)
+ if (DDR_DIST_VECT (ddr, 0)[idx] == 0
+ /* Unless it is the outermost loop which is the one
+ we eventually distribute. */
+ && idx != 0)
this_dir = 2;
}
}