[gcc r16-4076] tree-optimization/116816 - improve VMAT_ELEMENTWISE with SLP
Richard Biener
rguenth@gcc.gnu.org
Wed Sep 24 11:33:21 GMT 2025
https://gcc.gnu.org/g:1f6b1ed047105103c2fba9696fd0ed17ec5e1405
commit r16-4076-g1f6b1ed047105103c2fba9696fd0ed17ec5e1405
Author: Richard Biener <rguenther@suse.de>
Date: Wed Sep 24 12:19:17 2025 +0200
tree-optimization/116816 - improve VMAT_ELEMENTWISE with SLP
The following implements VMAT_ELEMENTWISE for grouped loads, in
particular for being able to serve as fallback for unhandled
load permutations since it's trivial to load elements in the
correct order.
PR tree-optimization/116816
* tree-vect-stmts.cc (get_load_store_type): Allow multi-lane
single-element interleaving to fall back to VMAT_ELEMENTWISE.
Fall back to VMAT_ELEMENTWISE when we cannot handle a load
permutation.
(vectorizable_load): Do not check a load permutation
for VMAT_ELEMENTWISE. Handle grouped loads with
VMAT_ELEMENTWISE and directly apply a load permutation.
Diff:
---
gcc/tree-vect-stmts.cc | 81 +++++++++++++++++++++-----------------------------
1 file changed, 34 insertions(+), 47 deletions(-)
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index 995151f9a271..cfc4f323a220 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -2134,41 +2134,26 @@ get_load_store_type (vec_info *vinfo, stmt_vec_info stmt_info,
|| *memory_access_type == VMAT_CONTIGUOUS_REVERSE)
&& maybe_gt (group_size, TYPE_VECTOR_SUBPARTS (vectype)))
{
- if (SLP_TREE_LANES (slp_node) == 1)
- {
- *memory_access_type = VMAT_ELEMENTWISE;
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "single-element interleaving not supported "
- "for not adjacent vector loads, using "
- "elementwise access\n");
- }
- else
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "single-element interleaving not supported "
- "for not adjacent vector loads\n");
- return false;
- }
+ *memory_access_type = VMAT_ELEMENTWISE;
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "single-element interleaving not supported "
+ "for not adjacent vector loads, using "
+ "elementwise access\n");
}
- /* For single-element interleaving also fall back to elementwise
- access in case we did not lower a permutation and cannot
- code generate it. */
+ /* Also fall back to elementwise access in case we did not lower a
+ permutation and cannot code generate it. */
if (loop_vinfo
- && single_element_p
- && SLP_TREE_LANES (slp_node) == 1
- && (*memory_access_type == VMAT_CONTIGUOUS
- || *memory_access_type == VMAT_CONTIGUOUS_REVERSE)
+ && *memory_access_type != VMAT_ELEMENTWISE
&& SLP_TREE_LOAD_PERMUTATION (slp_node).exists ()
&& !perm_ok)
{
*memory_access_type = VMAT_ELEMENTWISE;
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "single-element interleaving permutation not "
- "supported, using elementwise access\n");
+ "permutation not supported, using elementwise "
+ "access\n");
}
overrun_p = (loop_vinfo && gap != 0
@@ -2498,9 +2483,9 @@ get_load_store_type (vec_info *vinfo, stmt_vec_info stmt_info,
traditional behavior until that can be fixed. */
if (*memory_access_type == VMAT_ELEMENTWISE
&& !STMT_VINFO_STRIDED_P (first_stmt_info)
- && !(stmt_info == DR_GROUP_FIRST_ELEMENT (stmt_info)
- && !DR_GROUP_NEXT_ELEMENT (stmt_info)
- && !pow2p_hwi (DR_GROUP_SIZE (stmt_info))))
+ && !(STMT_VINFO_GROUPED_ACCESS (stmt_info)
+ && single_element_p
+ && !pow2p_hwi (group_size)))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -9485,11 +9470,11 @@ vectorizable_load (vec_info *vinfo,
/* ??? The following checks should really be part of
get_load_store_type. */
if (SLP_TREE_LOAD_PERMUTATION (slp_node).exists ()
- && !((memory_access_type == VMAT_ELEMENTWISE
- || mat_gather_scatter_p (memory_access_type))
- && SLP_TREE_LANES (slp_node) == 1
- && (!grouped_load
- || !DR_GROUP_NEXT_ELEMENT (first_stmt_info))))
+ && !(memory_access_type == VMAT_ELEMENTWISE
+ || (mat_gather_scatter_p (memory_access_type)
+ && SLP_TREE_LANES (slp_node) == 1
+ && (!grouped_load
+ || !DR_GROUP_NEXT_ELEMENT (first_stmt_info)))))
{
slp_perm = true;
@@ -9732,28 +9717,24 @@ vectorizable_load (vec_info *vinfo,
{
first_stmt_info = DR_GROUP_FIRST_ELEMENT (stmt_info);
first_dr_info = STMT_VINFO_DR_INFO (first_stmt_info);
+ ref_type = get_group_alias_ptr_type (first_stmt_info);
}
else
{
first_stmt_info = stmt_info;
first_dr_info = dr_info;
+ ref_type = reference_alias_ptr_type (DR_REF (dr_info->dr));
}
- if (grouped_load && memory_access_type == VMAT_STRIDED_SLP)
+ if (grouped_load)
{
- group_size = DR_GROUP_SIZE (first_stmt_info);
- ref_type = get_group_alias_ptr_type (first_stmt_info);
+ if (memory_access_type == VMAT_STRIDED_SLP)
+ group_size = DR_GROUP_SIZE (first_stmt_info);
+ else /* VMAT_ELEMENTWISE */
+ group_size = SLP_TREE_LANES (slp_node);
}
else
- {
- if (grouped_load)
- cst_offset
- = (tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (vectype)))
- * vect_get_place_in_interleaving_chain (stmt_info,
- first_stmt_info));
- group_size = 1;
- ref_type = reference_alias_ptr_type (DR_REF (dr_info->dr));
- }
+ group_size = 1;
if (!costing_p)
{
@@ -9892,6 +9873,7 @@ vectorizable_load (vec_info *vinfo,
int ncopies;
if (slp_perm)
{
+ gcc_assert (memory_access_type != VMAT_ELEMENTWISE);
/* We don't yet generate SLP_TREE_LOAD_PERMUTATIONs for
variable VF. */
unsigned int const_vf = vf.to_constant ();
@@ -9927,8 +9909,13 @@ vectorizable_load (vec_info *vinfo,
slp_node, 0, vect_body);
continue;
}
+ unsigned int load_el = group_el;
+ /* For elementwise accesses apply a load permutation directly. */
+ if (memory_access_type == VMAT_ELEMENTWISE
+ && SLP_TREE_LOAD_PERMUTATION (slp_node).exists ())
+ load_el = SLP_TREE_LOAD_PERMUTATION (slp_node)[group_el];
tree this_off = build_int_cst (TREE_TYPE (alias_off),
- group_el * elsz + cst_offset);
+ load_el * elsz + cst_offset);
tree data_ref = build2 (MEM_REF, ltype, running_off, this_off);
vect_copy_ref_info (data_ref, DR_REF (first_dr_info->dr));
new_temp = make_ssa_name (ltype);
More information about the Gcc-cvs
mailing list