5521 Commits

Author SHA1 Message Date
Paul Walker
3c382ed71f [AArch64][SVE] Remove BIC from logical operation DestructiveBinaryComm patterns
This reverts part of https://reviews.llvm.org/D124224 that causes
an assert because the register allocator triggers a pathological
situation where there's no safe way to insert a zeroing MOVPFRX
instruction.
2022-04-22 15:07:55 +01:00
zhongyunde
e1afae0311 [AArch64][SVE] Add some logical operation DestructiveBinaryComm patterns
Add DestructiveBinaryComm* patterns for ORR, EOR, AND and BIC.
The above instructions requires that the source and destination registers are
equal, so use movprfx should be beneficial to performance.
note: BIC (i.e. A & ~B) is not a commutative operation.

Reviewed By: paulwalker-arm, david-arm

Differential Revision: https://reviews.llvm.org/D124224
2022-04-22 20:31:00 +08:00
Daniel Kiss
de07cde67b [AArch64] Emit .cfi_negate_ra_state for PAC-auth instructions.
autiasp, autibsp instructions are the counterpart of paciasp/pacibsp instructions
therefore let's emit .cfi_negate_ra_state for these too.
In case of Armv8.3 instruction set the retaa/retbb will do the return and authentication
in one step here we can't emit the . cfi_negate_ra_state because that would be point after
the ret* instruction.

Reviewed By: nickdesaulniers, MaskRay

Differential Revision: https://reviews.llvm.org/D111780
2022-04-22 13:25:57 +02:00
Karl Meakin
81904454f7 [AArch64] Add foldOverflowCheck DAG combine
Differential Revision: https://reviews.llvm.org//D123779
2022-04-21 14:56:38 +01:00
Karl Meakin
13403a70e4 [AArch64] Add lowerings for {ADD,SUB}CARRY and S{ADD,SUB}O_CARRY
Differential Revision: https://reviews.llvm.org/D123322
2022-04-21 14:56:37 +01:00
Pengxuan Zheng
38612fbc89 Reland "[COFF, ARM64] Add __break intrinsic"
https://docs.microsoft.com/en-us/cpp/intrinsics/arm64-intrinsics?view=msvc-170

Reland after fixing the test failure. The failure was due to conflict with a
change (D122983) which was merged right before this patch.

Reviewed By: rnk, mstorsjo

Differential Revision: https://reviews.llvm.org/D124032
2022-04-20 13:01:30 -07:00
Pengxuan Zheng
bff8356b19 Revert "[COFF, ARM64] Add __break intrinsic"
This reverts commit 8a9b4fb4aa6d2dde026d9ae08459aa9e7a1edb05.
2022-04-20 11:57:49 -07:00
Pengxuan Zheng
8a9b4fb4aa [COFF, ARM64] Add __break intrinsic
https://docs.microsoft.com/en-us/cpp/intrinsics/arm64-intrinsics?view=msvc-170

Reviewed By: rnk, mstorsjo

Differential Revision: https://reviews.llvm.org/D124032
2022-04-20 11:20:26 -07:00
Alexey Bataev
2cca53c815 [DAG]Introduce llvm::processShuffleMasks and use it for shuffles in DAG Type Legalizer.
We can process the long shuffles (working across several actual
vector registers) in the best way if we take the actual register
represantion into account. We can build more correct representation of
register shuffles, improve number of recognised buildvector sequences.
Also, same function can be used to improve the cost model for the
shuffles. in future patches.

Part of D100486

Differential Revision: https://reviews.llvm.org/D115653
2022-04-20 09:37:16 -07:00
Alexey Bataev
5f7ac15912 Revert "[DAG]Introduce llvm::processShuffleMasks and use it for shuffles in DAG Type Legalizer."
This reverts commit 2f49163b3365e5dc046b03e422a048dd45aee3f0 to fix
a buildbot failure. Reported in https://lab.llvm.org/buildbot#builders/105/builds/24284
2022-04-20 06:35:55 -07:00
Alexey Bataev
2f49163b33 [DAG]Introduce llvm::processShuffleMasks and use it for shuffles in DAG Type Legalizer.
We can process the long shuffles (working across several actual
vector registers) in the best way if we take the actual register
represantion into account. We can build more correct representation of
register shuffles, improve number of recognised buildvector sequences.
Also, same function can be used to improve the cost model for the
shuffles. in future patches.

