summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp
Commit message (Collapse)AuthorAgeFilesLines
* [ARM] GlobalISel: Legalize G_FCMP for s32Diana Picus2017-07-061-0/+132
| | | | | | | | | | | | | | | | | | | | | This covers both hard and soft float. Hard float is easy, since it's just Legal. Soft float is more involved, because there are several different ways to handle it based on the predicate: one and ueq need not only one, but two libcalls to get a result. Furthermore, we have large differences between the values returned by the AEABI and GNU functions. AEABI functions return a nice 1 or 0 representing true and respectively false. GNU functions generally return a value that needs to be compared against 0 (e.g. for ogt, the value returned by the libcall is > 0 for true). We could introduce redundant comparisons for AEABI as well, but they don't seem easy to remove afterwards, so we do different processing based on whether or not the result really needs to be compared against something (and just truncate if it doesn't). llvm-svn: 307243
* [ARM] GlobalISel: Widen s1, s8, s16 G_CONSTANTDiana Picus2017-07-061-0/+2
| | | | | | Get the legalizer to widen small constants. llvm-svn: 307239
* [GlobalISel] Refactor Legalizer helpers for libcallsDiana Picus2017-07-051-4/+9
| | | | | | | | | | We used to have a helper that replaced an instruction with a libcall. That turns out to be too aggressive, since sometimes we need to replace the instruction with at least two libcalls. Therefore, change our existing helper to only create the libcall and leave the instruction removal as a separate step. Also rename the helper accordingly. llvm-svn: 307149
* [ARM] GlobalISel: Extract tiny helper. NFCDiana Picus2017-07-051-2/+5
| | | | | | Extract functionality for determining if the target uses AEABI. llvm-svn: 307145
* [GlobalISel] Make multi-step legalization work.Kristof Beyls2017-06-301-38/+1
| | | | | | | | | | | | | | | | In r301116, a custom lowering needed to be introduced to be able to legalize 8 and 16-bit divisions on ARM targets without a division instruction, since 2-step legalization (WidenScalar from 8 bit to 32 bit, then Libcall the 32-bit division) doesn't work. This fixes this and makes this kind of multi-step legalization, where first the size of the type needs to be changed and then some action is needed that doesn't require changing the size of the type, straighforward to specify. Differential Revision: https://reviews.llvm.org/D32529 llvm-svn: 306806
* [ARM] GlobalISel: Support G_SELECT for pointersDiana Picus2017-06-271-0/+1
| | | | | | All we need to do is mark it as legal, otherwise it's just like s32. llvm-svn: 306390
* [ARM] GlobalISel: Support G_SELECT for i32Diana Picus2017-06-271-0/+3
| | | | | | | | | | * Mark as legal for (s32, i1, s32, s32) * Map everything into GPRs * Select to two instructions: a CMP of the condition against 0, to set the flags, and a MOVCCr to select between the two inputs based on the flags that we've just set llvm-svn: 306382
* [ARM] GlobalISel: Support G_ICMP for s8 and s16Diana Picus2017-06-191-0/+2
| | | | | | Widen to s32 (like all other binary ops). llvm-svn: 305683
* [ARM] GlobalISel: Support G_ICMP for i32 and pointersDiana Picus2017-06-191-0/+4
| | | | | | | | | | | | | | Add support throughout the pipeline: - mark as legal for s32 and pointers - map to GPRs - lower to a sequence of instructions, which moves 0 or 1 into the result register based on the flags set by a CMPrr We have copied from FastISel a helper function which maps CmpInst predicates into ARMCC codes. Ideally, we should be able to move it somewhere that both FastISel and GlobalISel can use. llvm-svn: 305672
* [ARM] GlobalISel: Add support for i32 moduloDiana Picus2017-06-151-0/+45
| | | | | | | | | | | | | | | | | | Add support for modulo for targets that have hardware division and for those that don't. When hardware division is not available, we have to choose the correct libcall to use. This is generally straightforward, except for AEABI. The AEABI variant is trickier than the other libcalls because it returns { quotient, remainder }, instead of just one value like the other libcalls that we've seen so far. Therefore, we need to use custom lowering for it. However, we don't want to have too much special code, so we refactor the target-independent code in the legalizer by adding a helper for replacing an instruction with a libcall. This helper is used by the legalizer itself when dealing with simple calls, and also by the custom ARM legalization for the more complicated AEABI divmod calls. llvm-svn: 305459
* [ARM] GlobalISel: Support G_XORDiana Picus2017-06-071-1/+1
| | | | | | | | | Same as the other binary operators: - legalize to 32 bits - map to GPRs - select to EORrr via TableGen'erated code llvm-svn: 304898
* [ARM] GlobalISel: Support G_ORDiana Picus2017-06-071-1/+1
| | | | | | | | | Same as the other binary operators: - legalize to 32 bits - map to GPRs - select ORRrr thanks to TableGen'erated code llvm-svn: 304890
* [ARM] GlobalISel: Support G_ANDDiana Picus2017-06-071-1/+1
| | | | | | | | | This is identical to the support for the other binary operators: - widen to s32 - map into GPR - select ANDrr (via TableGen'erated code) llvm-svn: 304885
* [ARM][GlobalISel] Legalize narrow scalar ops by wideningDiana Picus2017-05-111-3/+5
| | | | | | | | | | | | | | This is the same as r292827 for AArch64: we widen 8- and 16-bit ADD, SUB and MUL to 32 bits since we only have TableGen patterns for 32 bits. See the commit message for r292827 for more details. At this point we could just remove some of the tests for regbankselect and instruction-select, since we're not going to see any narrow operations at those levels anymore. Instead I decided to update them with G_ANYEXT/G_TRUNC operations, so we can validate the full sequences generated by the legalizer. llvm-svn: 302782
* [ARM] GlobalISel: Legalize s8 and s16 G_(S|U)DIVDiana Picus2017-04-241-0/+52
| | | | | | | | | | | | | | We have to widen the operands to 32 bits and then we can either use hardware division if it is available or lower to a libcall otherwise. At the moment it is not enough to set the Legalizer action to WidenScalar, since for libcalls it won't know what to do (it won't be able to find what size to widen to, because it will find Libcall and not Legal for 32 bits). To hack around this limitation, we request Custom lowering, and as part of that we widen first and then we run another legalizeInstrStep on the widened DIV. llvm-svn: 301166
* [ARM] GlobalISel: Support G_(S|U)DIV for s32Diana Picus2017-04-241-0/+7
| | | | | | | | | Add support for both targets with hardware division and without. For hardware division we have to add support throughout the pipeline (legalizer, reg bank select, instruction select). For targets without hardware division, we only need to mark it as a libcall. llvm-svn: 301164
* [ARM] GlobalISel: Add support for G_MULDiana Picus2017-04-191-1/+1
| | | | | | | | Support G_MUL, very similar to G_ADD and G_SUB. The only difference is in the instruction selector, where we have to select either MUL or MULv5 depending on the target. llvm-svn: 300665
* [ARM] GlobalISel: Add support for G_SUBDiana Picus2017-04-181-2/+3
| | | | | | | Support G_SUB throughout the GlobalISel pipeline. It is exactly the same as G_ADD, nothing fancy. llvm-svn: 300546
* GlobalISel: Allow legalizing G_FADD to a libcallDiana Picus2017-04-111-0/+3
| | | | | | | | | Use the same handling in the generic legalizer code as for the other libcalls (G_FREM, G_FPOW). Enable it on ARM for float and double so we can test it. llvm-svn: 299931
* [ARM] GlobalISel: Support G_FPOW for float and doubleDiana Picus2017-04-101-2/+3
| | | | | | Legalize to a libcall. llvm-svn: 299841
* [ARM] GlobalISel: Support frem for 64-bit valuesDiana Picus2017-04-071-0/+1
| | | | | | Legalize to a libcall. llvm-svn: 299756
* [ARM] GlobalISel: Support frem for 32-bit valuesDiana Picus2017-04-071-1/+3
| | | | | | | | Legalize to a libcall. On this occasion, also start allowing soft float subtargets. For the moment G_FREM is the only legal floating point operation for them. llvm-svn: 299753
* [ARM] GlobalISel: Legalize 32-bit constantsDiana Picus2017-02-281-0/+2
| | | | llvm-svn: 296468
* [ARM] GlobalISel: Legalize G_GEP with 32-bit offsetsDiana Picus2017-02-281-0/+3
| | | | | | | At the moment we're only interested in GEPs for putting call parameters on the stack, so we'll stick to 32-bit offsets. llvm-svn: 296452
* [ARM] GlobalISel: Legalize storesDiana Picus2017-02-241-3/+6
| | | | | | Allow the same types that we allow for loads. llvm-svn: 296108
* Revert "[ARM] GlobalISel: Legalize stores"Diana Picus2017-02-241-5/+3
| | | | | | This reverts commit r296103 because the test broke on one of the bots. Sorry! llvm-svn: 296104
* [ARM] GlobalISel: Legalize storesDiana Picus2017-02-241-3/+5
| | | | | | Allow the same types that we allow for loads. llvm-svn: 296103
* [ARM] GlobalISel: Use Subtarget in LegalizerDiana Picus2017-02-171-10/+8
| | | | | | | | Start using the Subtarget to make decisions about what's legal. In particular, we only mark floating point operations as legal if we have VFP2, which is something we should've done from the very start. llvm-svn: 295439
* [ARM] GlobalISel: Legalize 64-bit G_FADD and G_LOADDiana Picus2017-02-161-0/+7
| | | | | | | | For now we just mark them as legal all the time and let the other passes bail out if they can't handle it. In the future, we'll want to move more of the brains into the legalizer. llvm-svn: 295300
* [ARM] GlobalISel: Add FPR reg bankDiana Picus2017-02-081-0/+4
| | | | | | | | | | | | | Add a register bank for floating point values and select simple instructions using them (add, copies from GPR). This assumes that the hardware can cope with a single precision add (VADDS) instruction, so the legalizer will treat G_FADD as legal and the instruction selector will refuse to select if the hardware doesn't support it. In the future we'll want to be more careful about this, and legalize to libcalls if we have to use soft float. llvm-svn: 294442
* [ARM] GlobalISel: Legalize loading pointersDiana Picus2017-02-021-1/+1
| | | | | | | Make it legal to load pointer values. Also check that pointers are assigned to the GPR reg bank by default. llvm-svn: 293886
* [ARM][LegalizerInfo] Specify the type of the opcode.Quentin Colombet2017-01-271-1/+1
| | | | | | | This is to fix the win7 bot that does not seem to be very good at infering the type when it gets used in an initiliazer list. llvm-svn: 293248
* [ARM] GlobalISel: Load i1, i8 and i16 args from stackDiana Picus2017-01-261-1/+2
| | | | | | | | | | | | | Add support for loading i1, i8 and i16 arguments from the stack, with or without the ABI extension flags. When the ABI extension flags are present, we load a 4-byte value, otherwise we preserve the size of the load and let the instruction selector replace it with a LDRB/LDRH. This generates the same thing as DAGISel. Differential Revision: https://reviews.llvm.org/D27803 llvm-svn: 293163
* [ARM] GlobalISel: Support i1 add and ABI extensionsDiana Picus2017-01-251-2/+3
| | | | | | | | | | | Add support for: * i1 add * i1 function arguments, if passed through registers * i1 returns, with ABI signext/zeroext Differential Revision: https://reviews.llvm.org/D27706 llvm-svn: 293035
* [ARM] GlobalISel: Support i8/i16 ABI extensionsDiana Picus2017-01-251-0/+6
| | | | | | | | | | | | | At the moment, this means supporting the signext/zeroext attribute on the return type of the function. For function arguments, signext/zeroext should be handled by the caller, so there's nothing for us to do until we start lowering calls. Note that this does not include support for other extensions (i8 to i16), those will be added later. Differential Revision: https://reviews.llvm.org/D27705 llvm-svn: 293034
* [ARM] GlobalISel: Allow i8 and i16 addsDiana Picus2016-12-191-1/+6
| | | | | | | | | Teach the instruction selector and legalizer that it's ok to have adds with 8 or 16-bit integers. This is the second part of https://reviews.llvm.org/D27704 llvm-svn: 290105
* [ARM] GlobalISel: Support loading from the stackDiana Picus2016-12-191-0/+6
| | | | | | | | | | Add support for selecting simple G_LOAD and G_FRAME_INDEX instructions (32-bit scalars only). This will be useful for functions that need to pass arguments on the stack. First part of https://reviews.llvm.org/D27195. llvm-svn: 290096
* [ARM] GlobalISel: Select add i32, i32Diana Picus2016-12-161-0/+5
| | | | | | | | | | | | | Add the minimal support necessary to select a function that returns the sum of two i32 values. This includes some support for argument/return lowering of i32 values through registers, as well as the handling of copy and add instructions throughout the GlobalISel pipeline. Differential Revision: https://reviews.llvm.org/D26677 llvm-svn: 289940
* [ARM] Add plumbing for GlobalISelDiana Picus2016-11-111-0/+28
Add GlobalISel skeleton, up to the point where we can select a ret void. llvm-svn: 286573
OpenPOWER on IntegriCloud