aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2016-02-15 09:40:01 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2016-02-15 09:40:01 +0000
commit17a3b967929eb6d344ae73bff4f28efc88c35ca9 (patch)
tree206b3a1f97e9938efc887592c89238d17e81a242
parented5d948da920f8de6041b7010625cfeff7014203 (diff)
downloadgcc-17a3b967929eb6d344ae73bff4f28efc88c35ca9.zip
gcc-17a3b967929eb6d344ae73bff4f28efc88c35ca9.tar.gz
gcc-17a3b967929eb6d344ae73bff4f28efc88c35ca9.tar.bz2
re PR tree-optimization/69783 (Loop is not vectorized after r233212)
2016-02-15 Richard Biener <rguenther@suse.de> PR tree-optimization/69783 * tree-vect-data-refs.c (vect_prune_runtime_alias_test_list): Add trivially correct cases. * gcc.dg/vect/pr69783.c: New testcase. From-SVN: r233420
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr69783.c39
-rw-r--r--gcc/tree-vect-data-refs.c68
4 files changed, 96 insertions, 22 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 59be0fd..6ef134f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2016-02-15 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/69783
+ * tree-vect-data-refs.c (vect_prune_runtime_alias_test_list):
+ Add trivially correct cases.
+
2016-02-15 Tom de Vries <tom@codesourcery.com>
PR lto/69655
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 4d129d8..2a0e538 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
2016-02-15 Richard Biener <rguenther@suse.de>
+ PR tree-optimization/69783
+ * gcc.dg/vect/pr69783.c: New testcase.
+
+2016-02-15 Richard Biener <rguenther@suse.de>
+
PR tree-optimization/69776
* gcc.dg/torture/pr69776.c: New testcase.
diff --git a/gcc/testsuite/gcc.dg/vect/pr69783.c b/gcc/testsuite/gcc.dg/vect/pr69783.c
new file mode 100644
index 0000000..5df95d0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr69783.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_float } */
+/* { dg-additional-options "-Ofast -funroll-loops" } */
+
+#define NXX 516
+#define NYY 516
+#define IND(x,y) ((x) + (y)*NXX)
+float **In, **Out, **V;
+
+void foo(int I, int J, int K1, int K2, int L1, int L2 )
+{
+ for(int i=0; i < I; i++)
+ {
+ float *v = V[i];
+
+ for(int j=0; j < J; j++)
+ {
+ float *in = In[j];
+ float *out = Out[j];
+ for(int l=L1; l<L2; l++)
+ {
+ for(int k=K1; k<K2; k++)
+ {
+ float sum = 0;
+ int offset = 0;
+ for(int m=-2; m<=2; m++)
+ {
+ for(int n=-2; n<=2; n++, offset++)
+ sum += in[IND((k+n), (l+m))] * v[offset];
+ }
+ out[IND(k,l)] = sum;
+ }
+ }
+
+ }
+ }
+}
+
+/* { dg-final { scan-tree-dump "improved number of alias checks from \[0-9\]* to 2" "vect" } } */
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index 765f6f7..f8695b1 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -3089,6 +3089,30 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo)
= tree_to_shwi (dr_a2->offset) - tree_to_shwi (dr_a1->offset);
+ bool do_remove = false;
+
+ /* If the left segment does not extend beyond the start of the
+ right segment the new segment length is that of the right
+ plus the segment distance. */
+ if (tree_fits_uhwi_p (dr_a1->seg_len)
+ && compare_tree_int (dr_a1->seg_len, diff) <= 0)
+ {
+ dr_a1->seg_len = size_binop (PLUS_EXPR, dr_a2->seg_len,
+ size_int (diff));
+ do_remove = true;
+ }
+ /* Generally the new segment length is the maximum of the
+ left segment size and the right segment size plus the distance.
+ ??? We can also build tree MAX_EXPR here but it's not clear this
+ is profitable. */
+ else if (tree_fits_uhwi_p (dr_a1->seg_len)
+ && tree_fits_uhwi_p (dr_a2->seg_len))
+ {
+ unsigned HOST_WIDE_INT seg_len_a1 = tree_to_uhwi (dr_a1->seg_len);
+ unsigned HOST_WIDE_INT seg_len_a2 = tree_to_uhwi (dr_a2->seg_len);
+ dr_a1->seg_len = size_int (MAX (seg_len_a1, diff + seg_len_a2));
+ do_remove = true;
+ }
/* Now we check if the following condition is satisfied:
DIFF - SEGMENT_LENGTH_A < SEGMENT_LENGTH_B
@@ -3101,39 +3125,39 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo)
one above:
1: DIFF <= MIN_SEG_LEN_B
- 2: DIFF - SEGMENT_LENGTH_A < MIN_SEG_LEN_B
-
- */
-
- unsigned HOST_WIDE_INT min_seg_len_b
- = (tree_fits_uhwi_p (dr_b1->seg_len)
- ? tree_to_uhwi (dr_b1->seg_len)
- : vect_factor);
+ 2: DIFF - SEGMENT_LENGTH_A < MIN_SEG_LEN_B */
+ else
+ {
+ unsigned HOST_WIDE_INT min_seg_len_b
+ = (tree_fits_uhwi_p (dr_b1->seg_len)
+ ? tree_to_uhwi (dr_b1->seg_len)
+ : vect_factor);
+
+ if (diff <= min_seg_len_b
+ || (tree_fits_uhwi_p (dr_a1->seg_len)
+ && diff - tree_to_uhwi (dr_a1->seg_len) < min_seg_len_b))
+ {
+ dr_a1->seg_len = size_binop (PLUS_EXPR,
+ dr_a2->seg_len, size_int (diff));
+ do_remove = true;
+ }
+ }
- if (diff <= min_seg_len_b
- || (tree_fits_uhwi_p (dr_a1->seg_len)
- && diff - tree_to_uhwi (dr_a1->seg_len) < min_seg_len_b))
+ if (do_remove)
{
if (dump_enabled_p ())
{
dump_printf_loc (MSG_NOTE, vect_location,
"merging ranges for ");
- dump_generic_expr (MSG_NOTE, TDF_SLIM,
- DR_REF (dr_a1->dr));
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dr_a1->dr));
dump_printf (MSG_NOTE, ", ");
- dump_generic_expr (MSG_NOTE, TDF_SLIM,
- DR_REF (dr_b1->dr));
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dr_b1->dr));
dump_printf (MSG_NOTE, " and ");
- dump_generic_expr (MSG_NOTE, TDF_SLIM,
- DR_REF (dr_a2->dr));
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dr_a2->dr));
dump_printf (MSG_NOTE, ", ");
- dump_generic_expr (MSG_NOTE, TDF_SLIM,
- DR_REF (dr_b2->dr));
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dr_b2->dr));
dump_printf (MSG_NOTE, "\n");
}
-
- dr_a1->seg_len = size_binop (PLUS_EXPR,
- dr_a2->seg_len, size_int (diff));
comp_alias_ddrs.ordered_remove (i--);
}
}