diff options
author | Richard Guenther <rguenther@suse.de> | 2009-11-24 11:57:26 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2009-11-24 11:57:26 +0000 |
commit | 1415abc0e76749e209a9e4decbf489fb96c66cb3 (patch) | |
tree | f19106fba13eb4041c815fa48f36964d90f21528 /gcc/tree-ssa-dce.c | |
parent | 09f0dc451db76a059e097c7cd115d65a86dff66e (diff) | |
download | gcc-1415abc0e76749e209a9e4decbf489fb96c66cb3.zip gcc-1415abc0e76749e209a9e4decbf489fb96c66cb3.tar.gz gcc-1415abc0e76749e209a9e4decbf489fb96c66cb3.tar.bz2 |
re PR tree-optimization/42142 (DCE miscompiles a certain quicksort implementation when optimizing with -O1 or higher)
2009-11-24 Richard Guenther <rguenther@suse.de>
PR tree-optimization/42142
* tree-ssa-dce.c (mark_aliased_reaching_defs_necessary_1):
Handle iv-dependent (non-)kills properly.
(mark_aliased_reaching_defs_necessary): Pass the basic-block
of the reference statement to mark_aliased_reaching_defs_necessary_1.
* gcc.c-torture/execute/pr42142.c: New testcase.
From-SVN: r154494
Diffstat (limited to 'gcc/tree-ssa-dce.c')
-rw-r--r-- | gcc/tree-ssa-dce.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c index f0135a9..056b7b5 100644 --- a/gcc/tree-ssa-dce.c +++ b/gcc/tree-ssa-dce.c @@ -495,11 +495,11 @@ static bool chain_ovfl = false; which is based on a non-aliased decl, necessary. It returns true whenever the defining statement of the current VDEF is a kill for REF, as no dominating may-defs are necessary for REF - anymore. DATA points to cached get_ref_base_and_extent data for REF. */ + anymore. DATA points to the basic-block that contains the + stmt that refers to REF. */ static bool -mark_aliased_reaching_defs_necessary_1 (ao_ref *ref, tree vdef, - void *data ATTRIBUTE_UNUSED) +mark_aliased_reaching_defs_necessary_1 (ao_ref *ref, tree vdef, void *data) { gimple def_stmt = SSA_NAME_DEF_STMT (vdef); @@ -529,6 +529,12 @@ mark_aliased_reaching_defs_necessary_1 (ao_ref *ref, tree vdef, } /* Or they need to be exactly the same. */ else if (ref->ref + /* Make sure there is no induction variable involved + in the references (gcc.c-torture/execute/pr42142.c). + The simplest way is to check if the kill dominates + the use. */ + && dominated_by_p (CDI_DOMINATORS, (basic_block) data, + gimple_bb (def_stmt)) && operand_equal_p (ref->ref, lhs, 0)) return true; } @@ -547,7 +553,7 @@ mark_aliased_reaching_defs_necessary (gimple stmt, tree ref) ao_ref_init (&refd, ref); chain = walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_aliased_reaching_defs_necessary_1, - NULL, NULL); + gimple_bb (stmt), NULL); if (chain > longest_chain) longest_chain = chain; total_chain += chain; |