aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2022-10-28 14:20:36 +0200
committerRichard Biener <rguenther@suse.de>2022-10-28 15:07:02 +0200
commit1add3635563b39e3c0e9bed4930d11b3f605fdd3 (patch)
tree172b91256d2daa827f12492d66f763b8292a9021
parent084128583212bd64308f50c2ab5f4c03be40e48c (diff)
downloadgcc-1add3635563b39e3c0e9bed4930d11b3f605fdd3.zip
gcc-1add3635563b39e3c0e9bed4930d11b3f605fdd3.tar.gz
gcc-1add3635563b39e3c0e9bed4930d11b3f605fdd3.tar.bz2
tree-optimization/107447 - avoid hoisting returns-twice calls in LIM
The following makes sure to not hoist returns-twice calls in LIM since we have no way to move the abnormal edge associated with it and we are prone having stray abnormal edges in the IL which will then cause IL verification failures even when the actual call does not return twice. PR tree-optimization/107447 * tree-ssa-loop-im.cc (determine_max_movement): Do not hoist returns-twice calls. * gcc.dg/torture/pr107447.c: New testcase.
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr107447.c23
-rw-r--r--gcc/tree-ssa-loop-im.cc13
2 files changed, 32 insertions, 4 deletions
diff --git a/gcc/testsuite/gcc.dg/torture/pr107447.c b/gcc/testsuite/gcc.dg/torture/pr107447.c
new file mode 100644
index 0000000..06f7b7b
--- /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 2ea8150..2119d40 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))
{