From c3bea07622b9a0ffc7a6724c06a04c9801642dfd Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 14 Oct 2015 12:59:15 +0000 Subject: [PATCH] re PR tree-optimization/67915 (ICE on valid code at -O2 and -O3 on x86_64-linux-gnu) 2015-10-14 Richard Biener 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. From-SVN: r228810 --- gcc/ChangeLog | 8 ++++++++ gcc/gimplify.c | 7 ++++--- gcc/match.pd | 12 ++++++++---- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/torture/pr67915.c | 23 +++++++++++++++++++++++ gcc/tree-cfgcleanup.c | 23 ++++++++++++++--------- 6 files changed, 62 insertions(+), 16 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr67915.c 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 + + 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 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 + + PR tree-optimization/67915 + * gcc.dg/torture/pr67915.c: New testcase. + 2015-10-14 Marek Polacek 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 (stmt)); break; default: - val = NULL_TREE; + ; } taken_edge = find_taken_edge (bb, val); if (!taken_edge) -- 2.30.2