This adds pre- and post- increment and decrements for MVE loads and stores. It uses the builtin pre and post load/store detection, unlike Neon. Loads are selected with the code in tryT2IndexedLoad, stores are selected with tablegen patterns. The immediates have a +/-7bit range, multiplied by the size of the element.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
llvm/include/llvm/Target/TargetSelectionDAG.td | ||
---|---|---|
1114 ↗ | (On Diff #206735) | nit: indent off by 1 |
1156 ↗ | (On Diff #206735) | here |
llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp | ||
151 ↗ | (On Diff #206735) | and here |
153 ↗ | (On Diff #206735) | and here that's it, just nitpicking! :-) |
llvm/lib/Target/ARM/ARMISelLowering.cpp | ||
332 ↗ | (On Diff #206735) | perhaps we could have a little bit of fun with c++ and do something like this: for (unsigned I : ISD::pre_inc_ins()) where pre_inc_ins() creates an iterator range, similar to what happens in MachineValueType.h |
The original version wasn't getting alignment correct in some cases. For little endian which instruction we choose has more to do with alignment and offset than type being loaded. I've rewritten parts of this to, at least for LE, get this hopefully more correct. I've tried to add BE too, but not added any tests for that yet. We still have a task to sort out BE properly.
llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp | ||
---|---|---|
1610 ↗ | (On Diff #209840) | bail here for BE? |
1612 ↗ | (On Diff #209840) | Why the >= comparisons for the alignment? Is that right? |
1631 ↗ | (On Diff #209840) | I am wondering if this is logically correct, the (IsLE || ... in particular. |
llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp | ||
---|---|---|
1610 ↗ | (On Diff #209840) | We still need to select instructions for BE. Granted I can't guarantee this will work correctly there yet, I have to go through and make sure all BE code works. |
1612 ↗ | (On Diff #209840) | The instruction (VLDRH) only supports alignments >= 2. Anything more than 2 is fine though (presuming it's a power of 2). |
1631 ↗ | (On Diff #209840) | The idea is that so long as we are LE, all the VLDRX instructions load data into the same lanes, so any can be used. The VLDRB.u8 will load the same data into the same place as a VLDRW.u32, just with a lower alignment constraint and a lower immediate range. In BE though, they will reverse the values as they are loaded into the lanes, so the types do actually become important. |
Looks reasonable
llvm/include/llvm/Target/TargetSelectionDAG.td | ||
---|---|---|
1114 ↗ | (On Diff #206735) | same nit if I'm not mistaken |
llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp | ||
1610 ↗ | (On Diff #209840) | Okay, got it. Given you're still working on BE, this looks okay. |
1612 ↗ | (On Diff #209840) | I was actually thinking about that, can we assume it's a power of 2? |
1631 ↗ | (On Diff #209840) | okay, got it, cheers. |
llvm/include/llvm/Target/TargetSelectionDAG.td | ||
---|---|---|
1114 ↗ | (On Diff #206735) | Sorry, I did mean to get to this! I need to rebase this over the bigendian code too. Let me do that now. |
llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp | ||
1612 ↗ | (On Diff #209840) | I believe alignments are always powers of 2. They can be 0 in IR, but then the abi alignment will be used by this point (which is 8 for these vectors, IIRC). |