re PR tree-optimization/69783 (Loop is not vectorized after r233212)
authorRichard Biener <rguenther@suse.de>
Mon, 15 Feb 2016 09:40:01 +0000 (09:40 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 15 Feb 2016 09:40:01 +0000 (09:40 +0000)
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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/pr69783.c [new file with mode: 0644]
gcc/tree-vect-data-refs.c

index 59be0fdd68578b138b583e59a07ce98b82327904..6ef134f12e834a47b7e13dad5e142d525294b610 100644 (file)
@@ -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
index 4d129d810f69a4c487f65b7bf9b6717719af28d9..2a0e538c4105e22daaeeb3c10d4ffac0cd302877 100644 (file)
@@ -1,3 +1,8 @@
+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
diff --git a/gcc/testsuite/gcc.dg/vect/pr69783.c b/gcc/testsuite/gcc.dg/vect/pr69783.c
new file mode 100644 (file)
index 0000000..5df95d0
--- /dev/null
@@ -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" } } */
index 765f6f7a02a5e2a09781e788793481e61bb510b2..f8695b13d6d2210864d95a3a39b40153dd8d0492 100644 (file)
@@ -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--);
            }
        }