re PR tree-optimization/88223 (Wrong code for intrinsic memmove)
authorRichard Biener <rguenther@suse.de>
Wed, 28 Nov 2018 13:51:42 +0000 (13:51 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 28 Nov 2018 13:51:42 +0000 (13:51 +0000)
2018-11-28  Richard Biener  <rguenther@suse.de>

PR tree-optimization/88223
* tree-ssa-sccvn.c (vn_reference_lookup_3): When skipping
over a stored-same value may-alias store make sure to consider
partial overlaps which are valid when TBAA reasonings do not
apply and byte-granular overlaps are possible at all.

* gcc.dg/torture/pr88223.c: New testcase.

From-SVN: r266560

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr88223.c [new file with mode: 0644]
gcc/tree-ssa-sccvn.c

index 2c5bfffb5ecc14330999e01d2218f4980b910b4c..695c1ff6093dda36875959c6281ccf1f6305ed58 100644 (file)
@@ -1,3 +1,11 @@
+2018-11-28  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/88223
+       * tree-ssa-sccvn.c (vn_reference_lookup_3): When skipping
+       over a stored-same value may-alias store make sure to consider
+       partial overlaps which are valid when TBAA reasonings do not
+       apply and byte-granular overlaps are possible at all.
+
 2018-11-28  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/88217
index 9f2383a38c362f048d67121b6b3683fd7445745e..52feffa476e0881f7c030efa8aa01553f6898b51 100644 (file)
@@ -1,3 +1,8 @@
+2018-11-28  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/88223
+       * gcc.dg/torture/pr88223.c: New testcase.
+
 2018-11-28  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/88217
diff --git a/gcc/testsuite/gcc.dg/torture/pr88223.c b/gcc/testsuite/gcc.dg/torture/pr88223.c
new file mode 100644 (file)
index 0000000..37df1cd
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do run } */
+
+extern void *memmove(void *, const void *, __SIZE_TYPE__);
+extern void abort(void);
+
+extern int
+main(void)
+{
+ char s[] = "12345";
+ memmove(s + 1, s, 4);
+ memmove(s + 1, s, 4);
+ memmove(s + 1, s, 4);
+ if (s[0] != '1' || s[1] != '1' || s[2] != '1' || s[3] != '1' || s[4] != '2')
+   abort ();
+ return (0);
+}
index b0b9d5221f49f81169456111507083e1ca100bce..8f2b4608b5c5ded98fafb59eaf3853bb3c7a3489 100644 (file)
@@ -1927,7 +1927,16 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_,
         VN_WALKREWRITE guard).  */
       if (vn_walk_kind == VN_WALKREWRITE
          && is_gimple_reg_type (TREE_TYPE (lhs))
-         && types_compatible_p (TREE_TYPE (lhs), vr->type))
+         && types_compatible_p (TREE_TYPE (lhs), vr->type)
+         /* The overlap restriction breaks down when either access
+            alias-set is zero.  Still for accesses of the size of
+            an addressable unit there can be no overlaps.  Overlaps
+            between different union members are not an issue since
+            activation of a union member via a store makes the
+            values of untouched bytes unspecified.  */
+         && (known_eq (ref->size, BITS_PER_UNIT)
+             || (get_alias_set (lhs) != 0
+                 && ao_ref_alias_set (ref) != 0)))
        {
          tree *saved_last_vuse_ptr = last_vuse_ptr;
          /* Do not update last_vuse_ptr in vn_reference_lookup_2.  */