diff options
author | Richard Biener <rguenther@suse.de> | 2015-10-14 12:59:15 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2015-10-14 12:59:15 +0000 |
commit | c3bea07622b9a0ffc7a6724c06a04c9801642dfd (patch) | |
tree | 1c951111002e36e36791d6b8c618654105a3bdc9 /gcc/tree-cfgcleanup.c | |
parent | 0155ad4011c58e3608d88e76d1fa0f628ccedcdb (diff) | |
download | gcc-c3bea07622b9a0ffc7a6724c06a04c9801642dfd.zip gcc-c3bea07622b9a0ffc7a6724c06a04c9801642dfd.tar.gz gcc-c3bea07622b9a0ffc7a6724c06a04c9801642dfd.tar.bz2 |
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
Diffstat (limited to 'gcc/tree-cfgcleanup.c')
-rw-r--r-- | gcc/tree-cfgcleanup.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c index 40e1456..eeedd8a 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) |