]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization/101151 - fix irreducible region check for sinking
authorRichard Biener <rguenther@suse.de>
Tue, 22 Jun 2021 08:14:02 +0000 (10:14 +0200)
committerRichard Biener <rguenther@suse.de>
Tue, 22 Jun 2021 10:09:59 +0000 (12:09 +0200)
The check whether two blocks are in the same irreducible region
and thus post-dominance checks being unreliable was incomplete
since an irreducible region can contain reducible sub-regions but
if one block is in the irreducible part and one not the check
still doesn't work as expected.

2021-06-22  Richard Biener  <rguenther@suse.de>

PR tree-optimization/101151
* tree-ssa-sink.c (statement_sink_location): Expand irreducible
region check.

* gcc.dg/torture/pr101151.c: New testcase.

gcc/testsuite/gcc.dg/torture/pr101151.c [new file with mode: 0644]
gcc/tree-ssa-sink.c

diff --git a/gcc/testsuite/gcc.dg/torture/pr101151.c b/gcc/testsuite/gcc.dg/torture/pr101151.c
new file mode 100644 (file)
index 0000000..15c9a7b
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+
+int a, *b = &a, c, d;
+int main() {
+  *b;
+  if (a) {
+  L1:
+    a = 0;
+  L2:
+    if (d) {
+      while (b)
+        ;
+      goto L1;
+    }
+  }
+  if (c)
+    goto L2;
+  return 0;
+}
index d252cbb5c518632477ed84650ec8f256244c618f..92f444ec1c818915c505cd2365a26f78a9bdc258 100644 (file)
@@ -398,7 +398,14 @@ statement_sink_location (gimple *stmt, basic_block frombb,
                      && dominated_by_p (CDI_POST_DOMINATORS, commondom, bb)
                      /* If the blocks are possibly within the same irreducible
                         cycle the above check breaks down.  */
-                     && !(bb->flags & commondom->flags & BB_IRREDUCIBLE_LOOP))
+                     && !((bb->flags & commondom->flags & BB_IRREDUCIBLE_LOOP)
+                          && bb->loop_father == commondom->loop_father)
+                     && !((commondom->flags & BB_IRREDUCIBLE_LOOP)
+                          && flow_loop_nested_p (commondom->loop_father,
+                                                 bb->loop_father))
+                     && !((bb->flags & BB_IRREDUCIBLE_LOOP)
+                          && flow_loop_nested_p (bb->loop_father,
+                                                 commondom->loop_father)))
                    continue;
                  bb = EDGE_PRED (bb, PHI_ARG_INDEX_FROM_USE (use_p))->src;
                }