2015-10-14 Richard Biener <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 14 Oct 2015 12:59:15 +0000 (12:59 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 14 Oct 2015 12:59:15 +0000 (12:59 +0000)
PR tree-optimization/67915
* match.pd: Handle comparisons of addresses of STRING_CSTs.
* gimplify.c (gimplify_cond_expr): Fold the GIMPLE conds we build.
* tree-cfgcleanup.c (cleanup_control_expr_graph): Remove GENERIC
stmt folding in favor of GIMPLE one.

* gcc.dg/torture/pr67915.c: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@228810 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/gimplify.c
gcc/match.pd
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr67915.c [new file with mode: 0644]
gcc/tree-cfgcleanup.c

index d85a270..b257f39 100644 (file)
@@ -1,3 +1,11 @@
+2015-10-14  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/67915
+       * match.pd: Handle comparisons of addresses of STRING_CSTs.
+       * gimplify.c (gimplify_cond_expr): Fold the GIMPLE conds we build.
+       * tree-cfgcleanup.c (cleanup_control_expr_graph): Remove GENERIC
+       stmt folding in favor of GIMPLE one.
+
 2015-10-14  Marek Polacek  <polacek@redhat.com>
 
        PR tree-optimization/67815
index 4a9f7fd..071645f 100644 (file)
@@ -3152,11 +3152,12 @@ gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
 
   gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
                                 &arm2);
-
   cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true,
-                                   label_false);
-
+                                label_false);
   gimplify_seq_add_stmt (&seq, cond_stmt);
+  gimple_stmt_iterator gsi = gsi_last (seq);
+  maybe_fold_stmt (&gsi);
+
   label_cont = NULL_TREE;
   if (!have_then_clause_p)
     {
index 6714796..655c9ff 100644 (file)
@@ -1998,8 +1998,12 @@ along with GCC; see the file COPYING3.  If not see
           && decl_in_symtab_p (base1))
          equal = symtab_node::get_create (base0)
                   ->equal_address_to (symtab_node::get_create (base1));
-       else if ((DECL_P (base0) || TREE_CODE (base0) == SSA_NAME)
-               && (DECL_P (base1) || TREE_CODE (base1) == SSA_NAME))
+       else if ((DECL_P (base0)
+                || TREE_CODE (base0) == SSA_NAME
+                || TREE_CODE (base0) == STRING_CST)
+               && (DECL_P (base1)
+                   || TREE_CODE (base1) == SSA_NAME
+                   || TREE_CODE (base1) == STRING_CST))
          equal = (base0 == base1);
      }
      (if (equal == 1
@@ -2007,9 +2011,9 @@ along with GCC; see the file COPYING3.  If not see
              /* If the offsets are equal we can ignore overflow.  */
              || off0 == off1
              || POINTER_TYPE_OVERFLOW_UNDEFINED
-             /* Or if we compare using pointers to decls.  */
+             /* Or if we compare using pointers to decls or strings.  */
              || (POINTER_TYPE_P (TREE_TYPE (@2))
-                 && DECL_P (base0))))
+                 && (DECL_P (base0) || TREE_CODE (base0) == STRING_CST))))
       (switch
        (if (cmp == EQ_EXPR)
        { constant_boolean_node (off0 == off1, type); })
index 670b9e4..e6a457b 100644 (file)
@@ -1,3 +1,8 @@
+2015-10-14  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/67915
+       * gcc.dg/torture/pr67915.c: New testcase.
+
 2015-10-14  Marek Polacek  <polacek@redhat.com>
 
        PR tree-optimization/67815
diff --git a/gcc/testsuite/gcc.dg/torture/pr67915.c b/gcc/testsuite/gcc.dg/torture/pr67915.c
new file mode 100644 (file)
index 0000000..77a2edf
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+
+int a, b, c, d, e, f, g;
+
+int
+fn1 (int p1)
+{
+  return p1;
+}
+
+void
+fn2 ()
+{
+lbl:
+  g = b;
+  if (fn1 (c && e))
+    {
+      f = a ? 0 : 1 << 1;
+      short h = b;
+      d = h < 0 || f ? 0 : 1;
+    }
+  goto lbl;
+}
index 40e1456..eeedd8a 100644 (file)
@@ -56,6 +56,9 @@ along with GCC; see the file COPYING3.  If not see
 #include "cfgloop.h"
 #include "tree-ssa-propagate.h"
 #include "tree-scalar-evolution.h"
+#include "gimple-match.h"
+#include "gimple-fold.h"
+
 
 /* The set of blocks in that at least one of the following changes happened:
    -- the statement at the end of the block was changed
@@ -96,32 +99,34 @@ cleanup_control_expr_graph (basic_block bb, gimple_stmt_iterator gsi)
   edge taken_edge;
   bool retval = false;
   gimple *stmt = gsi_stmt (gsi);
-  tree val;
 
   if (!single_succ_p (bb))
     {
       edge e;
       edge_iterator ei;
       bool warned;
-      location_t loc;
+      tree val = NULL_TREE;
 
       fold_defer_overflow_warnings ();
-      loc = gimple_location (stmt);
       switch (gimple_code (stmt))
        {
        case GIMPLE_COND:
-         val = fold_binary_loc (loc, gimple_cond_code (stmt),
-                                boolean_type_node,
-                                gimple_cond_lhs (stmt),
-                                gimple_cond_rhs (stmt));
-         break;
+         {
+           code_helper rcode;
+           tree ops[3] = {};
+           if (gimple_simplify (stmt, &rcode, ops, NULL, no_follow_ssa_edges,
+                                no_follow_ssa_edges)
+               && rcode == INTEGER_CST)
+             val = ops[0];
+           break;
+         }
 
        case GIMPLE_SWITCH:
          val = gimple_switch_index (as_a <gswitch *> (stmt));
          break;
 
        default:
-         val = NULL_TREE;
+         ;
        }
       taken_edge = find_taken_edge (bb, val);
       if (!taken_edge)