Hi!

Various places check that (ab) SSA_NAMEs that weren't referenced on a stmt
before don't appear on it, but all the checking is done on the gimple tuple
operands, while in this case it is added to operands of a comparison of
COND_EXPR/VEC_COND_EXPR.  The following patch fixes it,
bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2016-01-07  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/69167
        * gimple-match-head.c (gimple_simplify) <case GIMPLE_TERNARY_RHS>:
        Don't simplify condition if the condition simplification would
        introduce use of SSA_NAME_OCCURS_IN_ABNORMAL_PHI SSA_NAME not
        previously mentioned on the insn.
        * gimple-fold.h (has_use_on_stmt): New prototype.
        * gimple-fold.c (has_use_on_stmt): No longer static.

        * gcc.dg/pr69167.c: New test.

--- gcc/gimple-match-head.c.jj  2016-01-04 14:55:53.000000000 +0100
+++ gcc/gimple-match-head.c     2016-01-07 12:54:42.237334530 +0100
@@ -655,9 +655,23 @@ gimple_simplify (gimple *stmt,
                          valueized = true;
                          if (TREE_CODE_CLASS ((enum tree_code)rcode2)
                              == tcc_comparison)
-                           rhs1 = build2 (rcode2, TREE_TYPE (rhs1),
-                                          ops2[0], ops2[1]);
-                         else if (rcode2 == SSA_NAME
+                           {
+                             if (TREE_CODE (ops2[0]) == SSA_NAME
+                                 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops2[0])
+                                 && !has_use_on_stmt (ops2[0], stmt))
+                               valueized = false;
+                             if (TREE_CODE (ops2[1]) == SSA_NAME
+                                 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops2[1])
+                                 && !has_use_on_stmt (ops2[1], stmt))
+                               valueized = false;
+                             if (valueized)
+                               rhs1 = build2 (rcode2, TREE_TYPE (rhs1),
+                                              ops2[0], ops2[1]);
+                           }
+                         else if ((rcode2 == SSA_NAME
+                                   && (!SSA_NAME_OCCURS_IN_ABNORMAL_PHI
+                                                                     (ops2[0])
+                                       || has_use_on_stmt (ops2[0], stmt)))
                                   || rcode2 == INTEGER_CST
                                   || rcode2 == VECTOR_CST)
                            rhs1 = ops2[0];
--- gcc/gimple-fold.h.jj        2016-01-04 14:55:53.000000000 +0100
+++ gcc/gimple-fold.h   2016-01-07 13:01:52.938315972 +0100
@@ -34,6 +34,7 @@ extern tree maybe_fold_or_comparisons (e
                                       enum tree_code, tree, tree);
 extern bool arith_overflowed_p (enum tree_code, const_tree, const_tree,
                                const_tree);
+extern bool has_use_on_stmt (tree, gimple *);
 extern tree no_follow_ssa_edges (tree);
 extern tree follow_single_use_edges (tree);
 extern tree gimple_fold_stmt_to_constant_1 (gimple *, tree (*) (tree),
--- gcc/gimple-fold.c.jj        2016-01-07 11:37:36.000000000 +0100
+++ gcc/gimple-fold.c   2016-01-07 13:01:25.793695288 +0100
@@ -3270,7 +3270,7 @@ gimple_fold_call (gimple_stmt_iterator *
 
 /* Return true whether NAME has a use on STMT.  */
 
-static bool
+bool
 has_use_on_stmt (tree name, gimple *stmt)
 {
   imm_use_iterator iter;
--- gcc/testsuite/gcc.dg/pr69167.c.jj   2016-01-07 12:58:40.706002201 +0100
+++ gcc/testsuite/gcc.dg/pr69167.c      2016-01-07 12:58:22.000000000 +0100
@@ -0,0 +1,21 @@
+/* PR tree-optimization/69167 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int sigsetjmp (char *);
+void foo ();
+void bar (void (*) (int *));
+extern char t[];
+
+void
+baz (int *x)
+{
+  int *a = x;
+  foo ();
+  x = 0;
+  if (sigsetjmp (t))
+    while (1)
+      bar (a ? baz : 0);
+  if (x)
+    foo ();
+}

        Jakub

Reply via email to