On Tue, Jan 31, 2017 at 03:41:27PM -0700, Jeff Law wrote: > > useless_type_conversion_p says that precision 1 unsigned BOOLEAN_TYPE > > conversion to/from precision 1 unsigned integral type is useless, > > but apparently the vectorizer heavily relies on the BOOLEAN_TYPE vs. > > unsigned integral:1 distinction (uses VECTOR_BOOLEAN_TYPE_P types > > only for real BOOLEAN_TYPE). As the conversion is useless, we can end up > > as in the following testcase with e.g. binary operations which have boolean > > on one side and unsigned int:1 on another. > > > > The following patch replaces all explicit BOOLEAN_TYPE checks in the > > vectorizer with a new macro that handles unsigned integral:1 the same > > as BOOLEAN_TYPE. > > > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > > > 2017-01-31 Jakub Jelinek <ja...@redhat.com> > > > > PR tree-optimization/79284 > > * tree.h (INTEGRAL_BOOLEAN_TYPE_P): Define. > > * tree-vect-stmts.c (vect_get_vec_def_for_operand, > > vectorizable_mask_load_store, vectorizable_operation, > > vect_is_simple_cond, get_same_sized_vectype): Use it instead > > of comparing TREE_CODE of a type against BOOLEAN_TYPE. > > * tree-vect-patterns.c (check_bool_pattern, search_type_for_mask_1, > > vect_recog_bool_pattern, vect_recog_mask_conversion_pattern): Likewise. > > * tree-vect-slp.c (vect_get_constant_vectors): Likewise. > > * tree-vect-loop.c (vect_determine_vectorization_factor): Likewise. > Didn't we determine that the Ada front end generated boolean types with a > precision greater than 1? And if so, does that suggest that > INTEGRAL_BOOLEAN_TYPE_P might need further adjustment (and that we likely > have latent bugs in the vectorizer if it was presented with such types?)
Some BOOLEAN_TYPE types (I think in Fortran too, though it might have already changed) have bigger precision than one, but still have only 2 valid values, 0 and 1 and I'm not aware of the vectorizer generating something wrong for those. For the non-BOOLEAN_TYPEs, only unsigned:1 is special: if (INTEGRAL_TYPE_P (inner_type) && INTEGRAL_TYPE_P (outer_type)) { /* Preserve changes in signedness or precision. */ if (TYPE_UNSIGNED (inner_type) != TYPE_UNSIGNED (outer_type) || TYPE_PRECISION (inner_type) != TYPE_PRECISION (outer_type)) return false; /* Preserve conversions to/from BOOLEAN_TYPE if types are not of precision one. */ if (((TREE_CODE (inner_type) == BOOLEAN_TYPE) != (TREE_CODE (outer_type) == BOOLEAN_TYPE)) && TYPE_PRECISION (outer_type) != 1) return false; /* We don't need to preserve changes in the types minimum or maximum value in general as these do not generate code unless the types precisions are different. */ return true; } Jakub