Part of D100486

Differential Revision: https://reviews.llvm.org/D115653
2022-04-20 05:32:56 -07:00
Matt Arsenault
d16945d31b AArch64/GlobalISel: Add -global-isel-abort=1 to select tests
Otherwise the legalizer verifier error isn't triggered since the
default is fallback.
2022-04-19 21:04:32 -04:00
David Green
73dc996428 [AArch64] Add lane moves to PerfectShuffle tables
This teaches the perfect shuffle tables about lane inserts, that can
help reduce the cost of many entries. Many of the shuffle masks are
one-away from being correct, and a simple lane move can be a lot simpler
than trying to use ext/zip/etc. Because they are not exactly like the
other masks handled in the perfect shuffle tables, they require special
casing to generate them, with a special InsOp Operator.

The lane to insert into is encoded as the RHSID, and the move from is
grabbed from the original mask. This helps reduce the maximum perfect
shuffle entry cost to 3, with many more shuffles being generatable in a
single instruction.

Differential Revision: https://reviews.llvm.org/D123386
2022-04-19 14:49:50 +01:00
David Green
cc9495f679 [AArch64] Only mark cost 1 perfect shuffles as legal
The perfect shuffle tables encode a cost of either 0 (a nop-copy) or 1
(a single instruction) with a cost encoding of 0 in the upper 2 bits.
All perfect shuffles with any cost are then marked as legal shuffles
though (the maximum encoded cost is 3), which can confuse the DAG
combiner into thinking the shuffles are cheaper than the should be.

Limiting legal shuffles to single instructions seems to do better in
most case, producing less instructions for complex shuffles. There are
some cases that now become tbl, which may be better or worse depending
on whether the instruction is in a loop and the tbl load can be hoisted
out.

Differential Revision: https://reviews.llvm.org/D123377
2022-04-19 12:58:55 +01:00
David Green
50af82701c [AArch64] Cost all perfect shuffles entries as cost 1
A brief introduction to perfect shuffles - AArch64 NEON has a number of
shuffle operations - dups, zips, exts, movs etc that can in some way
shuffle around the lanes of a vector. Given a shuffle of size 4 with 2
inputs, some shuffle masks can be easily codegen'd to a single
instruction. A <0,0,1,1> mask for example is a zip LHS, LHS. This is
great, but some masks are not so simple, like a <0,0,1,2>. It turns out
we can generate that from zip LHS, <0,2,0,2>, having generated
<0,2,0,2> from uzp LHS, LHS, producing the result in 2 instructions.

It is not obvious from a given mask how to get there though. So we have
a simple program (PerfectShuffle.cpp in the util folder) that can scan
through all combinations of 4-element vectors and generate the perfect
combination of results needed for each shuffle mask (for some definition
of perfect). This is run offline to generate a table that is queried for
generating shuffle instructions. (Because the table could get quite big,
it is limited to 4 element vectors).

