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:
parent
f0cc75e078
commit
fe2ef088e0
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue