[PATCH] D70107: [VFABI] TargetLibraryInfo mappings in IR.

Francesco Petrogalli via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon May 4 12:54:24 PDT 2020


fpetrogalli added a comment.

In D70107#2018145 <https://reviews.llvm.org/D70107#2018145>, @anna wrote:

> @fpetrogalli  I have a high level question - why does this pass require that the function should be from one of the vector libraries (Mass, SMVL etc)? I'd like to piggy-back on the `vector-function-abi-variant` attribute to vectorize a call to a scalar function, once the front-end adds this attribute to the callsite. So, if we have the following code in IR, with a scalar call to a function `trivially.vectorizable.func` with the `vector-function-abi-variant` attribute, we will generate the vector function declarations and then LoopVectorizer/SLPVectorizer would do its thing.


Hi @anna ,

this is exactly what the attribute is for. This pass works only with the library recognized by the TLI as a shortcut implementation to avoid doing the codegeneration of the attribute for the library functions in the frontend.

As things are, if you run `opt` with `-O2` on your IR, the code should be vectorized with a call to the vector version, if  not for the fact that the IR is missing the declaration of the actual vector function. In fact, the vector-function-abi-variant attribute requires that all the mappings listed in the attribute are resolved by some declaration/definition in the IR (notice that unused _declarations_ are kept in the IR and not deleted because such declarations are passed as parameter to the IR intrinsics`@llvm.compiler.used`). You can find more infos on this attribute here: https://llvm.org/docs/LangRef.html#call-site-attributes

> Test IR:
> 
>   ; ModuleID = 'chk.ll'
>   source_filename = "chk.ll"
>   target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
>   target triple = "x86_64-unknown-linux-gnu"
>   define dso_local double @test(float* %Arr) {
>   entry:
>     br label %for.cond
>   
>   for.cond:
>     %Sum.0 = phi double [ 0.000000e+00, %entry ], [ %add, %for.inc ]
>     %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
>     %cmp = icmp slt i32 %i.0, 128
>     br i1 %cmp, label %for.body, label %for.cond.cleanup
>   
>   for.cond.cleanup:
>     br label %for.end
>   
>   for.body:
>     %idxprom = sext i32 %i.0 to i64
>     %arrayidx = getelementptr inbounds float, float* %Arr, i64 %idxprom
>     %0 = load float, float* %arrayidx, align 4
>     %conv = fpext float %0 to double
>     %1 = call fast double @trivially.vectorizable.func(double %conv) #2 <-- CALL OF INTEREST
>     %add = fadd fast double %Sum.0, %1
>     br label %for.inc
>   
>   for.inc:
>     %inc = add nsw i32 %i.0, 1
>     br label %for.cond
>   
>   for.end:
>     ret double %Sum.0
>   }
>   
>   declare double @trivially.vectorizable.func(double) #1
>   attributes #2 = { "vector-function-abi-variant"="_ZGV_LLVM_N2v_trivially.vectorizable.func(trivially.vectorizable.func.v2)" }
>   attributes #1 = { nounwind readnone speculatable willreturn }
> 
> 
> The way I'm thinking - this pass will add the declaration for the vector function in IR `declare <2 x double> @trivially.vectorizable.func.v2(<2 x double>)`. 
>  I've confirmed that once this is done, LoopVectorizer will vectorize that call, i.e. convert the scalar call to the vector version.

Yes, this is correct. Your code will vectorize as it sees the vector declaration. Just make sure to mark it with `@llvm.compiler.used` so it doesn't get deleted by other optimization in the pipelines before reaching the vectorizer.

> Is there any reason to avoid updating this pass with such a functionality? Basically, I'm trying to use something similar to simd pragma in clang (https://clang.llvm.org/docs/AttributeReference.html#id211), where we can specify any function as vectorizable.

This pass is not to be used as the main way to generate the IR attribute that carries the mappings. It is here only to translate the TLI mappings used by the libraries into IR information, as the loop vectorizer doesn not interface anymore with the TLI but uses a class called `VFDatabase` that loads the mappings from `vector-function-abi-variant`. Any other mapping should be added by the frontend. In fact, the `vector-function-abi-variant` attribute was originally designed to carry the information of the OpenMP `declare variant` and `declare simd` directives: http://lists.llvm.org/pipermail/llvm-dev/2019-June/133484.html (Please notice that non of the frontend changes discussed in that email has been implemented yet, all we have done for now are the backend pieces)

> Do we already have such support for front-ends to specify any scalar function as 'vectorizable' in IR? This is the only existing attribute that I see which can be reused for this purpose.

As I said, no. Changing the codegeneration of `declare simd` to use `vector-function-abi-variant` is on my to do list, unfortunately not as close as I would like them to be. I suspect that also you have your own pipeline of things to do, but let me know if `declare simd` becomes closer to you than to me, I can always help you getting things sorted! Of course, feel free to ignore my offer, which is essentially a friendly "patches are welcome!" :)

> Also, to clarify, this vectorized call is finally lowered before passing to the backend/linker etc. So, you can think of this as I have a handwritten nice vectorized form for "trivially.vectorizable.call", which will be inlined before passing to codegen (so these declarations needn't be kept around after the inlining). The main reason for such a usecase is if we want the "high level function call" remaining in IR form until some late pass, which is just before codegen. It is not to bypass some vectorizer code generation limitation. We have such usecases internally.

If the function is defined in the module, even if all its uses are inlined, why would you want to remove it? If the function declaration is in the module, it is because it is present in the original source? Even if it comes from a `declare simd` on a scalar function, the compiler is allowed to think it is there even if it is unused.

Please let me know if you have any more question!

Kind regards,

Francesco


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D70107/new/

https://reviews.llvm.org/D70107





More information about the llvm-commits mailing list