Avoid moving pure/const calls that may return twice in tree-ssa-sink: properly redirecting the associated abnormal edge is non-trivial.
gcc/ChangeLog: PR tree-optimization/107505 * tree-ssa-sink.cc (statement_sink_location): Additionally reject ECF_RETURNS_TWICE calls. gcc/testsuite/ChangeLog: PR tree-optimization/107505 * gcc.dg/pr107505.c: New test. --- Preapproved by Richi on the Bugzilla, pushed after testing. gcc/testsuite/gcc.dg/pr107505.c | 26 ++++++++++++++++++++++++++ gcc/tree-ssa-sink.cc | 5 +++-- 2 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr107505.c diff --git a/gcc/testsuite/gcc.dg/pr107505.c b/gcc/testsuite/gcc.dg/pr107505.c new file mode 100644 index 000000000..01270eac9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr107505.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-guess-branch-probability" } */ + +int n; + +void +bar (void); + +__attribute__ ((noinline, returns_twice)) int +zero (void) +{ + return 0; +} + +void +foo (void) +{ + int a = zero (); + + for (n = 0; n < 2; ++n) + { + } + + if (a) + bar (); +} diff --git a/gcc/tree-ssa-sink.cc b/gcc/tree-ssa-sink.cc index 921305201..eb7c2e681 100644 --- a/gcc/tree-ssa-sink.cc +++ b/gcc/tree-ssa-sink.cc @@ -263,12 +263,13 @@ statement_sink_location (gimple *stmt, basic_block frombb, *zero_uses_p = false; - /* We only can sink assignments and non-looping const/pure calls. */ + /* We only can sink assignments and const/pure calls that are guaranteed + to return exactly once. */ int cf; if (!is_gimple_assign (stmt) && (!is_gimple_call (stmt) || !((cf = gimple_call_flags (stmt)) & (ECF_CONST|ECF_PURE)) - || (cf & ECF_LOOPING_CONST_OR_PURE))) + || (cf & (ECF_LOOPING_CONST_OR_PURE|ECF_RETURNS_TWICE)))) return false; /* We only can sink stmts with a single definition. */ -- 2.37.2