re PR middle-end/71874 (memmove works wrong)
authorJakub Jelinek <jakub@redhat.com>
Tue, 19 Jul 2016 17:30:05 +0000 (19:30 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 19 Jul 2016 17:30:05 +0000 (19:30 +0200)
PR middle-end/71874
* gimple-fold.c (fold_builtin_memory_op): Use
get_addr_base_and_unit_offset instead of get_ref_base_and_extent.

* g++.dg/torture/pr71874.C: New test.

From-SVN: r238484

gcc/ChangeLog
gcc/gimple-fold.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr71874.C [new file with mode: 0644]

index 66657798607a3288809d1683b9a4111e33a8d9be..a59b4b3f40e41d57f8383a4691fd7eed3d49c3a3 100644 (file)
@@ -1,3 +1,9 @@
+2016-07-19  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/71874
+       * gimple-fold.c (fold_builtin_memory_op): Use
+       get_addr_base_and_unit_offset instead of get_ref_base_and_extent.
+
 2016-07-19  Uros Bizjak  <ubizjak@gmail.com>
 
        * builtins.c: Use HOST_WIDE_INT_1 instead of (HOST_WIDE_INT) 1,
index 3a5008839a50aaedde07a6eb4459085caf34f59b..73c231445fbf2c60c38708b64c3aae689d52eb8c 100644 (file)
@@ -796,22 +796,21 @@ gimple_fold_builtin_memory_op (gimple_stmt_iterator *gsi,
            {
              tree src_base, dest_base, fn;
              HOST_WIDE_INT src_offset = 0, dest_offset = 0;
-             HOST_WIDE_INT size = -1;
-             HOST_WIDE_INT maxsize = -1;
-             bool reverse;
+             HOST_WIDE_INT maxsize;
 
              srcvar = TREE_OPERAND (src, 0);
-             src_base = get_ref_base_and_extent (srcvar, &src_offset,
-                                                 &size, &maxsize, &reverse);
+             src_base = get_addr_base_and_unit_offset (srcvar, &src_offset);
+             if (src_base == NULL)
+               src_base = srcvar;
              destvar = TREE_OPERAND (dest, 0);
-             dest_base = get_ref_base_and_extent (destvar, &dest_offset,
-                                                  &size, &maxsize, &reverse);
+             dest_base = get_addr_base_and_unit_offset (destvar,
+                                                        &dest_offset);
+             if (dest_base == NULL)
+               dest_base = destvar;
              if (tree_fits_uhwi_p (len))
                maxsize = tree_to_uhwi (len);
              else
                maxsize = -1;
-             src_offset /= BITS_PER_UNIT;
-             dest_offset /= BITS_PER_UNIT;
              if (SSA_VAR_P (src_base)
                  && SSA_VAR_P (dest_base))
                {
index 00f0274a0187ec011183e7a8c7970673d9ad8eef..17fcb00d1c8202ad3658dca4a70de5ec910e2672 100644 (file)
@@ -1,5 +1,8 @@
 2016-07-19  Jakub Jelinek  <jakub@redhat.com>
 
+       PR middle-end/71874
+       * g++.dg/torture/pr71874.C: New test.
+
        PR middle-end/71734
        * g++.dg/vect/pr70729.cc: Don't include string.h or xmmintrin.h.
        (my_alloc): Rewritten to use __builtin_posix_memalign and
diff --git a/gcc/testsuite/g++.dg/torture/pr71874.C b/gcc/testsuite/g++.dg/torture/pr71874.C
new file mode 100644 (file)
index 0000000..d9b4e2f
--- /dev/null
@@ -0,0 +1,12 @@
+// PR middle-end/71874
+// { dg-do run }
+
+int
+main ()
+{
+  char str[] = "abcdefghijklmnopqrstuvwxyzABCDEF";
+  __builtin_memmove (str + 20, str + 15, 11);
+  if (__builtin_strcmp (str, "abcdefghijklmnopqrstpqrstuvwxyzF") != 0)
+    __builtin_abort ();
+  return 0;
+}