From d586ffcdee2085422d17f85222713671cf2b12d8 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 4 Sep 2019 11:56:15 +0000 Subject: [PATCH] backport: re PR tree-optimization/81740 (wrong code at -O3 in both 32-bit and 64-bit modes on x86_64-linux-gnu) 2019-09-04 Richard Biener Backport from mainline 2019-03-26 Bin Cheng PR tree-optimization/81740 * tree-vect-data-refs.c (vect_analyze_data_ref_dependence): In case of outer loop vectorization, check for backward dependence at the inner loop if outer loop dependence is reversed. * gcc.dg/vect/pr81740-1.c: New testcase. * gcc.dg/vect/pr81740-2.c: Likewise. From-SVN: r275372 --- gcc/ChangeLog | 10 ++++++++++ gcc/testsuite/ChangeLog | 9 +++++++++ gcc/testsuite/gcc.dg/vect/pr81740-1.c | 22 ++++++++++++++++++++++ gcc/testsuite/gcc.dg/vect/pr81740-2.c | 24 ++++++++++++++++++++++++ gcc/tree-vect-data-refs.c | 13 ++++++++++++- 5 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/vect/pr81740-1.c create mode 100644 gcc/testsuite/gcc.dg/vect/pr81740-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f666940c6076..475f194b71fb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2019-09-04 Richard Biener + + Backport from mainline + 2019-03-26 Bin Cheng + + PR tree-optimization/81740 + * tree-vect-data-refs.c (vect_analyze_data_ref_dependence): + In case of outer loop vectorization, check for backward dependence + at the inner loop if outer loop dependence is reversed. + 2019-09-04 Richard Biener Backport from mainline diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1e848f2b3b57..79b74c0b3f4c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2019-09-04 Richard Biener + + Backport from mainline + 2019-03-26 Bin Cheng + + PR tree-optimization/81740 + * gcc.dg/vect/pr81740-1.c: New testcase. + * gcc.dg/vect/pr81740-2.c: Likewise. + 2019-09-04 Richard Biener Backport from mainline diff --git a/gcc/testsuite/gcc.dg/vect/pr81740-1.c b/gcc/testsuite/gcc.dg/vect/pr81740-1.c new file mode 100644 index 000000000000..d2226fcdbeeb --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr81740-1.c @@ -0,0 +1,22 @@ +/* { dg-do run } */ +/* { dg-require-effective-target vect_int } */ + +#include "tree-vect.h" + +int a[8][10] = { [2][5] = 4 }, c; + +int +main () +{ + short b; + int i, d; + check_vect (); + for (b = 4; b >= 0; b--) + for (c = 0; c <= 6; c++) + a[c + 1][b + 2] = a[c][b + 1]; + for (i = 0; i < 8; i++) + for (d = 0; d < 10; d++) + if (a[i][d] != (i == 3 && d == 6) * 4) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/vect/pr81740-2.c b/gcc/testsuite/gcc.dg/vect/pr81740-2.c new file mode 100644 index 000000000000..76637ad0f816 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr81740-2.c @@ -0,0 +1,24 @@ +/* { dg-do run } */ +/* { dg-require-effective-target vect_int } */ + +#include "tree-vect.h" + +int a[8][10] = { [2][5] = 4 }, c; + +int +main () +{ + short b; + int i, d; + check_vect (); + for (b = 4; b >= 0; b--) + for (c = 6; c >= 0; c--) + a[c + 1][b + 2] = a[c][b + 1]; + for (i = 0; i < 8; i++) + for (d = 0; d < 10; d++) + if (a[i][d] != (i == 3 && d == 6) * 4) + __builtin_abort (); + return 0; +} + +/* { dg-final { scan-tree-dump "OUTER LOOP VECTORIZED" "vect" } } */ diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 022b7e3592ca..7915eeabac5a 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -470,8 +470,19 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr, reversed (to make distance vector positive), and the actual distance is negative. */ if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + dump_printf_loc (MSG_NOTE, vect_location, "dependence distance negative.\n"); + /* When doing outer loop vectorization, we need to check if there is + a backward dependence at the inner loop level if the dependence + at the outer loop is reversed. See PR81740. */ + if (nested_in_vect_loop_p (loop, DR_STMT (dra)) + || nested_in_vect_loop_p (loop, DR_STMT (drb))) + { + unsigned inner_depth = index_in_loop_nest (loop->inner->num, + DDR_LOOP_NEST (ddr)); + if (dist_v[inner_depth] < 0) + return true; + } /* Record a negative dependence distance to later limit the amount of stmt copying / unrolling we can perform. Only need to handle read-after-write dependence. */ -- 2.47.2