7003 Commits

Author SHA1 Message Date
Daniel Hoekwater
866ae69cfa [AArch64] [BranchRelaxation] Optimize for hot code size in AArch64 branch relaxation
On AArch64, it is safe to let the linker handle relaxation of
unconditional branches; in most cases, the destination is within range,
and the linker doesn't need to do anything. If the linker does insert
fixup code, it clobbers the x16 inter-procedural register, so x16 must
be available across the branch before linking. If x16 isn't available,
but some other register is, we can relax the branch either by spilling
x16 OR using the free register for a manually-inserted indirect branch.

This patch builds on D145211. While that patch is for correctness, this
one is for performance of the common case. As noted in
https://reviews.llvm.org/D145211#4537173, we can trust the linker to
relax cross-section unconditional branches across which x16 is
available.

Programs that use machine function splitting care most about the
performance of hot code at the expense of the performance of cold code,
so we prioritize minimizing hot code size.

Here's a breakdown of the cases:

   Hot -> Cold [x16 is free across the branch]
     Do nothing; let the linker relax the branch.

   Cold -> Hot [x16 is free across the branch]
     Do nothing; let the linker relax the branch.

   Hot -> Cold [x16 used across the branch, but there is a free register]
     Spill x16; let the linker relax the branch.

     Spilling requires fewer instructions than manually inserting an
     indirect branch.

   Cold -> Hot [x16 used across the branch, but there is a free register]
     Manually insert an indirect branch.

     Spilling would require adding a restore block in the hot section.

   Hot -> Cold [No free regs]
     Spill x16; let the linker relax the branch.

   Cold -> Hot [No free regs]
     Spill x16 and put the restore block at the end of the hot function; let the linker relax the branch.
     Ex:
       [Hot section]
       func.hot:
         ... hot code...
       func.restore:
         ... restore x16 ...
         B func.hot

       [Cold section]
         func.cold:
         ... spill x16 ...
         B func.restore

     Putting the restore block at the end of the function instead of
     just before the destination increases the cost of executing the
     store, but it avoids putting cold code in the middle of hot code.
     Since the restore is very rarely taken, this is a worthwhile
     tradeoff.

Differential Revision: https://reviews.llvm.org/D156767
2023-09-06 20:44:40 +00:00
Vladislav Dzhidzhoev
c39edd7b53 [AArch64][GlobalISel] Regenerate prelegalizercombiner-shuffle-vector.mir 2023-09-06 18:38:13 +02:00
Simon Pilgrim
e4d0e12099 [DAG] Fold (shl (sext (add_nsw x, c1)), c2) -> (add (shl (sext x), c2), c1 << c2) (REAPPLIED)
Assuming the ADD is nsw then it may be sign-extended to merge with a SHL op in a similar fold to the existing (shl (add x, c1), c2) -> (add (shl x, c2), c1 << c2) fold.

This is most useful for helping to expose address math for X86, but has also touched several aarch64 test cases as well.

Alive2: https://alive2.llvm.org/ce/z/2UpSbJ

Differential Revision: https://reviews.llvm.org/D159198
2023-09-06 13:19:42 +01:00
Dmitri Gribenko
97bf104d97 Revert "[DAG] Fold (shl (sext (add_nsw x, c1)), c2) -> (add (shl (sext x), c2), c1 << c2)"
This reverts commit b027ce0ab93060bc6cb79d5402d21520e8b93fb7.

This commit breaks Transforms/InferAddressSpaces/AMDGPU/flat_atomic.ll.
2023-09-06 11:28:55 +02:00
Simon Pilgrim
b027ce0ab9 [DAG] Fold (shl (sext (add_nsw x, c1)), c2) -> (add (shl (sext x), c2), c1 << c2)
Assuming the ADD is nsw then it may be sign-extended to merge with a SHL op in a similar fold to the existing (shl (add x, c1), c2) -> (add (shl x, c2), c1 << c2) fold.

This is most useful for helping to expose address math for X86, but has also touched several aarch64 test cases as well.

Alive2: https://alive2.llvm.org/ce/z/2UpSbJ

