re PR middle-end/44592 (wrong code at -O3)

PR middle-end/44592
	* gimple-fold.c (gimplify_and_update_call_from_tree): Maintain
	proper VDEF chain for intermediate stores in the sequence.

testsuite/
	PR middle-end/44592
	* gfortran.dg/pr44592.f90: New test.

From-SVN: r161496
This commit is contained in:
Michael Matz 2010-06-28 15:14:31 +00:00 committed by Michael Matz
parent f0cc75e078
commit fe2ef088e0
4 changed files with 81 additions and 4 deletions

View File

@ -1,3 +1,9 @@
2010-06-28 Michael Matz <matz@suse.de>
PR middle-end/44592
* gimple-fold.c (gimplify_and_update_call_from_tree): Maintain
proper VDEF chain for intermediate stores in the sequence.
2010-06-28 Jan Hubicka <jh@suse.cz>
PR tree-optimization/44357

View File

@ -1053,7 +1053,9 @@ fold_gimple_cond (gimple stmt)
is replaced. If the call is expected to produces a result, then it
is replaced by an assignment of the new RHS to the result variable.
If the result is to be ignored, then the call is replaced by a
GIMPLE_NOP. */
GIMPLE_NOP. A proper VDEF chain is retained by making the first
VUSE and the last VDEF of the whole sequence be the same as the replaced
statement and using new SSA names for stores in between. */
void
gimplify_and_update_call_from_tree (gimple_stmt_iterator *si_p, tree expr)
@ -1065,12 +1067,15 @@ gimplify_and_update_call_from_tree (gimple_stmt_iterator *si_p, tree expr)
gimple_seq stmts = gimple_seq_alloc();
struct gimplify_ctx gctx;
gimple last = NULL;
gimple laststore = NULL;
tree reaching_vuse;
stmt = gsi_stmt (*si_p);
gcc_assert (is_gimple_call (stmt));
lhs = gimple_call_lhs (stmt);
reaching_vuse = gimple_vuse (stmt);
push_gimplify_context (&gctx);
@ -1095,13 +1100,47 @@ gimplify_and_update_call_from_tree (gimple_stmt_iterator *si_p, tree expr)
new_stmt = gsi_stmt (i);
find_new_referenced_vars (new_stmt);
mark_symbols_for_renaming (new_stmt);
/* If the new statement has a VUSE, update it with exact SSA name we
know will reach this one. */
if (gimple_vuse (new_stmt))
{
/* If we've also seen a previous store create a new VDEF for
the latter one, and make that the new reaching VUSE. */
if (laststore)
{
reaching_vuse = make_ssa_name (gimple_vop (cfun), laststore);
gimple_set_vdef (laststore, reaching_vuse);
update_stmt (laststore);
laststore = NULL;
}
gimple_set_vuse (new_stmt, reaching_vuse);
gimple_set_modified (new_stmt, true);
}
if (gimple_assign_single_p (new_stmt)
&& !is_gimple_reg (gimple_assign_lhs (new_stmt)))
{
laststore = new_stmt;
}
last = new_stmt;
}
if (lhs == NULL_TREE)
{
unlink_stmt_vdef (stmt);
release_defs (stmt);
/* If we replace a call without LHS that has a VDEF and our new
sequence ends with a store we must make that store have the same
vdef in order not to break the sequencing. This can happen
for instance when folding memcpy calls into assignments. */
if (gimple_vdef (stmt) && laststore)
{
gimple_set_vdef (laststore, gimple_vdef (stmt));
move_ssa_defining_stmt_for_defs (laststore, stmt);
update_stmt (laststore);
}
else
{
unlink_stmt_vdef (stmt);
release_defs (stmt);
}
new_stmt = last;
}
else
@ -1111,8 +1150,15 @@ gimplify_and_update_call_from_tree (gimple_stmt_iterator *si_p, tree expr)
gsi_insert_before (si_p, last, GSI_NEW_STMT);
gsi_next (si_p);
}
if (laststore)
{
reaching_vuse = make_ssa_name (gimple_vop (cfun), laststore);
gimple_set_vdef (laststore, reaching_vuse);
update_stmt (laststore);
laststore = NULL;
}
new_stmt = gimple_build_assign (lhs, tmp);
gimple_set_vuse (new_stmt, gimple_vuse (stmt));
gimple_set_vuse (new_stmt, reaching_vuse);
gimple_set_vdef (new_stmt, gimple_vdef (stmt));
move_ssa_defining_stmt_for_defs (new_stmt, stmt);
}

View File

@ -1,3 +1,8 @@
2010-06-28 Michael Matz <matz@suse.de>
PR middle-end/44592
* gfortran.dg/pr44592.f90: New test.
2010-06-28 Jan Hubicka <jh@suse.cz>
PR tree-optimization/44357

View File

@ -0,0 +1,20 @@
! { dg-do run }
! { dg-options "-O3" }
! From forall_12.f90
! Fails with loop reversal at -O3
!
character(len=1) :: b(4) = (/"1","2","3","4"/), c(4)
c = b
i = 1
! This statement must be here for the abort below
b(1:3)(i:i) = b(2:4)(i:i)
b = c
b(4:2:-1)(i:i) = b(3:1:-1)(i:i)
! This fails. If the condition is printed, the result is F F F F
if (any (b .ne. (/"1","1","2","3"/))) i = 2
print *, b
print *, b .ne. (/"1","1","2","3"/)
if (i == 2) call abort
end