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.