#
9faa09b2 |
| 23-Nov-2017 |
Diana Picus <diana.picus@linaro.org> |
[ARM GlobalISel] Support G_FMUL for s32 and s64
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
[ARM GlobalISel] Support G_FMUL for s32 and s64
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
show more ...
|
#
b3bde2ea |
| 17-Nov-2017 |
David Blaikie <dblaikie@gmail.com> |
Fix a bunch more layering of CodeGen headers that are in Target
All these headers already depend on CodeGen headers so moving them into CodeGen fixes the layering (since CodeGen depends on Target, n
Fix a bunch more layering of CodeGen headers that are in Target
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
show more ...
|
#
af9814a1 |
| 07-Nov-2017 |
Kristof Beyls <kristof.beyls@arm.com> |
[GlobalISel] Enable legalizing non-power-of-2 sized types.
This changes the interface of how targets describe how to legalize, see the below description.
1. Interface for targets to describe how to
[GlobalISel] Enable legalizing non-power-of-2 sized types.
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
show more ...
|
Revision tags: llvmorg-5.0.1-rc1 |
|
#
5cde1ccb |
| 30-Oct-2017 |
Javed Absar <javed.absar@arm.com> |
[GlobalISel|ARM] : Allow legalizing G_FSUB
Adding support for VSUB. Reviewed by: @rovka Differential Revision: https://reviews.llvm.org/D39261
llvm-svn: 316902
|
#
2c957304 |
| 06-Oct-2017 |
Diana Picus <diana.picus@linaro.org> |
[ARM] GlobalISel: Mark shifts as legal for s32
The new legalize combiner introduces shifts all over the place, so we should support them sooner rather than later.
llvm-svn: 315064
|
Revision tags: llvmorg-5.0.0, llvmorg-5.0.0-rc5, llvmorg-5.0.0-rc4, llvmorg-5.0.0-rc3, llvmorg-5.0.0-rc2 |
|
#
250e050a |
| 03-Aug-2017 |
Quentin Colombet <qcolombet@apple.com> |
[GlobalISel] Make GlobalISel a non-optional library.
With this change, the GlobalISel library gets always built. In particular, this is not possible to opt GlobalISel out of the build using the LLVM
[GlobalISel] Make GlobalISel a non-optional library.
With this change, the GlobalISel library gets always built. In particular, this is not possible to opt GlobalISel out of the build using the LLVM_BUILD_GLOBAL_ISEL variable any more.
llvm-svn: 309990
show more ...
|
Revision tags: llvmorg-5.0.0-rc1 |
|
#
b1fd7849 |
| 26-Jul-2017 |
Diana Picus <diana.picus@linaro.org> |
[ARM] GlobalISel: Mark G_GLOBAL_VALUE as legal
llvm-svn: 309090
|
#
da25d5b8 |
| 18-Jul-2017 |
Diana Picus <diana.picus@linaro.org> |
[ARM] GlobalISel: Support G_(S|U)REM for s8 and s16
Widen to s32, and then do whatever Lowering/Custom/Libcall action the subtarget wants.
llvm-svn: 308285
|
#
87a70679 |
| 14-Jul-2017 |
Diana Picus <diana.picus@linaro.org> |
[ARM] GlobalISel: Support G_BRCOND
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
[ARM] GlobalISel: Support G_BRCOND
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
show more ...
|
#
443135c6 |
| 11-Jul-2017 |
Diana Picus <diana.picus@linaro.org> |
[ARM] GlobalISel: Fix oversight in G_FCMP legalization
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.
llv
[ARM] GlobalISel: Fix oversight in G_FCMP legalization
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
show more ...
|
#
b57bba83 |
| 11-Jul-2017 |
Diana Picus <diana.picus@linaro.org> |
[ARM] GlobalISel: Legalize s64 G_FCMP
Same as the s32 version, for both hard and soft float.
llvm-svn: 307633
|
#
d0104eaa |
| 06-Jul-2017 |
Diana Picus <diana.picus@linaro.org> |
[ARM] GlobalISel: Legalize G_FCMP for s32
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
[ARM] GlobalISel: Legalize G_FCMP for s32
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
show more ...
|
#
cd460c89 |
| 06-Jul-2017 |
Diana Picus <diana.picus@linaro.org> |
[ARM] GlobalISel: Widen s1, s8, s16 G_CONSTANT
Get the legalizer to widen small constants.
llvm-svn: 307239
|
#
fc1675eb |
| 05-Jul-2017 |
Diana Picus <diana.picus@linaro.org> |
[GlobalISel] Refactor Legalizer helpers for libcalls
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
[GlobalISel] Refactor Legalizer helpers for libcalls
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
show more ...
|
#
3e8851a1 |
| 05-Jul-2017 |
Diana Picus <diana.picus@linaro.org> |
[ARM] GlobalISel: Extract tiny helper. NFC
Extract functionality for determining if the target uses AEABI.
llvm-svn: 307145
|
#
b539ea53 |
| 30-Jun-2017 |
Kristof Beyls <kristof.beyls@arm.com> |
[GlobalISel] Make multi-step legalization work.
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, sin
[GlobalISel] Make multi-step legalization work.
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
show more ...
|
#
0e74a134 |
| 27-Jun-2017 |
Diana Picus <diana.picus@linaro.org> |
[ARM] GlobalISel: Support G_SELECT for pointers
All we need to do is mark it as legal, otherwise it's just like s32.
llvm-svn: 306390
|
#
7145d22f |
| 27-Jun-2017 |
Diana Picus <diana.picus@linaro.org> |
[ARM] GlobalISel: Support G_SELECT for i32
* 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
[ARM] GlobalISel: Support G_SELECT for i32
* 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
show more ...
|
#
78aaf7db |
| 19-Jun-2017 |
Diana Picus <diana.picus@linaro.org> |
[ARM] GlobalISel: Support G_ICMP for s8 and s16
Widen to s32 (like all other binary ops).
llvm-svn: 305683
|
#
621894ac |
| 19-Jun-2017 |
Diana Picus <diana.picus@linaro.org> |
[ARM] GlobalISel: Support G_ICMP for i32 and pointers
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
[ARM] GlobalISel: Support G_ICMP for i32 and pointers
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
show more ...
|
#
02e11010 |
| 15-Jun-2017 |
Diana Picus <diana.picus@linaro.org> |
[ARM] GlobalISel: Add support for i32 modulo
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 c
[ARM] GlobalISel: Add support for i32 modulo
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
show more ...
|
Revision tags: llvmorg-4.0.1, llvmorg-4.0.1-rc3 |
|
#
0196427b |
| 07-Jun-2017 |
Diana Picus <diana.picus@linaro.org> |
[ARM] GlobalISel: Support G_XOR
Same as the other binary operators: - legalize to 32 bits - map to GPRs - select to EORrr via TableGen'erated code
llvm-svn: 304898
|
#
eeb0aad8 |
| 07-Jun-2017 |
Diana Picus <diana.picus@linaro.org> |
[ARM] GlobalISel: Support G_OR
Same as the other binary operators: - legalize to 32 bits - map to GPRs - select ORRrr thanks to TableGen'erated code
llvm-svn: 304890
|
#
8445858a |
| 07-Jun-2017 |
Diana Picus <diana.picus@linaro.org> |
[ARM] GlobalISel: Support G_AND
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
|
Revision tags: llvmorg-4.0.1-rc2 |
|
#
9cfbc6d9 |
| 11-May-2017 |
Diana Picus <diana.picus@linaro.org> |
[ARM][GlobalISel] Legalize narrow scalar ops by widening
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.
[ARM][GlobalISel] Legalize narrow scalar ops by widening
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
show more ...
|