yonutix
yonutix

Reputation: 2449

Vector bitwise and with constant value on GCC

Is the following test case valid for gcc?

typedef signed char v16signed_char __attribute__ ((__vector_size__ (sizeof(signed char) * 16)));
v16signed_char and_imm(v16signed_char a)
{
    v16signed_char s = a & 0xFF;
    return s;
}

It fails on gcc, apparently because 0xFF is too large. Should it fail? By failure I mean compiler error:

error: conversion of scalar ‘int’ to vector ‘v4unsigned_int {aka __vector(4) signed char}’ involves truncation

Upvotes: 1

Views: 94

Answers (1)

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385194

The operation & itself is valid, fortunately: [ref]

The types defined in this manner can be used with a subset of normal C operations. Currently, GCC allows using the following operators on these types: +, -, *, /, unary minus, ^, |, &, ~, %.

However, it seems that you need to provide an operand of the base type.

0xFF is an int, but your base type is signed char.

So:

v16signed_char s = a & (signed char)0xFF;

The documentation says:

For convenience, it is allowed to use a binary vector operation where one operand is a scalar. In that case the compiler transforms the scalar operand into a vector where each element is the scalar from the operation. The transformation happens only if the scalar could be safely converted to the vector-element type.

Without a definition of "could be safely converted", I'm not sure I can say with confidence whether your original code is supposed to compile under these rules. However, I suspect they've taken a strict approach here since an arbitrary intsigned char conversion can lose data.

It may be (or be related to) bug 53784. Or it may be expected.

Though it's interesting, because in the case of this literal that's clearly not the case, and in non-vectorised code you would expect the usual warning to be elided in situations like this for that reason.

Upvotes: -1

Related Questions