From 89ee3a872fdf460402d1fc137e5cdce20f62bc8e Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 3 Dec 2019 10:46:52 +0000 Subject: [PATCH] re PR tree-optimization/92751 (VN partial def support confused about clobbers) 2019-12-03 Richard Biener PR tree-optimization/92751 * tree-ssa-sccvn.c (vn_walk_cb_data::push_partial_def): Fail when a clobber ends up in the partial-def vector. (vn_reference_lookup_3): Let clobbers be handled by the assignment from CTOR handling. * g++.dg/tree-ssa/pr92751.C: New testcase. From-SVN: r278931 --- gcc/ChangeLog | 8 ++++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/tree-ssa/pr92751.C | 26 +++++++++++++++++++++++++ gcc/tree-ssa-sccvn.c | 20 ++++++++++++++----- 4 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/tree-ssa/pr92751.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 68d1c288c51..7a5f5c2d7d1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2019-12-03 Richard Biener + + PR tree-optimization/92751 + * tree-ssa-sccvn.c (vn_walk_cb_data::push_partial_def): Fail + when a clobber ends up in the partial-def vector. + (vn_reference_lookup_3): Let clobbers be handled by the + assignment from CTOR handling. + 2019-12-03 Jakub Jelinek PR tree-optimization/92734 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 989ecd52b67..e7e07882a43 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-12-03 Richard Biener + + PR tree-optimization/92751 + * g++.dg/tree-ssa/pr92751.C: New testcase. + 2019-12-03 Richard Sandiford * gfortran.dg/loop_versioning_6.f90: XFAIL the scans for ! lp64. diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr92751.C b/gcc/testsuite/g++.dg/tree-ssa/pr92751.C new file mode 100644 index 00000000000..d107482f34d --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr92751.C @@ -0,0 +1,26 @@ +// { dg-do compile } +// { dg-options "-O -fdump-tree-fre1" } + +inline void* operator new(__SIZE_TYPE__, void* p) { return p; } +template +struct Vec { + Vec(int v) : lo(v), hi(v) {}; + Vec lo, hi; +}; +template<> +struct Vec<1> { + Vec(int v) : val(v) {} + int val; +}; + +typedef int v4si __attribute__((vector_size(16))); +void foo (v4si *dst) +{ + Vec<4> v(1); + v4si tem; + __builtin_memcpy (&tem, &v, sizeof (tem)); + *dst = tem; +} + +// FRE should be able to value-number 'tem' to a constant. */ +// { dg-final { scan-tree-dump "\\*dst_\[0-9\]*\\\(D\\\) = { 1, 1, 1, 1 };" "fre1" } } diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 8a7e0475ff8..8fbdb5163d6 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -1761,6 +1761,9 @@ vn_walk_cb_data::push_partial_def (const pd_data &pd, tree vuse, if (partial_defs.is_empty ()) { + /* If we get a clobber upfront, fail. */ + if (TREE_CLOBBER_P (pd.rhs)) + return (void *)-1; partial_defs.safe_push (pd); first_range.offset = pd.offset; first_range.size = pd.size; @@ -1792,7 +1795,8 @@ vn_walk_cb_data::push_partial_def (const pd_data &pd, tree vuse, && ranges_known_overlap_p (r->offset, r->size + 1, newr.offset, newr.size)) { - /* Ignore partial defs already covered. */ + /* Ignore partial defs already covered. Here we also drop shadowed + clobbers arriving here at the floor. */ if (known_subrange_p (newr.offset, newr.size, r->offset, r->size)) return NULL; r->size = MAX (r->offset + r->size, newr.offset + newr.size) - r->offset; @@ -1817,6 +1821,9 @@ vn_walk_cb_data::push_partial_def (const pd_data &pd, tree vuse, rafter->offset + rafter->size) - r->offset; splay_tree_remove (known_ranges, (splay_tree_key)&rafter->offset); } + /* If we get a clobber, fail. */ + if (TREE_CLOBBER_P (pd.rhs)) + return (void *)-1; partial_defs.safe_push (pd); /* Now we have merged newr into the range tree. When we have covered @@ -2355,10 +2362,6 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_, poly_int64 offset = ref->offset; poly_int64 maxsize = ref->max_size; - /* We can't deduce anything useful from clobbers. */ - if (gimple_clobber_p (def_stmt)) - return (void *)-1; - /* def_stmt may-defs *ref. See if we can derive a value for *ref from that definition. 1) Memset. */ @@ -2508,6 +2511,10 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_, if (data->partial_defs.is_empty () && known_subrange_p (offset, maxsize, offset2, size2)) { + /* While technically undefined behavior do not optimize + a full read from a clobber. */ + if (gimple_clobber_p (def_stmt)) + return (void *)-1; tree val = build_zero_cst (vr->type); return vn_reference_lookup_or_insert_for_pieces (vuse, get_alias_set (lhs), vr->type, vr->operands, val); @@ -2522,6 +2529,9 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_, && size2.is_constant (&size2i) && size2i % BITS_PER_UNIT == 0) { + /* Let clobbers be consumed by the partial-def tracker + which can choose to ignore them if they are shadowed + by a later def. */ pd_data pd; pd.rhs = gimple_assign_rhs1 (def_stmt); pd.offset = (offset2i - offseti) / BITS_PER_UNIT; -- 2.30.2