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>