[RFC] GCC vector extension: binary operators vs. differing signedness

Ulrich Weigand uweigand@de.ibm.com
Thu Dec 11 15:04:00 GMT 2014

Richard Biener wrote:
> On Wed, Dec 10, 2014 at 10:09 PM, Ulrich Weigand <uweigand@de.ibm.com> wrote:
> > So at the very least, we should bring the documentation in line with the
> > actual behavior.  However, as seen above, that actual behavior is probably
> > not really useful in any case, at least in C.
> >
> >
> > So I'm wondering whether we should:
> >
> > A. Bring C in line with C++ by making the result of a vector binary operator
> >    use the unsigned type if the two input types differ in signedness?
> >
> > and/or
> >
> > B. Enforce that both operands to a vector binary operator must have the same
> >    type (except for opaque vector types) unless -flax-vector-conversions?
> I suppose the current behavior comes from the idea that C would
> apply promotion rules to the operands of binary operators.  To the extent
> we can apply the same rules to vector operands we should probably
> support that.  This means that for example
>  1) promotions that only differ in signedness happen (partly the C frontend
> behavior)
>  2) promotions that change the size of the elements and thus the size of
> the vector happen (probably not a good idea by default)
>  3) promotions that change the kind of the elements of the vectors
> (float vs. non-float) happen (probably neither a good idea)

Just to clarify: your 1) is pretty much the same as my A., right?

The difference in behavior between C and C++ seems to originate in different
implementations in c_common_type vs. cp_common_type:

C has:

  /* If one type is a vector type, return that type.  (How the usual
     arithmetic conversions apply to the vector types extension is not
     precisely specified.)  */
  if (code1 == VECTOR_TYPE)
    return t1;

  if (code2 == VECTOR_TYPE)
    return t2;

while C++ has:

  if (code1 == VECTOR_TYPE)
      /* When we get here we should have two vectors of the same size.
         Just prefer the unsigned one if present.  */
      if (TYPE_UNSIGNED (t1))
        return build_type_attribute_variant (t1, attributes);
        return build_type_attribute_variant (t2, attributes);

> I think it's sensible to support 1) by default (also to not regress existing
> code) but fix it so it applies to C++ as well and accepts both cases
> in C.  And of course fix documentation.

I'm not sure I understand exactly what you mean here.  C++ already implements
the sign promotion rule; just C doesn't.  So we could do the same for C as is
currently done for C++.

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 ...


  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain

More information about the Gcc mailing list