Commit 96f9e25a by Jakub Jelinek Committed by Jakub Jelinek

re PR tree-optimization/58946 (internal compiler error: in operator[], at vec.h:722)

	PR tree-optimization/58946
	* tree-ssa-reassoc.c (maybe_optimize_range_tests): Update all
	bbs with bbinfo[idx].op != NULL before all blocks with
	bbinfo[idx].op == NULL.

	* gcc.c-torture/compile/pr58946.c: New test.

From-SVN: r204348
parent 2546da0b
2013-11-04 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/58946
* tree-ssa-reassoc.c (maybe_optimize_range_tests): Update all
bbs with bbinfo[idx].op != NULL before all blocks with
bbinfo[idx].op == NULL.
2013-11-04 Richard Sandiford <rdsandiford@googlemail.com> 2013-11-04 Richard Sandiford <rdsandiford@googlemail.com>
* config/avr/avr-log.c (avr_double_int_pop_digit): Delete. * config/avr/avr-log.c (avr_double_int_pop_digit): Delete.
2013-11-04 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/58946
* gcc.c-torture/compile/pr58946.c: New test.
2013-11-03 Paolo Carlini <paolo.carlini@oracle.com> 2013-11-03 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/52071 PR c++/52071
......
/* PR tree-optimization/58946 */
int
foo (unsigned int c)
{
unsigned int d, e, f;
if ((int) c < 0)
d = 0;
else
d = c;
if (d == 0)
e = __INT_MAX__ + 1U;
else
e = d;
if ((int) e < 0)
f = 0;
else
f = e;
return f;
}
...@@ -2657,6 +2657,7 @@ maybe_optimize_range_tests (gimple stmt) ...@@ -2657,6 +2657,7 @@ maybe_optimize_range_tests (gimple stmt)
edge e; edge e;
vec<operand_entry_t> ops = vNULL; vec<operand_entry_t> ops = vNULL;
vec<inter_bb_range_test_entry> bbinfo = vNULL; vec<inter_bb_range_test_entry> bbinfo = vNULL;
bool any_changes = false;
/* Consider only basic blocks that end with GIMPLE_COND or /* Consider only basic blocks that end with GIMPLE_COND or
a cast statement satisfying final_range_test_p. All a cast statement satisfying final_range_test_p. All
...@@ -2870,36 +2871,26 @@ maybe_optimize_range_tests (gimple stmt) ...@@ -2870,36 +2871,26 @@ maybe_optimize_range_tests (gimple stmt)
break; break;
} }
if (ops.length () > 1) if (ops.length () > 1)
any_changes = optimize_range_tests (ERROR_MARK, &ops);
if (any_changes)
{ {
unsigned int idx; unsigned int idx;
bool any_changes = optimize_range_tests (ERROR_MARK, &ops); /* update_ops relies on has_single_use predicates returning the
for (bb = last_bb, idx = 0; any_changes; bb = single_pred (bb), idx++) same values as it did during get_ops earlier. Additionally it
{ never removes statements, only adds new ones and it should walk
if (bbinfo[idx].first_idx < bbinfo[idx].last_idx) from the single imm use and check the predicate already before
making those changes.
On the other side, the handling of GIMPLE_COND directly can turn
previously multiply used SSA_NAMEs into single use SSA_NAMEs, so
it needs to be done in a separate loop afterwards. */
for (bb = last_bb, idx = 0; ; bb = single_pred (bb), idx++)
{
if (bbinfo[idx].first_idx < bbinfo[idx].last_idx
&& bbinfo[idx].op != NULL_TREE)
{ {
gimple stmt = last_stmt (bb);
tree new_op; tree new_op;
if (bbinfo[idx].op == NULL_TREE) stmt = last_stmt (bb);
{
if (ops[bbinfo[idx].first_idx]->op != NULL_TREE)
{
if (integer_zerop (ops[bbinfo[idx].first_idx]->op))
gimple_cond_make_false (stmt);
else if (integer_onep (ops[bbinfo[idx].first_idx]->op))
gimple_cond_make_true (stmt);
else
{
gimple_cond_set_code (stmt, NE_EXPR);
gimple_cond_set_lhs (stmt,
ops[bbinfo[idx].first_idx]->op);
gimple_cond_set_rhs (stmt, boolean_false_node);
}
update_stmt (stmt);
}
bbinfo[idx].op = new_op = boolean_false_node;
}
else
new_op = update_ops (bbinfo[idx].op, new_op = update_ops (bbinfo[idx].op,
(enum tree_code) (enum tree_code)
ops[bbinfo[idx].first_idx]->rank, ops[bbinfo[idx].first_idx]->rank,
...@@ -2956,6 +2947,28 @@ maybe_optimize_range_tests (gimple stmt) ...@@ -2956,6 +2947,28 @@ maybe_optimize_range_tests (gimple stmt)
if (bb == first_bb) if (bb == first_bb)
break; break;
} }
for (bb = last_bb, idx = 0; ; bb = single_pred (bb), idx++)
{
if (bbinfo[idx].first_idx < bbinfo[idx].last_idx
&& bbinfo[idx].op == NULL_TREE
&& ops[bbinfo[idx].first_idx]->op != NULL_TREE)
{
stmt = last_stmt (bb);
if (integer_zerop (ops[bbinfo[idx].first_idx]->op))
gimple_cond_make_false (stmt);
else if (integer_onep (ops[bbinfo[idx].first_idx]->op))
gimple_cond_make_true (stmt);
else
{
gimple_cond_set_code (stmt, NE_EXPR);
gimple_cond_set_lhs (stmt, ops[bbinfo[idx].first_idx]->op);
gimple_cond_set_rhs (stmt, boolean_false_node);
}
update_stmt (stmt);
}
if (bb == first_bb)
break;
}
} }
bbinfo.release (); bbinfo.release ();
ops.release (); ops.release ();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment