The following fixes a latent bug in vect_prune_runtime_alias_test_list,
not considering negative offset1 - offset2.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk
sofar.

Richard.

2016-02-08  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/69719
        * tree-vect-data-refs.c (vect_prune_runtime_alias_test_list):
        Properly use absolute of the difference of the two offsets to
        compare or adjust the segment length.

        * gcc.dg/torture/pr69719.c: New testcase.

Index: gcc/tree-vect-data-refs.c
===================================================================
*** gcc/tree-vect-data-refs.c   (revision 233211)
--- gcc/tree-vect-data-refs.c   (working copy)
*************** vect_prune_runtime_alias_test_list (loop
*** 2905,2912 ****
              || !tree_fits_shwi_p (dr_a2->offset))
            continue;
  
!         HOST_WIDE_INT diff = (tree_to_shwi (dr_a2->offset)
!                               - tree_to_shwi (dr_a1->offset));
  
  
          /* Now we check if the following condition is satisfied:
--- 2905,2913 ----
              || !tree_fits_shwi_p (dr_a2->offset))
            continue;
  
!         unsigned HOST_WIDE_INT diff
!           = absu_hwi (tree_to_shwi (dr_a2->offset)
!                       - tree_to_shwi (dr_a1->offset));
  
  
          /* Now we check if the following condition is satisfied:
*************** vect_prune_runtime_alias_test_list (loop
*** 2925,2937 ****
  
             */
  
!         HOST_WIDE_INT  min_seg_len_b = (tree_fits_shwi_p (dr_b1->seg_len)
!                                         ? tree_to_shwi (dr_b1->seg_len)
!                                         : vect_factor);
  
          if (diff <= min_seg_len_b
!             || (tree_fits_shwi_p (dr_a1->seg_len)
!                 && diff - tree_to_shwi (dr_a1->seg_len) < min_seg_len_b))
            {
              if (dump_enabled_p ())
                {
--- 2926,2939 ----
  
             */
  
!         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))
            {
              if (dump_enabled_p ())
                {
Index: gcc/testsuite/gcc.dg/torture/pr69719.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr69719.c      (revision 0)
--- gcc/testsuite/gcc.dg/torture/pr69719.c      (working copy)
***************
*** 0 ****
--- 1,24 ----
+ /* { dg-do run } */
+ 
+ int b, c = 1, e, f; 
+ int a[6][5] = { {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 1, 0, 0, 0} };
+ 
+ void  __attribute__((noinline))
+ fn1 ()
+ {
+   int d;
+   for (b = 0; b < 5; b++)
+     for (d = 4; d; d--)
+       a[c + 1][b] = a[d + 1][d];
+ }
+ 
+ int
+ main ()
+ {
+   fn1 ();
+ 
+   if (a[2][1] != 0) 
+     __builtin_abort (); 
+ 
+   return 0; 
+ }

Reply via email to