From cad984b289e2b3aca786314c673339eb0500fefa Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Sat, 16 Nov 2019 11:42:02 +0000 Subject: [PATCH] Dump the list of merged alias pairs This patch dumps the final (merged) list of alias pairs. It also adds: - WAW and RAW versions of vect-alias-check-8.c - a "well-ordered" version of vect-alias-check-9.c (i.e. all reads before any writes) - a test with mixed steps in the same alias pair I also tweaked the test value in vect-alias-check-9.c so that the result was less likely to be accidentally correct if the alias isn't honoured. 2019-11-16 Richard Sandiford gcc/ * tree-data-ref.c (dump_alias_pair): New function. (prune_runtime_alias_test_list): Use it to dump each merged alias pair. gcc/testsuite/ * gcc.dg/vect/vect-alias-check-8.c: Test for the RAW flag. * gcc.dg/vect/vect-alias-check-9.c: Test for the ARBITRARY flag. (TEST_VALUE): Use a higher value for early iterations. * gcc.dg/vect/vect-alias-check-14.c: New test. * gcc.dg/vect/vect-alias-check-15.c: Likewise. * gcc.dg/vect/vect-alias-check-16.c: Likewise. * gcc.dg/vect/vect-alias-check-17.c: Likewise. From-SVN: r278352 --- gcc/ChangeLog | 5 ++ gcc/testsuite/ChangeLog | 10 +++ .../gcc.dg/vect/vect-alias-check-14.c | 62 ++++++++++++++++++ .../gcc.dg/vect/vect-alias-check-15.c | 59 +++++++++++++++++ .../gcc.dg/vect/vect-alias-check-16.c | 64 +++++++++++++++++++ .../gcc.dg/vect/vect-alias-check-17.c | 13 ++++ .../gcc.dg/vect/vect-alias-check-8.c | 2 + .../gcc.dg/vect/vect-alias-check-9.c | 4 +- gcc/tree-data-ref.c | 52 +++++++++++++++ 9 files changed, 270 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/vect/vect-alias-check-14.c create mode 100644 gcc/testsuite/gcc.dg/vect/vect-alias-check-15.c create mode 100644 gcc/testsuite/gcc.dg/vect/vect-alias-check-16.c create mode 100644 gcc/testsuite/gcc.dg/vect/vect-alias-check-17.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 95f6363e8bf..31b5afce86f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-11-16 Richard Sandiford + + * tree-data-ref.c (dump_alias_pair): New function. + (prune_runtime_alias_test_list): Use it to dump each merged alias pair. + 2019-11-16 Richard Sandiford * tree-data-ref.h (DR_ALIAS_MIXED_STEPS): New flag. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 23a452b1e49..eb6060c8e92 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2019-11-16 Richard Sandiford + + * gcc.dg/vect/vect-alias-check-8.c: Test for the RAW flag. + * gcc.dg/vect/vect-alias-check-9.c: Test for the ARBITRARY flag. + (TEST_VALUE): Use a higher value for early iterations. + * gcc.dg/vect/vect-alias-check-14.c: New test. + * gcc.dg/vect/vect-alias-check-15.c: Likewise. + * gcc.dg/vect/vect-alias-check-16.c: Likewise. + * gcc.dg/vect/vect-alias-check-17.c: Likewise. + 2019-11-16 Richard Sandiford * gcc.target/aarch64/sve/scatter_store_1.c (TEST_LOOP): Start at 0. diff --git a/gcc/testsuite/gcc.dg/vect/vect-alias-check-14.c b/gcc/testsuite/gcc.dg/vect/vect-alias-check-14.c new file mode 100644 index 00000000000..35b16b70b91 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-alias-check-14.c @@ -0,0 +1,62 @@ +#define N 200 +#define M 4 + +typedef signed char sc; +typedef unsigned char uc; +typedef signed short ss; +typedef unsigned short us; +typedef int si; +typedef unsigned int ui; +typedef signed long long sll; +typedef unsigned long long ull; + +#define FOR_EACH_TYPE(M) \ + M (sc) M (uc) \ + M (ss) M (us) \ + M (si) M (ui) \ + M (sll) M (ull) \ + M (float) M (double) + +#define TEST_VALUE(I) ((I) * 17 / 2) + +#define ADD_TEST(TYPE) \ + void __attribute__((noinline, noclone)) \ + test_##TYPE (TYPE *a, TYPE *b) \ + { \ + for (int i = 0; i < N; i += 2) \ + { \ + TYPE b0 = b[i + 0]; \ + TYPE b1 = b[i + 1]; \ + a[i + 0] = b0 + 2; \ + a[i + 1] = b1 + 3; \ + } \ + } + +#define DO_TEST(TYPE) \ + for (int j = 0; j < M; ++j) \ + { \ + TYPE a[N + M]; \ + for (int i = 0; i < N + M; ++i) \ + a[i] = TEST_VALUE (i); \ + test_##TYPE (a + j, a); \ + for (int i = 0; i < N; i += 2) \ + { \ + TYPE base1 = j == 0 ? TEST_VALUE (i) : a[i]; \ + TYPE base2 = j <= 1 ? TEST_VALUE (i + 1) : a[i + 1]; \ + if (a[i + j] != (TYPE) (base1 + 2) \ + || a[i + j + 1] != (TYPE) (base2 + 3)) \ + __builtin_abort (); \ + } \ + } + +FOR_EACH_TYPE (ADD_TEST) + +int +main (void) +{ + FOR_EACH_TYPE (DO_TEST) + return 0; +} + +/* { dg-final { scan-tree-dump {flags: *WAR\n} "vect" { target vect_int } } } */ +/* { dg-final { scan-tree-dump-not {flags: [^\n]*ARBITRARY\n} "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-alias-check-15.c b/gcc/testsuite/gcc.dg/vect/vect-alias-check-15.c new file mode 100644 index 00000000000..d868c43130f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-alias-check-15.c @@ -0,0 +1,59 @@ +#define N 200 +#define DIST 32 + +typedef signed char sc; +typedef unsigned char uc; +typedef signed short ss; +typedef unsigned short us; +typedef int si; +typedef unsigned int ui; +typedef signed long long sll; +typedef unsigned long long ull; + +#define FOR_EACH_TYPE(M) \ + M (sc) M (uc) \ + M (ss) M (us) \ + M (si) M (ui) \ + M (sll) M (ull) \ + M (float) M (double) + +#define ADD_TEST(TYPE) \ + void __attribute__((noinline, noclone)) \ + test_##TYPE (TYPE *x, TYPE *y) \ + { \ + for (int i = 0; i < N; ++i) \ + { \ + x[i] = i; \ + y[i] = 42 - i * 2; \ + } \ + } + +#define DO_TEST(TYPE) \ + for (int i = 0; i < DIST * 2; ++i) \ + { \ + TYPE a[N + DIST * 2] = {}; \ + test_##TYPE (a + DIST, a + i); \ + for (int j = 0; j < N + DIST * 2; ++j) \ + { \ + TYPE expected = 0; \ + if (i > DIST && j >= i && j < i + N) \ + expected = 42 - (j - i) * 2; \ + if (j >= DIST && j < DIST + N) \ + expected = j - DIST; \ + if (i <= DIST && j >= i && j < i + N) \ + expected = 42 - (j - i) * 2; \ + if (expected != a[j]) \ + __builtin_abort (); \ + } \ + } + +FOR_EACH_TYPE (ADD_TEST) + +int +main (void) +{ + FOR_EACH_TYPE (DO_TEST) + return 0; +} + +/* { dg-final { scan-tree-dump {flags: *WAW\n} "vect" { target vect_int } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-alias-check-16.c b/gcc/testsuite/gcc.dg/vect/vect-alias-check-16.c new file mode 100644 index 00000000000..97ab77e7257 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-alias-check-16.c @@ -0,0 +1,64 @@ +#define N 200 +#define DIST 32 + +typedef signed char sc; +typedef unsigned char uc; +typedef signed short ss; +typedef unsigned short us; +typedef int si; +typedef unsigned int ui; +typedef signed long long sll; +typedef unsigned long long ull; + +#define FOR_EACH_TYPE(M) \ + M (sc) M (uc) \ + M (ss) M (us) \ + M (si) M (ui) \ + M (sll) M (ull) \ + M (float) M (double) + +#define TEST_VALUE(I) ((I) * 13 / 2) + +#define ADD_TEST(TYPE) \ + TYPE __attribute__((noinline, noclone)) \ + test_##TYPE (TYPE *x, TYPE *y) \ + { \ + TYPE res = 0; \ + for (int i = 0; i < N; ++i) \ + { \ + x[i] = i; \ + res += y[i]; \ + } \ + return res; \ + } + +#define DO_TEST(TYPE) \ + for (int i = 0; i < DIST * 2; ++i) \ + { \ + TYPE a[N + DIST * 2]; \ + for (int j = 0; j < N + DIST * 2; ++j) \ + a[j] = TEST_VALUE (j); \ + TYPE res = test_##TYPE (a + DIST, a + i); \ + for (int j = 0; j < N; ++j) \ + if (a[j + DIST] != (TYPE) j) \ + __builtin_abort (); \ + TYPE expected_res = 0; \ + for (int j = i; j < i + N; ++j) \ + if (i <= DIST && j >= DIST && j < DIST + N) \ + expected_res += j - DIST; \ + else \ + expected_res += TEST_VALUE (j); \ + if (expected_res != res) \ + __builtin_abort (); \ + } + +FOR_EACH_TYPE (ADD_TEST) + +int +main (void) +{ + FOR_EACH_TYPE (DO_TEST) + return 0; +} + +/* { dg-final { scan-tree-dump {flags: *RAW\n} "vect" { target vect_int } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-alias-check-17.c b/gcc/testsuite/gcc.dg/vect/vect-alias-check-17.c new file mode 100644 index 00000000000..0c8bec3c5e3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-alias-check-17.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_load_lanes } */ + +struct s { int x[100]; }; + +void +f (struct s *s1, int a, int b) +{ + for (int i = 0; i < 32; ++i) + s1->x[a + i] = s1->x[b + i * 2] + s1->x[b + i * 3]; +} + +/* { dg-final { scan-tree-dump {flags: *[^\n]*MIXED_STEPS} "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-alias-check-8.c b/gcc/testsuite/gcc.dg/vect/vect-alias-check-8.c index 0569ca487b5..df1969850ec 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-alias-check-8.c +++ b/gcc/testsuite/gcc.dg/vect/vect-alias-check-8.c @@ -58,3 +58,5 @@ main (void) FOR_EACH_TYPE (DO_TEST) return 0; } + +/* { dg-final { scan-tree-dump {flags: *WAR\n} "vect" { target vect_int } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-alias-check-9.c b/gcc/testsuite/gcc.dg/vect/vect-alias-check-9.c index 5685bfee576..f771462c6b9 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-alias-check-9.c +++ b/gcc/testsuite/gcc.dg/vect/vect-alias-check-9.c @@ -17,7 +17,7 @@ typedef unsigned long long ull; M (sll) M (ull) \ M (float) M (double) -#define TEST_VALUE(I) ((I) * 5 / 2) +#define TEST_VALUE(I) ((I) * 17 / 2) #define ADD_TEST(TYPE) \ void __attribute__((noinline, noclone)) \ @@ -51,3 +51,5 @@ main (void) FOR_EACH_TYPE (DO_TEST) return 0; } + +/* { dg-final { scan-tree-dump {flags: [^\n]*ARBITRARY\n} "vect" { target vect_int } } } */ diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index bc5d2130ae1..7fc401f2a59 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -1452,6 +1452,54 @@ comp_dr_with_seg_len_pair (const void *pa_, const void *pb_) return 0; } +/* Dump information about ALIAS_PAIR, indenting each line by INDENT. */ + +static void +dump_alias_pair (dr_with_seg_len_pair_t *alias_pair, const char *indent) +{ + dump_printf (MSG_NOTE, "%sreference: %T vs. %T\n", indent, + DR_REF (alias_pair->first.dr), + DR_REF (alias_pair->second.dr)); + + dump_printf (MSG_NOTE, "%ssegment length: %T", indent, + alias_pair->first.seg_len); + if (!operand_equal_p (alias_pair->first.seg_len, + alias_pair->second.seg_len, 0)) + dump_printf (MSG_NOTE, " vs. %T", alias_pair->second.seg_len); + + dump_printf (MSG_NOTE, "\n%saccess size: ", indent); + dump_dec (MSG_NOTE, alias_pair->first.access_size); + if (maybe_ne (alias_pair->first.access_size, alias_pair->second.access_size)) + { + dump_printf (MSG_NOTE, " vs. "); + dump_dec (MSG_NOTE, alias_pair->second.access_size); + } + + dump_printf (MSG_NOTE, "\n%salignment: %d", indent, + alias_pair->first.align); + if (alias_pair->first.align != alias_pair->second.align) + dump_printf (MSG_NOTE, " vs. %d", alias_pair->second.align); + + dump_printf (MSG_NOTE, "\n%sflags: ", indent); + if (alias_pair->flags & DR_ALIAS_RAW) + dump_printf (MSG_NOTE, " RAW"); + if (alias_pair->flags & DR_ALIAS_WAR) + dump_printf (MSG_NOTE, " WAR"); + if (alias_pair->flags & DR_ALIAS_WAW) + dump_printf (MSG_NOTE, " WAW"); + if (alias_pair->flags & DR_ALIAS_ARBITRARY) + dump_printf (MSG_NOTE, " ARBITRARY"); + if (alias_pair->flags & DR_ALIAS_SWAPPED) + dump_printf (MSG_NOTE, " SWAPPED"); + if (alias_pair->flags & DR_ALIAS_UNSWAPPED) + dump_printf (MSG_NOTE, " UNSWAPPED"); + if (alias_pair->flags & DR_ALIAS_MIXED_STEPS) + dump_printf (MSG_NOTE, " MIXED_STEPS"); + if (alias_pair->flags == 0) + dump_printf (MSG_NOTE, " "); + dump_printf (MSG_NOTE, "\n"); +} + /* Merge alias checks recorded in ALIAS_PAIRS and remove redundant ones. FACTOR is number of iterations that each data reference is accessed. @@ -1655,6 +1703,8 @@ prune_runtime_alias_test_list (vec *alias_pairs, dr_with_seg_len_pair_t. If we ended up combining swapped and unswapped pairs into the same check, we have to invalidate any RAW, WAR and WAW information for it. */ + if (dump_enabled_p ()) + dump_printf (MSG_NOTE, "merged alias checks:\n"); FOR_EACH_VEC_ELT (*alias_pairs, i, alias_pair) { unsigned int swap_mask = (DR_ALIAS_SWAPPED | DR_ALIAS_UNSWAPPED); @@ -1664,6 +1714,8 @@ prune_runtime_alias_test_list (vec *alias_pairs, else if (swapped != DR_ALIAS_UNSWAPPED) alias_pair->flags |= DR_ALIAS_ARBITRARY; alias_pair->flags &= ~swap_mask; + if (dump_enabled_p ()) + dump_alias_pair (alias_pair, " "); } } -- 2.30.2