[PATCH] D69791: [ARM,MVE] Add intrinsics for gather/scatter load/stores.

Simon Tatham via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Nov 4 01:54:09 PST 2019


simon_tatham created this revision.
simon_tatham added a reviewer: dmgreen.
Herald added subscribers: llvm-commits, cfe-commits, hiraditya, kristof.beyls.
Herald added projects: clang, LLVM.
simon_tatham added parent revisions: D69789: [clang,MveEmitter] Fix sign/zero extension in range limits., D69790: [ARM,MVE] Integer-type nitpicks in MVE intrinsics..

This patch adds two new families of intrinsics, both of which are
memory accesses taking a vector of locations to load from / store to.

The vldrq_gather_base / vstrq_scatter_base intrinsics take a vector of
base addresses, and an immediate offset to be added consistently to
each one. vldrq_gather_offset / vstrq_scatter_offset take a scalar
base address, and a vector of offsets to add to it. The
'shifted_offset' variants also multiply each offset by the element
size type, so that the vector is effectively of array indices.

At the IR level, these operations are represented by a single set of
four IR intrinsics: {gather,scatter} × {base,offset}. The other
details (signed/unsigned, shift, and memory element size as opposed to
vector element size) are all specified by IR intrinsic polymorphism
and immediate operands, because that made the selection job easier
than making a huge family of similarly named intrinsics.

I considered using the standard IR representations such as
llvm.masked.gather, but they're not a good fit. In order to use
llvm.masked.gather to represent a gather_offset load with element size
smaller than a pointer, you'd have to expand the <8 x i16> vector of
offsets into an <8 x i16*> vector of pointers, which would be split up
during legalization, so you'd spend most of your time undoing the mess
it had made. Also, ISel support for llvm.masked.gather would be easy
enough in a trivial way (you can expand it into a gather-base load
with a zero immediate offset), but instruction-selecting lots of
fiddly idioms back into all the _other_ MVE load instructions would be
much more work. So I think dedicated IR intrinsics are the more
sensible approach, at least for the moment.

On the clang tablegen side, I've added two new features to MveEmitter:
a 'CopyKind' type node for defining a type that varies with the
parameter type (it lets you ask for an unsigned integer type of the
same width as the parameter), and an 'unsignedflag' value node for
passing an immediate IR operand which is 0 for a signed integer type
or 1 for an unsigned one. That lets me write each kind of intrinsic
just once and get all its subtypes and immediate arguments generated
automatically.

On the MC side, I've enhanced MVEVectorVTInfo so that it can tell you
not only the full assembly-language suffix for a given vector type
(like 's32' or 'u16') but also the numeric-only one used by store
instructions (just '32' or '16').


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D69791

Files:
  clang/include/clang/Basic/arm_mve.td
  clang/include/clang/Basic/arm_mve_defs.td
  clang/test/CodeGen/arm-mve-intrinsics/scatter-gather.c
  clang/test/Sema/arm-mve-immediates.c
  clang/utils/TableGen/MveEmitter.cpp
  llvm/include/llvm/IR/IntrinsicsARM.td
  llvm/lib/Target/ARM/ARMInstrMVE.td
  llvm/test/CodeGen/Thumb2/mve-intrinsics/scatter-gather.ll

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D69791.227661.patch
Type: text/x-patch
Size: 213366 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20191104/5b98dfe1/attachment-0001.bin>


More information about the cfe-commits mailing list