re PR tree-optimization/28888 (ICE in tree check: expected cond_expr, have label_expr in simplify_using_initial_conditions, at tree-ssa-loop-niter.c)

PR tree-optimization/28888
	* tree-if-conv.c (combine_blocks): Rewritten.
	* tree-cfg.c (tree_verify_flow_info): Check that edges with
	EDGE_TRUE/FALSE_VALUE follow COND_EXPR.

	* gcc.dg/pr28888.c: New test.

From-SVN: r117135
This commit is contained in:
Zdenek Dvorak 2006-09-22 10:02:47 +00:00
parent 3735874658
commit 36b2419387
5 changed files with 109 additions and 67 deletions

View File

@ -1,3 +1,10 @@
2006-09-22 Zdenek Dvorak <dvorakz@suse.cz>
PR tree-optimization/28888
* tree-if-conv.c (combine_blocks): Rewritten.
* tree-cfg.c (tree_verify_flow_info): Check that edges with
EDGE_TRUE/FALSE_VALUE follow COND_EXPR.
2006-09-22 Jakub Jelinek <jakub@redhat.com>
* tree-ssa-propagate.c (set_rhs): Copy EXPR_LOCATION if

View File

@ -1,3 +1,8 @@
2006-09-22 Zdenek Dvorak <dvorakz@suse.cz>
PR tree-optimization/28888
* gcc.dg/pr28888.c: New test.
2006-09-21 Mark Mitchell <mark@codesourcery.com>
PR c++/29016
@ -5,15 +10,15 @@
2006-09-21 Lee Millward <lee.millward@codesourcery.com>
PR c++/28861
* g++.dg/template/spec32.C: New test.
* g++.dg/parse/crash9.C: Adjust error markers.
PR c++/28861
* g++.dg/template/spec32.C: New test.
* g++.dg/parse/crash9.C: Adjust error markers.
PR c++/28303
* g++.dg/template/typedef6.C: New test.
* g++.dg/init/error1.C: Adjust error markers.
* g++.dg/parse/crash9.C: Likewise.
* g++.dg/template/crash55.C: Likewise.
* g++.dg/template/typedef6.C: New test.
* g++.dg/init/error1.C: Adjust error markers.
* g++.dg/parse/crash9.C: Likewise.
* g++.dg/template/crash55.C: Likewise.
2006-09-21 Janis Johnson <janis187@us.ibm.com>

View File

@ -0,0 +1,21 @@
/* { dg-do compile } */
/* { dg-options "-O2 -ftree-vectorize" } */
static const unsigned char _c30[] =
"statistic of allocated integer registers:";
Allocate__WriteStats (void)
{
register int i0, i1, i2, i3, i4, i5;
l0:i1 = (int) (i5 << 2);
if (i0)
i4 = i5;
l1:i2 += i1;
if (i1)
goto l0;
l3:i0 = i1 == 255;
i1++;
Out__LongInt ((int) i0, (int) 0);
i0 = i4 >= i1;
if (i0)
goto l3;
}

View File

