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