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

Reply via email to