These are bugfixes that prepare handling of SLP loads with gaps
and more SLP permutation kinds.

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

Richard.

2015-04-29  Richard Biener  <rguent...@suse.de>

        * tree-vect-data-refs.c (vect_analyze_group_access): Properly
        compute GROUP_SIZE for basic-block SLP.
        * tree-vect-slp.c (vect_get_place_in_interleaving_chain): Properly
        take into account gaps.
        (vect_get_mask_element): Properly reject references to previous
        vectors.
        (vect_transform_slp_perm_load): Likewise.

Index: gcc/tree-vect-data-refs.c
===================================================================
*** gcc/tree-vect-data-refs.c   (revision 222514)
--- gcc/tree-vect-data-refs.c   (working copy)
*************** vect_analyze_group_access (struct data_r
*** 2245,2251 ****
          }
  
        if (groupsize == 0)
!         groupsize = count;
  
        GROUP_SIZE (vinfo_for_stmt (stmt)) = groupsize;
        if (dump_enabled_p ())
--- 2271,2277 ----
          }
  
        if (groupsize == 0)
!         groupsize = count + gaps;
  
        GROUP_SIZE (vinfo_for_stmt (stmt)) = groupsize;
        if (dump_enabled_p ())
Index: gcc/tree-vect-slp.c
===================================================================
*** gcc/tree-vect-slp.c (revision 222514)
--- gcc/tree-vect-slp.c (working copy)
*************** vect_get_place_in_interleaving_chain (gi
*** 223,230 ****
      {
        if (next_stmt == stmt)
        return result;
-       result++;
        next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt));
      }
    while (next_stmt);
  
--- 223,231 ----
      {
        if (next_stmt == stmt)
        return result;
        next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt));
+       if (next_stmt)
+       result += GROUP_GAP (vinfo_for_stmt (next_stmt));
      }
    while (next_stmt);
  
*************** vect_get_mask_element (gimple stmt, int
*** 3008,3013 ****
--- 3033,3050 ----
    /* Adjust the value in case it's a mask for second and third vectors.  */
    *current_mask_element -= mask_nunits * (*number_of_mask_fixes - 1);
  
+   if (*current_mask_element < 0)
+     {
+       if (dump_enabled_p ())
+       {
+         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                          "permutation requires past vector ");
+         dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
+         dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
+       }
+       return false;
+     }
+ 
    if (*current_mask_element < mask_nunits)
      *needs_first_vector = true;
  
*************** vect_transform_slp_perm_load (slp_tree n
*** 3178,3184 ****
                                          &number_of_mask_fixes, &mask_fixed,
                                          &needs_first_vector))
                return false;
!             gcc_assert (current_mask_element < 2 * nunits);
              mask[index++] = current_mask_element;
  
                if (index == nunits)
--- 3215,3222 ----
                                          &number_of_mask_fixes, &mask_fixed,
                                          &needs_first_vector))
                return false;
!             gcc_assert (current_mask_element >= 0
!                         && current_mask_element < 2 * nunits);
              mask[index++] = current_mask_element;
  
                if (index == nunits)

Reply via email to