summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp
Commit message (Collapse)AuthorAgeFilesLines
* [ARM GlobalISel] 64-bit memops should be alignedDiana Picus2019-03-251-9/+10
| | | | | | | | | | We currently use only VLDR/VSTR for all 64-bit loads/stores, so the memory operands must be word-aligned. Mark aligned operations as legal and narrow non-aligned ones to 32 bits. While we're here, also mark non-power-of-2 loads/stores as unsupported. llvm-svn: 356872
* [ARM GlobalISel] Support G_CTLZ for Thumb2Diana Picus2019-03-011-7/+0
| | | | | | Same as ARM mode but with different opcode. llvm-svn: 355191
* [ARM GlobalISel] Support global variables for Thumb2Diana Picus2019-02-281-2/+1
| | | | | | | | | | | | | | | | | | | Add the same level of support as for ARM mode (i.e. still no TLS support). In most cases, it is sufficient to replace the opcodes with the t2-equivalent, but there are some idiosyncrasies that I decided to preserve because I don't understand the full implications: * For ARM we use LDRi12 to load from constant pools, but for Thumb we use t2LDRpci (I'm not sure if the ideal would be to use t2LDRi12 for Thumb as well, or to use LDRcp for ARM). * For Thumb we don't have an equivalent for MOV|LDRLIT_ga_pcrel_ldr, so we have to generate MOV|LDRLIT_ga_pcrel plus a load from GOT. The tests are in separate files because they're hard enough to read even without doubling the number of checks. llvm-svn: 355077
* [ARM GlobalISel] Support floating point for Thumb2Diana Picus2019-02-221-29/+29
| | | | | | | | | | | | | | | This is exactly the same as arm mode, so for the instruction selector tests we just extract them to a new file and run with the same checks for both arm and thumb mode. For the legalizer we need to update the tests for soft float a bit, but only because BL and tBL are slightly different. We could be pedantic and check that we get a well-formed BL for arm mode and a tBL for thumb, but for the purposes of the legalizer test it's sufficient to just skip over the predicate operands in the checks. Also note that we have the pedantic checks in the divmod test, so we're covered. llvm-svn: 354665
* [ARM GlobalISel] Support G_FRAME_INDEX for Thumb2Diana Picus2019-02-211-1/+2
| | | | | | Same as arm mode. llvm-svn: 354579
* [ARM GlobalISel] Support G_PHI for Thumb2Diana Picus2019-02-191-5/+5
| | | | | | Same as arm mode. llvm-svn: 354310
* [ARM GlobalISel] Support branches for Thumb2Diana Picus2019-02-151-2/+2
| | | | | | Just like arm mode, but with different opcodes. llvm-svn: 354113
* GlobalISel: Add alignment to LegalityQuery MMOsMatt Arsenault2019-02-141-6/+6
| | | | | | | This allows targets to specify the minimum alignment required for the load/store. llvm-svn: 354071
* [ARM GlobalISel] Support G_SELECT for Thumb2Diana Picus2019-02-131-3/+3
| | | | | | Same as arm mode, but slightly different opcodes. llvm-svn: 353938
* [ARM GlobalISel] Support G_ICMP for Thumb2Diana Picus2019-02-071-4/+4
| | | | | | | Mark as legal and use the t2* equivalents of the arm mode instructions, e.g. t2CMPrr instead of plain CMPrr. llvm-svn: 353392
* [ARM GlobalISel] Support G_GEP for Thumb2Diana Picus2019-02-051-2/+2
| | | | | | Same as ARM, but use a different opcode in the instruction selection. llvm-svn: 353151
* GlobalISel: Allow bitcount ops to have different result typeMatt Arsenault2019-01-311-4/+8
| | | | | | For AMDGPU the result is always 32-bit for 64-bit inputs. llvm-svn: 352717
* [ARM GlobalISel] Support integer division for Thumb2Diana Picus2019-01-281-19/+21
| | | | | | | | | Support G_SDIV, G_UDIV, G_SREM and G_UREM. The only significant difference between arm and thumb mode is that we need to check a different subtarget feature. llvm-svn: 352346
* [ARM GlobalISel] Support shifts for Thumb2Diana Picus2019-01-251-4/+4
| | | | | | | | | | Same as ARM. On this occasion we split some of the instruction select tests for more complicated instructions into their own files, so we can reuse them for ARM and Thumb mode. Likewise for the legalizer tests. llvm-svn: 352188
* [ARM GlobalISel] Remove rebase artifact from r351882. NFCDiana Picus2019-01-251-3/+0
| | | | | | | r351882 introduced some superfluous calls to mark G_INTTOPTR and G_PTRTOINT as legal (looks like a rebase mishap). Remove them. llvm-svn: 352187
* GlobalISel: Allow shift amount to be a different typeMatt Arsenault2019-01-221-1/+6
| | | | | | | | | For AMDGPU the shift amount is never 64-bit, and this needs to use a 32-bit shift. X86 uses i8, but seemed to be hacking around this before. llvm-svn: 351882
* Update the file headers across all of the LLVM projects in the monorepoChandler Carruth2019-01-191-4/+3
| | | | | | | | | | | | | | | | | to reflect the new license. We understand that people may be surprised that we're moving the header entirely to discuss the new license. We checked this carefully with the Foundation's lawyer and we believe this is the correct approach. Essentially, all code in the project is now made available by the LLVM project under our new license, so you will see that the license headers include that license only. Some of our contributors have contributed code under our old license, and accordingly, we have retained a copy of our old license notice in the top-level files in each project and repository. llvm-svn: 351636
* [ARM GlobalISel] Support G_CONSTANT for Thumb2Diana Picus2018-12-191-4/+4
| | | | | | | | | | | All we have to do is mark it as legal. This allows us to select a lot of new patterns handled by TableGen. This patch adds tests for them and splits up the existing test file for binary operators into 2 files, one for arithmetic ops and one for logical ones. llvm-svn: 349610
* [ARM GlobalISel] Thumb2: casts between int and ptrDiana Picus2018-12-141-3/+3
| | | | | | Mark as legal and add tests. Nothing special to do. llvm-svn: 349147
* [ARM GlobalISel] Allow simple binary ops in Thumb2Diana Picus2018-12-141-4/+4
| | | | | | | | | | | Mark G_ADD, G_SUB, G_MUL, G_AND, G_OR and G_XOR as legal for both ARM and Thumb2. Extract the legalizer tests for these opcodes into another file. Add tests for the instruction selector. llvm-svn: 349142
* [ARM GlobalISel] Support exts and truncs for Thumb2Diana Picus2018-12-131-3/+3
| | | | | | | | | | | Mark G_SEXT, G_ZEXT and G_ANYEXT to 32 bits as legal and add support for them in the instruction selector. This uses handwritten code again because the patterns that are generated with TableGen are tuned for what the DAG combiner would produce and not for simple sext/zext nodes. Luckily, we only need to update the opcodes to use the Thumb2 variants, everything else can be reused from ARM. llvm-svn: 349026
* [ARM GlobalISel] Select load/store for Thumb2Diana Picus2018-12-121-4/+18
| | | | | | | | | | | | Unfortunately we can't use TableGen for this because it doesn't yet support predicates on the source pattern root. Therefore, add a bit of handwritten code to the instruction selector to handle the most basic cases. Also mark them as legal and extract their legalizer test cases to a new test file. llvm-svn: 348920
* [ARM GlobalISel] Nothing is legal for ThumbDiana Picus2018-12-061-0/+7
| | | | | | | | | | | | | | ...yet! A lot of the current code should be shared for arm and thumb mode, but until we add tests and work out some of the details (e.g. checking the correct subtarget feature for G_SDIV) it's safer to bail out as early as possible for thumb targets. This should have arguably been part of r348347, which allowed Thumb functions to be handled by the IR Translator. llvm-svn: 348472
* [GISel]: Provide standard interface to observe changes in GISel passesAditya Nandakumar2018-12-051-1/+2
| | | | | | | | | | | | | https://reviews.llvm.org/D54980 This provides a standard API across GISel passes to observe and notify passes about changes (insertions/deletions/mutations) to MachineInstrs. This patch also removes the recordInsertion method in MachineIRBuilder and instead provides method to setObserver. Reviewed by: vkeles. llvm-svn: 348406
* [ARM GlobalISel] Support G_CTLZ and G_CTLZ_ZERO_UNDEFDiana Picus2018-11-261-0/+16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | We can now select CLZ via the TableGen'erated code, so support G_CTLZ and G_CTLZ_ZERO_UNDEF throughout the pipeline for types <= s32. Legalizer: If the CLZ instruction is available, use it for both G_CTLZ and G_CTLZ_ZERO_UNDEF. Otherwise, use a libcall for G_CTLZ_ZERO_UNDEF and lower G_CTLZ in terms of it. In order to achieve this we need to add support to the LegalizerHelper for the legalization of G_CTLZ_ZERO_UNDEF for s32 as a libcall (__clzsi2). We also need to allow lowering of G_CTLZ in terms of G_CTLZ_ZERO_UNDEF if that is supported as a libcall, as opposed to just if it is Legal or Custom. Due to a minor refactoring of the helper function in charge of this, we will also allow the same behaviour for G_CTTZ and G_CTPOP. This is not going to be a problem in practice since we don't yet have support for treating G_CTTZ and G_CTPOP as libcalls (not even in DAGISel). Reg bank select: Map G_CTLZ to GPR. G_CTLZ_ZERO_UNDEF should not make it to this point. Instruction select: Nothing to do. llvm-svn: 347545
* [GlobalISel][ARM] LegalizerInfo verifier: Adding LegalizerInfo::verify(...) ↵Roman Tereshin2018-05-311-3/+5
| | | | | | | | | | | | call and fixing bugs exposed Reviewers: aemerson, qcolombet Reviewed By: qcolombet Differential Revision: https://reviews.llvm.org/D46339 llvm-svn: 333663
* [IR][CodeGen] Remove dependency on EVT from IR/Function.cpp. Move EVT to ↵Craig Topper2018-03-291-1/+1
| | | | | | | | | | | | CodeGen layer. Currently EVT is in the IR layer only because of Function.cpp needing a very small piece of the functionality of EVT::getEVTString(). The rest of EVT is used in codegen making CodeGen a better place for it. The previous code converted a Type* to EVT and then called getEVTString. This was only expected to handle the primitive types from Type*. Since there only a few primitive types, we can just print them as strings directly. Differential Revision: https://reviews.llvm.org/D45017 llvm-svn: 328806
* Fix layering by moving ValueTypes.h from CodeGen to IRDavid Blaikie2018-03-231-1/+1
| | | | | | ValueTypes.h is implemented in IR already. llvm-svn: 328397
* Fix formatting for r323876. NFCDiana Picus2018-01-311-5/+5
| | | | llvm-svn: 323878
* [ARM GlobalISel] Modernize LegalizerInfo. NFCIDiana Picus2018-01-311-126/+68
| | | | | | | | | Start using the new LegalizerInfo API introduced in r323681. Keep the old API for opcodes that need Lowering in some circumstances (G_FNEG and G_UREM/G_SREM). llvm-svn: 323876
* [ARM GlobalISel] Legalize G_SITOFP and G_UITOFPDiana Picus2018-01-301-0/+11
| | | | | | | | Legal if we have hardware support, libcall otherwise. Also add supporting code to the legalizer helper for libcalls. llvm-svn: 323730
* [ARM GlobalISel] Legalize G_FPTOSI and G_FPTOUIDiana Picus2018-01-301-3/+12
| | | | | | | | | Legal if we have hardware support for floating point, libcalls otherwise. Also add the necessary support for libcalls in the legalizer helper. llvm-svn: 323726
* [ARM][GISel] PR35965 Constrain RegClasses of nested instructions built from ↵Daniel Sanders2018-01-291-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Dst Pattern Summary: Apparently, we missed on constraining register classes of VReg-operands of all the instructions built from a destination pattern but the root (top-level) one. The issue exposed itself while selecting G_FPTOSI for armv7: the corresponding pattern generates VTOSIZS wrapped into COPY_TO_REGCLASS, so top-level COPY_TO_REGCLASS gets properly constrained, while nested VTOSIZS (or rather its destination virtual register to be exact) does not. Fixing this by issuing GIR_ConstrainSelectedInstOperands for every nested GIR_BuildMI. https://bugs.llvm.org/show_bug.cgi?id=35965 rdar://problem/36886530 Patch by Roman Tereshin Reviewers: dsanders, qcolombet, rovka, bogner, aditya_nandakumar, volkan Reviewed By: dsanders, qcolombet, rovka Subscribers: aemerson, javed.absar, kristof.beyls, llvm-commits Differential Revision: https://reviews.llvm.org/D42565 llvm-svn: 323692
* [globalisel] Make LegalizerInfo::LegalizeAction available outside of ↵Daniel Sanders2018-01-291-10/+12
| | | | | | | | | | | | LegalizerInfo. NFC Summary: The improvements to the LegalizerInfo discussed in D42244 require that LegalizerInfo::LegalizeAction be available for use in other classes. As such, it needs to be moved out of LegalizerInfo. This has been done separately to the next patch to minimize the noise in that patch. llvm-svn: 323669
* [ARM GlobalISel] Rename local variable. NFCDiana Picus2018-01-171-2/+2
| | | | llvm-svn: 322667
* [ARM GlobalISel] Legalize G_FPEXT and G_FPTRUNCDiana Picus2018-01-171-0/+12
| | | | | | | | | | | Mark G_FPEXT and G_FPTRUNC as legal or libcall, depending on hardware support, but only for conversions between float and double. Also add the necessary boilerplate so that the LegalizerHelper can introduce the required libcalls. This also works only for float and double, but isn't too difficult to extend when the need arises. llvm-svn: 322651
* [ARM GlobalISel] Legalize G_FMADiana Picus2018-01-121-0/+7
| | | | | | | | | | | For hard float with VFP4, it is legal. Otherwise, we use libcalls. This needs a bit of support in the LegalizerHelper for soft float because we didn't handle G_FMA libcalls yet. The support is trivial, as the only difference between G_FMA and other libcalls that we already handle is that it has 3 input operands rather than just 2. llvm-svn: 322366
* [ARM GlobalISel] Legalize G_FNEG for s32 and s64Diana Picus2018-01-101-1/+2
| | | | | | | | | | | | | For hard float, it is legal. For soft float, we need to lower to 0 - x first, and then we can use the libcall for G_FSUB. This is undoing some of the canonicalization performed by the IRTranslator (which introduces G_FNEG when it sees a 0 - x). Ideally, that canonicalization would be performed by a pre-legalizer pass that would allow targets to opt out of this behaviour rather than dance around it in the legalizer. llvm-svn: 322168
* [ARM GlobalISel] Legalize s32/s64 G_FCONSTANTDiana Picus2018-01-101-3/+14
| | | | | | | | Legal for hard float. Change to G_CONSTANT for soft float (but preserve the binary representation). llvm-svn: 322164
* [ARM GlobalISel] Legalize G_CONSTANT for scalars > 32 bitsDiana Picus2018-01-101-3/+4
| | | | | | Make G_CONSTANT narrow for any scalars larger than 32 bits. llvm-svn: 322162
* [ARM GlobalISel] Legalize scalar G_PHIDiana Picus2018-01-041-0/+7
| | | | | | | Mark G_PHI as Legal for s32 and p0, and also for s64 if we have hard float. Widen any smaller types. llvm-svn: 321795
* [ARM GlobalISel] Support G_INTTOPTR and G_PTRTOINT for s32Diana Picus2017-12-221-0/+6
| | | | | | | Mark conversions between pointers and 32-bit scalars as legal, map them to the GPR and select to a simple COPY. llvm-svn: 321356
* [ARM GlobalISel] Support pointer constantsDiana Picus2017-12-221-0/+1
| | | | | | | | | | Pointer constants are pretty rare, since we usually represent them as integer constants and then cast to pointer. One notable exception is the null pointer constant, which is represented directly as a G_CONSTANT 0 with pointer type. Mark it as legal and make sure it is selected like any other integer constant. llvm-svn: 321354
* [ARM GlobalISel] Fix G_(UN)MERGE_VALUES handling after r319524Diana Picus2017-12-181-9/+5
| | | | | | | | | r319524 has made more G_MERGE_VALUES/G_UNMERGE_VALUES pairs legal than are supported by the rest of the pipeline. Restrict that to only the cases that we can currently handle: packing 32-bit values into 64-bit ones, when we have hardware FP. llvm-svn: 320980
* MachineFunction: Return reference from getFunction(); NFCMatthias Braun2017-12-151-2/+2
| | | | | | The Function can never be nullptr so we can return a reference. llvm-svn: 320884
* GlobalISel: Enable the legalization of G_MERGE_VALUES and G_UNMERGE_VALUESVolkan Keles2017-12-011-0/+9
| | | | | | | | | | | | | | Summary: LegalizerInfo assumes all G_MERGE_VALUES and G_UNMERGE_VALUES instructions are legal, so it is not possible to legalize vector operations on illegal vector types. This patch fixes the problem by removing the related check and adding default actions for G_MERGE_VALUES and G_UNMERGE_VALUES. Reviewers: qcolombet, ab, dsanders, aditya_nandakumar, t.p.northover, kristof.beyls Reviewed By: dsanders Subscribers: rovka, javed.absar, igorb, llvm-commits Differential Revision: https://reviews.llvm.org/D39823 llvm-svn: 319524
* [ARM GlobalISel] Support G_FDIV for s32 and s64Diana Picus2017-11-231-2/+2
| | | | | | | | | | | | TableGen already generates code for selecting a G_FDIV, so we only need to add a test. For the legalizer and reg bank select, we do the same thing as for the other floating point binary operations: either mark as legal if we have a FP unit or lower to a libcall, and map to the floating point registers. llvm-svn: 318915
* [ARM GlobalISel] Support G_FMUL for s32 and s64Diana Picus2017-11-231-2/+2
| | | | | | | | | | | TableGen already generates code for selecting a G_FMUL, so we only need to add a test for that part. For the legalizer and reg bank select, we do the same thing as the other floating point binary operators: either mark as legal if we have a FP unit or lower to a libcall, and map to the floating point registers. llvm-svn: 318910
* Fix a bunch more layering of CodeGen headers that are in TargetDavid Blaikie2017-11-171-1/+1
| | | | | | | | All these headers already depend on CodeGen headers so moving them into CodeGen fixes the layering (since CodeGen depends on Target, not the other way around). llvm-svn: 318490
* [GlobalISel] Enable legalizing non-power-of-2 sized types.Kristof Beyls2017-11-071-13/+58
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This changes the interface of how targets describe how to legalize, see the below description. 1. Interface for targets to describe how to legalize. In GlobalISel, the API in the LegalizerInfo class is the main interface for targets to specify which types are legal for which operations, and what to do to turn illegal type/operation combinations into legal ones. For each operation the type sizes that can be legalized without having to change the size of the type are specified with a call to setAction. This isn't different to how GlobalISel worked before. For example, for a target that supports 32 and 64 bit adds natively: for (auto Ty : {s32, s64}) setAction({G_ADD, 0, s32}, Legal); or for a target that needs a library call for a 32 bit division: setAction({G_SDIV, s32}, Libcall); The main conceptual change to the LegalizerInfo API, is in specifying how to legalize the type sizes for which a change of size is needed. For example, in the above example, how to specify how all types from i1 to i8388607 (apart from s32 and s64 which are legal) need to be legalized and expressed in terms of operations on the available legal sizes (again, i32 and i64 in this case). Before, the implementation only allowed specifying power-of-2-sized types (e.g. setAction({G_ADD, 0, s128}, NarrowScalar). A worse limitation was that if you'd wanted to specify how to legalize all the sized types as allowed by the LLVM-IR LangRef, i1 to i8388607, you'd have to call setAction 8388607-3 times and probably would need a lot of memory to store all of these specifications. Instead, the legalization actions that need to change the size of the type are specified now using a "SizeChangeStrategy". For example: setLegalizeScalarToDifferentSizeStrategy( G_ADD, 0, widenToLargerAndNarrowToLargest); This example indicates that for type sizes for which there is a larger size that can be legalized towards, do it by Widening the size. For example, G_ADD on s17 will be legalized by first doing WidenScalar to make it s32, after which it's legal. The "NarrowToLargest" indicates what to do if there is no larger size that can be legalized towards. E.g. G_ADD on s92 will be legalized by doing NarrowScalar to s64. Another example, taken from the ARM backend is: for (unsigned Op : {G_SDIV, G_UDIV}) { setLegalizeScalarToDifferentSizeStrategy(Op, 0, widenToLargerTypesUnsupportedOtherwise); if (ST.hasDivideInARMMode()) setAction({Op, s32}, Legal); else setAction({Op, s32}, Libcall); } For this example, G_SDIV on s8, on a target without a divide instruction, would be legalized by first doing action (WidenScalar, s32), followed by (Libcall, s32). The same principle is also followed for when the number of vector lanes on vector data types need to be changed, e.g.: setAction({G_ADD, LLT::vector(8, 8)}, LegalizerInfo::Legal); setAction({G_ADD, LLT::vector(16, 8)}, LegalizerInfo::Legal); setAction({G_ADD, LLT::vector(4, 16)}, LegalizerInfo::Legal); setAction({G_ADD, LLT::vector(8, 16)}, LegalizerInfo::Legal); setAction({G_ADD, LLT::vector(2, 32)}, LegalizerInfo::Legal); setAction({G_ADD, LLT::vector(4, 32)}, LegalizerInfo::Legal); setLegalizeVectorElementToDifferentSizeStrategy( G_ADD, 0, widenToLargerTypesUnsupportedOtherwise); As currently implemented here, vector types are legalized by first making the vector element size legal, followed by then making the number of lanes legal. The strategy to follow in the first step is set by a call to setLegalizeVectorElementToDifferentSizeStrategy, see example above. The strategy followed in the second step "moreToWiderTypesAndLessToWidest" (see code for its definition), indicating that vectors are widened to more elements so they map to natively supported vector widths, or when there isn't a legal wider vector, split the vector to map it to the widest vector supported. Therefore, for the above specification, some example legalizations are: * getAction({G_ADD, LLT::vector(3, 3)}) returns {WidenScalar, LLT::vector(3, 8)} * getAction({G_ADD, LLT::vector(3, 8)}) then returns {MoreElements, LLT::vector(8, 8)} * getAction({G_ADD, LLT::vector(20, 8)}) returns {FewerElements, LLT::vector(16, 8)} 2. Key implementation aspects. How to legalize a specific (operation, type index, size) tuple is represented by mapping intervals of integers representing a range of size types to an action to take, e.g.: setScalarAction({G_ADD, LLT:scalar(1)}, {{1, WidenScalar}, // bit sizes [ 1, 31[ {32, Legal}, // bit sizes [32, 33[ {33, WidenScalar}, // bit sizes [33, 64[ {64, Legal}, // bit sizes [64, 65[ {65, NarrowScalar} // bit sizes [65, +inf[ }); Please note that most of the code to do the actual lowering of non-power-of-2 sized types is currently missing, this is just trying to make it possible for targets to specify what is legal, and how non-legal types should be legalized. Probably quite a bit of further work is needed in the actual legalizing and the other passes in GlobalISel to support non-power-of-2 sized types. I hope the documentation in LegalizerInfo.h and the examples provided in the various {Target}LegalizerInfo.cpp and LegalizerInfoTest.cpp explains well enough how this is meant to be used. This drops the need for LLT::{half,double}...Size(). Differential Revision: https://reviews.llvm.org/D30529 llvm-svn: 317560
OpenPOWER on IntegriCloud