@ -3757,6 +3757,19 @@ tree_verify_flow_info (void)
}
}
if (TREE_CODE (stmt) != COND_EXPR)
{
/* Verify that there are no edges with EDGE_TRUE/FALSE_FLAG set
after anything else but if statement. */
FOR_EACH_EDGE (e, ei, bb->succs)
if (e->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE))
{
error ("true/false edge after a non-COND_EXPR in bb %d",
bb->index);
err = 1;
}
}
switch (TREE_CODE (stmt))
{
case COND_EXPR:

View File

@ -866,72 +866,74 @@ combine_blocks (struct loop *loop)
basic_block bb, exit_bb, merge_target_bb;
unsigned int orig_loop_num_nodes = loop->num_nodes;
unsigned int i;
unsigned int n_exits;
edge *exits;
edge e;
edge_iterator ei;
exits = get_loop_exit_edges (loop, &n_exits);
free (exits);
/* Process phi nodes to prepare blocks for merge. */
process_phi_nodes (loop);
/* Merge basic blocks. First remove all the edges in the loop, except
for those from the exit block. */
exit_bb = NULL;
for (i = 0; i < orig_loop_num_nodes; i++)
{
bb = ifc_bbs[i];
if (bb_with_exit_edge_p (loop, bb))
{
exit_bb = bb;
break;
}
}
gcc_assert (exit_bb != loop->latch);
for (i = 1; i < orig_loop_num_nodes; i++)
{
bb = ifc_bbs[i];
for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei));)
{
if (e->src == exit_bb)
ei_next (&ei);
else
remove_edge (e);
}
}
if (exit_bb != NULL)
{
if (exit_bb != loop->header)
{
/* Connect this node with loop header. */
make_edge (loop->header, exit_bb, EDGE_FALLTHRU);
set_immediate_dominator (CDI_DOMINATORS, exit_bb, loop->header);
}
/* Redirect non-exit edges to loop->latch. */
FOR_EACH_EDGE (e, ei, exit_bb->succs)
{
if (!loop_exit_edge_p (loop, e))
redirect_edge_and_branch (e, loop->latch);
}
set_immediate_dominator (CDI_DOMINATORS, loop->latch, exit_bb);
}
else
{
/* If the loop does not have exit then reconnect header and latch. */
make_edge (loop->header, loop->latch, EDGE_FALLTHRU);
set_immediate_dominator (CDI_DOMINATORS, loop->latch, loop->header);
}
/* Merge basic blocks */
merge_target_bb = loop->header;
for (i = 1; i < orig_loop_num_nodes; i++)
{
edge e;
block_stmt_iterator bsi;
tree_stmt_iterator last;
bb = ifc_bbs[i];
if (!exit_bb && bb_with_exit_edge_p (loop, bb))
exit_bb = bb;
if (bb == exit_bb)
{
edge_iterator ei;
/* Connect this node with loop header. */
make_edge (ifc_bbs[0], bb, EDGE_FALLTHRU);
set_immediate_dominator (CDI_DOMINATORS, bb, ifc_bbs[0]);
if (exit_bb != loop->latch)
{
/* Redirect non-exit edge to loop->latch. */
FOR_EACH_EDGE (e, ei, bb->succs)
{
if (!loop_exit_edge_p (loop, e))
{
redirect_edge_and_branch (e, loop->latch);
set_immediate_dominator (CDI_DOMINATORS, loop->latch, bb);
}
}
}
continue;
}
if (bb == loop->latch && empty_block_p (bb))
if (bb == exit_bb || bb == loop->latch)
continue;
/* It is time to remove this basic block. First remove edges. */
while (EDGE_COUNT (bb->preds) > 0)
remove_edge (EDGE_PRED (bb, 0));
/* This is loop latch and loop does not have exit then do not
delete this basic block. Just remove its PREDS and reconnect
loop->header and loop->latch blocks. */
if (bb == loop->latch && n_exits == 0)
{
make_edge (loop->header, loop->latch, EDGE_FALLTHRU);
set_immediate_dominator (CDI_DOMINATORS, loop->latch, loop->header);
continue;
}
while (EDGE_COUNT (bb->succs) > 0)
remove_edge (EDGE_SUCC (bb, 0));
/* Remove labels and make stmts member of loop->header. */
for (bsi = bsi_start (bb); !bsi_end_p (bsi); )
{
@ -956,8 +958,6 @@ combine_blocks (struct loop *loop)
delete_from_dominance_info (CDI_POST_DOMINATORS, bb);
/* Remove basic block. */
if (bb == loop->latch)
loop->latch = merge_target_bb;
remove_bb_from_loops (bb);
expunge_block (bb);
}
@ -966,15 +966,11 @@ combine_blocks (struct loop *loop)
This reduces number of basic blocks to 2. Auto vectorizer addresses
loops with two nodes only. FIXME: Use cleanup_tree_cfg(). */
if (exit_bb
&& loop->header != loop->latch
&& exit_bb != loop->latch
&& empty_block_p (loop->latch))
&& exit_bb != loop->header
&& can_merge_blocks_p (loop->header, exit_bb))
{
if (can_merge_blocks_p (loop->header, exit_bb))
{
remove_bb_from_loops (exit_bb);
merge_blocks (loop->header, exit_bb);
}
remove_bb_from_loops (exit_bb);
merge_blocks (loop->header, exit_bb);
}
}