diff mbox

Fix memmove to memcpy folding (PR middle-end/71874)

Message ID 20160719165255.GM7387@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek July 19, 2016, 4:52 p.m. UTC
Hi!

As mentioned in the PR and discussed on IRC, get_ref_base_and_extent
can return size != maxsize or maxsize -1 and then we really can't trust
the offset for the purposes we want.  So this patch instead uses a different
function that just computes the base and offset if the offset is constant;
we don't really care about the access size.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/6.2,
for 5.5 the 4.9 patch applied to gimple-fold.c instead of bultins.c and for
4.9.4 the attached patch?

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.

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


	Jakub
2016-07-19  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/71874
	* builtins.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.

--- gcc/builtins.c.jj	2016-04-28 21:47:35.000000000 +0200
+++ gcc/builtins.c	2016-07-19 13:13:41.563148783 +0200
@@ -8793,21 +8793,21 @@ fold_builtin_memory_op (location_t loc,
 	    {
 	      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;
+	      HOST_WIDE_INT maxsize;
 
 	      srcvar = TREE_OPERAND (src, 0);
-	      src_base = get_ref_base_and_extent (srcvar, &src_offset,
-						  &size, &maxsize);
+	      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);
+	      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))
 		{
--- gcc/testsuite/g++.dg/torture/pr71874.C.jj	2016-07-19 12:58:54.816402724 +0200
+++ gcc/testsuite/g++.dg/torture/pr71874.C	2016-07-19 13:00:04.106521149 +0200
@@ -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;
+}

Comments

Richard Biener July 19, 2016, 5:20 p.m. UTC | #1
On July 19, 2016 6:52:55 PM GMT+02:00, Jakub Jelinek <jakub@redhat.com> wrote:
>Hi!
>
>As mentioned in the PR and discussed on IRC, get_ref_base_and_extent
>can return size != maxsize or maxsize -1 and then we really can't trust
>the offset for the purposes we want.  So this patch instead uses a
>different
>function that just computes the base and offset if the offset is
>constant;
>we don't really care about the access size.
>
>Bootstrapped/regtested on x86_64-linux and i686-linux, ok for
>trunk/6.2,
>for 5.5 the 4.9 patch applied to gimple-fold.c instead of bultins.c and
>for
>4.9.4 the attached patch?

OK.

Thanks
Richard.

>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.
>
>	* g++.dg/torture/pr71874.C: New test.
>
>--- gcc/gimple-fold.c.jj	2016-07-19 15:24:42.870004660 +0200
>+++ gcc/gimple-fold.c	2016-07-19 15:26:55.449343027 +0200
>@@ -796,22 +796,21 @@ gimple_fold_builtin_memory_op (gimple_st
> 	    {
> 	      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))
> 		{
>--- gcc/testsuite/g++.dg/torture/pr71874.C.jj	2016-07-19
>15:23:37.097832377 +0200
>+++ gcc/testsuite/g++.dg/torture/pr71874.C	2016-07-19
>15:23:37.097832377 +0200
>@@ -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;
>+}
>
>	Jakub
diff mbox

Patch

--- gcc/gimple-fold.c.jj	2016-07-19 15:24:42.870004660 +0200
+++ gcc/gimple-fold.c	2016-07-19 15:26:55.449343027 +0200
@@ -796,22 +796,21 @@  gimple_fold_builtin_memory_op (gimple_st
 	    {
 	      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))
 		{
--- gcc/testsuite/g++.dg/torture/pr71874.C.jj	2016-07-19 15:23:37.097832377 +0200
+++ gcc/testsuite/g++.dg/torture/pr71874.C	2016-07-19 15:23:37.097832377 +0200
@@ -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;
+}