[ARM] MVE vector lane interleaving
authorDavid Green <david.green@arm.com>
Sun, 28 Mar 2021 18:34:58 +0000 (19:34 +0100)
committerDavid Green <david.green@arm.com>
Sun, 28 Mar 2021 18:34:58 +0000 (19:34 +0100)
commit7b6f760fcd19c52149a5dea81512bdceb222032a
tree26c7519b34797e71ba8cdf5296d933cacd8e9aba
parent53c98d85a8a609552448043d5512e70313b1eb1b
[ARM] MVE vector lane interleaving

MVE does not have a single sext/zext or trunc instruction that takes the
bottom half of a vector and extends to a full width, like NEON has with
MOVL. Instead it is expected that this happens through top/bottom
instructions. So the MVE equivalent VMOVLT/B instructions take either
the even or odd elements of the input and extend them to the larger
type, producing a vector with half the number of elements each of double
the bitwidth. As there is no simple instruction for a normal extend, we
often have to expand sext/zext/trunc into a series of lane moves (or
stack loads/stores, which we do not do yet).

This pass takes vector code that starts at truncs, looks for
interconnected blobs of operations that end with sext/zext and
transforms them by adding shuffles so that the lanes are interleaved and
the MVE VMOVL/VMOVN instructions can be used. This is done pre-ISel so
that it can work across basic blocks.

This initial version of the pass just handles a limited set of
instructions, not handling constants or splats or FP, which can all come
as extensions to this base.

Differential Revision: https://reviews.llvm.org/D95804
llvm/lib/Target/ARM/ARM.h
llvm/lib/Target/ARM/ARMTargetMachine.cpp
llvm/lib/Target/ARM/CMakeLists.txt
llvm/lib/Target/ARM/MVELaneInterleavingPass.cpp [new file with mode: 0644]
llvm/test/CodeGen/ARM/O3-pipeline.ll
llvm/test/CodeGen/Thumb2/mve-laneinterleaving-cost.ll
llvm/test/CodeGen/Thumb2/mve-laneinterleaving.ll