82 Commits

Author SHA1 Message Date
Jonas Hahnfeld
dd6e8b981d [AArch64/ARM] Fix two compiler warnings in InstructionSelector, NFCI
1) GCC complains that KnownValid is set but not used.
2) In ARMInstructionSelector::selectGlobal() the code is mixing "enumeral
   and non-enumeral type in conditional expression". Solve this by casting
   to unsigned which is the final type anyway.

Differential Revision: https://reviews.llvm.org/D58834

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@355304 91177308-0d34-0410-b5e6-96231b3b80d8
2019-03-04 08:51:32 +00:00
Diana Picus
6ca659aaa4 [ARM GlobalISel] Make arm_i32imm an IntImmLeaf
This gets rid of some duplication in the TableGen definition, but it
forces us to keep both a pointer and a reference to the subtarget in the
ARMInstructionSelector. That is pretty ugly but it might be a reasonable
trade-off, since the TableGen descriptions should outlive the code in
the selector (or in the worst case we can update to use just the
reference when we get rid of DAGISel).

Differential Revision: https://reviews.llvm.org/D58031

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@355083 91177308-0d34-0410-b5e6-96231b3b80d8
2019-02-28 11:13:05 +00:00
Diana Picus
c8a454ac13 [ARM GlobalISel] Support global variables for Thumb2
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@355077 91177308-0d34-0410-b5e6-96231b3b80d8
2019-02-28 10:42:47 +00:00
Diana Picus
063c3128bc [ARM GlobalISel] Support G_FRAME_INDEX for Thumb2
Same as arm mode.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@354579 91177308-0d34-0410-b5e6-96231b3b80d8
2019-02-21 13:00:02 +00:00
Diana Picus
697f2a80e9 [ARM GlobalISel] Style fix. NFCI
Add the opcode for ADDrr / t2ADDrr to the Opcode cache, as we did for
all other opcodes where the handling is otherwise the same between arm
mode and thumb2.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@354115 91177308-0d34-0410-b5e6-96231b3b80d8
2019-02-15 10:50:02 +00:00
Diana Picus
3cbeb27e3b [ARM GlobalISel] Support branches for Thumb2
Just like arm mode, but with different opcodes.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@354113 91177308-0d34-0410-b5e6-96231b3b80d8
2019-02-15 10:24:03 +00:00
Diana Picus
8810171ee8 [ARM GlobalISel] Support G_SELECT for Thumb2
Same as arm mode, but slightly different opcodes.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@353938 91177308-0d34-0410-b5e6-96231b3b80d8
2019-02-13 11:25:32 +00:00
Sam Parker
fcb98b7928 [ARM] Add OptMinSize to ARMSubtarget
In many places in the backend, we like to know whether we're
optimising for code size and this is performed by checking the
current machine function attributes. A subtarget is created on a
per-function basis, so it's possible to know when we're compiling for
code size on construction so record this in the new object.

Differential Revision: https://reviews.llvm.org/D57812


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@353501 91177308-0d34-0410-b5e6-96231b3b80d8
2019-02-08 07:57:42 +00:00
Diana Picus
f118c99457 [ARM GlobalISel] Support G_ICMP for Thumb2
Mark as legal and use the t2* equivalents of the arm mode instructions,
e.g. t2CMPrr instead of plain CMPrr.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@353392 91177308-0d34-0410-b5e6-96231b3b80d8
2019-02-07 11:05:33 +00:00
Diana Picus
6f4bd04ecc [ARM GlobalISel] Support G_GEP for Thumb2
Same as ARM, but use a different opcode in the instruction selection.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@353151 91177308-0d34-0410-b5e6-96231b3b80d8
2019-02-05 10:21:37 +00:00
Chandler Carruth
6b547686c5 Update the file headers across all of the LLVM projects in the monorepo
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351636 91177308-0d34-0410-b5e6-96231b3b80d8
2019-01-19 08:50:56 +00:00
Diana Picus
53a285d891 [ARM GlobalISel] Minor refactoring. NFCI
Refactor the ARMInstructionSelector to cache some opcodes in the
constructor instead of checking all the time if we're in ARM or Thumb
mode.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@349143 91177308-0d34-0410-b5e6-96231b3b80d8
2018-12-14 12:37:24 +00:00
Diana Picus
69dfdcbfa7 [ARM GlobalISel] Support exts and truncs for Thumb2
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@349026 91177308-0d34-0410-b5e6-96231b3b80d8
2018-12-13 12:06:54 +00:00
Diana Picus
041c1c53bb [ARM GlobalISel] Select load/store for Thumb2
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@348920 91177308-0d34-0410-b5e6-96231b3b80d8
2018-12-12 10:32:15 +00:00
Roman Tereshin
1741de4285 [GlobalISel][ARM] Adding HPR and QPR regclasses to FPRB regbank
Also bringing ARMRegisterBankInfo::getRegBankFromRegClass
implementation up to speed with the *.td-definition.

