diff mbox series

tree-optimization/101151 - fix irreducible region check for sinking

Message ID or281q70-22o0-1s13-2141-pqsr1592sqoo@fhfr.qr
State New
Headers show
Series tree-optimization/101151 - fix irreducible region check for sinking | expand

Commit Message

Richard Biener June 22, 2021, 10:09 a.m. UTC
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.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

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 | 19 +++++++++++++++++++
 gcc/tree-ssa-sink.c                     |  9 ++++++++-
 2 files changed, 27 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr101151.c
diff mbox series

Patch

diff --git a/gcc/testsuite/gcc.dg/torture/pr101151.c b/gcc/testsuite/gcc.dg/torture/pr101151.c
new file mode 100644
index 00000000000..15c9a7b7f57
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr101151.c
@@ -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;
+}
diff --git a/gcc/tree-ssa-sink.c b/gcc/tree-ssa-sink.c
index d252cbb5c51..92f444ec1c8 100644
--- a/gcc/tree-ssa-sink.c
+++ b/gcc/tree-ssa-sink.c
@@ -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;
 		}