In the perfect shuffle tables zip, unz and trn shuffles were being cost
as 2, which is higher than needed and skews the perfect shuffle tables
to create inefficient combinations. This sets them to 1 and regenerates
the tables. The codegen will usually be better and the costs should be
more precise (but it can get less second-order re-use of values from
multiple shuffles, these cases should be fixed up in subsequent patches.

Differential Revision: https://reviews.llvm.org/D123379
2022-04-19 12:05:05 +01:00
chenglin.bi
222adf338a [Arch64][SelectionDAG] Add target-specific implementation of srem
1. X%C to the equivalent of X-X/C*C is not always fastest path if there is no SDIV pair exist. So check target have faster for srem only first.
2. Add AArch64 faster path for SREM only pow2 case.

Fix https://github.com/llvm/llvm-project/issues/54649

Reviewed By: efriedma

Differential Revision: https://reviews.llvm.org/D122968
2022-04-19 02:49:42 +08:00
Momchil Velikov
e0ff354b83 [AArch64] Async unwind - Adjust unwind info in AArch64LoadStoreOptimizer
[Re-commit after fixing a dereference of "end" iterator]

The AArch64LoadStoreOptimnizer pass may merge a register
increment/decrement with a following memory operation. In doing so, it
may break CFI by moving a stack pointer adjustment past the CFI
instruction that described *that* adjustment.

This patch fixes this issue by moving said CFI instruction after the
merged instruction, where the SP increment/decrement actually takes
place.

Reviewed By: efriedma

Differential Revision: https://reviews.llvm.org/D114547
2022-04-18 12:09:44 +01:00
chenglin.bi
acfc025a72 Revert "[Arch64][SelectionDAG] Add target-specific implementation of srem"
This reverts commit 9d9eddd3dde46751a5c415b7e5e475b4feb76600.
2022-04-18 10:35:09 +08:00
chenglin.bi
9d9eddd3dd [Arch64][SelectionDAG] Add target-specific implementation of srem
X%C to the equivalent of X-X/C*C is not always fastest path if there is no SDIV pair exist. So check target have faster for srem only first. Add AArch64 faster path for SREM only pow2 case.

Fix https://github.com/llvm/llvm-project/issues/54649

Reviewed By: efriedma

Differential Revision: https://reviews.llvm.org/D122968
2022-04-16 12:29:11 +08:00
Momchil Velikov
24c84bd236 [AArch64] Async unwind - Fix MTE codegen emitting frame adjustments in a loop
When untagging the stack, the compiler may emit a sequence like:
```
        .LBB0_1:
          st2g sp, [sp], #32
          sub x8, x8, #32
          cbnz x8, .LBB0_1
          stg sp, [sp], #16
```
These stack adjustments cannot be described by CFI instructions.

This patch disables merging of SP update with untagging, i.e. makes the
compiler use an additional scratch register (there should be plenty
available at this point as we are in the epilogue) and generate:
```
            mov     x9, sp
            mov     x8, #256
            stg     x9, [x9], #16
    .LBB0_1:
            sub     x8, x8, #32
            st2g    x9, [x9], #32
            cbnz    x8, .LBB0_1
            add     sp, sp, #272
```
Merging is disabled only when we need to generate asynchronous unwind
tables.

Reviewed By: eugenis

Differential Revision: https://reviews.llvm.org/D114548
2022-04-15 14:00:23 +01:00
John Brawn
27a8735a44 [AArch64] Add mayRaiseFPException to appropriate instructions
This is mostly handled by adding "let mayRaiseFPException = 1" before
the definition of the relevant instruction classes, but there are a
couple of complications:
 * When we have a multiclass where currently some instantiations are
   of instructions that can raise an exception and others aren't we
   need to split that into two multiclasses, one inheriting from the
   other using a multiclass parameter to enable exceptions.
 * In a couple of places in the globalisel instruction selector we
   need to manually set the NoFPExcept flag. There's also another
   place that looks like it should need it, but that code is never hit
   for those opcodes due to them being handled by the generic
   instruction selector, so I've instead just removed them from the
   switch.

Differential Revision: https://reviews.llvm.org/D115352
2022-04-14 16:51:22 +01:00
John Brawn
12c1022679 [AArch64] Lowering and legalization of strict FP16
For strict FP16 to work correctly needs some changes in lowering and
legalization:
 * SelectionDAGLegalize::PromoteNode was missing handling for some
   strict fp opcodes.
 * Some of the custom lowering of strict fp operations needed to be
   adjusted to work with FP16.
 * Custom lowering needed to be added for round-to-int operations.

With this, and the previous patches for the rest of the strict fp
isel, we can set IsStrictFPEnabled = true.

Differential Revision: https://reviews.llvm.org/D115620
2022-04-14 16:51:22 +01:00
David Green
1ba8f4f67d [AArch64] Move v4i8 concat load lowering to a combine.
The existing code was not updating the uses of loads that it recreated,
leading to incorrect chains which could break the ordering between
nodes. This moves the code to a combine instead, and makes sure we
update the chain references. This does mean it happens earlier -
potentially before the concats are simplified. This can lead to
inefficiencies in the codegen, which will be fixed in followups.
2022-04-14 15:19:33 +01:00
Paul Walker
0c44115e51 [SVE] Add support for non-element-type sized scaling when lowering MGATHER/MSCATTER.
The lowering code did not use the scale operand of MGATHER/MSCATTER
nodes, but instead assumed scaled indices were always scaled based
on the element type of the memory type. This patch adds the missing
support by rewritting the nodes as unscaled variants.

Differential Revision: https://reviews.llvm.org/D123670
2022-04-14 11:54:46 +01:00
Momchil Velikov
62d4686be3 Revert "[AArch64] Async unwind - Adjust unwind info in AArch64LoadStoreOptimizer"
This reverts commit ecbf32dd88fc91b4fe709dc14bb3493dda6e8854.

It's possible this patch is the reason for an asertion failure
`!NodePtr->isKnownSentinel()` in `AArch64LoadStoreOpt::mergeUpdateInsn`
(https://lab.llvm.org/buildbot/#/builders/185/builds/1555) reverting while I
investigate.
2022-04-14 09:33:40 +01:00
David Green
4585bff408 [AArch64] Add new shuffles tests, and regenerate aarch64-wide-shuffle.ll and neon-wide-splat.ll. NFC 2022-04-13 18:10:49 +01:00
chenglin.bi
82e5976b7d [AArch64][SelectionDAG] stick all the power-of-two tests in a separate file; NFC
Baseline tests for D122968 (issue #54649).
2022-04-14 00:48:28 +08:00
Momchil Velikov
ecbf32dd88 [AArch64] Async unwind - Adjust unwind info in AArch64LoadStoreOptimizer
The AArch64LoadStoreOptimnizer pass may merge a register
increment/decrement with a following memory operation. In doing so, it
may break CFI by moving a stack pointer adjustment past the CFI
instruction that described *that* adjustment.

This patch fixes this issue by moving said CFI instruction after the
merged instruction, where the SP increment/decrement actually takes
place.

Reviewed By: efriedma

Differential Revision: https://reviews.llvm.org/D114547
2022-04-13 17:04:53 +01:00
Alex Richardson
ee44896cf4 [AArch64] Add missing HasNEON predicate in scalar FABD patterns
I was trying to compile with -march=+nosimd and hit the following assertion:
`Attempting to emit FABD64 instruction but the Feature_HasNEON predicate(s) are not met`.
This adds a HasNEON predicate to the patterns which was omitted in commit
21d9b33d62772c58267cc0aa725e35ac9a4661db for some reason.
The new code generation matches GCC with -mcpu=<cpu>+nosimd:
https://godbolt.org/z/n1Y7xh5jo

Differential Revision: https://reviews.llvm.org/D123491
2022-04-13 09:30:11 +00:00
Alex Richardson
32a353a5e0 [AArch64] Baseline test for D123491 2022-04-13 09:30:11 +00:00
David Sherwood
44271e7c55 [AArch64][SVE] Fix lowering of "fcmp ueq/one" when using SVE
We were previously lowering to the incorrect instructions for the
setcc DAG node when using the SETUEQ and SETONE floating point
condition codes. I have fixed this by marking the SETONE code
as Expand and letting the SETUNE code be legal. I have also
fixed up the patterns for FCMNE_PPzZZ and FCMNE_PPzZ0 to use
the correct opcode.

Differential Revision: https://reviews.llvm.org/D121905
2022-04-13 10:24:03 +01:00
Daniel Kiss
b0343a38a5 Support the min of module flags when linking, use for AArch64 BTI/PAC-RET
LTO objects might compiled with different `mbranch-protection` flags which will cause an error in the linker.
Such a setup is allowed in the normal build with this change that is possible.

Reviewed By: pcc

Differential Revision: https://reviews.llvm.org/D123493
2022-04-13 09:31:51 +02:00
Matt Arsenault
6009122250 AArch64/GlobalISel: Remove pointless s1 legalize rules
These have no net effect on the legalize rules.
2022-04-12 16:54:04 -04:00
Matt Arsenault
3f2cc7cc2b GlobalISel: Fix lowerSelect handling of boolean high bits
This was making several invalid assumptions about the incoming
select. First, it was assuming the incoming condition was either s1 or
already sign extended, not accounting for different boolean high bits
behavior between scalar and vector conditions. We only had a vector
boolean due to the intermediate step vector select, which is now
avoided.

Second, it was assuming it can use the result vector type as a boolean
mask. These types don't have anything to do with other, and only makes
sense in the context of the expansion to bit operations. Since these
logically are part of the same lowering, do the complete expansion in
a single step.

The added select_v4s1_s1 test does fail to legalize, since it seems
AArch64's vector legalization support is pretty incomplete.
2022-04-12 16:54:03 -04:00
Ahmed Bougacha
cfa4fe7c51 [AArch64][LOH] Don't ignore regmasks in bundles by iterating over instrs.
The LOH pass iterates over instructions to build its custom register
state machine, but it uses the top-level bundle iterator.
This should be okay, because when the wrapper BUNDLE MI is built,
it aggregates the register defs/uses in its instructions into MOs.

However, that doesn't apply to regmasks, and accumulating regmasks
across multiple instructions would be messy business.
There are a couple AnalyzePhysRegInBundle (/Virt) helpers that
do look at regmasks, but those don't fit in very well here.

AArch64 has started to use a few bundle instructions, specifically
as glorified pseudos for variant call instructions, which have regmasks.
So the LOH pass ends up ignoring regmasks.

Concretely, this has been wrong for a while, but, on aarch64, the
most common bundle (rv_marker call) was always followed by the
attached call instruction, a plain BL with a regmask.  Which
was properly detected by the pass.

However, we recently started keeping the attached call in the bundle,
so the regmask is now ignored.  And the pass happily combines ADRPs, of
say, x8, across the bundle, resulting in corrupt pointers later.
2022-04-12 10:34:54 -07:00
Ahmed Bougacha
f3e76dcae3 [AArch64] Cleanup call-rv-marker.ll test. NFC.
This was doing -iphoneos instead of -ios. While there,
remove an old TODO and cleanup some alignment.
2022-04-12 10:34:54 -07:00
Momchil Velikov
d0ea42a7c1 [AArch64] Async unwind - function epilogues
Reviewed By: MaskRay, chill

Differential Revision: https://reviews.llvm.org/D112330
2022-04-12 16:50:50 +01:00
Matt Arsenault
7e8ff962b3 AArch64/GlobalISel: Regenerate mir test checks
Minimizes the test diffs in future changes from introduction of -NEXT.
2022-04-11 20:12:22 -04:00
Matt Arsenault
492d0eab89 AArch64/GlobalISel: Remove IR section from a test 2022-04-11 19:43:37 -04:00
Biplob Mishra
d06fb9045b AArch64 adding more tests to show the simple scenarios for or/and combine 2022-04-11 20:54:12 +01:00
Momchil Velikov
b4ad28da19 [CodeGen] Async unwind - add a pass to fix CFI information
This pass inserts the necessary CFI instructions to compensate for the
inconsistency of the call-frame information caused by linear (non-CGA
aware) nature of the unwind tables.

Unlike the `CFIInstrInserer` pass, this one almost always emits only
`.cfi_remember_state`/`.cfi_restore_state`, which results in smaller
unwind tables and also transparently handles custom unwind info
extensions like CFA offset adjustement and save locations of SVE
registers.

This pass takes advantage of the constraints taht LLVM imposes on the
placement of save/restore points (cf. `ShrinkWrap.cpp`):

  * there is a single basic block, containing the function prologue

  * possibly multiple epilogue blocks, where each epilogue block is
    complete and self-contained, i.e. CSR restore instructions (and the
    corresponding CFI instructions are not split across two or more
    blocks.

  * prologue and epilogue blocks are outside of any loops

Thus, during execution, at the beginning and at the end of each basic
block the function can be in one of two states:

  - "has a call frame", if the function has executed the prologue, or
     has not executed any epilogue

  - "does not have a call frame", if the function has not executed the
    prologue, or has executed an epilogue

These properties can be computed for each basic block by a single RPO
traversal.

From the point of view of the unwind tables, the "has/does not have
call frame" state at beginning of each block is determined by the
state at the end of the previous block, in layout order.

Where these states differ, we insert compensating CFI instructions,
which come in two flavours:

- CFI instructions, which reset the unwind table state to the
    initial one.  This is done by a target specific hook and is
    expected to be trivial to implement, for example it could be:
```
     .cfi_def_cfa <sp>, 0
     .cfi_same_value <rN>
     .cfi_same_value <rN-1>
     ...
```
where `<rN>` are the callee-saved registers.

- CFI instructions, which reset the unwind table state to the one
    created by the function prologue. These are the sequence:
```
       .cfi_restore_state
       .cfi_remember_state
```
In this case we also insert a `.cfi_remember_state` after the
last CFI instruction in the function prologue.

Reviewed By: MaskRay, danielkiss, chill

Differential Revision: https://reviews.llvm.org/D114545
2022-04-11 13:27:26 +01:00
Sanjay Patel
2ed15984b4 [SDAG] try to reduce compare of funnel shift equal 0
fshl (or X, Y), X, C ==/!= 0 --> or (shl Y, C), X ==/!= 0
fshl X, (or X, Y), C ==/!= 0 --> or (srl Y, BW-C), X ==/!= 0

This is similar to an existing setcc-of-rotate fold, but the
matching requires more checks for the more general funnel op:
https://alive2.llvm.org/ce/z/Ab2jDd

We are effectively decomposing the funnel shift into logical
shifts, reassociating, and removing a shift.

This should get us the final improvements for x86-64 that were
originally shown in D111530
( https://github.com/llvm/llvm-project/issues/49541 );
x86-32 still shows some SHLD/SHRD, so the pattern is not
matching there yet.

Differential Revision: https://reviews.llvm.org/D122919
2022-04-11 07:44:58 -04:00
Tim Northover
901831a4e6 Revert "AArch64: take compact unwind frame size from last CFI instruction."
It was on ToT when I pushed and committed unintentionally.
2022-04-11 12:25:58 +01:00
Tim Northover
9fe32ca697 AArch64: add nvcast patterns for v1f64 2022-04-11 12:24:48 +01:00
Tim Northover
4120a3abdd AArch64: take compact unwind frame size from last CFI instruction.
Asynchronous exception support for the prologue means that there can be
multiple .cfi_def_cfa_offset instructions in a single function, which tripped
up an assertion in the compact unwind generator.

In reality the compact unwind format is far too restrictive to represent
asynchronous frames so if we ever wanted that on Darwin we'd fall back to DWARF
(possibly keeping compact unwind around for synchronous users). So the compact
format should continue to represent the synchronous situation, and the
assertion can be removed.
2022-04-11 12:24:48 +01:00
Tim Northover
6c85668d28 Tail calls: look through AssertZExt to find register copy.
arm64_32 guarantees the high 32 bits of pointer parameters are passed as 0, and
this is modelled in the IR by inserting an AssertZExt after the CopyFromReg.
The function deciding whether registers that need to be preserved actually are
wasn't expecting this so it banned perfectly legitimate tail calls.
2022-04-11 12:24:47 +01:00
Alexander Shaposhnikov
626039cdcc [AArch64] Split fuse-literals feature
This diff splits fuse-literals feature and enables fuse-adrp-add by default,
in particular, it adjusts instruction scheduling to place ADRP+ADD pairs together.
This also enables the linker to apply the relaxations described in
d2ca58c54b.

Differential revision: https://reviews.llvm.org/D120104

Test plan: make check-all
2022-04-11 05:27:11 +00:00
Karl Meakin
784b9d468a [AArch64] Update tests with the update_llc_test_checks.py script (NFC)
Reviewed By: Kmeakin

Differential Revision: https://reviews.llvm.org/D123317
2022-04-07 18:06:15 +01:00
Paul Walker
a88e8374db [SVE] Add more gather/scatter tests to highlight bugs in their generated code. 2022-04-07 17:13:48 +01:00
Martin Storsjö
8d7a17b7c8 [AArch64] Fix the upper limit for folded address offsets for COFF
In COFF, the immediates in IMAGE_REL_ARM64_PAGEBASE_REL21 relocations
are limited to 21 bit signed, i.e. the offset has to be less than
(1 << 20). The previous limit did intend to cover for this case, but
had missed that the 21 bit field was signed.

This fixes issue https://github.com/llvm/llvm-project/issues/54753.

Differential Revision: https://reviews.llvm.org/D123160
2022-04-06 22:54:13 +03:00