re PR tree-optimization/67915 (ICE on valid code at -O2 and -O3 on x86_64-linux-gnu)

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.

From-SVN: r228810
This commit is contained in:
Richard Biener 2015-10-14 12:59:15 +00:00 committed by Richard Biener
parent 0155ad4011
commit c3bea07622
6 changed files with 62 additions and 16 deletions

View 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> 2015-10-14 Marek Polacek <polacek@redhat.com>
PR tree-optimization/67815 PR tree-optimization/67815

View 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, gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
&arm2); &arm2);
cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true, cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true,
label_false); label_false);
gimplify_seq_add_stmt (&seq, cond_stmt); gimplify_seq_add_stmt (&seq, cond_stmt);
gimple_stmt_iterator gsi = gsi_last (seq);
maybe_fold_stmt (&gsi);
label_cont = NULL_TREE; label_cont = NULL_TREE;
if (!have_then_clause_p) if (!have_then_clause_p)
{ {

View file

@ -1998,8 +1998,12 @@ along with GCC; see the file COPYING3. If not see
&& decl_in_symtab_p (base1)) && decl_in_symtab_p (base1))
equal = symtab_node::get_create (base0) equal = symtab_node::get_create (base0)
->equal_address_to (symtab_node::get_create (base1)); ->equal_address_to (symtab_node::get_create (base1));
else if ((DECL_P (base0) || TREE_CODE (base0) == SSA_NAME) else if ((DECL_P (base0)
&& (DECL_P (base1) || TREE_CODE (base1) == SSA_NAME)) || 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); equal = (base0 == base1);
} }
(if (equal == 1 (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. */ /* If the offsets are equal we can ignore overflow. */
|| off0 == off1 || off0 == off1
|| POINTER_TYPE_OVERFLOW_UNDEFINED || 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)) || (POINTER_TYPE_P (TREE_TYPE (@2))
&& DECL_P (base0)))) && (DECL_P (base0) || TREE_CODE (base0) == STRING_CST))))
(switch (switch
(if (cmp == EQ_EXPR) (if (cmp == EQ_EXPR)
{ constant_boolean_node (off0 == off1, type); }) { constant_boolean_node (off0 == off1, type); })

View 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> 2015-10-14 Marek Polacek <polacek@redhat.com>
PR tree-optimization/67815 PR tree-optimization/67815

View file

@ -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;
}

View file

@ -56,6 +56,9 @@ along with GCC; see the file COPYING3. If not see
#include "cfgloop.h" #include "cfgloop.h"
#include "tree-ssa-propagate.h" #include "tree-ssa-propagate.h"
#include "tree-scalar-evolution.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 set of blocks in that at least one of the following changes happened:
-- the statement at the end of the block was changed -- 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; edge taken_edge;
bool retval = false; bool retval = false;
gimple *stmt = gsi_stmt (gsi); gimple *stmt = gsi_stmt (gsi);
tree val;
if (!single_succ_p (bb)) if (!single_succ_p (bb))
{ {
edge e; edge e;
edge_iterator ei; edge_iterator ei;
bool warned; bool warned;
location_t loc; tree val = NULL_TREE;
fold_defer_overflow_warnings (); fold_defer_overflow_warnings ();
loc = gimple_location (stmt);
switch (gimple_code (stmt)) switch (gimple_code (stmt))
{ {
case GIMPLE_COND: case GIMPLE_COND:
val = fold_binary_loc (loc, gimple_cond_code (stmt), {
boolean_type_node, code_helper rcode;
gimple_cond_lhs (stmt), tree ops[3] = {};
gimple_cond_rhs (stmt)); if (gimple_simplify (stmt, &rcode, ops, NULL, no_follow_ssa_edges,
break; no_follow_ssa_edges)
&& rcode == INTEGER_CST)
val = ops[0];
break;
}
case GIMPLE_SWITCH: case GIMPLE_SWITCH:
val = gimple_switch_index (as_a <gswitch *> (stmt)); val = gimple_switch_index (as_a <gswitch *> (stmt));
break; break;
default: default:
val = NULL_TREE; ;
} }
taken_edge = find_taken_edge (bb, val); taken_edge = find_taken_edge (bb, val);
if (!taken_edge) if (!taken_edge)