2965 Commits

Author SHA1 Message Date
Craig Topper
8677aaa1a3 [RISCV][GISel] Add initial pre-legalizer combiners copying from AArch64. 2023-09-18 10:59:00 -07:00
Philip Reames
0722800289 [RISCV] Match constant indices of non-index type when forming strided ops (#65777)
When checking to see if our index expressions can be converted into strided
operations, we previously gave up if the index type wasn't an exact match for
the intptrty for the address. Per gep semantics, this mismatch implies a sext
or trunc cast to the respective index type. For constants, go ahead and
evaluate that cast instead of giving up.

Note that the motivation of this is mostly test cleanup. We canonicalize at IR
such that the gep index will match the intptrty. This is mostly useful so that
we can write both RV32 and RV64 tests from the same source. Its also helpful in
preventing confusion - I've stumbled across this at least four times now and
wasted time each one.

Note: The test change for scatters unit stride cases contains a minor
regression for rv32 and 64 bit indices.  This is an artifact of order in which
changes are landing.  This will be addressed in a near future change for all
configurations.
2023-09-18 09:41:34 -07:00
Philip Reames
bb7b8726a4 [RISCV] Merge some test checks rvv/fixed-vectors-masked-gather.ll [nfc] 2023-09-18 09:20:12 -07:00
Craig Topper
8f04d81ede [SelectionDAG][RISCV] Mask constants to narrow size in TargetLowering::expandUnalignedStore.
If the SRL for Hi constant folds, but we don't remoe those bits from
the Lo, we can end up with strange constant folding through DAGCombine later.
I've only seen this with constants being lowered to constant pools
during lowering on RISC-V.
2023-09-18 09:10:19 -07:00
Craig Topper
17a12a27ec [RISCV] Add test case to show bad codegen for unaligned i64 store of a large constant.
On the first split we create two i32 trunc stores and a srl to shift
the high part down. The srl gets constant folded, but to produce
a new i32 constant. But the truncstore for the low store still uses
the original constant.

This original constant then gets converted to a constant pool
before we revisit the stores to further split them. The constant
pool prevents further constant folding of the additional srls.

After legalization is done, we run DAGCombiner and get some constant
folding of srl via computeKnownBits which can peek through the constant
pool load. This can create new constants that also need a constant pool.
2023-09-18 09:10:19 -07:00
Piyou Chen
b83a1ed594 [RISCV] Only emit .option when extension is supported
It maybe emit the .option directive without any follow up. Only emit the .option push/pop when there are supported extension difference between function and module.

Reviewed By: craig.topper

Differential Revision: https://reviews.llvm.org/D159399
2023-09-18 00:30:13 -07:00
Piyou Chen
d861b3183c [RISCV][NFC] precommit for D159399
Reviewed By: craig.topper

Differential Revision: https://reviews.llvm.org/D159400
2023-09-18 00:18:08 -07:00
wangpc
cedf2ea7b5 [RISCV] Teach RISCVMergeBaseOffset to handle BlockAddress
We can get `BlockAddress` in user code via `Labels as Values` so
we should be able to merge the access to `BlockAddress`.

Reviewed By: craig.topper

Differential Revision: https://reviews.llvm.org/D159429
2023-09-18 11:47:14 +08:00
wangpc
28efe4d38e [RISCV] Add tests for merging base offset of BlockAddress
We can get `BlockAddress` in user code via `Labels as Values`.

Reviewed By: craig.topper

Differential Revision: https://reviews.llvm.org/D159428
2023-09-18 11:47:13 +08:00
Vettel
ddae50d1e6
[RISCV] Combine trunc (sra sext (x), zext (y)) to sra (x, smin (y, scalarsizeinbits(y) - 1)) (#65728)
For RVV, If we want to perform an i8 or i16 element-wise vector
arithmetic right shift in the upper C/C++ program, the value to be
shifted would be first sign extended to i32, and the shift amount would
also be zero_extended to i32 to perform the vsra.vv instruction, and
followed by a truncate to get the final calculation result, such pattern
will later expanded to a series of "vsetvli" and "vnsrl" instructions
later, this is because the RVV spec only support 2 * SEW -> SEW
truncate. But for vector, the shift amount can also be determined by
smin (Y, ScalarSizeInBits(Y) - 1)). Also, for the vsra instruction, we
only care about the low lg2(SEW) bits as the shift amount.

- Alive2: https://alive2.llvm.org/ce/z/u3-Zdr
- C++ Test cases : https://gcc.godbolt.org/z/q1qE7fbha
2023-09-17 17:11:28 +08:00
Yingwei Zheng
e042ff7eef
[SDAG][RISCV] Avoid expanding is-power-of-2 pattern on riscv32/64 with zbb
This patch adjusts the legality check for riscv to use `cpop/cpopw` since `isOperationLegal(ISD::CTPOP, MVT::i32)` returns false on rv64gc_zbb.
Clang vs gcc: https://godbolt.org/z/rc3s4hjPh

Reviewed By: craig.topper

Differential Revision: https://reviews.llvm.org/D156390
2023-09-17 02:56:09 +08:00
Yingwei Zheng
b423e1f05d
[SDAG][RISCV] Avoid neg instructions when lowering atomic_load_sub with a constant rhs
This patch avoids creating (sub x0, rhs) when lowering atomic_load_sub with a constant rhs.
Comparison with GCC: https://godbolt.org/z/c5zPdP7j4

Reviewed By: craig.topper

Differential Revision: https://reviews.llvm.org/D158673
2023-09-16 17:09:41 +08:00
Philip Reames
c663401f69 [RISCV] Prefer vrgatherei16 for shuffles (#66291)
If the data type is larger than e16, and the requires more than LMUL1 register
class, prefer the use of vrgatherei16.  This has three major benefits:
1) Less work needed to evaluate the constant for e.g. vid sequences.  Remember
that arithmetic generally scales lineary with LMUL.
2) Less register pressure.  In particular, the source and indices registers
*can* overlap so using a smaller index can significantly help at m8.
3) Smaller constants.  We've got a bunch of tricks for materializing small
constants, and if needed, can use a EEW=16 load.
2023-09-15 15:57:23 -07:00
Philip Reames
ff2622b5ac [RISCV] Optimize gather/scatter to unit-stride memop + shuffle (#66279)
If we have a gather or a scatter whose index describes a permutation of the
lanes, we can lower this as a shuffle + a unit strided memory operation.  For
RISCV, this replaces a indexed load/store with a unit strided memory operation
and a vrgather (at worst).

I did not bother to implement the vp.scatter and vp.gather variants of these
transforms because they'd only be legal when EVL was VLMAX.  Given that, they
should have been transformed to the non-vp variants anyways.  I haven't checked
to see if they actually are.
2023-09-15 15:54:32 -07:00
Craig Topper
ac182deee8 [RISCV][GlobalISel] Select ALU GPR instructions
Some instruction selection patterns required for ALU GPR instructions have
already been automatically imported from existing TableGen descriptions -
this patch simply adds testing for them. The first of the GIComplexPatternEquiv
definitions required to select the shiftMaskXLen ComplexPattern has been added.

Some instructions require special handling due to i32 not being a legal
type on RV64 in SelectionDAG so we can't reuse SelectionDAG patterns.

Co-authored-by: Lewis Revill <lewis.revill@embecosm.com>

Reviewed By: nitinjohnraj

Differential Revision: https://reviews.llvm.org/D76445
2023-09-15 15:49:38 -07:00
Philip Reames
37aa07ad31 [RISCV] Move narrowIndex to be a DAG combine over target independent nodes
In D154687, we added a transform to narrow indexed load/store indices of the
form (shl (zext), C).  We can move this into a generic transform over the
target independent nodes instead, and pick up the fixed vector cases with no
additional work required.  This is an alternative to D158163.

Performing this transform points out that we weren't eliminating zero_extends
via the the generic DAG combine.  Adjust the (existing) callbacks so that we
do.

This change *removes* the existing transform on the target specific intrinsic
nodes.  If anyone has a use case this impacts, please speak up.

Note: Reviewed as part of a stack of changes in PR# 66405.
2023-09-15 15:02:14 -07:00
Guozhi Wei
cbdccb30c2 [RA] Split a virtual register in cold blocks if it is not assigned preferred physical register
If a virtual register is not assigned preferred physical register, it means some
COPY instructions will be changed to real register move instructions. In this
case we can try to split the virtual register in colder blocks, if success, the
original COPY instructions can be deleted, and the new COPY instructions in
colder blocks will be generated as register move instructions. It results in
fewer dynamic register move instructions executed.

The new test case split-reg-with-hint.ll gives an example, the hot path contains
24 instructions without this patch, now it is only 4 instructions with this
patch.

Differential Revision: https://reviews.llvm.org/D156491
2023-09-15 19:52:50 +00:00
Philip Reames
52b33ff760 [RISCV] Avoid toggling VL for hidden splat case in constant buildvector lowering
We have the analogous case in the single insert path.  The reasoning here is that if the original VL fits in LMUL1, we'd prefer to clobber a few extra dead lanes than to force two VL toggles.  VTYPE toggles are generally cheaper than VL toggles.
2023-09-15 12:33:21 -07:00
Paul Walker
c7d65e4466 [IR] Enable load/store/alloca for arrays of scalable vectors.
Differential Revision: https://reviews.llvm.org/D158517
2023-09-14 13:49:01 +00:00
Jianjian Guan
c31dda4e6e
[RISCV] Update Zicntr and Zihpm to version 2p0 (#66323) 2023-09-14 15:43:50 +08:00
Simon Pilgrim
e6b85c3027 [DAG] FoldSetCC - add missing icmp(X,undef) -> isTrueWhenEqual case (REAPPLIED)
Followup to D59363 which failed to handle the icmp(X,undef) -> isTrueWhenEqual case - similar to llvm::ConstantFoldCompareInstruction

As discussed on the review, this is affecting some previously reduced test cases, but will also prevent reductions from relying on this inconsistent behaviour in the future.

Reapplied after reversion at e1e3c75c7dad72 with a tweak to the pseudo-probe-peep.ll test

Differential Revision: https://reviews.llvm.org/D158068
2023-09-13 12:33:39 +01:00
Simon Pilgrim
e1e3c75c7d Revert rG6c56cf71ee82ec3a28e0dfc2b751bd10c16929da "[DAG] FoldSetCC - add missing icmp(X,undef) -> isTrueWhenEqual case"
Need to address a missed test change
2023-09-13 11:27:47 +01:00
Simon Pilgrim
6c56cf71ee [DAG] FoldSetCC - add missing icmp(X,undef) -> isTrueWhenEqual case
Followup to D59363 which failed to handle the icmp(X,undef) -> isTrueWhenEqual case - similar to llvm::ConstantFoldCompareInstruction

As discussed on the review, this is affecting some previously reduced test cases, but will also prevent reductions from relying on this inconsistent behaviour in the future.

Differential Revision: https://reviews.llvm.org/D158068
2023-09-13 11:01:58 +01:00
Yingwei Zheng
4793c2c3de
[DAGCombiner][RISCV] Prefer to sext i32 non-negative values (#65984)
By default, `DAGCombiner` folds `sext x` to `zext x` when `x` is
non-negative. It will generate redundant `zext` inst seq on riscv64
(typically `slli (srli x, 32), 32`).
godbolt: https://godbolt.org/z/osf6adP1o
This patch applies the transform iff `zext` is **cheaper** than `sext`.
2023-09-12 19:02:35 +08:00
Fangrui Song
cfc1a87878 [test] Change llc -march= to -mtriple= & llvm-mc -arch= to -triple=
Similar to 806761a7629df268c8aed49657aeccffa6bca449
2023-09-11 15:11:01 -07:00
Fangrui Song
806761a762 [test] Change llc -march= to -mtriple=
The issue is uncovered by #47698: for IR files without a target triple,
-mtriple= specifies the full target triple while -march= merely sets the
architecture part of the default target triple, leaving a target triple which
may not make sense, e.g. riscv64-apple-darwin.

Therefore, -march= is error-prone and not recommended for tests without a target
triple. The issue has been benign as we recognize $unknown-apple-darwin as ELF instead
of rejecting it outrightly.
2023-09-11 14:42:37 -07:00
Philip Reames
5352c79398
[RISCV] Add a combine to form masked.load from unit strided load (#65674)
Add a DAG combine to form a masked.load from a masked_strided_load
intrinsic with stride equal to element size. This covers a couple of
extra test cases, and allows us to simplify and common some existing
code on the concat_vector(load, ...) to strided load transform.

This is the first in a mini-patch series to try and generalize our
strided load and gather matching to handle more cases, and common up
different approaches to the same problems in different places.
2023-09-11 13:01:14 -07:00
Philip Reames
299d710e3d [RISCV] Lower fixed vectors extract_vector_elt through stack at high LMUL
This is the extract side of D159332. The goal is to avoid non-linear costing on patterns where an entire vector is split back into scalars. This is an idiomatic pattern for SLP.

Each vslide operation is linear in LMUL on common hardware. (For instance, the sifive-x280 cost model models slides this way.) If we do a VL unique extracts, each with a cost linear in LMUL, the overall cost is O(LMUL2) * VLEN/ETYPE. To avoid the degenerate case, fallback to the stack if we're beyond LMUL2.

There's a subtly here. For this to work, we're *relying* on an optimization in LegalizeDAG which tries to reuse the stack slot from a previous extract. In practice, this appear to trigger for patterns within a block, but if we ended up with an explode idiom split across multiple blocks, we'd still be in quadratic territory. I don't think that variant is fixable within SDAG.

It's tempting to think we can do better than going through the stack, but well, I haven't found it yet if it exists. Here's the results for sifive-s280 on all the variants I wrote (all 16 x i64 with V):

output/sifive-x280/linear_decomp_with_slidedown.mca:Total Cycles:      20703
output/sifive-x280/linear_decomp_with_vrgather.mca:Total Cycles:      23903
output/sifive-x280/naive_linear_with_slidedown.mca:Total Cycles:      21604
output/sifive-x280/naive_linear_with_vrgather.mca:Total Cycles:      22804
output/sifive-x280/recursive_decomp_with_slidedown.mca:Total Cycles:      15204
output/sifive-x280/recursive_decomp_with_vrgather.mca:Total Cycles:      18404
output/sifive-x280/stack_by_vreg.mca:Total Cycles:      12104
output/sifive-x280/stack_element_by_element.mca:Total Cycles:      4304

I am deliberately excluding scalable vectors. It functionally works, but frankly, the code quality for an idiomatic explode loop is so terrible either way that it felt better to leave that for future work.

Differential Revision: https://reviews.llvm.org/D159375
2023-09-11 10:49:17 -07:00
Luke Lau
e33f3f09b8
[RISCV] Shrink vslidedown when lowering fixed extract_subvector (#65598)
As noted in
https://github.com/llvm/llvm-project/pull/65392#discussion_r1316259471,
when lowering an extract of a fixed length vector from another vector,
we don't need to perform the vslidedown on the full vector type. Instead
we can extract the smallest subregister that contains the subvector to
be extracted and perform the vslidedown with a smaller LMUL. E.g, with
+Zvl128b:

v2i64 = extract_subvector nxv4i64, 2

is currently lowered as

vsetivli zero, 2, e64, m4, ta, ma
vslidedown.vi v8, v8, 2

This patch shrinks the vslidedown to LMUL=2:

vsetivli zero, 2, e64, m2, ta, ma
vslidedown.vi v8, v8, 2

Because we know that there's at least 128*2=256 bits in v8 at LMUL=2,
and we only need the first 256 bits to extract a v2i64 at index 2.

lowerEXTRACT_VECTOR_ELT already has this logic, so this extracts it out
and reuses it.

I've split this out into a separate PR rather than include it in #65392,
with the hope that we'll be able to generalize it later.

This patch refactors extract_subvector lowering to lower to
extract_subreg directly, and to shortcut whenever the index is 0 when
extracting a scalable vector. This doesn't change any of the existing
behaviour, but makes an upcoming patch that extends the scalable path
slightly easier to read.
2023-09-11 17:25:12 +01:00
Luke Lau
46f3ea5952
[RISCV] Add extract_subvector tests for a statically-known VLEN. NFC (#65389)
This is partly a precommit for an upcoming patch, and partly to remove
the fixed length LMUL restriction similarly to what was done in
https://reviews.llvm.org/D158270, since it's no longer that relevant.
2023-09-11 16:28:53 +01:00
Yeting Kuo
1f15155d5e
[RISCV] Disable zcmp push/pop for variadic functions. (#65302)
Variadic function needs a save region for variable arguement and the
region is possible to be overlaped with the region of zcmp push/pop
used.
2023-09-11 13:09:01 +08:00
Philip Reames
0a298277d3 [RISCV] Add a negative case for strided load matching
This covers the bug identified in review of pr 65777.
2023-09-08 13:33:52 -07:00
Philip Reames
5ee7dc04de
[RISCV] Match gather(splat(ptr)) as zero strided load (#65769)
We were already handling the case where the broadcast was being done via
a GEP, but we hadn't handled the case of a broadcast via a shuffle.
2023-09-08 09:37:52 -07:00
Philip Reames
8dd87a5f57 [RISCV] Add gather test coverage for non-intptr index widths
Note that these are non-canonical.  At IR, we will generally canonicalize to the intptrty width form if knownbits allows.
2023-09-08 08:53:19 -07:00
Philip Reames
b4a99f1cd6
[RISCV] Lower constant build_vectors with few non-sign bits via vsext (#65648)
If we have a build_vector such as [i64 0, i64 3, i64 1, i64 2], we
instead lower this as vsext([i8 0, i8 3, i8 1, i8 2]). For vectors with
4 or fewer elements, the resulting narrow vector can be generated via
scalar materialization.

For shuffles which get lowered to vrgathers, constant build_vectors of
small constants are idiomatic. As such, this change covers all shuffles
with an output type of 4 or less.

I deliberately started narrow here. I think it makes sense to expand
this to longer vectors, but we need a more robust profit model on the
recursive expansion. It's questionable if we want to do the zsext if
we're going to generate a constant pool load for the narrower type
anyways.

One possibility for future exploration is to allow the narrower VT to be
less than 8 bits. We can't use vsext for that, but we could use
something analogous to our widening interleave lowering with some extra
shifts and ands.
2023-09-07 16:01:16 -07:00
Philip Reames
063524e35a [RISCV] Add coverage for missing gather/scatter combines 2023-09-07 11:57:30 -07:00
Jianjian Guan
fab2594968
[RISCV][NFC] Remove unused checkline (#65560) 2023-09-07 16:24:31 +08:00
Craig Topper
bb810d8fa0 [RISCV] Disable machine verifier in gisel-commandline-option.ll. NFC
Hopefully this fixes the expensive checks build.
2023-09-06 09:32:32 -07:00
Luke Lau
74f985b793
[RISCV] Remove -riscv-v-vector-bits-min in tests. NFC (#65404)
V implies Zvl128b, but a lot of the fixed vector tests also redundantly
specify -riscv-v-vector-bits-min=128. This patch removes them where
there isn't another minimum vlen being tested for, and for cases where
Zve* is being used Zvl128b was added to maintain the old test diff (and
because an awkward vlen probably isn't interesting to test for). Other
places where -risc-v-vector-bits-min were being used were replaced with
Zvl.
2023-09-06 10:43:41 +01:00
Kito Cheng
af9b25f9db [RISCV] Optimize floating point scalar move and splat
In D158086, we limit all floating point scalar move and splat can't fuse
vsetvli with different SEW, and this patch try to relax the constraint
as possible by introducing new SEW demand type:
SEWGreaterThanOrEqualAndLessThan64, that allow SEW fused with larger
SEW, but constraint it can't fused with SEW=64.

Reviewed By: rogfer01

Differential Revision: https://reviews.llvm.org/D158177
2023-09-06 16:39:30 +08:00
laichunfeng
71b5f57f0d [RISCV] Adjust first sp size to use c.addi16sp.
addi sp, sp, 512 may be used to recover the sp in the epilogue
when stack size is larger than 2047(2^11 - 1), however, it can
not be compressed using C extension, and addi sp, sp, 496 is
able to be compressed, so try to use 496 as the ajust amount of
the fisrt sp if function doesn't need extra instructions after
adjust.

Reviewed By: wangpc

Differential Revision: https://reviews.llvm.org/D159431
2023-09-06 14:26:52 +08:00
Craig Topper
2a7b8ab07c
[RISCV] Use add.uw for (or (and X, 0xFFFFFFFF), Y) if Y has zeroes in the lower 32 bits. (#65402) 2023-09-05 21:05:53 -07:00
Philip Reames
de34d39b66 [RISCV] Cap build vector cost to avoid quadratic cost at high LMULs
Each vslide1down operation is linear in LMUL on common hardware. (For instance, the sifive-x280 cost model models slides this way.) If we do a VL unique inserts, each with a cost linear in LMUL, the overall cost is O(VL*LMUL).  Since VL is a linear function of LMUL, this means the current lowering is quadradic in both LMUL and VL.  To avoid the degenerate case, fallback to the stack if the cost is more than a fixed (linear) threshold.

For context, here's the sifive-x280 llvm-mca results for the current lowering and stack based lowering for each LMUL (using e64). Assumes code was compiled for V (i.e. zvl128b).
  buildvector_m1_via_stack.mca:Total Cycles: 1904
  buildvector_m2_via_stack.mca:Total Cycles: 2104
  buildvector_m4_via_stack.mca:Total Cycles: 2504
  buildvector_m8_via_stack.mca:Total Cycles: 3304
  buildvector_m1_via_vslide1down.mca:Total Cycles:  804
  buildvector_m2_via_vslide1down.mca:Total Cycles:  1604
  buildvector_m4_via_vslide1down.mca:Total Cycles:  6400
  buildvector_m8_via_vslide1down.mca:Total Cycles: 25599

There are other schemes we could use to cap the cost. The next best is recursive decomposition of the vector into smaller LMULs. That's still quadratic, but with a better constant. However, stack based seems to cost better on all LMULs, so we can just go with the simpler scheme.

Arguably, this patch is fixing a regression introduced with my D149667 as before that change, we'd always fallback to the stack, and thus didn't have the non-linearity.

Differential Revision: https://reviews.llvm.org/D159332
2023-09-05 09:03:26 -07:00
Craig Topper
fa31ce5320
[RISCV][GISel] Add gisel-commandline-option.ll similar to AArch64. (#65299)
This allows us to see the pass pipeline for GlobalISel.
2023-09-05 09:01:50 -07:00
Luke Lau
2fc6fadeaf [RISCV] Fix typo in test title. NFC 2023-09-05 15:57:18 +01:00
Luke Lau
6098d7d5f6 [RISCV] Lower shuffles as rotates without zvbb
Now that the codegen for the expanded ISD::ROTL sequence has been improved,
it's probably profitable to lower a shuffle that's a rotate to the
vsll+vsrl+vor sequence to avoid a vrgather where possible, even if we don't
have the vror instruction.

This patch relaxes the restriction on ISD::ROTL being legal in
lowerVECTOR_SHUFFLEAsRotate. It also attempts to do the lowering twice: Once
if zvbb is enabled before any of the interleave/deinterleave/vmerge lowerings,
and a second time unconditionally just before it falls back to the vrgather.
This way it doesn't interfere with any of the above patterns that may be more
profitable than the expanded ISD::ROTL sequence.

Reviewed By: craig.topper

Differential Revision: https://reviews.llvm.org/D159353
2023-09-04 09:35:12 +01: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
Philip Reames
7c4f455992 {RISCV] Add test coverage for fully scalarizing a vector
This pattern comes up heavily when partially vectorizing a forrest in SLP.
2023-09-01 11:17:42 -07:00
Craig Topper
319aba645f [RISCV] Teach MatInt to use (ADD_UW X, (SLLI X, 32)) to materialize some constants.
If the high and low 32 bits are the same, we try to use
(ADD X, (SLLI X, 32)) but that only works if bit 31 is clear since
the low 32 bits will be sign extended.

If we have Zba we can use add.uw to zero the sign extended bits.

Reviewed By: reames, wangpc

Differential Revision: https://reviews.llvm.org/D159253
2023-08-31 20:24:34 -07:00
Jim Lin
10c8619701 [RISCV] Remove unused check prefixes for tests. NFC 2023-09-01 10:42:53 +08:00