On 12/11/2025 14:27, Richard Biener wrote:
On Tue, 11 Nov 2025, Christopher Bazley wrote:
On 05/11/2025 12:08, Richard Biener wrote:
On Tue, 4 Nov 2025, Christopher Bazley wrote:
On 04/11/2025 13:57, Christopher Bazley wrote:
On 28/10/2025 13:29, Richard Biener wrote:
Isn't SLP_TREE_CAN_USE_PARTIAL_VECTORS_P redundant given
SLP_TREE_CAN_USE_MASK_P || SLP_TREE_CAN_USE_LEN_P should be exactly this?
SLP_TREE_CAN_USE_PARTIAL_VECTORS_P might be sth for an SLP instance
(or a subgraph with multiple entries (instances)) if we want to have
consistent len vs. mask use? (but I see no particular reason to force
consistency)
SLP_TREE_CAN_USE_PARTIAL_VECTORS_P is initialised to true and may
subsequently be set to false via vect_cannot_use_partial_vectors.
vect_analyze_stmt uses the value of SLP_TREE_CAN_USE_PARTIAL_VECTORS_P to
decided whether to return a failure result in cases where tail-predication
is required. If SLP_TREE_CAN_USE_MASK_P || SLP_TREE_CAN_USE_LEN_P were
used
for that purpose instead, it would follow that neither
SLP_TREE_CAN_USE_MASK_P nor SLP_TREE_CAN_USE_LEN_P could be set to true in
cases where vect_cannot_use_partial_vectors might subsequently be called
(which seems impossible because vect_load_lanes_supported can be called
with
different values of 'count', and we cannot predict those values) , or else
that vect_cannot_use_partial_vectors would have to set both
SLP_TREE_CAN_USE_MASK_P and SLP_TREE_CAN_USE_LEN_P to false.
Setting both flags to false in vect_cannot_use_partial_vectors would be
trivial, but SLP_TREE_CAN_USE_PARTIAL_VECTORS_P has another purpose: it
gives the return value of vect_can_use_partial_vectors_p. How did you
envisage the return value of vect_can_use_partial_vectors_p being decided
for BB SLP? If it always returns true then I think that the vectoriser
might
carry on trying to use partial vectors when it should have already given
up;
if it returns SLP_TREE_CAN_USE_MASK_P || SLP_TREE_CAN_USE_LEN_P then that
would prevent check_load_store_for_partial_vectors from being called for
the
first time.
Together, the three flags allow the following states to be represented:
1. Might be able to operate on partial vectors, but don't yet know whether
we would use len or mask.
2. Might be able to operate on partial vectors with len.
3. Might be able to operate on partial vectors with mask.
4. (Invalid) Might be able to operate on partial vectors with both len and
mask.
5. Cannot operate on partial vectors.
6. (Strictly redundant) Cannot operate on partial vectors although we
previously thought we might be able to use len.
7. (Strictly redundant) Cannot operate on partial vectors although we
previously thought we might be able to use mask.
8. (Invalid) Cannot operate on partial vectors although we previously
thought we might be able to use both len and mask.
It would be impossible to encode the four states that neither invalid nor
redundant in only two bits. In any case, my goal was to keep the new logic
for BB SLP as close as possible to the existing logic for loop
vectorisation.
Sorry, it would clearly be possible to encode four values in 2 bits (00,
01,
10, 11) by encoding the "Might be able to operate on partial vectors" state
as
both bits clear and "Cannot operate on partial vectors" state as "Might be
able to operate on partial vectors with both len and mask" (both bits set).
A
reversal of the current encoding would probably make more sense: set both
'len' and 'mask' bits at the start, clear the 'mask' bit when 'len' is
chosen,
clear the 'len' bit when 'mask' is chosen, and clear both bits when neither
is
valid. Maybe this encoding could also be applied to the loop vectoriser.
Do you want me to make that change?
So I think I'm somewhat confused to the extent that with BB
vectorization we do not really have a choice - if partial vectors
are necessary (because there's padding), then if we cannot use
partial vectors, the stmt analysis should fail. I had the impression
That's what this code in does vect_analyze_stmt:
if (bb_vinfo)
{
unsigned int group_size = SLP_TREE_LANES (node);
tree vectype = SLP_TREE_VECTYPE (node);
poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype);
bool needs_partial = known_lt (group_size, nunits);
if (needs_partial && !SLP_TREE_CAN_USE_PARTIAL_VECTORS_P (node))
return opt_result::failure_at (stmt_info->stmt,
"not vectorized: SLP node needs but "
"cannot use partial vectors: %G",
stmt_info->stmt);
if (maybe_gt (group_size, nunits))
gcc_assert (multiple_p (group_size, nunits));
}
Conservative enough I guess, some operations might not need masking,
so it can be improved.
The current mechanism works regardless of whether operations such as
'add' need a mask or not.
The SLP_TREE_CAN_USE_PARTIAL_VECTORS_P flag just records whether the
target could support the operation if the vector were partial; it does
not say anything about whether the vector is partial, or how the target
would support the operation on a partial vector. Some kinds of node
require mask/length for partial vectors; others don't.
SLP_TREE_CAN_USE_PARTIAL_VECTORS_P returns true for nodes in the second
category.
--
Christopher Bazley
Staff Software Engineer, GNU Tools Team.
Arm Ltd, 110 Fulbourn Road, Cambridge, CB1 9NJ, UK.
http://www.arm.com/