Differential Revision: https://reviews.llvm.org/D159198
2023-09-06 10:06:21 +01:00
Amara Emerson
6c31f20fee
[GlobalISel] Fold fmul x, 1.0 -> x (#65379) 2023-09-06 03:14:16 +08:00
Amara Emerson
08e04209d8
[GlobalISel] Commute G_FMUL and G_FADD constant LHS to RHS. (#65298) 2023-09-05 23:48:34 +08:00
Vladislav Dzhidzhoev
13b7629a58 [GlobalISel][AArch64] Combine unmerge(G_EXT v, undef) to unmerge(v).
When having <N x t> d1, unused = unmerge(G_EXT <2*N x t> v1, undef, N),
it is possible to express it just as unused, d1 = unmerge v1.

It is useful for tackling regressions in arm64-vcvt_f.ll, introduced in
https://reviews.llvm.org/D144670.
2023-09-05 16:14:44 +02:00
Vladislav Dzhidzhoev
7eeeeb0cc9 Revert "[GlobalISel][AArch64] Combine unmerge(G_EXT v, undef) to unmerge(v)."
This reverts commit 6b37a65264bb4e7d400d5283a65f9e8e1575f2d7.
Accindentally pushed before squashing.
2023-09-05 16:13:27 +02:00
Vladislav Dzhidzhoev
0e826f0e6d Refactored, added MIR test. 2023-09-05 16:00:48 +02:00
Vladislav Dzhidzhoev
6b37a65264 [GlobalISel][AArch64] Combine unmerge(G_EXT v, undef) to unmerge(v).
When having <N x t> d1, unused = unmerge(G_EXT <2*N x t> v1, undef, N),
it is possible to express it just as unused, d1 = unmerge v1.

It is useful for tackling regressions in arm64-vcvt_f.ll, introduced in
https://reviews.llvm.org/D144670.
2023-09-05 16:00:48 +02:00
Jingu Kang
67fc0d3d39 [AArch64] Remove copy instruction between uaddlv and dup
If there are copy instructions between uaddlv and dup for transfer from gpr to
fpr, try to remove them with duplane.

Differential Revision: https://reviews.llvm.org/D159267
2023-09-05 14:41:28 +01:00
David Sherwood
50598f0ff4 [DAGCombiner][SVE] Add support for illegal extending masked loads
In some cases where the same mask is used for multiple
extending masked loads it can be more efficient to combine
the zero- or sign-extend into the load even if it's not a
legal or custom operation. This leads to splitting up the
extending load into smaller parts, which also requires
splitting the mask. For SVE at least this improves the
performance of the SPEC benchmark x264 slightly on
neoverse-v1 (~0.3%), and at least one other benchmark
improves by around 30%. The uplift for SVE seems due to
removing the dependencies (vector unpacks) introduced
between the loads and the vector operations, since this
should increase the level of parallelism.

See tests:

  CodeGen/AArch64/sve-masked-ldst-sext.ll
  CodeGen/AArch64/sve-masked-ldst-zext.ll

https://reviews.llvm.org/D159191
2023-09-05 10:41:21 +00:00
David Sherwood
64094e3e6d [DAGCombiner] Pre-commit tests for D159191
I've added some missing tests for the following cases:

1. Zero- and sign-extends from unpacked vector types to wide,
   illegal types. For example,
   %aext = zext <vscale x 4 x i8> %a to <vscale x 4 x i64>
2. Normal loads combined with 1
3. Masked loads combined with 1

Differential Revision: https://reviews.llvm.org/D159192
2023-09-05 10:41:21 +00:00
Amara Emerson
12e4921709
[GlobalISel] Constant fold sitofp/uitofp of 0. (#65307) 2023-09-05 17:33:57 +08:00
pvanhout
844c0da777 [TableGen][GlobalISel] Add MIR Pattern Builtins
Adds a new feature to MIR patterns: builtin instructions.
They offer some additional capabilities that currently cannot be expressed without falling back to C++ code.
There are two builtins added with this patch, but more can be added later as new needs arise:
 - GIReplaceReg
 - GIEraseRoot

Depends on D158714, D158713

Reviewed By: arsenm, aemerson

Differential Revision: https://reviews.llvm.org/D158975
2023-09-05 08:19:07 +02:00
Amara Emerson
91746d15d2
[GlobalISel] Fix G_PTR_ADD immediate chain combine using the wrong im… (#65271) 2023-09-05 08:06:40 +08:00
Amara Emerson
f51b7992c9 [GlobalISel] Precommit a ptradd combine test. 2023-09-04 08:27:20 -07:00
Vladislav Dzhidzhoev
a15144f2ba [AArch64][GlobalISel] Lower G_EXTRACT_VECTOR_ELT with variable indices
G_EXTRACT_VECTOR_ELT instructions with non-constant indices are not
selected, so they need to be lowered.

Fixes https://github.com/llvm/llvm-project/issues/65049.

Reviewed By: Peter

Differential Revision: https://reviews.llvm.org/D159096
2023-09-04 16:19:16 +02:00
sdesmalen-arm
dbf9b93f25
[AArch64][SME] Disable tail-call optimization for __arm_locally_streaming functions. (#65258)
When calling a function which requires no streaming-mode change from an
__arm_locally_streaming function, LLVM would otherwise emit:

  // function prologue
  smstart
  b streaming_compatible_function   // tail call
  // never an smstop
2023-09-04 15:11:22 +01:00
Sander de Smalen
702c3f56d3 [SME] Don't scavenge a spillslot in callee-save area in presence of streaming-mode changes.
If no frame-pointer is available and the compiler has scavenged a
spill-slot in the callee-save area, the compiler may be forced to emit an
'addvl' inside the streaming-mode-changing call sequence when it needs to
fill (reload) an FP register being passed to the call.

We can avoid this entirely by disabling stack-slot scavenging when there
are streaming-mode-changing call-sequences in the function.

Reviewed By: david-arm

Differential Revision: https://reviews.llvm.org/D159196
2023-09-04 10:14:44 +00:00
Amara Emerson
0065640f40 [GlobalISel] Look through a G_PTR_ADD's def register instead of it's source operand's
uses when looking for load/store users. This was a simple logic bug during translation
of the equivalent function in SelectionDAG:
```
    for (SDNode *Node : N->uses()) {
      if (auto *LoadStore = dyn_cast<MemSDNode>(Node)) {
```
2023-09-04 00:28:57 -07:00
Amara Emerson
59cbee4599 [GlobalISel] Fix an incorrect ptradd reassoc test. NFC.
The lookthrough int<->ptr cast tests and code were both wrongly checking the wrong
register uses. This change is fixing and precommiting the test to prepare for
the code fix.
2023-09-04 00:28:56 -07:00
Amara Emerson
69d8ca21af [GlobalISel] Regenerate ptradd reassociation tests checks. 2023-09-04 00:03:38 -07:00
Matt Arsenault
b14e83d1a4 IR: Add llvm.exp10 intrinsic
We currently have log, log2, log10, exp and exp2 intrinsics. Add exp10
to fix this asymmetry. AMDGPU already has most of the code for f32
exp10 expansion implemented alongside exp, so the current
implementation is duplicating nearly identical effort between the
compiler and library which is inconvenient.

https://reviews.llvm.org/D157871
2023-09-01 19:45:03 -04:00
Amara Emerson
8fb12f8ade [AArch64][GlobalISel] Re-generate stale test checks. 2023-09-01 08:29:34 -07:00
Sander de Smalen
b09a52d589 [AArch64] NFC: Move llvm.aarch64.sve.fadda tests back 2023-09-01 13:37:51 +00:00
David Green
03f338e7e0 [AArch64] Ensure we do not access illegal operands in tryCombineMULLWithUZP1
https://github.com/llvm/llvm-project/issues/65015 shows a case where
tryCombineMULLWithUZP1 could attempt to look at the wrong operand of another
user instruction. This adds an extra else as if we don't find the right opcode,
we don't need to check the operands.

Differential Revision: https://reviews.llvm.org/D159282
2023-09-01 14:12:31 +01:00
Sander de Smalen
9e9be99c97 [AArch64][SME] Disable remat of VL-dependent ops when function changes streaming mode.
This is a way to prevent the register allocator from inserting instructions
which behave differently for different runtime vector-lengths, inside a
call-sequence which changes the streaming-SVE mode before/after the call.

I've considered using BUNDLEs in Machine IR, but found that using this is
not possible for a few reasons:
* Most passes don't look inside BUNDLEs, but some passes would need to
  look inside these call-sequence bundles, for example the PrologEpilog
  pass (to remove the CALLSEQSTART/END), a PostRA pass to remove COPY
  instructions, or the AArch64PseudoExpand pass.
* Within the streaming-mode-changing call sequence, one of the instructions
  is a CALLSEQEND. The corresponding CALLSEQBEGIN (AArch64::ADJCALLSTACKUP)
  is outside this sequence. This means we'd end up with a BUNDLE that has
  [SMSTART, COPY, BL, ADJCALLSTACKUP, COPY, SMSTOP]. The MachineVerifier
  doesn't accept this, and we also can't move the CALLSEQSTART into the
  call sequence.

Maybe in the future we could model this differently by modelling
the runtime vector-length as a value that's used by certain operations
(similar to e.g. NCZV flags) and clobbered by SMSTART/MMSTOP, such that the
register allocator can consider these as actual dependences and avoid
rematerialization. For now we just want to address the immediate problem.

Reviewed By: paulwalker-arm, aemerson

Differential Revision: https://reviews.llvm.org/D159193
2023-09-01 12:13:27 +00:00
Sander de Smalen
7e815dd76d [AArch64][SME] Create new interface for isSVEAvailable.
When a function is compiled to be in Streaming(-compatible) mode, the full
set of SVE instructions may not be available. This patch adds an interface
to query that and changes the codegen for FADDA (not legal in Streaming-SVE
mode) to instead be expanded for fixed-length vectors, or otherwise not to
code-generate for scalable vectors.

Reviewed By: david-arm

Differential Revision: https://reviews.llvm.org/D156109
2023-09-01 12:00:36 +00:00
Simon Pilgrim
2a81396b1b [DAG] SimplifyDemandedBits - add SMIN/SMAX KnownBits comparison analysis
Followup to D158364

Also, final fix for Issue #59902 which noted that the snippet should just return 1
2023-09-01 12:42:30 +01:00
David Green
55dc73af97 [AArch64][GISel] Expand coverage of FRem.
This adds some more extensive test coverage for frem through global isel,
making sure that vector types are all scalarized and all fp16 become f32
libcalls.
2023-09-01 09:21:53 +01:00
Amara Emerson
8ba1c38a0d [AArch64][GlobalISel] Add heuristics for G_FCONSTANT localization.
Now that in an earlier commit we adopt the heuristics for SDAG's expansion
of 32/64b fpimms to either GPR materializations or CP load, we can also improve
the localizer to also understand the same heuristics. This avoids localizing
expensive immediates as that increases code size.

The combination of these two changes results in minor improvements in CTMark -Os,
and bigger improvements in some other cases.
2023-08-31 22:23:36 -07:00
Amara Emerson
49d5bb4b34 [AArch64][GlobalISel] Materialize 64b FP immediates instead of loading if profitable.
This just mimics what the SDAG backend does.
2023-08-31 22:23:36 -07:00
Hiroshi Yamauchi
8942d3047c [AArch64][WinCFI] Handle cases where no SEH opcodes in the prologue
but there are some in the epilogue.

Make a decision whether or not to have a startepilogue/endepilogue
based on whether we actually insert SEH opcodes in the epilogue,
rather than whether we had SEH opcodes in the prologue or not.

This fixes an assert failure when there are no SEH opcodes in the
prologue but there are SEH opcodes in the epilogue (for example, when
there is no stack frame but there are stack arguments) which was not
covered in https://reviews.llvm.org/D88641.

Assertion failed: HasWinCFI == MF.hasWinCFI(), file C:\Users\hiroshi\llvm-project\llvm\lib\Target\AArch64\AArch64FrameLowering.cpp, line 1988

Differential Revision: https://reviews.llvm.org/D159238
2023-08-31 12:43:26 -07:00
Daniel Paoliello
0c5c7b52f0 Emit the CodeView S_ARMSWITCHTABLE debug symbol for jump tables
The CodeView `S_ARMSWITCHTABLE` debug symbol is used to describe the layout of a jump table, it contains the following information:

* The address of the branch instruction that uses the jump table.
* The address of the jump table.
* The "base" address that the values in the jump table are relative to.
* The type of each entry (absolute pointer, a relative integer, a relative integer that is shifted).

Together this information can be used by debuggers and binary analysis tools to understand what an jump table indirect branch is doing and where it might jump to.

Documentation for the symbol can be found in the Microsoft PDB library dumper: 0fe89a942f/cvdump/dumpsym7.cpp (L5518)

This change adds support to LLVM to emit the `S_ARMSWITCHTABLE` debug symbol as well as to dump it out (for testing purposes).

Reviewed By: efriedma

Differential Revision: https://reviews.llvm.org/D149367
2023-08-31 12:06:50 -07:00
Konstantina Mitropoulou
17fc78e7a4 [DAGCombiner] Change foldAndOrOfSETCC() to optimize and/or patterns with floating points.
This reverts commit 48fa79a503a7cf380f98b6335fbd349afae1bd86.

Reviewed By: brooksmoses

Differential Revision: https://reviews.llvm.org/D159240
2023-08-31 11:36:50 -07:00
hstk30
db8f6c009e [AArch64] Fix arm neon vstx lane memVT size
StN lane memory size set too big lead to alias analysis goes wrong.

Fixes https://github.com/llvm/llvm-project/issues/64696

Differential Revision: https://reviews.llvm.org/D158611
2023-08-31 17:54:57 +01:00
Sander de Smalen
a6293228fd Reland "[AArch64][SME] Add support for Copy/Spill/Fill of strided ZPR2/ZPR4 registers."
This patch contains a few changes:

* It changes the alignment of the strided/contiguous ZPR2/ZPR4 registers to
  128-bits. This is important, because when we spill these registers to the
  stack, the address doesn't need to be 256/512 bits aligned because we
  split the single-store/reload pseudo instruction up into multiple
  STR_ZXI/LDR_ZXI (single vector store/load) instructions, which only
  require a 128-bit alignment. Additionally, an alignment larger than the
  stack-alignment is not supported for scalable vectors.

* It adds support for these register classes in storeRegToStackSlot,
  loadRegFromStackSlot and copyPhysReg.

* It adds tests only for the strided forms. There is no need to also
  test the contiguous forms, because a register such as z2_z3 or
  z4_z5_z6_z7 are also part of the regular ZPR2 and ZPR4 register classes,
  respectively, which are already covered and tested.

Reviewed By: dtemirbulatov

Differential Revision: https://reviews.llvm.org/D159189
2023-08-31 15:03:19 +00:00
Sander de Smalen
d6bd6f244e Revert "[AArch64][SME] Add support for Copy/Spill/Fill of strided ZPR2/ZPR4 registers."
This reverts commit 64da981b8b259c18313560bf629e1a8b3b7c1d52.
2023-08-31 14:14:56 +00:00
Sander de Smalen
64da981b8b [AArch64][SME] Add support for Copy/Spill/Fill of strided ZPR2/ZPR4 registers.
This patch contains a few changes:

* It changes the alignment of the strided/contiguous ZPR2/ZPR4 registers to
  128-bits. This is important, because when we spill these registers to the
  stack, the address doesn't need to be 256/512 bits aligned because we
  split the single-store/reload pseudo instruction up into multiple
  STR_ZXI/LDR_ZXI (single vector store/load) instructions, which only
  require a 128-bit alignment. Additionally, an alignment larger than the
  stack-alignment is not supported for scalable vectors.

* It adds support for these register classes in storeRegToStackSlot,
  loadRegFromStackSlot and copyPhysReg.

* It adds tests only for the strided forms. There is no need to also
  test the contiguous forms, because a register such as z2_z3 or
  z4_z5_z6_z7 are also part of the regular ZPR2 and ZPR4 register classes,
  respectively, which are already covered and tested.

Reviewed By: dtemirbulatov

Differential Revision: https://reviews.llvm.org/D159189
2023-08-31 13:47:46 +00:00
Igor Kirillov
e2cb07c322 [CodeGen] Fix incorrect insertion point selection for reduction nodes in ComplexDeinterleavingPass
When replacing ComplexDeinterleavingPass::ReductionOperation, we can do it
either from the Real or Imaginary part. The correct way is to take whichever
is later in the BasicBlock, but before the patch, we just always took the
Real part.

Fixes https://github.com/llvm/llvm-project/issues/65044

Differential Revision: https://reviews.llvm.org/D159209
2023-08-31 10:38:01 +00:00
David Green
58a2f839fd [AArch64][GISel] Expand coverage of FDiv and move into place.
This adds some more extensive test coverage for fdiv through global isel,
switching the opcodes to use the more complete ActionDefinitions to handle more
cases and moving it into the position of the existing code which is no longer
needed.
2023-08-30 22:09:53 +01:00
Amara Emerson
c95ed6e492 [GlobalISel] Try to commute G_CONSTANT_FOLD_BARRIER LHS operands to RHS.
Differential Revision: https://reviews.llvm.org/D159097
2023-08-30 08:07:22 -07:00
OverMighty
38c92c1ee2 [AArch64] Add patterns for FMADD, FMSUB
FMADD, FMSUB instructions perform better or the same compared to indexed
FMLA, FMLS.

For example, the Arm Cortex-A55 Software Optimization Guide lists "FP
multiply accumulate" FMADD, FMSUB instructions with a throughput of 2
IPC, whereas it lists "ASIMD FP multiply accumulate, by element" FMLA,
FMLS with a throughput of 1 IPC.

The Arm Cortex-A77 Software Optimization Guide, however, does not
separately list "by element" variants of the "ASIMD FP multiply
accumulate" instructions, which are listed with the same throughput of 2
IPC as "FP multiply accumulate" instructions.

Reviewed By: samtebbs, dzhidzhoev

Differential Revision: https://reviews.llvm.org/D158008
2023-08-30 12:39:04 +02:00
Dinar Temirbulatov
73e3866acb [AArch64][SME] Promote mask for masked load to a similar type size with load value.
The legalizer could keep an original mask type of masked load combined with
sign/zero extend, but we have to extend the mask to a type similar to our
combined load otherwise instruction selection could not lower the load.

Differential Revision: https://reviews.llvm.org/D158386
2023-08-30 08:54:46 +00:00
Jingu Kang
82e851a407 [AArch64] Change bound for known zero bits of uaddlv intrinsic
As @efriedma's comment, the largest number of bits that can actually be set
for a v8i8 is 11 (the number of bits set in 8*255) so we can change the bound.
Additionally, v16i8 type is supported as v8i8.

Differential Revision: https://reviews.llvm.org/D158613
2023-08-30 08:21:13 +01:00
Danila Malyutin
2fce8f74b3 [CodeGen][AArch64] Commit test for #65044 2023-08-29 19:06:24 +03:00
Serguei Katkov
a701b7e368 [CGP] Remove dead PHI nodes before elimination of mostly empty blocks
Before elimination of mostly empty block it makes sense to remove dead PHI nodes.
It open more opportunity for elimination plus eliminates dead code itself.

It appeared that change results in failing many unit tests and some of
them I've updated and for another one I disable this optimization.
The pattern I observed in the tests is that there is a infinite loop
without side effects. As a result after elimination of dead phi node all other
related instruction are also removed and tests stops to check what it is expected.

Reviewed By: efriedma
Differential Revision: https://reviews.llvm.org/D158503
2023-08-29 04:35:06 +00:00
Daniel Hoekwater
3f00c7b2ab [CodeGen][AArch64] Precommit tests for D156767 (NFC)
Differential Revision: https://reviews.llvm.org/D158871
2023-08-28 17:25:18 +00:00