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)