The following shows that tail-merging will make dead SSA defs live
in paths where it wasn't before, possibly introducing UB or as
in this case, uses of abnormals that eventually fail coalescing
later.  The fix is to register such defs for stmt comparison.

Bootstrap and regtest running on x86_64-unknown-linux-gnu.

        PR tree-optimization/98845
        * tree-ssa-tail-merge.cc (stmt_local_def): Consider a
        def with no uses not local.

        * gcc.dg/pr98845.c: New testcase.
---
 gcc/testsuite/gcc.dg/pr98845.c | 33 +++++++++++++++++++++++++++++++++
 gcc/tree-ssa-tail-merge.cc     |  8 ++++++++
 2 files changed, 41 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/pr98845.c

diff --git a/gcc/testsuite/gcc.dg/pr98845.c b/gcc/testsuite/gcc.dg/pr98845.c
new file mode 100644
index 00000000000..074c979678f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr98845.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-tree-dce -fno-tree-dse" } */
+
+int n;
+
+__attribute__ ((returns_twice)) void
+foo (void);
+
+void
+bar (void);
+
+void
+quux (int x)
+{
+  if (x)
+    ++x;
+  else
+    {
+      if (n)
+        {
+          x = 1;
+          foo ();
+        }
+      else
+        bar ();
+
+      if (n)
+        {
+          ++x;
+          ++n;
+        }
+    }
+}
diff --git a/gcc/tree-ssa-tail-merge.cc b/gcc/tree-ssa-tail-merge.cc
index d897970079c..857e91c206b 100644
--- a/gcc/tree-ssa-tail-merge.cc
+++ b/gcc/tree-ssa-tail-merge.cc
@@ -336,10 +336,13 @@ stmt_local_def (gimple *stmt)
 
   def_bb = gimple_bb (stmt);
 
+  bool any_use = false;
   FOR_EACH_IMM_USE_FAST (use_p, iter, val)
     {
       if (is_gimple_debug (USE_STMT (use_p)))
        continue;
+
+      any_use = true;
       bb = gimple_bb (USE_STMT (use_p));
       if (bb == def_bb)
        continue;
@@ -351,6 +354,11 @@ stmt_local_def (gimple *stmt)
       return false;
     }
 
+  /* When there is no use avoid making the stmt live on other paths.
+     This can happen with DCE disabled or not done as seen in PR98845.  */
+  if (!any_use)
+    return false;
+
   return true;
 }
 
-- 
2.43.0

Reply via email to