aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2021-06-22 10:14:02 +0200
committerRichard Biener <rguenther@suse.de>2021-06-22 12:09:59 +0200
commita2ef8395fa970498985764514044e5fd00f7d5c0 (patch)
tree10b6023661e131ef103b33f2cca0018f39c8df1f /gcc
parent7822285515cd4dab86f722a9f4969b6952904a37 (diff)
downloadgcc-a2ef8395fa970498985764514044e5fd00f7d5c0.zip
gcc-a2ef8395fa970498985764514044e5fd00f7d5c0.tar.gz
gcc-a2ef8395fa970498985764514044e5fd00f7d5c0.tar.bz2
tree-optimization/101151 - fix irreducible region check for sinking
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr101151.c19
-rw-r--r--gcc/tree-ssa-sink.c9
2 files changed, 27 insertions, 1 deletions
diff --git a/gcc/testsuite/gcc.dg/torture/pr101151.c b/gcc/testsuite/gcc.dg/torture/pr101151.c
new file mode 100644
index 0000000..15c9a7b
--- /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 d252cbb..92f444e 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;
}