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,41 +2871,31 @@ maybe_optimize_range_tests (gimple stmt) ...@@ -2870,41 +2871,31 @@ 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
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) 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);
{ new_op = update_ops (bbinfo[idx].op,
if (ops[bbinfo[idx].first_idx]->op != NULL_TREE) (enum tree_code)
{ ops[bbinfo[idx].first_idx]->rank,
if (integer_zerop (ops[bbinfo[idx].first_idx]->op)) ops, &bbinfo[idx].first_idx,
gimple_cond_make_false (stmt); loop_containing_stmt (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,
(enum tree_code)
ops[bbinfo[idx].first_idx]->rank,
ops, &bbinfo[idx].first_idx,
loop_containing_stmt (stmt));
if (new_op == NULL_TREE) if (new_op == NULL_TREE)
{ {
gcc_assert (bb == last_bb); gcc_assert (bb == last_bb);
...@@ -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