On 01/31/2017 03:46 PM, Jakub Jelinek wrote:
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;
Which makes your patch safe -- but introduces a non-obvious dependency
between useless_type_conversion_p and your definition of
INTEGRAL_BOOLEAN_TYPE and how it's used in the vectorizer.
I think if you checked for a TYPE_PRECISION of 1 in
INTEGRAL_BOOLEAN_TYPE, that would help -- but leaves
INTEGRAL_BOOLEAN_TYPE poorly named.
Am I missing something here?
jeff