On 19/08/2026 11:40, Pengfei Li wrote:
On 30/07/2026 15:56, Christopher Bazley wrote:
@@ -5079,6 +5097,53 @@ vect_analyze_slp_reductions (loop_vec_info
loop_vinfo,
return true;
}
+/* Update MIN_NUNITS to reflect the minimum number of subparts for
all of the
+ vector types used by the SLP subgraph rooted at NODE. VISITED is
used to
+ avoid reevaluating any node in the subgraph; it thereby prevents
infinite
+ recursion should a cycle be encountered. The value of MIN_NUNITS
will only be
+ updated if any node in the subgraph has a vector type with a
number of
+ subparts that is smaller than the passed-in value of MIN_NUNITS.
Before
+ calling this function for the first time, initialize MIN_NUNITS to
+ UINT64_MAX. */
+
+static void
+vect_update_slp_min_nunits_for_node (slp_tree node, poly_uint64
&min_nunits,
+ hash_set<slp_tree> &visited)
+{
+ if (!node || SLP_TREE_DEF_TYPE (node) != vect_internal_def)
+ return;
+
+ if (visited.add (node))
+ return;
+
+ for (slp_tree child : SLP_TREE_CHILDREN (node))
+ vect_update_slp_min_nunits_for_node (child, min_nunits, visited);
+
+ tree vectype = SLP_TREE_VECTYPE (node);
+ if (!vectype)
+ return;
+
+ /* All unit counts have the form vec_info::vector_size * X for some
+ rational X, therefore we know the values are ordered. */
+ poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype);
+ min_nunits = known_eq (min_nunits, UINT64_MAX)
+ ? nunits
+ : ordered_min (min_nunits, nunits);
+}
+
+/* For NODE, return the minimum number of subparts for all of the vector
+ types used in the given SLP subgraph. */
+
+static poly_uint64
+vect_slp_tree_min_nunits (slp_tree node)
+{
+ poly_uint64 min_nunits = UINT64_MAX;
+ hash_set<slp_tree> visited;
+ vect_update_slp_min_nunits_for_node (node, min_nunits, visited);
+ gcc_checking_assert (known_ne (min_nunits, UINT64_MAX));
+ return min_nunits;
+}
+
/* Analyze an SLP instance starting from a group of grouped stores.
Call
vect_build_slp_tree to build a tree of packed stmts if possible.
Return FALSE if it's impossible to SLP any stmt in the group. */
@@ -5148,8 +5213,8 @@ vect_analyze_slp_instance (vec_info *vinfo,
poly_uint64 unrolling_factor
= calculate_unrolling_factor (max_nunits, group_size);
- if (maybe_ne (unrolling_factor, 1U)
- && is_a <bb_vec_info> (vinfo))
+ if (maybe_ne (unrolling_factor, 1U) && is_a<bb_vec_info> (vinfo)
+ && !known_ge (vect_slp_tree_min_nunits (node), group_size))
Could the new condition use maybe_lt instead? Avoiding the negated
known_ge reads clearer.
OK. I see an existing invocation !known_ge (j, TYPE_VECTOR_SUBPARTS
(vectype)) in vect_build_slp_tree_2 but I don't mind changing it.
You may also want to update the dump message in this if block.
Given that no tests appear to require an exact match with the existing
message, I will replace it with the following:
"Build SLP failed: store group size might not be a multiple of the
largest vector size and might exceed the smallest vector size in basic
block SLP"
Thanks,
--
Christopher Bazley
Staff Software Engineer, GNU Tools Team.
Arm Ltd, 110 Fulbourn Road, Cambridge, CB1 9NJ, UK.
http://www.arm.com/