Thank you Szabolcs for working on this.

> On Nov 14, 2019, at 2:23 PM, Szabolcs Nagy <szabolcs.n...@arm.com> wrote:
> 
> Sorry v2 had a bug.
> 
> v2: added documentation and tests.
> v3: fixed expand_simd_clones so different isa variants are actually
>    generated.
> 
> GCC currently supports two ways to declare the availability of vector
> variants of a scalar function:
> 
>  #pragma omp declare simd
>  void f (void);
> 
> and
> 
>  __attribute__ ((simd))
>  void f (void);
> 
> However these declare a set of symbols that are different simd variants
> of f, so a library either provides definitions for all those symbols or
> it cannot use these declarations. (The set of declared symbols can be
> narrowed down with additional omp clauses, but not enough to allow
> declaring a single symbol. OpenMP 5 has a declare variant feature that
> allows declaring more specific simd variants, but it is complicated and
> still requires gcc or vendor extension for unambiguous declarations.)
> 

It is not just that it is complicated, it is also a good idea to make math 
function vectorization orthogonal to OpenMP.
This is needed din clang too, thank you for shaping a solution. It would be 
good if we could come up with a common solution!

> This patch extends the gcc specific simd attribute such that it can
> specify a single vector variant of simple scalar functions (functions
> that only take and return scalar integer or floating type values):
> 
>       
> 
> where mask is "inbranch" or "notinbranch" like now, simdlen is an int
> with the same meaning as in omp declare simd and simdabi is a string
> specifying the call ABI (which the intel vector ABI calls ISA). The
> name is optional and allows a library to use a different symbol name
> than what the vector ABI specifies.
> 

Can we have also handling also the simplest case for the use of linear (just 
with step = OpenMP default = 1)? It will be useful for `sincos`.

OpenMP `linear` uses parameters name, in the attribute, which applies to 
declaration with unnamed parameters, we could use positions.

Also, can we avoid making the attribute a varargs attribute, but requires all 
arguments to be present? We could use dummy values when the descriptor is not 
needed (e.g. `no_linear`).

I would also require the name to be specified, with the additional requirement 
to make the declaration of name visible in the same compilation unit.

For example, on Arm, mapping `sincos` and `exp` to unmasked vector versions 
with 2 lanes would be:

```
void _ZGVnN2vl8l8_sincos(float64x2_t, double *, double *);

void sincos(double, double*, double *) 
__attribute__(simd(notinbranch,2,”simd”,_ZGVnN2vl8l8_sincos, linear(2,3)));

void _ZGVnN2v_exp(float64x2_t);

void exp(double) __attribute__(simd(notinbranch,2,”simd”,_ZGVnN2v_exp, 
no_linear));
```

For scalable vectorization on SVE, this could be rendered as (note that SVE 
requires mask parameter to be present independently of the [not]inbranch 
clause, see [1]):

```
void _ZGVsMxvl8l8_sincos(svfloat64_t, double *, double *, svbool_t);

void sincos(double, double*, double *) 
__attribute__(simd(inbranch,scalable,”sve”,_ZGVsMxvl8l8_sincos, linear(2,3)));

void _ZGVsNxv_exp(svfloat64_t, svbool_t);

void exp(double) __attribute__(simd(inbranch,scalable,”sve”,_ZGVsMxv_exp, 
no_linear));
```

SVE specific note: the “scalable” token could be replaced with 0. My preference 
would be for using scalable as a keywords, because 0 is not allowed by OpenMP 
(and might also be misleading).

Kind regards,

Francesco

[1] 
https://github.com/ARM-software/software-standards/blob/master/abi/vfabia64/vfabia64.rst#masking

> The simd attribute currently can be used for both declarations and
> definitions, in the latter case the simd varaints of the function are
> generated, which should work with the extended simd attribute too.
> 
> Tested on aarch64-linux-gnu and x86_64-linux-gnu.
> 
> gcc/ChangeLog:
> 
> 2019-11-14  Szabolcs Nagy  <szabolcs.n...@arm.com>
> 
>       * cgraph.h (struct cgraph_simd_clone): Add simdname field.
>       * doc/extend.texi: Update the simd attribute documentation.
>       * tree.h (OMP_CLAUSE__SIMDABI__EXPR): Define.
>       (OMP_CLAUSE__SIMDNAME__EXPR): Define.
>       * tree.c (walk_tree_1): Handle new omp clauses.
>       * tree-core.h (enum omp_clause_code): Likewise.
>       * tree-nested.c (convert_nonlocal_omp_clauses): Likewise.
>       * tree-pretty-print.c (dump_omp_clause): Likewise.
>       * omp-low.c (scan_sharing_clauses): Likewise.
>       * omp-simd-clone.c (simd_clone_clauses_extract): Likewise.
>       (simd_clone_mangle): Handle simdname.
>       (expand_simd_clones): Reset vecsize_mangle when generating clones.
>       * config/aarch64/aarch64.c
>       (aarch64_simd_clone_compute_vecsize_and_simdlen): Warn about
>       unsupported SIMD ABI.
>       * config/i386/i386.c
>       (ix86_simd_clone_compute_vecsize_and_simdlen): Likewise.
> 
> gcc/c-family/ChangeLog:
> 
> 2019-11-14  Szabolcs Nagy  <szabolcs.n...@arm.com>
> 
>       * c-attribs.c (handle_simd_attribute): Handle 4 arguments.
> 
> gcc/testsuite/ChangeLog:
> 
> 2019-11-14  Szabolcs Nagy  <szabolcs.n...@arm.com>
> 
>       * c-c++-common/attr-simd-5.c: Update.
>       * c-c++-common/attr-simd-6.c: New test.
>       * c-c++-common/attr-simd-7.c: New test.
>       * c-c++-common/attr-simd-8.c: New test.
> <simd.diff>

Reply via email to