PR 63748 reports a false-positive uninitialized warning under the
presence of abnormal edges.  The statements for which the uninitialized
warnings are emitted all look like:

  buf_117(ab) = buf_317(D)(ab);

This PR is similar to PR 57287 which also reports false-positive
uninitialized warnings under the presence of abnormal edges.  That PR
fixed the reported issue by allowing to propagate default definitions
which appear in abnormal PHI nodes.  That is, it allowed propagating the
following kinds of copies:

  buf_24 = buf_16(D)(ab);

But it still did not allow propagating copies whose destination operand
occurs in an abnormal PHI node.  To fix PR 63748, this patch extends the
fix to PR 57287 to allow propagating such copies too.

Full bootstrap + regtesting on x86_64-unknown-linux-gnu is in progress.
Is this patch OK if testing succeeds with no new regressions?

2014-11-10  Patrick Palka  <ppa...@gcc.gnu.org>

gcc/
        PR middle-end/63748
        * tree-ssa-propagate.c (may_propagate_copy): Allow propagating
        SSA copies whose source and destination names both occur in
        abnormal edges.

gcc/testsuite/
        PR middle-end/63748
        * gcc.dg/pr63748.c: New testcase.
---
 gcc/testsuite/gcc.dg/pr63748.c | 36 ++++++++++++++++++++++++++++++++++++
 gcc/tree-ssa-propagate.c       | 27 +++++++++++++++------------
 2 files changed, 51 insertions(+), 12 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr63748.c

diff --git a/gcc/testsuite/gcc.dg/pr63748.c b/gcc/testsuite/gcc.dg/pr63748.c
new file mode 100644
index 0000000..2e50445
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr63748.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wall" } */
+
+#include <setjmp.h>
+
+jmp_buf *alloc_jmp_buf ();
+int foo (void *);
+
+int
+test (int op, int noside)
+{
+  void *argvec = 0;
+
+  if (op)
+    {
+      jmp_buf *buf = alloc_jmp_buf (); /* { dg-bogus "uninitialized" } */
+      setjmp (*buf);
+
+      if (noside)
+        goto nosideret;
+
+    do_call_it:
+
+      if (noside)
+        goto nosideret;
+
+      return foo (argvec);
+    }
+
+  argvec = __builtin_alloca (1);
+  goto do_call_it;
+
+nosideret:
+  return 1;
+}
+
diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c
index 9f4d381..9e61baf 100644
--- a/gcc/tree-ssa-propagate.c
+++ b/gcc/tree-ssa-propagate.c
@@ -1275,21 +1275,24 @@ may_propagate_copy (tree dest, tree orig)
   tree type_d = TREE_TYPE (dest);
   tree type_o = TREE_TYPE (orig);
 
-  /* If ORIG flows in from an abnormal edge, it cannot be propagated.  */
+  /* If ORIG is a default definition which flows in from an abnormal edge
+     then the copy can be propagated.  It is important that we do so to avoid
+     uninitialized regular copies.  */
   if (TREE_CODE (orig) == SSA_NAME
       && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig)
-      /* If it is the default definition and an automatic variable then
-         we can though and it is important that we do to avoid
-        uninitialized regular copies.  */
-      && !(SSA_NAME_IS_DEFAULT_DEF (orig)
-          && (SSA_NAME_VAR (orig) == NULL_TREE
-              || TREE_CODE (SSA_NAME_VAR (orig)) == VAR_DECL)))
+      && SSA_NAME_IS_DEFAULT_DEF (orig)
+      && (SSA_NAME_VAR (orig) == NULL_TREE
+         || TREE_CODE (SSA_NAME_VAR (orig)) == VAR_DECL))
+    ;
+  /* Otherwise if ORIG just flows in from an abnormal edge then the copy cannot
+     be propagated.  */
+  else if (TREE_CODE (orig) == SSA_NAME
+          && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig))
     return false;
-
-  /* If DEST is an SSA_NAME that flows from an abnormal edge, then it
-     cannot be replaced.  */
-  if (TREE_CODE (dest) == SSA_NAME
-      && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (dest))
+  /* Similarly if DEST flows in from an abnormal edge then the copy cannot be
+     propagated.  */
+  else if (TREE_CODE (dest) == SSA_NAME
+          && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (dest))
     return false;
 
   /* Do not copy between types for which we *do* need a conversion.  */
-- 
2.2.0.rc0.18.ga1ad247

Reply via email to