[llvm-dev] [RFC] Expose user provided vector function for auto-vectorization.

Renato Golin via llvm-dev llvm-dev at lists.llvm.org
Tue May 28 14:11:53 PDT 2019

Hi Francesco,

Nice to finally see this RFC, thanks! :)

Overall, I like the proposal. Clean, concise and complete.

I have a few comments inline, but from a high level this is looking good.

On Tue, 28 May 2019 at 20:44, Francesco Petrogalli
<Francesco.Petrogalli at arm.com> wrote:
> The directive `#pragma clang declare variant` follows the syntax of the
> `#pragma omp declare variant` directive of OpenMP.
> We define the new directive in the `clang` namespace instead of using
> the `omp` one of OpenMP to allow the compiler to perform
> auto-vectorization outside of an OpenMP SIMD context.

So, the only difference is that pragma "omp" includes and links OMP
stuff, while pragma "clang" doesn't, right?

What happens if I have code with "pragma clang declare variant" and
"pragma omp" elsewhere, would the clang pragma behave identically as
if it was omp?

> The mechanism is base on OpenMP to provide a uniform user experience
> across the two mechanism, and to maximise the number of shared
> components of the infrastructure needed in the compiler frontend to
> enable the feature.
> Changes in LLVM IR {#llvmIR}
> ------------------
> The IR is enriched with metadata that details the availability of vector
> versions of an associated scalar function. This metadata is attached to
> the call site of the scalar function.

If the metadata gets dropped by some middle-end pass, the user will be
confused why the vector function is not being called.

Do we have that problem with OMP stuff already? If so, how do we fix this?

>     // ...
>     ... = call double @sin(double) #0
>     // ...
>     #0 = { vector-variant = {"_ZGVcN2v_sin(__svml_sin2),
>                               _ZGVdN4v_sin(__svml_sin4),
>                               ..."} }

I'm assuming in all ABIs, the arguments and return values are
guaranteed to be the same, but vector versions. Ie. there are no
special arguments / flags / status regs that are used / changed in the
vector version that the compiler will have to "just know". If the
whole point is that this is a "variant", having specialist knowledge
for random variant ABIs won't scale.

Is that a problem or can we class those as "user-error"?

> The SVFS can add new function definitions, in the same module as the
> `Call`, to provide vector functions that are not present within the
> vector-variant metadata. For example, if a library provides a vector
> version of a function with a vectorization factor of 2, but the
> vectorizer is requesting a vectorization factor of 4, the SVFS is
> allowed to create a definition that calls the 2-lane version twice. This
> capability applies similarly for providing masked and unmasked versions
> when the request does not match what is available in the library.

Nice! Those thunks will play nicely with inlining later, sort of like unrolling.

> The `construct` set in the directive, together with the `device` set, is
> used to generate the vector mangled name to be used in the
> `vector-variant` attribute, for example `_ZGVnN2v_sin`, when targeting
> AArch64 Advanced SIMD code generation. The rule for mangling the name of
> the scalar function in the vector name are defined in the the Vector
> Function ABI specification of the target.

And I assume the user is responsible for linking the libraries that
export those signatures or they will have a linking error. Giving that
this is user definition (in the pragma), and that we really can't know
if the library will be available at link time, it's the only thing we
can do.


More information about the llvm-dev mailing list