Reviewed By: qcolombet

Differential Revision: https://reviews.llvm.org/D43982

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@333056 91177308-0d34-0410-b5e6-96231b3b80d8
2018-05-23 02:59:31 +00:00
Nicola Zaghen
0818e789cb Rename DEBUG macro to LLVM_DEBUG.
The DEBUG() macro is very generic so it might clash with other projects.
The renaming was done as follows:
- git grep -l 'DEBUG' | xargs sed -i 's/\bDEBUG\s\?(/LLVM_DEBUG(/g'
- git diff -U0 master | ../clang/tools/clang-format/clang-format-diff.py -i -p1 -style LLVM
- Manual change to APInt
- Manually chage DOCS as regex doesn't match it.

In the transition period the DEBUG() macro is still present and aliased
to the LLVM_DEBUG() one.

Differential Revision: https://reviews.llvm.org/D43624



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@332240 91177308-0d34-0410-b5e6-96231b3b80d8
2018-05-14 12:53:11 +00:00
Matt Arsenault
6f1d6423b3 TargetMachine: Add address space to getPointerSize
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@327467 91177308-0d34-0410-b5e6-96231b3b80d8
2018-03-14 00:36:23 +00:00
Diana Picus
ece975ca81 [ARM GlobalISel] Select G_PHI
Select G_PHI to PHI and manually constrain the result register. This is
very similar to how COPY is handled, so extract and reuse some of that
code.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@321797 91177308-0d34-0410-b5e6-96231b3b80d8
2018-01-04 13:09:25 +00:00
Diana Picus
79a984ff1c [ARM GlobalISel] Fix selection of pointer constants
We used to handle G_CONSTANT with pointer type by forcing the type of
the result register to s32 and then letting TableGen handle it.
Unfortunately, setting the type only works for generic virtual
registers, that haven't yet been constrained to a register class (e.g.
those used only by a COPY later on). If the result register has already
been constrained as a use of a previously selected instruction, then
setting the type will assert.

It would be nice to be able to teach TableGen to select pointer
constants the same as integer constants, but since it's such an edge
case (at the moment the only pointer constant that we're generally
interested in is 0, and that is mostly used for comparisons and selects,
which are also not supported by TableGen) it's probably not worth the
effort right now. Instead, handle pointer constants with some trivial
handwritten code.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@321793 91177308-0d34-0410-b5e6-96231b3b80d8
2018-01-04 10:54:57 +00:00
Diana Picus
05f02d544f [ARM GlobalISel] Support G_INTTOPTR and G_PTRTOINT for s32
Mark conversions between pointers and 32-bit scalars as legal, map them
to the GPR and select to a simple COPY.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@321356 91177308-0d34-0410-b5e6-96231b3b80d8
2017-12-22 13:05:51 +00:00
Diana Picus
8b6a32148d [ARM GlobalISel] Support pointer constants
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@321354 91177308-0d34-0410-b5e6-96231b3b80d8
2017-12-22 11:09:18 +00:00
Diana Picus
395b777795 [ARM GlobalISel] Fix assertion in RegBankSelect
We get an assertion in RegBankSelect for code along the lines of
my_32_bit_int = my_64_bit_int, which tends to translate into a 64-bit
load, followed by a G_TRUNC, followed by a 32-bit store. This appears in
a couple of places in the test-suite.

At the moment, the legalizer doesn't distinguish between integer and
floating point scalars, so a 64-bit load will be marked as legal for
targets with VFP, and so will the rest of the sequence, leading to a
slightly bizarre G_TRUNC reaching RegBankSelect.

