diff options
author | Alexander Monakov <amonakov@ispras.ru> | 2022-11-07 15:33:01 +0300 |
---|---|---|
committer | Alexander Monakov <amonakov@ispras.ru> | 2022-11-07 16:01:14 +0300 |
commit | 5d060d8b0477ff4911f41c816281daaa24b41a13 (patch) | |
tree | c50c40b221a09b3b2e98e85f9c17360d0391c370 /gcc | |
parent | 3bff15c1c9fb3eb0bb042717e072476ec2d6d88c (diff) | |
download | gcc-5d060d8b0477ff4911f41c816281daaa24b41a13.zip gcc-5d060d8b0477ff4911f41c816281daaa24b41a13.tar.gz gcc-5d060d8b0477ff4911f41c816281daaa24b41a13.tar.bz2 |
tree-ssa-sink: do not touch calls that return twice
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/testsuite/gcc.dg/pr107505.c | 26 | ||||
-rw-r--r-- | gcc/tree-ssa-sink.cc | 5 |
2 files changed, 29 insertions, 2 deletions
diff --git a/gcc/testsuite/gcc.dg/pr107505.c b/gcc/testsuite/gcc.dg/pr107505.c new file mode 100644 index 0000000..01270eac --- /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 9213052..eb7c2e6 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. */ |