The following patch does $subject by fixing the bogus removal of load-permutations. This means gaps are now handled by the permutation support (well, if the required permutation is supported).
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied. Richard. 2015-06-09 Richard Biener <rguent...@suse.de> * tree-vect-slp.c (vect_build_slp_tree_1): Remove bailout on gaps. (vect_analyze_slp_instance): Instead do not falsely drop load permutations. Index: gcc/tree-vect-slp.c =================================================================== *** gcc/tree-vect-slp.c (revision 224271) --- gcc/tree-vect-slp.c (working copy) *************** vect_build_slp_tree_1 (loop_vec_info loo *** 762,794 **** else { /* Load. */ - unsigned unrolling_factor - = least_common_multiple - (*max_nunits, group_size) / group_size; - /* FORNOW: Check that there is no gap between the loads - and no gap between the groups when we need to load - multiple groups at once. */ - if (unrolling_factor > 1 - && ((GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) == stmt - && GROUP_GAP (vinfo_for_stmt (stmt)) != 0) - /* If the group is split up then GROUP_GAP - isn't correct here, nor is GROUP_FIRST_ELEMENT. */ - || GROUP_SIZE (vinfo_for_stmt (stmt)) > group_size)) - { - if (dump_enabled_p ()) - { - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "Build SLP failed: grouped " - "loads have gaps "); - dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, - stmt, 0); - dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); - } - /* Fatal mismatch. */ - matches[0] = false; - return false; - } - /* Check that the size of interleaved loads group is not greater than the SLP group size. */ unsigned ncopies --- 762,767 ---- *************** vect_analyze_slp_instance (loop_vec_info *** 1846,1852 **** this_load_permuted = true; load_permutation.safe_push (load_place); } ! if (!this_load_permuted) { load_permutation.release (); continue; --- 1834,1846 ---- this_load_permuted = true; load_permutation.safe_push (load_place); } ! if (!this_load_permuted ! /* The load requires permutation when unrolling exposes ! a gap either because the group is larger than the SLP ! group-size or because there is a gap between the groups. */ ! && (unrolling_factor == 1 ! || (group_size == GROUP_SIZE (vinfo_for_stmt (first_stmt)) ! && GROUP_GAP (vinfo_for_stmt (first_stmt)) == 0))) { load_permutation.release (); continue;