diff options
author | Richard Biener <rguenther@suse.de> | 2021-06-22 10:14:02 +0200 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2021-06-22 12:09:59 +0200 |
commit | a2ef8395fa970498985764514044e5fd00f7d5c0 (patch) | |
tree | 10b6023661e131ef103b33f2cca0018f39c8df1f /gcc | |
parent | 7822285515cd4dab86f722a9f4969b6952904a37 (diff) | |
download | gcc-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.c | 19 | ||||
-rw-r--r-- | gcc/tree-ssa-sink.c | 9 |
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; } |