vect: Fix offset calculation for -ve strides [PR93767]

Message ID mptsgj6kc6t.fsf@arm.com
State New
Headers show
Series
  • vect: Fix offset calculation for -ve strides [PR93767]
Related show

Commit Message

Richard Sandiford Feb. 19, 2020, 12:12 p.m.
This PR is a regression caused by r256644, which added support for alias
checks involving variable strides.  One of the changes in that commit
was to split the access size out of the segment length.  The PR shows
that I hadn't done that correctly for the handling of negative strides
in vect_compile_time_alias.  The old code was:

      const_length_a = (-wi::to_poly_wide (segment_length_a)).force_uhwi ();
      offset_a = (offset_a + vect_get_scalar_dr_size (a)) - const_length_a;

where vect_get_scalar_dr_size (a) was cancelling out the subtraction
of the access size inherent in "- const_length_a".  Taking the access
size out of the segment length meant that the addition was no longer
needed/correct.

Tested on aarch64-linux-gnu and x86_64-linux-gnu.  OK to install?

Richard


2020-02-19  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
	PR tree-optimization/93767
	* tree-vect-data-refs.c (vect_compile_time_alias): Remove the
	access-size bias from the offset calculations for negative strides.

gcc/testsuite/
	PR tree-optimization/93767
	* gcc.dg/vect/pr93767.c: New test.
---
 gcc/testsuite/gcc.dg/vect/pr93767.c | 13 +++++++++++++
 gcc/tree-vect-data-refs.c           |  4 ++--
 2 files changed, 15 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/vect/pr93767.c

Comments

Richard Biener Feb. 19, 2020, 1:09 p.m. | #1
On Wed, Feb 19, 2020 at 1:13 PM Richard Sandiford
<richard.sandiford@arm.com> wrote:
>

> This PR is a regression caused by r256644, which added support for alias

> checks involving variable strides.  One of the changes in that commit

> was to split the access size out of the segment length.  The PR shows

> that I hadn't done that correctly for the handling of negative strides

> in vect_compile_time_alias.  The old code was:

>

>       const_length_a = (-wi::to_poly_wide (segment_length_a)).force_uhwi ();

>       offset_a = (offset_a + vect_get_scalar_dr_size (a)) - const_length_a;

>

> where vect_get_scalar_dr_size (a) was cancelling out the subtraction

> of the access size inherent in "- const_length_a".  Taking the access

> size out of the segment length meant that the addition was no longer

> needed/correct.

>

> Tested on aarch64-linux-gnu and x86_64-linux-gnu.  OK to install?


OK.

Thanks,
Richard.

> Richard

>

>

> 2020-02-19  Richard Sandiford  <richard.sandiford@arm.com>

>

> gcc/

>         PR tree-optimization/93767

>         * tree-vect-data-refs.c (vect_compile_time_alias): Remove the

>         access-size bias from the offset calculations for negative strides.

>

> gcc/testsuite/

>         PR tree-optimization/93767

>         * gcc.dg/vect/pr93767.c: New test.

> ---

>  gcc/testsuite/gcc.dg/vect/pr93767.c | 13 +++++++++++++

>  gcc/tree-vect-data-refs.c           |  4 ++--

>  2 files changed, 15 insertions(+), 2 deletions(-)

>  create mode 100644 gcc/testsuite/gcc.dg/vect/pr93767.c

>

> diff --git a/gcc/testsuite/gcc.dg/vect/pr93767.c b/gcc/testsuite/gcc.dg/vect/pr93767.c

> new file mode 100644

> index 00000000000..5f95d7bd35b

> --- /dev/null

> +++ b/gcc/testsuite/gcc.dg/vect/pr93767.c

> @@ -0,0 +1,13 @@

> +int

> +main ()

> +{

> +  int a[10], b;

> +  for (b = 6; b >= 3; b--)

> +    {

> +      a[b] = 1;

> +      a[b + 2] = a[3];

> +    }

> +  if (a[5] != 1)

> +    __builtin_abort ();

> +  return 0;

> +}

> diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c

> index 554ef892254..0192aa64636 100644

> --- a/gcc/tree-vect-data-refs.c

> +++ b/gcc/tree-vect-data-refs.c

> @@ -3261,14 +3261,14 @@ vect_compile_time_alias (dr_vec_info *a, dr_vec_info *b,

>    if (tree_int_cst_compare (DR_STEP (a->dr), size_zero_node) < 0)

>      {

>        const_length_a = (-wi::to_poly_wide (segment_length_a)).force_uhwi ();

> -      offset_a = (offset_a + access_size_a) - const_length_a;

> +      offset_a -= const_length_a;

>      }

>    else

>      const_length_a = tree_to_poly_uint64 (segment_length_a);

>    if (tree_int_cst_compare (DR_STEP (b->dr), size_zero_node) < 0)

>      {

>        const_length_b = (-wi::to_poly_wide (segment_length_b)).force_uhwi ();

> -      offset_b = (offset_b + access_size_b) - const_length_b;

> +      offset_b -= const_length_b;

>      }

>    else

>      const_length_b = tree_to_poly_uint64 (segment_length_b);

Patch

diff --git a/gcc/testsuite/gcc.dg/vect/pr93767.c b/gcc/testsuite/gcc.dg/vect/pr93767.c
new file mode 100644
index 00000000000..5f95d7bd35b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr93767.c
@@ -0,0 +1,13 @@ 
+int
+main ()
+{
+  int a[10], b;
+  for (b = 6; b >= 3; b--)
+    {
+      a[b] = 1;
+      a[b + 2] = a[3];
+    }
+  if (a[5] != 1)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index 554ef892254..0192aa64636 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -3261,14 +3261,14 @@  vect_compile_time_alias (dr_vec_info *a, dr_vec_info *b,
   if (tree_int_cst_compare (DR_STEP (a->dr), size_zero_node) < 0)
     {
       const_length_a = (-wi::to_poly_wide (segment_length_a)).force_uhwi ();
-      offset_a = (offset_a + access_size_a) - const_length_a;
+      offset_a -= const_length_a;
     }
   else
     const_length_a = tree_to_poly_uint64 (segment_length_a);
   if (tree_int_cst_compare (DR_STEP (b->dr), size_zero_node) < 0)
     {
       const_length_b = (-wi::to_poly_wide (segment_length_b)).force_uhwi ();
-      offset_b = (offset_b + access_size_b) - const_length_b;
+      offset_b -= const_length_b;
     }
   else
     const_length_b = tree_to_poly_uint64 (segment_length_b);