summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2015-10-14 12:59:15 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2015-10-14 12:59:15 +0000
commit04a37b12bbd351cd32ea592906aef2f1033253e0 (patch)
tree1c951111002e36e36791d6b8c618654105a3bdc9
parent389034a4ab3bc82b6feee643ddab6b130ca46388 (diff)
downloadgcc-04a37b12bbd351cd32ea592906aef2f1033253e0.tar.gz
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. * gcc.dg/torture/pr67915.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@228810 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/gimplify.c7
-rw-r--r--gcc/match.pd12
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr67915.c23
-rw-r--r--gcc/tree-cfgcleanup.c23
6 files changed, 62 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d85a2704aad..b257f3908d7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 4a9f7fd6cbf..071645fc0e3 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -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)
{
diff --git a/gcc/match.pd b/gcc/match.pd
index 6714796943e..655c9ffcf26 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -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); })
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 670b9e43ce5..e6a457b4f7f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 00000000000..77a2edf17a0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr67915.c
@@ -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;
+}
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
index 40e14566ed1..eeedd8a423b 100644
--- a/gcc/tree-cfgcleanup.c
+++ b/gcc/tree-cfgcleanup.c
@@ -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)