diff options
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/pr69783.c | 39 | ||||
-rw-r--r-- | gcc/tree-vect-data-refs.c | 68 |
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--); } } |