Since the current support for 64-bit integers is rather immature, this
patch works around the issue by explicitly handling this case in
RegBankSelect and InstructionSelect. In the future, we may want to
revisit this decision and make sure 64-bit integer loads are narrowed
before reaching RegBankSelect.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@321165 91177308-0d34-0410-b5e6-96231b3b80d8
2017-12-20 11:27:10 +00:00
Daniel Sanders
02ef0610a9 Revert r319691: [globalisel][tablegen] Split atomic load/store into separate opcode and enable for AArch64.
Some concerns were raised with the direction. Revert while we discuss it and look into an alternative



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@319739 91177308-0d34-0410-b5e6-96231b3b80d8
2017-12-05 05:52:07 +00:00
Daniel Sanders
e35711676b [globalisel][tablegen] Split atomic load/store into separate opcode and enable for AArch64.
This patch splits atomics out of the generic G_LOAD/G_STORE and into their own
G_ATOMIC_LOAD/G_ATOMIC_STORE. This is a pragmatic decision rather than a
necessary one. Atomic load/store has little in implementation in common with
non-atomic load/store. They tend to be handled very differently throughout the
backend. It also has the nice side-effect of slightly improving the common-case
performance at ISel since there's no longer a need for an atomicity check in the
matcher table.

All targets have been updated to remove the atomic load/store check from the
G_LOAD/G_STORE path. AArch64 has also been updated to mark
G_ATOMIC_LOAD/G_ATOMIC_STORE legal.

There is one issue with this patch though which also affects the extending loads
and truncating stores. The rules only match when an appropriate G_ANYEXT is
present in the MIR. For example,
  (G_ATOMIC_STORE (G_TRUNC:s16 (G_ANYEXT:s32 (G_ATOMIC_LOAD:s16 X))))
will match but:
  (G_ATOMIC_STORE (G_ATOMIC_LOAD:s16 X))
will not. This shouldn't be a problem at the moment, but as we get better at
eliminating extends/truncates we'll likely start failing to match in some
cases. The current plan is to fix this in a patch that changes the
representation of extending-load/truncating-store to allow the MMO to describe
a different type to the operation.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@319691 91177308-0d34-0410-b5e6-96231b3b80d8
2017-12-04 20:39:32 +00:00
Diana Picus
c7436ce110 [ARM GlobalISel] Fix selecting G_BRCOND
When lowering a G_BRCOND, we generate a TSTri of the condition against
1, which sets the flags, and then a Bcc which branches based on the
value of the flags.

Unfortunately, we were using the wrong condition code to check whether
we need to branch (EQ instead of NE), which caused all our branches to
do the opposite of what they were intended to do. This patch fixes the
issue by using the correct condition code.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@319313 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-29 14:20:06 +00:00
Daniel Sanders
64b77007a6 [globalisel][tablegen] Generate rule coverage and use it to identify untested rules
Summary:
This patch adds a LLVM_ENABLE_GISEL_COV which, like LLVM_ENABLE_DAGISEL_COV,
causes TableGen to instrument the generated table to collect rule coverage
information. However, LLVM_ENABLE_GISEL_COV goes a bit further than
LLVM_ENABLE_DAGISEL_COV. The information is written to files
(${CMAKE_BINARY_DIR}/gisel-coverage-* by default). These files can then be
concatenated into ${LLVM_GISEL_COV_PREFIX}-all after which TableGen will
read this information and use it to emit warnings about untested rules.

This technique could also be used by SelectionDAG and can be further
extended to detect hot rules and give them priority over colder rules.

