This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix bool vs. unsigned:1 vectorization (PR tree-optimization/79284)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Biener <rguenther at suse dot de>
- Cc: Jeff Law <law at redhat dot com>, gcc-patches at gcc dot gnu dot org
- Date: Wed, 1 Feb 2017 11:25:56 +0100
- Subject: Re: [PATCH] Fix bool vs. unsigned:1 vectorization (PR tree-optimization/79284)
- Authentication-results: sourceware.org; auth=none
- References: <20170131224617.GO14051@tucnak> <dee6069f-e5e0-e5a5-e2cb-0b2c21c255c2@redhat.com> <20170131232249.GP14051@tucnak> <521f001d-1951-827b-98df-2cd0f06eed9d@redhat.com> <20170201080157.GQ14051@tucnak> <alpine.LSU.2.20.1702010910230.12993@r111.fhfr.qr> <20170201095048.GT14051@tucnak> <alpine.LSU.2.20.1702011056360.12993@r111.fhfr.qr> <20170201100337.GU14051@tucnak> <alpine.LSU.2.20.1702011105110.12993@r111.fhfr.qr>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Wed, Feb 01, 2017 at 11:07:18AM +0100, Richard Biener wrote:
> > On Wed, Feb 01, 2017 at 10:58:29AM +0100, Richard Biener wrote:
> > > > > +/* Nonzero if TYPE represents a (scalar) boolean type or type
> > > > > + in the middle-end compatible with it. */
> > > > > +
> > > > > +#define INTEGRAL_BOOLEAN_TYPE_P(TYPE) \
> > > > > + (TREE_CODE (TYPE) == BOOLEAN_TYPE \
> > > > > + || ((TREE_CODE (TYPE) == INTEGER_TYPE \
> > > > > + || TREE_CODE (TYPE) == ENUMERAL_TYPE) \
> > > > > + && TYPE_PRECISION (TYPE) == 1 \
> > > > > + && TYPE_UNSIGNED (TYPE)))
> > > > >
> > > > > (just to quote what you proposed).
> > > >
> > > > So would it help to use
> > > > (TREE_CODE (TYPE) == BOOLEAN_TYPE
> > > > || (INTEGRAL_TYPE_P (TYPE)
> > > > && useless_type_conversion_p (boolean_type_node, TYPE)))
> > > > It would be much slower than the above, but would be less dependent
> > > > on useless_type_conversion_p details.
> > >
> > > For the vectorizer it likely would break the larger logical type
> > > handling?
> >
> > Why? It is the same thing as the earlier macro above.
> > Any kind of boolean, plus anything that could be initially boolean
> > and the middle-end might have replaced it with.
>
> boolean_type_node is QImode but logical(8) is DImode for example.
> Both have precision == 1 but they are not types_compatible_p
> (you probably missed the mode check in useless_type_conversion_p).
Then the earlier macro should have used also a TYPE_MODE check.
The latter macro is what I've been looking for in the patch, except that
I thought it is too expensive (plus might actually not DTRT if
boolean_type_node has > 1 precision, but some unsigned precision 1
BOOLEAN_TYPE exists too; as Fortran has changed, now it is only Ada that
doesn't have precision 1 boolean_type_node, but then it likely doesn't
have any precision 1 BOOLEAN_TYPEs).
> > > The question is really what the vectorizer and other places are looking
> > > for -- which isually is a 1-bit precision, eventually unsigned,
> > > integral type.
> >
> > It is looking for any type where the only valid values are 0 (false) and 1
> > (true), so that it can actually vectorize it as a bitmask, or vector of
> > integers with -1 and 0 values.
>
> That's INTEGRAL_TYPE_P && TYPE_PRECISION == 1 && TYPE_UNSIGNED. The
> Ada types do not fall under this category as far as I understand as
> the exceptional values may exist in memory(?)
But the exceptional values are undefined behavior I believe.
Anyway, we've been vectorizing not just the 1-bit precision BOOLEAN_TYPEs
but other BOOLEAN_TYPEs (Ada and especially Fortran) for a couple of years
this way already and I'm not aware of issues with that.
So suddenly stopping doing that because we want to fix a bug related
to the fact that for 1-bit precision unsigned QImode BOOLEAN_TYPE the
middle-end considers other types to be compatible with those is strange
and very risky, especially at this point in GCC 7 development.
Jakub