[llvm-dev] [RFC][SDAG] Convert build_vector of ops on extractelts into ops on input vectors

Simon Pilgrim via llvm-dev llvm-dev at lists.llvm.org
Sat Jan 11 05:25:32 PST 2020


Performing vectorization in the SelectionDAG tends to be fraught with 
problems as we don't have a cost model mechanism to control it; we hit 
this in https://bugs.llvm.org/show_bug.cgi?id=35732 where conversion ops 
were being vectorized in DAG whether we wanted to or not, purely based 
on a isOperationLegalOrCustom call (just because an op is possible 
doesn't mean its efficient to do so under all circumstances).

In general I think we should be relying on the SLPVectorizer to handle 
this instead. If SLP is failing, we're probably better off spending dev 
time fixing it there instead of trying to cleanup in DAG (e.g. too often 
I find its a case of tweaking the TTI cost models).

Having said that, we do hit cases where vectorizable patterns do appear 
during legalization - x86 does some very limited bitwise op 
vectorization in lowerBuildVectorToBitOp as this was such a common 
occurrence. So there's probably scope to provide some common helper 
functions in SelectionDAG.cpp to recognise vectorizable patterns 
(similar to SelectionDAG::matchBinOpReduction) but we leave it up to the 
target's build_vector combiner/lowering to actually decide whether to 
make use of them.

Simon.

On 10/01/2020 21:49, Nemanja Ivanovic via llvm-dev wrote:
> I have added a few PPC-specific DAG combines in the past that follow 
> this pattern on specific operations. Now that it appears that this 
> would be useful to do on yet another operation, I'm wondering what 
> people think about doing this in the target-independent DAG Combiner 
> for any legal/custom operation on the target.
>
> TL; DR;
> The generic pattern would look like this:
> (build_vector (op (extractelt %a, 0), [(extractelt %b, 0)]...), (op 
> (extractelt %a, 1), [(extractelt %b, 1)]...), ...)
> Basically, if the build vector is built from the same operation 
> applied on elements extracted from another vector (or pair of vectors 
> for binary ops), then we can check for the legality of the operation 
> on the vector type. If the operation is legal for the vector type (and 
> the operand and result vector types are the same), then we can just 
> convert this to (op %a [, %b])
> Which is likely going to produce better code in all cases. Of course, 
> things like this have a tendency to not be better in all cases, but I 
> think we can probably account for any corner cases that arise. 
> Example: (v2i64 build_vector (mulhs (extractelt %a, 0), (extractelt 
> %b, 0)),                     (mulhs (extractelt %a, 1), (extractelt 
> %b, 1))) Can be converted to the following on a target that has the 
> operation available on vectors. (v2i64 mulhs %a, %b)
> A further improvement might be if the order of extracted elements 
> doesn't match the order in the build_vector, that we shuffle one or 
> both input vectors prior to applying the operation.
> If you think this is a good idea (or a terrible idea), please let me 
> know.
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200111/b06be483/attachment.html>


More information about the llvm-dev mailing list