+2019-09-04 Richard Biener <rguenther@suse.de>
+
+ Backport from mainline
+ 2019-03-26 Bin Cheng <bin.cheng@linux.alibaba.com>
+
+ 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 <rguenther@suse.de>
Backport from mainline
+2019-09-04 Richard Biener <rguenther@suse.de>
+
+ Backport from mainline
+ 2019-03-26 Bin Cheng <bin.cheng@linux.alibaba.com>
+
+ PR tree-optimization/81740
+ * gcc.dg/vect/pr81740-1.c: New testcase.
+ * gcc.dg/vect/pr81740-2.c: Likewise.
+
2019-09-04 Richard Biener <rguenther@suse.de>
Backport from mainline
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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" } } */
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. */