diff --git a/gcc/testsuite/gcc.dg/torture/pr97559-1.c b/gcc/testsuite/gcc.dg/torture/pr97559-1.c new file mode 100644 index 000000000000..d5de3bdb39e5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr97559-1.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ + +int printf (char *, ...); + +int a, b, c, d; + +void e () { + int f = a; + if (b) { + L1: + b = 0; + L2: + if (c) { + if (f) + printf("0"); + goto L1; + } + } + if (d) + goto L2; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr97559-2.c b/gcc/testsuite/gcc.dg/torture/pr97559-2.c new file mode 100644 index 000000000000..b512e6db7cae --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr97559-2.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ + +int a, b, c, d; + +void e() { + int f = b; + if (a) { + L1: + a = 0; + L2: + if (a) { + c = b; + goto L1; + } + } + if (d) + goto L2; +} diff --git a/gcc/tree-ssa-sink.c b/gcc/tree-ssa-sink.c index 207aae2818ae..b0abf4147d69 100644 --- a/gcc/tree-ssa-sink.c +++ b/gcc/tree-ssa-sink.c @@ -390,12 +390,15 @@ statement_sink_location (gimple *stmt, basic_block frombb, with the use. */ if (gimple_code (use_stmt) == GIMPLE_PHI) { - /* In case the PHI node post-dominates the current insert location - we can disregard it. But make sure it is not dominating - it as well as can happen in a CFG cycle. */ + /* In case the PHI node post-dominates the current insert + location we can disregard it. But make sure it is not + dominating it as well as can happen in a CFG cycle. */ if (commondom != bb && !dominated_by_p (CDI_DOMINATORS, commondom, bb) - && dominated_by_p (CDI_POST_DOMINATORS, commondom, bb)) + && 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)) continue; bb = EDGE_PRED (bb, PHI_ARG_INDEX_FROM_USE (use_p))->src; } @@ -407,7 +410,8 @@ statement_sink_location (gimple *stmt, basic_block frombb, continue; /* There is no easy way to disregard defs not on the path from frombb to commondom so just consider them all. */ - commondom = nearest_common_dominator (CDI_DOMINATORS, bb, commondom); + commondom = nearest_common_dominator (CDI_DOMINATORS, + bb, commondom); if (commondom == frombb) return false; }