This is the mail archive of the
mailing list for the GCC project.
Re: [RFC] GCC vector extension: binary operators vs. differing signedness
- From: "Ulrich Weigand" <uweigand at de dot ibm dot com>
- To: richard dot guenther at gmail dot com (Richard Biener)
- Cc: gcc at gcc dot gnu dot org (GCC Development)
- Date: Tue, 16 Dec 2014 19:42:09 +0100 (CET)
- Subject: Re: [RFC] GCC vector extension: binary operators vs. differing signedness
- Authentication-results: sourceware.org; auth=none
Richard Biener wrote:
> On Fri, Dec 12, 2014 at 1:08 PM, Ulrich Weigand <firstname.lastname@example.org> wrote:
> > Richard Biener wrote:
> >> On Thu, Dec 11, 2014 at 4:04 PM, Ulrich Weigand <email@example.com> wrote:
> >> > However, if we make that change, there will be some cases that regress: the
> >> > problem is that an expression "x + y" has *one* result type, and some things
> >> > you do with the result will require that type to match precisely (including
> >> > signedness). So *any* change that affects what that result type is will
> >> > regress some code that happened to rely on the precise result type ...
> >> True, but IMHO that's still better. You may want to check the openCL spec
> >> which we tried to follow losely as to what we allow.
> >> So again, implementing your A is ok with me.
> > Well, the openCL spec says that operations between signed and unsigned
> > vectors are simply prohibited (both openCL 1.2 and openCL 2.0 agree on
> > this, and it matches the behavior of my old openCL compiler ...):
> The question is what the fallout is if we reject this by default (I suppose
> we accept it with -flax-vector-conversions). I'm ok with following
> OpenCL as well,
> that is either solution that makes behavior consistent between C and C++.
I agree that we should certainly continue to support mixed types with
-flax-vector-conversions. (This means we really should fix the C/C++
inconsistency as to return type in any case, even if we disable mixed
type support by default.)
What the fallout of disabling mixed types by default would be is hard
to say. On the one hand, all other standards I've looked at (OpenCL,
Altivec/VSX, Cell SPU) prohibit mixing signed/unsigned types. So this
hopefully means users of the GCC extension don't use this feature (much).
[Of course, Altivec does not really talk about operators, but ideally
GCC's a + b should be equivalent to the Altivec vec_add (a, b), which
does not support mixing signed/unsigned types.]
On the other hand, I've noticed at least two related areas where disabling
mixed types could result in unexpected fallout: opaque types and platform
specific vector types (e.g. "vector bool" on Altivec).
Opaque types are a somewhat under-specified GCC feature that is used for
different purposes by various platforms and the middle-end itself:
- some platform-specific types (PPC SPE __ev64_opaque__ or MEP cp_vector)
- function parameters for overloaded builtins in C before resolution
- the output of vector comparison operators and vector truth_type_for
It should be possible to use an opaque type together with vectors of
different types, even with -flax-vector-conversions (and even if we
disable support for signed/unsigned mixed types); the result of an
operation on an opaque type and a non-opaque type should be the
non-opaque type; it's not quite clear to me how operations on two
different opaque types are (should be?) defined.
Platform-specific types like Altivec "vector bool" are not really known
to the middle-end; this particular case is treated just like a normal
unsigned integer vector type. This means that as a side-effect of
disabling signed/unsigned mixed types, we would also disallow mixing
signed/bool types. But at least for Altivec vec_add, the latter is
explicitly *allowed* (returning the signed type). It would certainly
be preferable for + to be compatible to vec_add also for the bool types.
[ Note that the current implementation also does not fully match that
goal, because while signed + bool is allowed, the return value is
sometimes the bool type instead of the signed type. ]
This can probably only be fully solved by making the middle-end aware
that things like "vector bool" need to be handled specially. I had
thought that maybe the back-end simply needs to mark "vector bool"
as an opaque type (after all, the middle-end also uses this for
vector truth types), but that doesn't work as-is, since one of the
other features of opaque types is that they cannot be initialized.
(Altivec vector bool *can* be initialized.) Maybe those two features
should be decoupled, so we can have opaque types used as truth types,
and those that cannot be initialized ...
So overall the list of actions probably looks like this:
1. Fix the selection of the common type to use for binary vector operations
- C and C++ need to be consistent
- If one type is opaque and the other isn't, use the non-opaque type
- If one type is unsigned and the other is signed, use the unsigned type
- What to do with different types where neither of the above rules apply?
2. Rework support for opaque and platform-specific vector types
- Instead of the single "opaque" bit, have two flags:
* Mark type as compatible with other types in assignment/operations
* Mark type as "cannot be initialized"
- Use initializable opaque types for Altivec "vector bool" (and others?)
3. Disable mixing signed/unsigned types in binary operations
- This remains allowed if -flax-vector-conversions
Doing just 1. will at least fix the current C/C++ inconsistencies.
Doing 2. in addition will fix the current "vector bool" inconsistencies.
Doing all 3 will get us in line with OpenCL, Altivec, etc.
If this sounds reasonable, I can try to come up with a set of patches ...
Dr. Ulrich Weigand
GNU/Linux compilers and toolchain