diff --git a/gcc/testsuite/gcc.dg/torture/pr107447.c b/gcc/testsuite/gcc.dg/torture/pr107447.c new file mode 100644 index 0000000000000000000000000000000000000000..06f7b7b15ae7b138ea126be8ef10701f03814948 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr107447.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ + +int n; + +void +bar (int, int); + +__attribute__ ((noinline, returns_twice)) int +zero (void) +{ + return 0; +} + +void +foo (void) +{ + (void) zero (); + + n = 0; + + for (;;) + bar (zero (), n); +} diff --git a/gcc/tree-ssa-loop-im.cc b/gcc/tree-ssa-loop-im.cc index 2ea815050d18b93422bc2add54bf7d6c4d85f9b1..2119d4072d3a9dd36ff5b92b8e7d563b9c8c1c5d 100644 --- a/gcc/tree-ssa-loop-im.cc +++ b/gcc/tree-ssa-loop-im.cc @@ -835,10 +835,15 @@ determine_max_movement (gimple *stmt, bool must_preserve_exec) return true; } - else - FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, SSA_OP_USE) - if (!add_dependency (val, lim_data, loop, true)) - return false; + + /* A stmt that receives abnormal edges cannot be hoisted. */ + if (is_a <gcall *> (stmt) + && (gimple_call_flags (stmt) & ECF_RETURNS_TWICE)) + return false; + + FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, SSA_OP_USE) + if (!add_dependency (val, lim_data, loop, true)) + return false; if (gimple_vuse (stmt)) {