From e46ec6e243c704f0858d16af380a7d9c36fc4244 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 23 Jun 2021 09:59:28 +0200 Subject: [PATCH] tree-optimization/101173 - fix interchange dependence checking This adjusts the loop interchange dependence checking to properly guard all dependence checks with DDR_REVERSED_P or its inverse. 2021-07-07 Richard Biener PR tree-optimization/101173 PR tree-optimization/101280 * gimple-loop-interchange.cc (tree_loop_interchange::valid_data_dependences): Properly guard all dependence checks with DDR_REVERSED_P or its inverse. * gcc.dg/torture/pr101173.c: New testcase. --- gcc/gimple-loop-interchange.cc | 5 ++++- gcc/testsuite/gcc.dg/torture/pr101173.c | 18 +++++++++++++++ .../gcc.dg/tree-ssa/loop-interchange-16.c | 22 +++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr101173.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/loop-interchange-16.c diff --git a/gcc/gimple-loop-interchange.cc b/gcc/gimple-loop-interchange.cc index f45b93646444..7b799eca805c 100644 --- a/gcc/gimple-loop-interchange.cc +++ b/gcc/gimple-loop-interchange.cc @@ -1044,7 +1044,10 @@ tree_loop_interchange::valid_data_dependences (unsigned i_idx, unsigned o_idx, /* Be conservative, skip case if either direction at i_idx/o_idx levels is not '=' or '<'. */ - if (dist_vect[i_idx] < 0 || dist_vect[o_idx] < 0) + if ((!DDR_REVERSED_P (ddr) && dist_vect[i_idx] < 0) + || (DDR_REVERSED_P (ddr) && dist_vect[i_idx] > 0) + || (!DDR_REVERSED_P (ddr) && dist_vect[o_idx] < 0) + || (DDR_REVERSED_P (ddr) && dist_vect[o_idx] > 0)) return false; } } diff --git a/gcc/testsuite/gcc.dg/torture/pr101173.c b/gcc/testsuite/gcc.dg/torture/pr101173.c new file mode 100644 index 000000000000..0c9090d66867 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr101173.c @@ -0,0 +1,18 @@ +/* { dg-do run } */ +/* { dg-additional-options "-floop-interchange" } */ + +int a[6][9]; +int main() +{ + a[1][3] = 8; + for (int b = 1; b <= 5; b++) + for (int d = 0; d <= 5; d++) +#pragma GCC unroll 0 + for (int c = 0; c <= 5; c++) + a[b][c] = a[b][c + 2] & 216; + for (int e = 0; e < 6; e++) + for (int f = 0; f < 9; f++) + if (a[e][f] != 0) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-interchange-16.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-interchange-16.c new file mode 100644 index 000000000000..781555e085d1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-interchange-16.c @@ -0,0 +1,22 @@ +/* PR/101280 */ +/* { dg-do compile } */ +/* { dg-options "-O3 -fdump-tree-linterchange-details" } */ + +void dummy (double *, double *); +#define LEN_2D 32 +double aa[LEN_2D][LEN_2D], bb[LEN_2D][LEN_2D]; +double s231(int iterations) +{ +// loop interchange +// loop with data dependency + for (int nl = 0; nl < 100*(iterations/LEN_2D); nl++) { + for (int i = 0; i < LEN_2D; ++i) { + for (int j = 1; j < LEN_2D; j++) { + aa[j][i] = aa[j - 1][i] + bb[j][i]; + } + } + dummy(aa[0],bb[0]); + } +} + +/* { dg-final { scan-tree-dump "loops interchanged" "linterchange" } } */ -- 2.47.2