Usage:
* Enable LLVM_ENABLE_GISEL_COV in CMake
* Build the compiler and run some tests
* cat gisel-coverage-[0-9]* > gisel-coverage-all
* Delete lib/Target/*/*GenGlobalISel.inc*
* Build the compiler

Known issues:
* ${LLVM_GISEL_COV_PREFIX}-all must be generated as a manual
  step due to a lack of a portable 'cat' command. It should be the
  concatenation of all ${LLVM_GISEL_COV_PREFIX}-[0-9]* files.
* There's no mechanism to discard coverage information when the ruleset
  changes

Depends on D39742

Reviewers: ab, qcolombet, t.p.northover, aditya_nandakumar, rovka

Reviewed By: rovka

Subscribers: vsk, arsenm, nhaehnle, mgorny, kristof.beyls, javed.absar, igorb, llvm-commits

Differential Revision: https://reviews.llvm.org/D39747

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@318356 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-16 00:46:35 +00:00
Diana Picus
155567c8fe [ARM GlobalISel] Remove C++ code for G_CONSTANT
Get rid of the handwritten instruction selector code for handling
G_CONSTANT. This code wasn't checking all the preconditions correctly
anyway, so it's better to leave it to TableGen, which can handle at
least some cases correctly (e.g. MOVi, MOVi16, folding into binary
operations). Also add tests to cover those cases.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@318146 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-14 11:20:32 +00:00
Evgeniy Stepanov
fbb029c5bb [arm] Fix Unnecessary reloads from GOT.
Summary:
This fixes PR35221.
Use pseudo-instructions to let MachineCSE hoist global address computation.

Subscribers: aemerson, javed.absar, kristof.beyls, llvm-commits, hiraditya

Differential Revision: https://reviews.llvm.org/D39871

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@318081 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-13 20:45:38 +00:00
David Blaikie
7be6b37802 InstructionSelectorImpl.h: Modularize/remove ODR violations by using a static member function to expose the debug name
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316715 91177308-0d34-0410-b5e6-96231b3b80d8
2017-10-26 23:39:54 +00:00
Diana Picus
e4864187fd [ARM] GlobalISel: Select shifts
Unfortunately TableGen doesn't handle this yet:
Unable to deduce gMIR opcode to handle Src (which is a leaf).

Just add some temporary hand-written code to generate the proper MOVsr.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@315071 91177308-0d34-0410-b5e6-96231b3b80d8
2017-10-06 15:39:16 +00:00
Diana Picus
853df63505 [ARM] GlobalISel: Minor cleanups in inst selector
Use the STI member of ARMInstructionSelector instead of
TII.getSubtarget() and also make use of STI's methods instead of
checking the object format manually.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@312522 91177308-0d34-0410-b5e6-96231b3b80d8
2017-09-05 08:22:47 +00:00
Diana Picus
cd919a1d28 [ARM] GlobalISel: Support global variables for RWPI
In RWPI code, globals that are not read-only are accessed relative to
the SB register (R9). This is achieved by explicitly generating an ADD
instruction between SB and an offset that we either load from a constant
pool or movw + movt into a register.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@312521 91177308-0d34-0410-b5e6-96231b3b80d8
2017-09-05 07:57:41 +00:00
Diana Picus
6470656cc2 [ARM] GlobalISel: Support ROPI global variables
In the ROPI relocation model, read-only variables are accessed relative
to the PC. We use the (MOV|LDRLIT)_ga_pcrel pseudoinstructions for this.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@312323 91177308-0d34-0410-b5e6-96231b3b80d8
2017-09-01 11:13:39 +00:00
Diana Picus
d29af7c957 [ARM] GlobalISel: Select globals in PIC mode
Support the selection of G_GLOBAL_VALUE in the PIC relocation model. For
simplicity we use the same pseudoinstructions for both Darwin and ELF:
(MOV|LDRLIT)_ga_pcrel(_ldr).

This is new for ELF, so it requires a small update to the ARM pseudo
expansion pass to make sure it adds the correct constant pool modifier
and add-current-address in the case of ELF.

Differential Revision: https://reviews.llvm.org/D36507

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@311992 91177308-0d34-0410-b5e6-96231b3b80d8
2017-08-29 09:47:55 +00:00
Quentin Colombet
f6eeaf64bb [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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@309990 91177308-0d34-0410-b5e6-96231b3b80d8
2017-08-03 21:52:25 +00:00
Diana Picus
14dbdbf7e4 [ARM] GlobalISel: Select simple G_GLOBAL_VALUE instructions
Add support in the instruction selector for G_GLOBAL_VALUE for ELF and
MachO for the static relocation model. We don't handle Windows yet
because that's Thumb-only, and we don't handle Thumb in general at the
moment.

Support for PIC, ROPI, RWPI and TLS will be added in subsequent commits.

Differential Revision: https://reviews.llvm.org/D35883

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@309927 91177308-0d34-0410-b5e6-96231b3b80d8
2017-08-03 09:14:59 +00:00
Daniel Sanders
e0714cfc0f Re-commit: r309094 [globalisel][tablegen] Fuse the generated tables together.
Summary:
Now that we have control flow in place, fuse the per-rule tables into a
single table. This is a compile-time saving at this point. However, this will
also enable the optimization of a table so that similar instructions can be
tested together, reducing the time spent on the matching the code.

This is NFC in terms of externally visible behaviour but some internals have
changed slightly. State.MIs is no longer reset between each rule that is
attempted because it's not necessary to do so. As a consequence of this the
restriction on the order that instructions are added to State.MIs has been
relaxed to only affect recorded instructions that require new elements to be
added to the vector. GIM_RecordInsn can now write to any element from 1 to
State.MIs.size() instead of just State.MIs.size().

The compile-time regressions from the last commit were caused by the ARM target
including a non-const variable (zero_reg) in the table and therefore generating
an initializer for it. That variable is now const.

Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar

Reviewed By: rovka

Subscribers: kristof.beyls, igorb, llvm-commits

Differential Revision: https://reviews.llvm.org/D35681



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@309264 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-27 11:03:45 +00:00
Diana Picus
a6ef55bfe2 [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).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@308009 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-14 09:46:06 +00:00
Diana Picus
a3db45981c [ARM] GlobalISel: Simplify inst selector code. NFC
Refactor CmpHelper into something simpler. It was overkill to use
templates for this - instead, use a simple CmpConstants structure to
hold the opcodes and other constants that are different when selecting
int / float / double comparisons. Also, extract some of the helpers that
were in CmpHelper into ARMInstructionSelector and make use of some of
them when selecting other things than just compares.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307766 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-12 10:31:16 +00:00
Diana Picus
8577619105 [ARM] GlobalISel: Select s64 G_FCMP
Very similar to how we select s32 G_FCMP, the only thing that is
different is the exact opcodes that we use.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307763 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-12 09:01:54 +00:00
Diana Picus
4f529ec57c [ARM] GlobalISel: Fixup r307365
Rename member DebugLoc -> DbgLoc (so it doesn't conflict with the class
name).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307366 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-07 08:53:27 +00:00
Diana Picus
a479e53b55 [ARM] GlobalISel: Select hard G_FCMP for s32
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307365 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-07 08:39:04 +00:00
Daniel Sanders
8175dca995 [globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.

The following patches will expand on this further to fully fix the regressions.

Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar

Reviewed By: ab

Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls

Differential Revision: https://reviews.llvm.org/D33758

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307079 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-04 14:35:06 +00:00
Diana Picus
99b52fe13c [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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306382 91177308-0d34-0410-b5e6-96231b3b80d8
2017-06-27 09:19:51 +00:00
Diana Picus
df1f7afc1e [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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305672 91177308-0d34-0410-b5e6-96231b3b80d8
2017-06-19 09:40:51 +00:00
Diana Picus
f6257e92c0 [ARM] GlobalISel: Purge G_SEQUENCE
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304902 91177308-0d34-0410-b5e6-96231b3b80d8
2017-06-07 12:35:05 +00:00
Diana Picus
663da44a76 Reland r303247: [ARM] GlobalISel: Remove dead instruction selection code
It only failed on llvm-clang-x86_64-expensive-checks-win, probably
because the TableGen stuff hasn't been regenerated.
Requires a clean build.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@303252 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-17 12:42:52 +00:00
Diana Picus
c2b55b1065 Revert "[ARM] GlobalISel: Remove dead instruction selection code"
This reverts commit r303247 because the tests are failing on some bots.
Sorry!

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@303249 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-17 11:56:07 +00:00
Diana Picus
dc1b6e1988 [ARM] GlobalISel: Remove dead instruction selection code
We can now generate code for selecting G_ADD, G_SUB and G_MUL. Remove
the hand-written versions.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@303247 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-17 11:39:26 +00:00
Diana Picus
62bc4f0ac3 [ARM][GlobalISel] Support for G_ANYEXT
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302778 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-11 08:28:31 +00:00