diff options
author | Michael Matz <matz@suse.de> | 2010-06-28 15:14:31 +0000 |
---|---|---|
committer | Michael Matz <matz@gcc.gnu.org> | 2010-06-28 15:14:31 +0000 |
commit | fe2ef088e065f9e15311b221db3fcbf864dfb250 (patch) | |
tree | 9de962d5f754d58a1f456143f4c86710db0e4087 /gcc | |
parent | f0cc75e07893d05abcfe0287dc2c1071680e0c6f (diff) | |
download | gcc-fe2ef088e065f9e15311b221db3fcbf864dfb250.zip gcc-fe2ef088e065f9e15311b221db3fcbf864dfb250.tar.gz gcc-fe2ef088e065f9e15311b221db3fcbf864dfb250.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/gimple-fold.c | 54 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/pr44592.f90 | 20 |
4 files changed, 81 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index aa93333..fd8b6d9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index a37b4a3..8fb604d 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -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); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 59b0bf9..7bdfc348 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 diff --git a/gcc/testsuite/gfortran.dg/pr44592.f90 b/gcc/testsuite/gfortran.dg/pr44592.f90 new file mode 100644 index 0000000..8b043ba --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr44592.f90 @@ -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 |