re PR tree-optimization/89595 (DOM miscompiles code)

2019-03-07  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/89595
	* tree-ssa-dom.c (dom_opt_dom_walker::optimize_stmt): Take
	stmt iterator as reference, take boolean output parameter to
	indicate whether the stmt was removed and thus the iterator
	already advanced.
	(dom_opt_dom_walker::before_dom_children): Re-iterate over
	stmts created by folding.

	* gcc.dg/torture/pr89595.c: New testcase.

From-SVN: r269453
This commit is contained in:
Richard Biener 2019-03-07 12:46:44 +00:00 committed by Richard Biener
parent f879f0e3f2
commit 1a438d160e
4 changed files with 105 additions and 11 deletions

View File

@ -1,3 +1,13 @@
2019-03-07 Richard Biener <rguenther@suse.de>
PR tree-optimization/89595
* tree-ssa-dom.c (dom_opt_dom_walker::optimize_stmt): Take
stmt iterator as reference, take boolean output parameter to
indicate whether the stmt was removed and thus the iterator
already advanced.
(dom_opt_dom_walker::before_dom_children): Re-iterate over
stmts created by folding.
2019-03-07 Jakub Jelinek <jakub@redhat.com>
PR c++/89585

View File

@ -1,3 +1,8 @@
2019-03-07 Richard Biener <rguenther@suse.de>
PR tree-optimization/89595
* gcc.dg/torture/pr89595.c: New testcase.
2019-03-07 Jakub Jelinek <jakub@redhat.com>
PR c++/89585

View File

@ -0,0 +1,39 @@
/* { dg-do run } */
/* { dg-additional-options "-fgimple" } */
int __attribute__((noipa))
__GIMPLE(startwith("dom")) bar(int cond, int val)
{
int i;
if (0 != 0)
goto bb_6;
else
goto bb_2;
bb_2:
if (cond_5(D) != 0)
goto bb_4;
else
goto bb_5;
bb_4:
i_6 = val_2(D);
i_1 = val_2(D) > 0 ? i_6 : 0;
bb_5:
i_3 = __PHI (bb_4: i_1, bb_2: 0);
return i_3;
bb_6:
i_4 = 1;
i_9 = 2;
goto bb_2;
}
int main()
{
if (bar (1, 1) != 1)
__builtin_abort ();
return 0;
}

View File

@ -618,7 +618,7 @@ private:
various tables mantained by DOM. Returns the taken edge if
the statement is a conditional with a statically determined
value. */
edge optimize_stmt (basic_block, gimple_stmt_iterator);
edge optimize_stmt (basic_block, gimple_stmt_iterator *, bool *);
};
/* Jump threading, redundancy elimination and const/copy propagation.
@ -1480,10 +1480,48 @@ dom_opt_dom_walker::before_dom_children (basic_block bb)
m_avail_exprs_stack->pop_to_marker ();
edge taken_edge = NULL;
/* Initialize visited flag ahead of us, it has undefined state on
pass entry. */
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
gimple_set_visited (gsi_stmt (gsi), false);
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
{
/* Do not optimize a stmt twice, substitution might end up with
_3 = _3 which is not valid. */
if (gimple_visited_p (gsi_stmt (gsi)))
{
gsi_next (&gsi);
continue;
}
/* Compute range information and optimize the stmt. */
evrp_range_analyzer.record_ranges_from_stmt (gsi_stmt (gsi), false);
taken_edge = this->optimize_stmt (bb, gsi);
bool removed_p = false;
taken_edge = this->optimize_stmt (bb, &gsi, &removed_p);
if (!removed_p)
gimple_set_visited (gsi_stmt (gsi), true);
/* Go back and visit stmts inserted by folding after substituting
into the stmt at gsi. */
if (gsi_end_p (gsi))
{
gcc_checking_assert (removed_p);
gsi = gsi_last_bb (bb);
while (!gsi_end_p (gsi) && !gimple_visited_p (gsi_stmt (gsi)))
gsi_prev (&gsi);
}
else
{
do
{
gsi_prev (&gsi);
}
while (!gsi_end_p (gsi) && !gimple_visited_p (gsi_stmt (gsi)));
}
if (gsi_end_p (gsi))
gsi = gsi_start_bb (bb);
else
gsi_next (&gsi);
}
/* Now prepare to process dominated blocks. */
@ -1951,7 +1989,8 @@ test_for_singularity (gimple *stmt, gcond *dummy_cond,
condition to an equality condition. */
edge
dom_opt_dom_walker::optimize_stmt (basic_block bb, gimple_stmt_iterator si)
dom_opt_dom_walker::optimize_stmt (basic_block bb, gimple_stmt_iterator *si,
bool *removed_p)
{
gimple *stmt, *old_stmt;
bool may_optimize_p;
@ -1959,7 +1998,7 @@ dom_opt_dom_walker::optimize_stmt (basic_block bb, gimple_stmt_iterator si)
bool was_noreturn;
edge retval = NULL;
old_stmt = stmt = gsi_stmt (si);
old_stmt = stmt = gsi_stmt (*si);
was_noreturn = is_gimple_call (stmt) && gimple_call_noreturn_p (stmt);
if (dump_file && (dump_flags & TDF_DETAILS))
@ -1982,9 +2021,9 @@ dom_opt_dom_walker::optimize_stmt (basic_block bb, gimple_stmt_iterator si)
/* Try to fold the statement making sure that STMT is kept
up to date. */
if (fold_stmt (&si))
if (fold_stmt (si))
{
stmt = gsi_stmt (si);
stmt = gsi_stmt (*si);
gimple_set_modified (stmt, true);
if (dump_file && (dump_flags & TDF_DETAILS))
@ -2032,8 +2071,8 @@ dom_opt_dom_walker::optimize_stmt (basic_block bb, gimple_stmt_iterator si)
if (callee
&& fndecl_built_in_p (callee, BUILT_IN_CONSTANT_P))
{
propagate_tree_value_into_stmt (&si, integer_zero_node);
stmt = gsi_stmt (si);
propagate_tree_value_into_stmt (si, integer_zero_node);
stmt = gsi_stmt (*si);
}
}
@ -2089,9 +2128,9 @@ dom_opt_dom_walker::optimize_stmt (basic_block bb, gimple_stmt_iterator si)
}
update_stmt_if_modified (stmt);
eliminate_redundant_computations (&si, m_const_and_copies,
eliminate_redundant_computations (si, m_const_and_copies,
m_avail_exprs_stack);
stmt = gsi_stmt (si);
stmt = gsi_stmt (*si);
/* Perform simple redundant store elimination. */
if (gimple_assign_single_p (stmt)
@ -2118,13 +2157,14 @@ dom_opt_dom_walker::optimize_stmt (basic_block bb, gimple_stmt_iterator si)
{
basic_block bb = gimple_bb (stmt);
unlink_stmt_vdef (stmt);
if (gsi_remove (&si, true))
if (gsi_remove (si, true))
{
bitmap_set_bit (need_eh_cleanup, bb->index);
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " Flagged to clear EH edges.\n");
}
release_defs (stmt);
*removed_p = true;
return retval;
}
}