r278409 - in /trunk/gcc: ChangeLog testsuite/Ch...

rsandifo@gcc.gnu.org rsandifo@gcc.gnu.org
Mon Nov 18 15:26:00 GMT 2019


Author: rsandifo
Date: Mon Nov 18 15:26:55 2019
New Revision: 278409

URL: https://gcc.gnu.org/viewcvs?rev=278409&root=gcc&view=rev
Log:
Optimise WAR and WAW alias checks

For:

  void
  f1 (int *x, int *y)
  {
    for (int i = 0; i < 32; ++i)
      x[i] += y[i];
  }

we checked at runtime whether one vector at x would overlap one vector
at y.  But in cases like this, the vector code would handle x <= y just
fine, since any write to address A still happens after any read from
address A.  The only problem is if x is ahead of y by less than a
vector.

The same is true for two writes:

  void
  f2 (int *x, int *y)
  {
    for (int i = 0; i < 32; ++i)
      {
        x[i] = i;
        y[i] = 2;
      }
  }

if y <= x then a vector write at y after a vector write at x would
have the same net effect as the original scalar writes.

This patch optimises the alias checks for these two cases.  E.g.,
before the patch, f1 used:

        add     x2, x0, 15
        sub     x2, x2, x1
        cmp     x2, 30
        bls     .L2

whereas after the patch it uses:

        add     x2, x1, 4
        sub     x2, x0, x2
        cmp     x2, 8
        bls     .L2

Read-after-write cases like:

  int
  f3 (int *x, int *y)
  {
    int res = 0;
    for (int i = 0; i < 32; ++i)
      {
        x[i] = i;
        res += y[i];
      }
    return res;
  }

can cope with x == y, but otherwise don't allow overlap in either
direction.  Since checking for x == y at runtime would require extra
code, we're probably better off sticking with the current overlap test.

An overlap test is also needed if the scalar or vector accesses covered
by the alias check are mixed together, rather than all statements for
the second access following all statements for the first access.

The new code for gcc.target/aarch64/sve/var_strict_[135].c is slightly
better than before.

2019-11-18  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
	* tree-data-ref.c (create_intersect_range_checks_index): If the
	alias pair describes simple WAW and WAR dependencies, just check
	whether the first B access overlaps later A accesses.
	(create_waw_or_war_checks): New function that performs the same
	optimization on addresses.
	(create_intersect_range_checks): Call it.

gcc/testsuite/
	* gcc.dg/vect/vect-alias-check-8.c: Expect WAR/WAW checks to be used.
	* gcc.dg/vect/vect-alias-check-14.c: Likewise.
	* gcc.dg/vect/vect-alias-check-15.c: Likewise.
	* gcc.dg/vect/vect-alias-check-18.c: Likewise.
	* gcc.dg/vect/vect-alias-check-19.c: Likewise.
	* gcc.target/aarch64/sve/var_stride_1.c: Update expected sequence.
	* gcc.target/aarch64/sve/var_stride_2.c: Likewise.
	* gcc.target/aarch64/sve/var_stride_3.c: Likewise.
	* gcc.target/aarch64/sve/var_stride_5.c: Likewise.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gcc.dg/vect/vect-alias-check-14.c
    trunk/gcc/testsuite/gcc.dg/vect/vect-alias-check-15.c
    trunk/gcc/testsuite/gcc.dg/vect/vect-alias-check-18.c
    trunk/gcc/testsuite/gcc.dg/vect/vect-alias-check-19.c
    trunk/gcc/testsuite/gcc.dg/vect/vect-alias-check-8.c
    trunk/gcc/testsuite/gcc.target/aarch64/sve/var_stride_1.c
    trunk/gcc/testsuite/gcc.target/aarch64/sve/var_stride_2.c
    trunk/gcc/testsuite/gcc.target/aarch64/sve/var_stride_3.c
    trunk/gcc/testsuite/gcc.target/aarch64/sve/var_stride_5.c
    trunk/gcc/tree-data-ref.c



More information about the Gcc-cvs mailing list