https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118529

--- Comment #7 from Tamar Christina <tnfchris at gcc dot gnu.org> ---
(In reply to rguent...@suse.de from comment #6)
> On Fri, 17 Jan 2025, tnfchris at gcc dot gnu.org wrote:
> 
> > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118529
> > 
> > --- Comment #5 from Tamar Christina <tnfchris at gcc dot gnu.org> ---
> > (In reply to Richard Biener from comment #4)
> > > Confirmed.
> > > OTOH the initial choice of mask mode for the compare by the vectorizer
> > > is a bit odd.  We get there from vect_recog_bool_pattern handling
> > > 
> > >   _28 = _24 ? 0 : _20;
> > > 
> > > which builds
> > > 
> > >   patt_15 = _24 != 0;
> > > 
> > > but assigns that a vector truth type based on '_24' rather than on '_28'
> > > which is where it's going to be used.  Using get_mask_type_for_scalar_type
> > > is also more likely off.
> > > 
> > 
> > _28 would be wrong no? As the results of patt_15 should be used inside the
> > conditional.
> 
> Yes, I only showed the original COND.
> 
> > The bool recog pattern should be trying to convert _24 into a boolean of the
> > same precision as it wasn't one, and it's vectorization of _28 that should
> > handle the mismatch.
> > 
> > It has to since if the precision of _24 and _28 don't match and you make the
> > boolean mask based on _28 the compare would have to convert to boolean &
> > widen/truncate which we don't support and throws off VF detection.
> > 
> > That's why the pattern does this today and leaves the precision conversion 
> > to
> > later so that analysis sees it needs to happen.
> 
> The pattern oddly chooses the mask vector type for patt_15 based on the
> type of _24 - but we are trying to build a mask for the COND so the
> mask vector type should be built based on _28.
> 
> With
> 
> diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc
> index 5aebf950548..eed2b1f8c6c 100644
> --- a/gcc/tree-vect-patterns.cc
> +++ b/gcc/tree-vect-patterns.cc
> @@ -5597,11 +5597,7 @@ vect_recog_bool_pattern (vec_info *vinfo,
>        pattern_stmt = gimple_build_assign (lhs_var, NE_EXPR, var,
>                                           build_zero_cst (TREE_TYPE 
> (var)));
>  
> -      tree new_vectype = get_mask_type_for_scalar_type (vinfo, TREE_TYPE 
> (var));
> -      if (!new_vectype)
> -       return NULL;
> -
> -      new_vectype = truth_type_for (new_vectype);
> +      tree new_vectype = truth_type_for (vectype);
>        append_pattern_def_seq (vinfo, stmt_vinfo, pattern_stmt, 
> new_vectype,
>                               TREE_TYPE (var));
>  
> we're a bit closer to that but then vect_get_vector_types_for_stmt again
> looks at the compare in isolation and wrecks things, using
> ->mask_precision which we fail to appropriately set here.
> 
> This is all quite a mess, and pattern recog should not commit to
> any vector types anyway.

Agreed... but the reason it does it this way today is that if say

_24 == QI and _28 == SI we can't do

_28 = patt_25 ? a : b

where patt_25 is SI.  As then the operation patt_25 = has to result in multiple
vectors which the cond needs to use.
i.e. precision aside, because patterns need a vectype it must reflect the type
of the comparison which isn't expected to change container precision.

At least when I last tried this it ended up with two problems:

1. The wrong VF or unrolling can be chosen because this is currently mostly
based on types. and it already thinks the type of _28 and patt_25 match.  The
result is a type mismatch and we just don't vectorize.

2. The vectorizer couldn't actually produce code for this construct.. i.e.
vectorizable_comparison didn't like it.

prior to the lowering of the conditional this was all handled completely in
vectorizable_comparison which would produce the compare during the act of
codegen rather than explicitly.

But as you said, the problem is we have to commit to a type quite early today.

Reply via email to