[ARM] Fix loads and stores for predicate vectors
commita5b2c393bfb9a072be44b756646a007da8938162
authorDavid Green <david.green@arm.com>
Mon, 9 Sep 2019 16:35:49 +0000 (9 16:35 +0000)
committerDavid Green <david.green@arm.com>
Mon, 9 Sep 2019 16:35:49 +0000 (9 16:35 +0000)
tree679495b63a0c23dda4945524b301612e027b90e5
parent705fd17fee8577ca71da7777723b7b9a3818b596
[ARM] Fix loads and stores for predicate vectors

These predicate vectors can usually be loaded and stored with a single
instruction, a VSTR_P0. However this instruction will store the entire P0
predicate, 16 bits, zeroextended to 32bits. Each lane of the the
v4i1/v8i1/v16i1 representing 4/2/1 bits.

As far as I understand, when llvm says "store this v4i1", it really does need
to store 4 bits (or 8, that being the size of a byte, with this bottom 4 as the
interesting bits). For example a bitcast from a v8i1 to a i8 is defined as a
store followed by a load, which is how the code is expanded.

So this instead lowers the v4i1/v8i1 load/store through some shuffles to get
the bits into the correct positions. This, as you might imagine, is not as
efficient as a single instruction. But I believe it is needed for correctness.
v16i1 equally should not load/store 32bits, only storing the 16bits of data.
Stack loads/stores are still using the VSTR_P0 (as can be seen by the test not
changing). This is fine as they are self-consistent, it is only "externally
observable loads/stores" (from our point of view) that need to be corrected.

Differential revision: https://reviews.llvm.org/D67085

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@371419 91177308-0d34-0410-b5e6-96231b3b80d8
lib/Target/ARM/ARMISelLowering.cpp
lib/Target/ARM/ARMInstrMVE.td
test/CodeGen/Thumb2/mve-masked-ldst.ll
test/CodeGen/Thumb2/mve-masked-load.ll
test/CodeGen/Thumb2/mve-masked-store.ll
test/CodeGen/Thumb2/mve-pred-bitcast.ll
test/CodeGen/Thumb2/mve-pred-loadstore.ll