diff options
author | Richard Biener <rguenther@suse.de> | 2020-03-03 11:01:09 +0100 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2020-03-03 11:02:28 +0100 |
commit | 3d6fd7ce6dc4b6baa11920387d62dc001980aa70 (patch) | |
tree | 8254ced343f8ecb9cdfe76b13dd1680c361cbbef /gcc/tree-ssa-dse.c | |
parent | 01eb1bb0237a24fe50ed0631857f3dfc31782f54 (diff) | |
download | gcc-3d6fd7ce6dc4b6baa11920387d62dc001980aa70.zip gcc-3d6fd7ce6dc4b6baa11920387d62dc001980aa70.tar.gz gcc-3d6fd7ce6dc4b6baa11920387d62dc001980aa70.tar.bz2 |
tree-optimization/93946 - fix bogus redundant store removal in FRE, DSE and DOM
This fixes a common mistake in removing a store that looks redudnant but
is not because it changes the dynamic type of the memory and thus makes
a difference for following loads with TBAA.
2020-03-03 Richard Biener <rguenther@suse.de>
PR tree-optimization/93946
* alias.h (refs_same_for_tbaa_p): Declare.
* alias.c (refs_same_for_tbaa_p): New function.
* tree-ssa-alias.c (ao_ref_alias_set): For a NULL ref return
zero.
* tree-ssa-scopedtables.h
(avail_exprs_stack::lookup_avail_expr): Add output argument
giving access to the hashtable entry.
* tree-ssa-scopedtables.c (avail_exprs_stack::lookup_avail_expr):
Likewise.
* tree-ssa-dom.c: Include alias.h.
(dom_opt_dom_walker::optimize_stmt): Validate TBAA state before
removing redundant store.
* tree-ssa-sccvn.h (vn_reference_s::base_set): New member.
(ao_ref_init_from_vn_reference): Adjust prototype.
(vn_reference_lookup_pieces): Likewise.
(vn_reference_insert_pieces): Likewise.
* tree-ssa-sccvn.c: Track base alias set in addition to alias
set everywhere.
(eliminate_dom_walker::eliminate_stmt): Also check base alias
set when removing redundant stores.
(visit_reference_op_store): Likewise.
* dse.c (record_store): Adjust valdity check for redundant
store removal.
* gcc.dg/torture/pr93946-1.c: New testcase.
* gcc.dg/torture/pr93946-2.c: Likewise.
Diffstat (limited to 'gcc/tree-ssa-dse.c')
-rw-r--r-- | gcc/tree-ssa-dse.c | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c index 374143e..f2a4ed9 100644 --- a/gcc/tree-ssa-dse.c +++ b/gcc/tree-ssa-dse.c @@ -658,6 +658,17 @@ dse_optimize_redundant_stores (gimple *stmt) { int cnt = 0; + /* TBAA state of STMT, if it is a call it is effectively alias-set zero. */ + alias_set_type earlier_set = 0; + alias_set_type earlier_base_set = 0; + if (is_gimple_assign (stmt)) + { + ao_ref lhs_ref; + ao_ref_init (&lhs_ref, gimple_assign_lhs (stmt)); + earlier_set = ao_ref_alias_set (&lhs_ref); + earlier_base_set = ao_ref_base_alias_set (&lhs_ref); + } + /* We could do something fairly complex and look through PHIs like DSE_CLASSIFY_STORE, but it doesn't seem to be worth the effort. @@ -698,10 +709,27 @@ dse_optimize_redundant_stores (gimple *stmt) { gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt); if (is_gimple_assign (use_stmt)) - delete_dead_or_redundant_assignment (&gsi, "redundant", - need_eh_cleanup); + { + ao_ref lhs_ref; + ao_ref_init (&lhs_ref, gimple_assign_lhs (use_stmt)); + if ((earlier_set == ao_ref_alias_set (&lhs_ref) + || alias_set_subset_of (ao_ref_alias_set (&lhs_ref), + earlier_set)) + && (earlier_base_set == ao_ref_base_alias_set (&lhs_ref) + || alias_set_subset_of + (ao_ref_base_alias_set (&lhs_ref), + earlier_base_set))) + delete_dead_or_redundant_assignment (&gsi, "redundant", + need_eh_cleanup); + } else if (is_gimple_call (use_stmt)) - delete_dead_or_redundant_call (&gsi, "redundant"); + { + if ((earlier_set == 0 + || alias_set_subset_of (0, earlier_set)) + && (earlier_base_set == 0 + || alias_set_subset_of (0, earlier_base_set))) + delete_dead_or_redundant_call (&gsi, "redundant"); + } else gcc_unreachable (); } |