re PR tree-optimization/92751 (VN partial def support confused about clobbers)
authorRichard Biener <rguenther@suse.de>
Tue, 3 Dec 2019 10:46:52 +0000 (10:46 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 3 Dec 2019 10:46:52 +0000 (10:46 +0000)
2019-12-03  Richard Biener  <rguenther@suse.de>

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
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/tree-ssa/pr92751.C [new file with mode: 0644]
gcc/tree-ssa-sccvn.c

index 68d1c288c514a02e2c99f1b44969118cb060dd71..7a5f5c2d7d11345c85725ff11ef04f4248794726 100644 (file)
@@ -1,3 +1,11 @@
+2019-12-03  Richard Biener  <rguenther@suse.de>
+
+       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  <jakub@redhat.com>
 
        PR tree-optimization/92734
index 989ecd52b67fafae710a65bcf17dbb8acbc88f17..e7e07882a4343904dd88ecb502f122409dd57ca1 100644 (file)
@@ -1,3 +1,8 @@
+2019-12-03  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/92751
+       * g++.dg/tree-ssa/pr92751.C: New testcase.
+
 2019-12-03  Richard Sandiford  <richard.sandiford@arm.com>
 
        * 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 (file)
index 0000000..d107482
--- /dev/null
@@ -0,0 +1,26 @@
+// { dg-do compile }
+// { dg-options "-O -fdump-tree-fre1" }
+
+inline void* operator new(__SIZE_TYPE__, void* p) { return p; }
+template<int N>
+struct Vec {
+  Vec(int v) : lo(v), hi(v) {};
+  Vec<N/2> 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" } }
index 8a7e0475ff8307430994d1ab452b5e008c706634..8fbdb5163d6f15a8d3c5e6b77908ed74504591f7 100644 (file)
@@ -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;