summaryrefslogtreecommitdiffstats
path: root/llvm/test/CodeGen/ARM/GlobalISel
Commit message (Collapse)AuthorAgeFilesLines
...
* [ARM] GlobalISel: Support G_(S|U)REM for s8 and s16Diana Picus2017-07-182-0/+226
| | | | | | | Widen to s32, and then do whatever Lowering/Custom/Libcall action the subtarget wants. llvm-svn: 308285
* [ARM] GlobalISel: Support G_BRCONDDiana Picus2017-07-144-10/+102
| | | | | | | | | | | | Insert a TSTri to set the flags and a Bcc to branch based on their values. This is a bit inefficient in the (common) cases where the condition for the branch comes from a compare right before the branch, since we set the flags both as part of the compare lowering and as part of the branch lowering. We're going to live with that until we settle on a principled way to handle this kind of situation, which occurs with other patterns as well (combines might be the way forward here). llvm-svn: 308009
* [ARM] GlobalISel: Support G_BRDiana Picus2017-07-133-0/+52
| | | | | | | | This boils down to not crashing in reg bank select due to the lack of register operands on this instruction, and adding some tests. The instruction selection is already covered by the TableGen'erated code. llvm-svn: 307904
* [ARM] GlobalISel: Select s64 G_FCMPDiana Picus2017-07-121-0/+605
| | | | | | | Very similar to how we select s32 G_FCMP, the only thing that is different is the exact opcodes that we use. llvm-svn: 307763
* [ARM] GlobalISel: Tighten G_FCMP selection test. NFCDiana Picus2017-07-111-68/+68
| | | | | | | | Use CHECK-NEXT for the comparison sequence, to make sure we don't get any unexpected instructions in the middle of our flag manipulation efforts. llvm-svn: 307656
* [ARM] GlobalISel: Add reg mapping for s64 G_FCMPDiana Picus2017-07-111-0/+29
| | | | | | Map the result into GPR and the operands into FPR. llvm-svn: 307653
* [ARM] GlobalISel: Tighten legalizer tests. NFCDiana Picus2017-07-113-0/+110
| | | | | | | | | | | | | | Make sure that all the legalizer tests where the original instruction needs to be removed check for the removal. We do this by adding CHECK-NOT lines before and after the replacement sequence. This won't catch pathological cases where the instruction remains somewhere in the middle of the instruction sequence that's supposed to replace it, but hopefully that won't occur in practice (since ideally we'd be setting the insert point for the new instruction sequence either before or after the original instruction and not fiddle with it while building the sequence). llvm-svn: 307647
* [ARM] GlobalISel: Fix oversight in G_FCMP legalizationDiana Picus2017-07-111-0/+8
| | | | | | | We used to forget to erase the original instruction when replacing a G_FCMP true/false. Fix this bug and make sure the tests check for it. llvm-svn: 307639
* [ARM] GlobalISel: Legalize s64 G_FCMPDiana Picus2017-07-111-0/+878
| | | | | | Same as the s32 version, for both hard and soft float. llvm-svn: 307633
* [ARM] GlobalISel: Select hard G_FCMP for s32Diana Picus2017-07-072-0/+637
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We lower to a sequence consisting of: - MOVi 0 into a register - VCMPS to do the actual comparison and set the VFP flags - FMSTAT to move the flags out of the VFP unit - MOVCCi to either use the "zero register" that we have previously set with the MOVi, or move 1 into the result register, based on the values of the flags As was the case with soft-float, for some predicates (one, ueq) we actually need two comparisons instead of just one. When that happens, we generate two VCMPS-FMSTAT-MOVCCi sequences and chain them by means of using the result of the first MOVCCi as the "zero register" for the second one. This is a bit overkill, since one comparison followed by two non-flag-setting conditional moves should be enough. In any case, the backend manages to CSE one of the comparisons away so it doesn't matter much. Note that unlike SelectionDAG and FastISel, we always use VCMPS, and not VCMPES. This makes the code a lot simpler, and it also seems correct since the LLVM Lang Ref defines simple true/false returns if the operands are QNaN's. For SNaN's, even VCMPS throws an Invalid Operand exception, so they won't be slipping through unnoticed. Implementation-wise, this introduces a template so we can share the same code that we use for handling integer comparisons, since the only differences are in the details (exact opcodes to be used etc). Hopefully this will be easy to extend to s64 G_FCMP. llvm-svn: 307365
* [ARM] GlobalISel: Map s32 G_FCMP in reg bank selectDiana Picus2017-07-061-0/+29
| | | | | | Map hard G_FCMP operands to FPR and the result to GPR. llvm-svn: 307245
* [ARM] GlobalISel: Legalize G_FCMP for s32Diana Picus2017-07-061-0/+654
| | | | | | | | | | | | | | | | | | | | | 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/+15
| | | | | | Get the legalizer to widen small constants. llvm-svn: 307239
* GlobalISel: add G_IMPLICIT_DEF instruction.Tim Northover2017-06-301-5/+5
| | | | | | | | | It looks like there are two target-independent but not GISel instructions that need legalization, IMPLICIT_DEF and PHI. These are already anomalies since their operands have important LLTs attached, so to make things more uniform it seems like a good idea to add generic variants. Starting with G_IMPLICIT_DEF. llvm-svn: 306875
* [ARM] GlobalISel: Support G_SELECT for pointersDiana Picus2017-06-273-3/+76
| | | | | | 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-274-0/+106
| | | | | | | | | | * 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
* GlobalISel: convert buildSequence to use non-deprecated instructions.Tim Northover2017-06-231-2/+5
| | | | | | | | G_SEQUENCE is going away soon so as a first step the MachineIRBuilder needs to be taught how to emulate it with alternatives. We use G_MERGE_VALUES where possible, and a sequence of G_INSERTs if not. llvm-svn: 306119
* [ARM] GlobalISel: Support G_ICMP for s8 and s16Diana Picus2017-06-192-3/+74
| | | | | | Widen to s32 (like all other binary ops). llvm-svn: 305683
* [ARM] GlobalISel: Support G_ICMP for i32 and pointersDiana Picus2017-06-194-0/+457
| | | | | | | | | | | | | | 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-152-0/+96
| | | | | | | | | | | | | | | | | | 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: Lower only homogeneous struct argsDiana Picus2017-06-152-158/+45
| | | | | | | | | | | | | Lowering mixed struct args, params and returns used G_INSERT, which is a bit more convoluted to support through the entire pipeline. Since they don't occur that often in practice, it's probably wiser to leave them out until later. Meanwhile, we can lower homogeneous structs using G_MERGE_VALUES, which has good support in the legalizer. These occur e.g. as the return of __aeabi_idivmod, so it's nice to be able to support them. llvm-svn: 305458
* [ARM] GlobalISel: Add more tests. NFCDiana Picus2017-06-081-0/+149
| | | | | | | | Add a couple of tests to increase coverage for the TableGen'erated code, in particular for rules where 2 generic instructions may be combined into a single machine instruction. llvm-svn: 304971
* [ARM] GlobalISel: Purge G_SEQUENCEDiana Picus2017-06-075-64/+46
| | | | | | | | | | | | | | | | | According to the commit message from r296921, G_MERGE_VALUES and G_INSERT are to be preferred over G_SEQUENCE. Therefore, stop generating G_SEQUENCE in the ARM backend and remove the code dealing with it. This boils down to the code breaking up double values for the soft float calling convention. Use G_MERGE_VALUES + G_UNMERGE_VALUES instead of G_SEQUENCE + G_EXTRACT for it. This maps very nicely to VMOVDRR + VMOVRRD and simplifies the code in the instruction selector. There's one occurence of G_SEQUENCE left in arm-irtranslator.ll, but that is part of the target-independent code for translating constant structs. Therefore, it is beyond the scope of this commit. llvm-svn: 304902
* [ARM] GlobalISel: Support G_XORDiana Picus2017-06-074-0/+168
| | | | | | | | | 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-074-0/+168
| | | | | | | | | 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-074-0/+170
| | | | | | | | | 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
* Vivek Pandya2017-06-064-111/+111
| | | | | | | | | | | | [Improve CodeGen Testing] This patch renables MIRPrinter print fields which have value equal to its default. If -simplify-mir option is passed then MIRPrinter will not print such fields. This change also required some lit test cases in CodeGen directory to be changed. Reviewed By: MatzeB Differential Revision: https://reviews.llvm.org/D32304 llvm-svn: 304779
* [ARM] GlobalISel: Constrain callee register on indirect callsDiana Picus2017-06-051-4/+6
| | | | | | | | | | | | | When lowering calls, we generate instructions with machine opcodes rather than generic ones. Therefore, we need to constrain the register classes of the operands. Also enable the machine verifier on the arm-irtranslator.ll test, since that would've caught this issue. Fixes (part of) PR32146. llvm-svn: 304712
* [ARM] GlobalISel: Support struct params/returnsDiana Picus2017-06-022-4/+71
| | | | | | | | | | | | Very very similar to the support for arrays. As with arrays, we don't support returning large structs that wouldn't fit in R0-R3. Most front-ends would likely use sret arguments for that anyway. The only significant difference is that when splitting a struct, we need to make sure we set the correct original alignment on each member, otherwise it may get split incorrectly between stack and registers. llvm-svn: 304536
* [ARM] GlobalISel: Support array returnsDiana Picus2017-05-291-24/+87
| | | | | | | These are a bit rare in practice, but they don't require anything special compared to array parameters, so support them as well. llvm-svn: 304137
* [ARM] GlobalISel: Support array parameters/argumentsDiana Picus2017-05-292-5/+298
| | | | | | | | | Clang coerces structs into arrays, so it's a good idea to support them. Most of the support boils down to getting the splitToValueTypes helper to actually split types. We then use G_INSERT/G_EXTRACT to deal with the parts. llvm-svn: 304132
* [GlobalISel] IRTranslator: Translate ConstantStructVolkan Keles2017-05-191-0/+30
| | | | | | | | | | | | Reviewers: qcolombet, ab, t.p.northover, aditya_nandakumar, dsanders Reviewed By: qcolombet Subscribers: rovka, kristof.beyls, javed.absar, igorb, llvm-commits Differential Revision: https://reviews.llvm.org/D33317 llvm-svn: 303412
* [ARM][GlobalISel] Legalize narrow scalar ops by wideningDiana Picus2017-05-113-54/+213
| | | | | | | | | | | | | | 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] Support for G_ANYEXTDiana Picus2017-05-112-0/+99
| | | | | | | | | | | | | | G_ANYEXT can be introduced by the legalizer when widening scalars. Add support for it in the register bank info (same mapping as everything else) and in the instruction selector. When selecting it, we treat it as a COPY, just like G_TRUNC. On this occasion we get rid of some assertions in selectCopy so we can reuse it. This shouldn't be a problem at the moment since we're not supporting any complicated cases (e.g. FPR, different register banks). We might want to separate the paths when we do. llvm-svn: 302778
* Add extra operand to CALLSEQ_START to keep frame part set up previouslySerge Pavlov2017-05-091-8/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Using arguments with attribute inalloca creates problems for verification of machine representation. This attribute instructs the backend that the argument is prepared in stack prior to CALLSEQ_START..CALLSEQ_END sequence (see http://llvm.org/docs/InAlloca.htm for details). Frame size stored in CALLSEQ_START in this case does not count the size of this argument. However CALLSEQ_END still keeps total frame size, as caller can be responsible for cleanup of entire frame. So CALLSEQ_START and CALLSEQ_END keep different frame size and the difference is treated by MachineVerifier as stack error. Currently there is no way to distinguish this case from actual errors. This patch adds additional argument to CALLSEQ_START and its target-specific counterparts to keep size of stack that is set up prior to the call frame sequence. This argument allows MachineVerifier to calculate actual frame size associated with frame setup instruction and correctly process the case of inalloca arguments. The changes made by the patch are: - Frame setup instructions get the second mandatory argument. It affects all targets that use frame pseudo instructions and touched many files although the changes are uniform. - Access to frame properties are implemented using special instructions rather than calls getOperand(N).getImm(). For X86 and ARM such replacement was made previously. - Changes that reflect appearance of additional argument of frame setup instruction. These involve proper instruction initialization and methods that access instruction arguments. - MachineVerifier retrieves frame size using method, which reports sum of frame parts initialized inside frame instruction pair and outside it. The patch implements approach proposed by Quentin Colombet in https://bugs.llvm.org/show_bug.cgi?id=27481#c1. It fixes 9 tests failed with machine verifier enabled and listed in PR27481. Differential Revision: https://reviews.llvm.org/D32394 llvm-svn: 302527
* [ARM] GlobalISel: Tighten test. NFCDiana Picus2017-04-281-27/+27
| | | | | | Explicitly check types and load sizes in the IRTranslator test. llvm-svn: 301627
* [ARM] GlobalISel: Fix extended stack operandsDiana Picus2017-04-272-4/+52
| | | | | | | | | | | | | | Fix a crash when trying to extend a value passed as a sign- or zero-extended stack parameter. The cause of the crash was that we were setting the size of the loaded value to 32 bits, and then tyring to extend again to 32 bits. This patch addresses the issue by also introducing a G_TRUNC after the load. This will leave the unused bits to their original values set by the caller, while being consistent about the types. For values that are not extended, we just use a smaller load. llvm-svn: 301531
* [ARM] GlobalISel: Legalize s8 and s16 G_(S|U)DIVDiana Picus2017-04-242-4/+203
| | | | | | | | | | | | | | 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-244-0/+225
| | | | | | | | | 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: Select G_CONSTANT with CImm operandsDiana Picus2017-04-242-3/+32
| | | | | | | | | | | | | | When selecting a G_CONSTANT to a MOVi, we need the value to be an Imm operand. We used to just leave the G_CONSTANT operand unchanged, which works in some cases (such as the GEP offsets that we create when referring to stack slots). However, in many other places the G_CONSTANTs are created with CImm operands. This patch makes sure to handle those as well, and to error out gracefully if in the end we don't end up with an Imm operand. Thanks to Oliver Stannard for reporting this issue. llvm-svn: 301162
* [ARM] GlobalISel: Add support for G_TRUNCDiana Picus2017-04-213-0/+77
| | | | | | | | Select them as copies. We only select if both the source and the destination are on the same register bank, so this shouldn't cause any trouble. llvm-svn: 300971
* [ARM] GlobalISel: Make struct arguments fail elegantlyDiana Picus2017-04-211-0/+80
| | | | | | | | | | | The condition in isSupportedType didn't handle struct/array arguments properly. Fix the check and add a test to make sure we use the fallback path in this kind of situation. The test deals with some common cases where the call lowering should error out. There are still some issues here that need to be addressed (tail calls come to mind), but they can be addressed in other patches. llvm-svn: 300967
* [ARM] GlobalISel: Add support for G_MULDiana Picus2017-04-194-1/+326
| | | | | | | | 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-185-0/+329
| | | | | | | 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-112-6/+112
| | | | | | | | | 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-102-3/+114
| | | | | | Legalize to a libcall. llvm-svn: 299841
* [ARM] GlobalISel: Test hard float properlyDiana Picus2017-04-071-16/+26
| | | | | | | | It turns out -float-abi=hard doesn't set the hard float calling convention for libcalls. We need to use a hard float triple instead (e.g. gnueabihf). llvm-svn: 299761
* [ARM] GlobalISel: Support frem for 64-bit valuesDiana Picus2017-04-072-0/+58
| | | | | | Legalize to a libcall. llvm-svn: 299756
* [ARM] GlobalISel: Support frem for 32-bit valuesDiana Picus2017-04-072-0/+48
| | | | | | | | 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
* [GlobalISel] Fix shufflevector testsVolkan Keles2017-03-211-25/+25
| | | | | | | | clang-lld-x86_64-2stage fails because of the order of the instructions. `CHECK-DAG` directives should fix the problem. llvm-svn: 298367
OpenPOWER on IntegriCloud