On 7/17/24 4:36 PM, Richard Biener wrote:
On Wed, Jul 17, 2024 at 10:17 AM Tejas Belagod <tejas.bela...@arm.com> wrote:
On 7/15/24 6:05 PM, Richard Biener wrote:
On Mon, Jul 15, 2024 at 1:22 PM Tejas Belagod <tejas.bela...@arm.com> wrote:
On 7/15/24 12:16 PM, Tejas Belagod wrote:
On 7/12/24 6:40 PM, Richard Biener wrote:
On Fri, Jul 12, 2024 at 3:05 PM Jakub Jelinek <ja...@redhat.com> wrote:
On Fri, Jul 12, 2024 at 02:56:53PM +0200, Richard Biener wrote:
Padding is only an issue for very small vectors - the obvious choice is
to disallow vector types that would require any padding. I can hardly
see where those are faster than using a vector of up to 4 char
elements.
Problematic are 1-bit elements with 4, 2 or one element vectors,
2-bit elements
with 2 or one element vectors and 4-bit elements with 1 element
vectors.
I'd really like to avoid having to support something like
_BitInt(16372) __attribute__((vector_size (sizeof (_BitInt(16372)) *
16)))
_BitInt(2) to say size of long long could be acceptable.
I'd disallow _BitInt(n) with n >= 8, it should be just the syntactic
way to say
the element should have n (< 8) bits.
I have no idea what the stance of supporting _BitInt in C++ are,
but most certainly diverging support (or even semantics) of the
vector extension in C vs. C++ is undesirable.
I believe Clang supports it in C++ next to C, GCC doesn't and Jason
didn't
look favorably to _BitInt support in C++, so at least until something
like
that is standardized in C++ the answer is probably no.
OK, I think that rules out _BitInt use here so while bool is then natural
for 1-bit elements for 2-bit and 4-bit elements we'd have to specify the
number of bits explicitly. There is signed_bool_precision but like
vector_mask it's use is restricted to the GIMPLE frontend because
interaction with the rest of the language isn't defined.
Thanks for all the suggestions - really insightful (to me) discussions.
Yeah, BitInt seemed like it was best placed for this, but not having C++
support is definitely a blocker. But as you say, in the absence of
BitInt, bool becomes the natural choice for bit sizes 1, 2 and 4. One
way to specify non-1-bit widths could be overloading vector_size.
Also, I think overloading GIMPLE's vector_mask takes us into the
earlier-discussed territory of what it should actually mean - it meaning
the target truth type in GIMPLE and a generic vector extension in the FE
will probably confuse gcc developers more than users.
That said - we're mixing two things here. The desire to have "proper"
svbool (fix: declare in the backend) and the desire to have "packed"
bit-precision vectors (for whatever actual reason) as part of the
GCC vector extension.
If we leave lane-disambiguation of svbool to the backend, the values I
see in supporting 1, 2 and 4 bitsizes are 1) first step towards
supporting BitInt(N) vectors possibly in the future 2) having a way for
targets to define their intrinsics' bool vector types using GNU
extensions 3) feature parity with Clang's ext_vector_type?
I believe the primary motivation for Clang to support ext_vector_type
was to have a way to define target intrinsics' vector bool type using
vector extensions.
Interestingly, Clang seems to support
typedef struct {
_Bool i:1;
} STR;
typedef struct { _Bool i: 1; } __attribute__((vector_size (sizeof (STR)
* 4))) vec;
int foo (vec b) {
return sizeof b;
}
I can't find documentation about how it is implemented, but I suspect
the vector is constructed as an array STR[] i.e. possibly each
bit-element padded to byte boundary etc. Also, I can't seem to apply
many operations other than sizeof.
I don't know if we've tried to support such cases in GNU in the past?
Why should we do that? It doesn't make much sense.
single-bit vectors is what _BitInt was invented for.
Forgive me if I'm misunderstanding - I'm trying to figure out how
_BitInts can be made to have single-bit generic vector semantics. For
eg. If I want to initialize a _BitInt as vector, I can't do:
_BitInt (4) a = (_BitInt (4)){1, 0, 1, 1};
as 'a' expects a scalar initialization.
Of if I want to convert an int vector to bit vector, I can't do
v4si_p = v4si_a > v4si_b;
_BitInt (4) vbool = __builtin_convertvector (v4si_p, _BitInt (4));
Also semantics of conditionals with _BitInt behave like scalars
_BitInt (4) p = a && b; // Here a and b are _BitInt (4), but they
behave as scalars.
Also, I can't do things like
typedef _BitInt (2) vbool __attribute__((vector_size(sizeof (_BitInt
(2)) * 4)));
to force it to behave as a vector because _BitInt is disallowed here.
All I'm trying to say is that when people want to use vector<bool> as
a large packed bitfield they can now use _BitInt instead. Of course
with a different (but portable) API.
> I don't see single-bit element vectors something as especially
useful with a "vector API". What's its the use-case? (similar
for the two and four bit elements, with or without padding)
I'm trying to figure out if we had a portable (generic) way to represent
predicate vectors(eg BitInts) in the front end, and had rules(or a
vector API?)) that cast from integer vectors acting as bools to BitInts,
would it be more efficient to lower to target predicate modes (VNx16BI
etc on targets that support n-bit mode predicates)? It could also
possibly interoperate with target intrinsics better than int bool vectors.
I don't know if this is a compelling-enough use-case.
Thanks,
Tejas.
Richard.
2-bit and 4-bit
element vectors is what's missing, but the scope is narrow and
efficient lowering or native support is missing. Vectors of bit
elements but with padding is just something stupid to look for
as a general feature.
Fair enough.
Thanks,
Tejas.
Richard.
Thanks,
Tejas.