From: Richard Biener <richard.guenther@gmail.com>
To: Tejas Belagod <Tejas.Belagod@arm.com>
Cc: "gcc-patches@gcc.gnu.org" <gcc-patches@gcc.gnu.org>
Subject: Re: [RFC] GNU Vector Extension -- Packed Boolean Vectors
Date: Mon, 26 Jun 2023 10:50:16 +0200 [thread overview]
Message-ID: <CAFiYyc3KFDjXa3XTqDJhuqWFwE+cAqvWGO4HZ9q6fC0nFdNdSw@mail.gmail.com> (raw)
In-Reply-To: <AS8PR08MB7079EB8008E1C57F58587E88EA26A@AS8PR08MB7079.eurprd08.prod.outlook.com>
On Mon, Jun 26, 2023 at 8:24 AM Tejas Belagod via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> Hi,
>
> Packed Boolean Vectors
> ----------------------
>
> I'd like to propose a feature addition to GNU Vector extensions to add packed
> boolean vectors (PBV). This has been discussed in the past here[1] and a variant has
> been implemented in Clang recently[2].
>
> With predication features being added to vector architectures (SVE, MVE, AVX),
> it is a useful feature to have to model predication on targets. This could
> find its use in intrinsics or just used as is as a GNU vector extension being
> mapped to underlying target features. For example, the packed boolean vector
> could directly map to a predicate register on SVE.
>
> Also, this new packed boolean type GNU extension can be used with SVE ACLE
> intrinsics to replace a fixed-length svbool_t.
>
> Here are a few options to represent the packed boolean vector type.
The GIMPLE frontend uses a new 'vector_mask' attribute:
typedef int v8si __attribute__((vector_size(8*sizeof(int))));
typedef v8si v8sib __attribute__((vector_mask));
it get's you a vector type that's the appropriate (dependent on the
target) vector
mask type for the vector data type (v8si in this case).
> 1. __attribute__((vector_size (n))) where n represents bytes
>
> typedef bool vbool __attribute__ ((vector_size (1)));
>
> In this approach, the shape of the boolean vector is unclear. IoW, it is not
> clear if each bit in 'n' controls a byte or an element. On targets
> like SVE, it would be natural to have each bit control a byte of the target
> vector (therefore resulting in an 'unpacked' layout of the PBV) and on AVX, each
> bit would control one element/lane on the target vector(therefore resulting in a
> 'packed' layout with all significant bits at the LSB).
>
> 2. __attribute__((vector_size (n))) where n represents num of lanes
>
> typedef int v4si __attribute__ ((vector_size (4 * sizeof (int)));
> typedef bool v4bi __attribute__ ((vector_size (sizeof v4si / sizeof (v4si){0}[0])));
>
> Here the 'n' in the vector_size attribute represents the number of bits that
> is needed to represent a vector quantity. In this case, this packed boolean
> vector can represent upto 'n' vector lanes. The size of the type is
> rounded up the nearest byte. For example, the sizeof v4bi in the above
> example is 1.
>
> In this approach, because of the nature of the representation, the n bits required
> to represent the n lanes of the vector are packed at the LSB. This does not naturally
> align with the SVE approach of each bit representing a byte of the target vector
> and PBV therefore having an 'unpacked' layout.
>
> More importantly, another drawback here is that the change in units for vector_size
> might be confusing to programmers. The units will have to be interpreted based on the
> base type of the typedef. It does not offer any flexibility in terms of the layout of
> the bool vector - it is fixed.
>
> 3. Combination of 1 and 2.
>
> Combining the best of 1 and 2, we can introduce extra parameters to vector_size that will
> unambiguously represent the layout of the PBV. Consider
>
> typedef bool vbool __attribute__((vector_size (s, n[, w])));
>
> where 's' is size in bytes, 'n' is the number of lanes and an optional 3rd parameter 'w'
> is the number of bits of the PBV that represents a lane of the target vector. 'w' would
> allow a target to force a certain layout of the PBV.
>
> The 2-parameter form of vector_size allows the target to have an
> implementation-defined layout of the PBV. The target is free to choose the 'w'
> if it is not specified to mirror the target layout of predicate registers. For
> eg. AVX would choose 'w' as 1 and SVE would choose s*8/n.
>
> As an example, to represent the result of a comparison on 2 int16x8_t, we'd need
> 8 lanes of boolean which could be represented by
>
> typedef bool v8b __attribute__ ((vector_size (2, 8)));
>
> SVE would implement v8b layout to make every 2nd bit significant i.e. w == 2
>
> and AVX would choose a layout where all 8 consecutive bits packed at LSB would
> be significant i.e. w == 1.
>
> This scheme would accomodate more than 1 target to effectively represent vector
> bools that mirror the target properties.
>
> 4. A new attribite
>
> This is based on a suggestion from Richard S in [3]. The idea is to introduce a new
> attribute to define the PBV and make it general enough to
>
> * represent all targets flexibly (SVE, AVX etc)
> * represent sub-byte length predicates
> * have no change in units of vector_size/no new vector_size signature
> * not have the number of bytes constrain representation
>
> If we call the new attribute 'bool_vec' (for lack of a better name), consider
>
> typedef bool vbool __attribute__((bool_vec (n[, w])))
>
> where 'n' represents number of lanes/elements and the optional 'w' is bits-per-lane.
>
> If 'w' is not specified, it and bytes-per-predicate are implementation-defined based on target.
> If 'w' is specified, sizeof (vbool) will be ceil (n*w/8).
>
> 5. Behaviour of the packed vector boolean type.
>
> Taking the example of one of the options above, following is an illustration of it's behavior
>
> * ABI
>
> New ABI rules will need to be defined for this type - eg alignment, PCS,
> mangling etc
>
> * Initialization:
>
> Packed Boolean Vectors(PBV) can be initialized like so:
>
> typedef bool v4bi __attribute__ ((vector_size (2, 4, 4)));
> v4bi p = {false, true, false, false};
>
> Each value in the initizlizer constant is of type bool. The lowest numbered
> element in the const array corresponds to the LSbit of p, element 1 is
> assigned to bit 4 etc.
>
> p is effectively a 2-byte bitmask with value 0x0010
>
> With a different layout
>
> typedef bool v4bi __attribute__ ((vector_size (2, 4, 1)));
> v4bi p = {false, true, false, false};
>
> p is effectively a 2-byte bitmask with value 0x0002
>
> * Operations:
>
> Packed Boolean Vectors support the following operations:
> . unary ~
> . unary !
> . binary&,|andˆ
> . assignments &=, |= and ˆ=
> . comparisons <, <=, ==, !=, >= and >
> . Ternary operator ?:
>
> Operations are defined as applied to the individual elements i.e the bits
> that are significant in the PBV. Whether the PBVs are treated as bitmasks
> or otherwise is implementation-defined.
>
> Insignificant bits could affect results of comparisons or ternary operators.
> In such cases, it is implementation defined how the unused bits are treated.
>
> . Subscript operator []
>
> For the subscript operator, the packed boolean vector acts like a array of
> elements - the first or the 0th indexed element being the LSbit of the PBV.
> Subscript operator yields a scalar boolean value.
> For example:
>
> typedef bool v8b __attribute__ ((vector_size (2, 8, 2)));
>
> // Subscript operator result yields a boolean value.
> // x[3] is the 7th LSbit and x[1] is the 3rd LSbit of x.
> bool foo (v8b p, int n) { p[3] = true; return p[1]; }
>
> Out of bounds access: OOB access can be determined at compile time given the
> strong typing of the PBVs.
>
> PBV does not support address of operator(&) for elements of PBVs.
>
> . Implicit conversion from integer vectors to PBVs
>
> We would like to support the output of comparison operations to be PBVs. This
> requires us to define the implicit conversion from an integer vector to PBV
> as the result of vector comparisons are integer vectors.
>
> To define this operation:
>
> bool_vector = vector <cmpop> vector
>
> There is no change in how vector <cmpop> vector behavior i.e. this comparison
> would still produce an int_vector type as it does now.
>
> temp_int_vec = vector <cmpop> vector
> bool_vec = temp_int_vec // Implicit conversion from int_vec to bool_vec
>
> The implicit conversion from int_vec to bool I'd define simply to be:
>
> bool_vec[n] = (_Bool) int_vec[n]
>
> where the C11 standard rules apply
> 6.3.1.2 Boolean type When any scalar value is converted to _Bool, the result
> is 0 if the value compares equal to 0; otherwise, the result is 1.
>
>
> [1] https://lists.llvm.org/pipermail/cfe-dev/2020-May/065434.html
> [2] https://reviews.llvm.org/D88905
> [3] https://reviews.llvm.org/D81083
>
> Thoughts?
>
> Thanks,
> Tejas.
next prev parent reply other threads:[~2023-06-26 8:53 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-26 6:23 Tejas Belagod
2023-06-26 8:50 ` Richard Biener [this message]
2023-06-27 6:30 ` Tejas Belagod
2023-06-27 7:28 ` Richard Biener
2023-06-28 11:26 ` Tejas Belagod
2023-06-29 13:25 ` Richard Biener
2023-07-03 6:50 ` Tejas Belagod
2023-07-03 8:01 ` Richard Biener
2023-07-13 10:14 ` Tejas Belagod
2023-07-13 10:35 ` Richard Biener
2023-07-14 10:18 ` Tejas Belagod
2023-07-17 12:16 ` Richard Biener
2023-07-26 7:21 ` Tejas Belagod
2023-07-26 12:26 ` Richard Biener
2023-07-26 12:33 ` Richard Biener
2023-10-05 20:48 ` Matthias Kretz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAFiYyc3KFDjXa3XTqDJhuqWFwE+cAqvWGO4HZ9q6fC0nFdNdSw@mail.gmail.com \
--to=richard.guenther@gmail.com \
--cc=Tejas.Belagod@arm.com \
--cc=gcc-patches@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).