5339 Commits

Author SHA1 Message Date
Philip Reames
db746c65b1
[RISCV] Allow constants in tryFoldSelectIntoOp (#157376)
For simm12 constants this allows the use of e.g. addi/xori, and for
non-simm12 constants seems to still produce better code than the default
lowering.
2025-09-08 13:11:34 -07:00
Philip Reames
c2c7b7efab [RISCV] Add coverage for the tryFoldSelectIntoOp combine with constants
An upcoming change will relax the requirement that the operands be
non-constant.
2025-09-07 17:01:26 -07:00
Craig Topper
151c6edd45
[RISCV] Check for legal type before calling getSimpleValueType() in matchSplatAsGather. (#157188)
This just reorders existing so we do the legal type check first.

In this particular test case we're also protected by the i1 check that I
also moved earlier.

Fixes #157177.
2025-09-05 22:00:38 -07:00
Luke Lau
5facf08193
[RISCV] Use non-vp select in RISCVGatherScatterLowering. NFCish (#157071)
Similar to #157070 and #157068, let RISCVVLOptimizer do the work.
2025-09-06 11:46:02 +08:00
Philip Reames
1455b3cabd
[RISCV] Reorganize select lowering to pull binop expansion early (#156974)
This is purely stylistic, but I think makes the code easier to follow.

It isn't quite NFC because it undoes the arithmetic lowering added yesterday in #156957 for the select c, simm12, 0 cases for a processor with both conditional move forwarding and zicond.  What the right code is for that combination of features is currently an open question.
2025-09-05 18:13:53 -07:00
Craig Topper
7506900b88
[RISCV] Add th.ext(u) to isSignExtendingOpW in RISCVOptWInstrs. (#157147)
These instructions extract and range of bits, move them to the LSB
then sign or zero extend the result to fill the upper bits. If
the extracted bits is small enough then the result will have 33
sign bits.
2025-09-05 12:05:28 -07:00
Craig Topper
faab8f76d5
[RISCV] Add th.ext(u) to RISCVDAGToDAGISel::hasAllNBitUsers. (#157133)
These instructions are being used by the scalar efficiency SIG to
determine if we should have a standard instruction. Improving our
support for these instructions may give better data for their analysis.

I'll follow up by adding this to RISCVOptWInstrs too which will remove
the 'w' suffixes added here.
2025-09-05 11:57:26 -07:00
Craig Topper
85dbe18bee
[RISCV] Add -print-pipeline-passes test as follow up to #156798. NFC (#157011) 2025-09-05 08:07:39 -07:00
Shaoce SUN
eb623e650b
[RISCV][GISel] Lower G_ABDS and G_ABDU (#155888)
Implementation follows the `ISD::ABDS` handling in
`RISCVTargetLowering`.
2025-09-05 21:16:35 +08:00
Luke Lau
95fabfd9a6
[RISCV][LoopIdiomVectorize] Replace vp.icmp -> regular icmp. NFCish (#157068)
To match the general direction of the loop vectorizer and reduce our
dependency on [trivial VP
intrinsics](https://discourse.llvm.org/t/rfc-remove-codegen-support-for-trivial-vp-intrinsics-in-the-risc-v-backend/87999),
replace the use of vp.icmp with a regular icmp. RISCVVLOptimizer can
take care of propagating VL.
2025-09-05 11:09:07 +00:00
Florian Hahn
74ec38fad0
[SCEV] Fold (C * A /u C) -> A, if A is a multiple of C and C a pow-of-2. (#156730)
Alive2 Proof: https://alive2.llvm.org/ce/z/JoHJE9

PR: https://github.com/llvm/llvm-project/pull/156730
2025-09-05 08:45:13 +00:00
Sudharsan Veeravalli
e71ec0f7a4
[RISCV] Use QC_E_LI to materialise addresses (#155819)
This is only used in the small code model and when `Xqcili` is enabled,
where addresses would otherwise use `LUI/ADDI`. Other code models need
to use pc-relative addressing. This patch does this for global/block
addresses, constant pools and jumptables.

Overall, this gives a better code size saving as` QC.E.LI` is easier to
relax to `QC.LI/LI` etc than` LUI/ADDI` (especially when the `LUI/ADDI`
might have sharing, or be split apart). `QC.E.LI` has the
`RISCV_QC_E_32` local relocation attached to it.
2025-09-05 12:58:28 +05:30
Brandon Wu
7fb1dc08d2
[RISCV] Support ZVqdot Codegen and C intrinsics (#154915)
spec: https://github.com/riscv/riscv-dot-product/tree/main

Node: we pack 4 int8/uint8 element in rs1 to a uint32.
2025-09-05 11:38:58 +08:00
Luke Lau
dc2ed00432
[RISCV] Handle non uimm5 VL constants in isVLKnownLE (#156639)
If a VL operand is > 31 then it will be materialized into an ADDI $x0,
imm. We can reason about it by peeking at the virtual register
definition which allows RISCVVectorPeephole and RISCVVLOptimizer to
catch more cases.

There's a separate issue with RISCVVLOptimizer where the materialized
immediate may not always dominate the instruction we want to reduce the
VL of, but this is left to another patch.
2025-09-05 00:25:48 +00:00
Philip Reames
91e85cc950
[RISCV] Use arithmetic for select c, 0, simm12 even with zicond (#156957)
The arithmetic expansion requires fewer registers, and is often fewer
instructions. The critical path does increase by (up to) one
instruction.

This is a sub-case of the expansion we do without zicond, but restricted
specifically to the simm12 case. In the general case where the other
source is a register using zicond is likely better. (Edit: While
technically true, this is a bit misleading, we do this in
combineSelectToBinOp which is also used in the zicond path, just further
down.)
2025-09-04 14:51:14 -07:00
Min-Yih Hsu
b45582fe98
[RISCV][VLOPT] Support segmented store instructions (#155467)
Add RISCVVLOptimizer supported for unit-stride, strided, and indexed
strided segmented stores. The biggest change was adding the capability
to look through INSERT_SUBREG, which was used for composing segmented
register class values.

Fix #149350
2025-09-04 19:35:35 +00:00
Min-Yih Hsu
b4a43b3bfa [RISCV][NFC] Add zeroext attribute to evl arguments in vp-vector-interleaved-access.ll test
Such that we can merge most of the RV32 & RV64 check lines and get rid
of redundant add.uw instructions.

NFC.
2025-09-04 11:54:56 -07:00
Philip Reames
e90ab31024 [RISCV] Add coverage for select between simm12 constant and zero [nfc]
The zicond codegen for this involves an extra register for basically
no purpose; to be addressed in an upcoming change.
2025-09-04 08:14:07 -07:00
Craig Topper
97d4c7d1eb
[RISCV] Fold (X & (7 << 29)) == 0 -> (srliw X, 29) == 0 for RV64. (#156769)
This is similar to the recently added (X & -4096) == 0 -> (X >> 12) ==
0,
but operating only on the lower 32 bits.
    
This also removes the (X & (1 << 31)) == 0 -> (xor (srliw X, 31), 1)
isel pattern. seqz and xori 1 should have similar cost and encoding
size.
2025-09-03 22:16:05 -07:00
Craig Topper
3fa3932e98
[RISCV] Correct getOperandLog2EEW for VCOMPRESS_VM. (#156719)
The mask operand has EEW=1.
2025-09-03 22:14:42 -07:00
Min-Yih Hsu
a4104abb2b
[RISCV] Fold (vslide1up undef, v, (extract_elt x, 0)) into (vslideup x, v, 1) (#154847)
To a slide1up, if the scalar value we're sliding in was extracted from
the first element of a vector, we can use a normal vslideup of 1 instead
with its passthru being that vector. This can eliminate an
extract_element instruction (i.e. vfmv.f.s, vmv.x.s).

---------

Co-authored-by: Craig Topper <craig.topper@sifive.com>
2025-09-03 21:20:47 -07:00
Luke Lau
a95edec28a
[RISCV] Use vleff's AVL when output VL doesn't dominate in RISCVVLOptimizer (#156618)
If an instruction's demanded VL is a virtual register defined by a vleff
instruction, it might not dominate and fail to have its VL reduced.

In leiu of the output VL, we can try and use the AVL passed to the vleff
itself since it will be at least greater than or equal the original VL.

I tried to create an LLVM IR test for this in but didn't have any luck
because the scheduler kept on moving the instruction past the vleff, so
it always dominated. So I've just included some mir tests instead.
2025-09-04 11:56:29 +08:00
Craig Topper
fd8f549092
[RISCV] Add exhausted_gprs_fprs test to calling-conv-half.ll. NFC (#156586)
The existing test case only exhausted the GPRs so the stack wasn't tested if FPRs were also available for arguments. This new test exhausts the GPRs and FPRs.
2025-09-03 16:17:34 -07:00
Amara Emerson
4829dedfa9
[GlobalISel] Add multi-way splitting support for wide scalar shifts. (#155353)
This patch implements direct N-way splitting for wide scalar shifts
instead
of recursive binary splitting. For example, an i512 G_SHL can now be
split
directly into 8 i64 operations rather than going through i256 -> i128 ->
i64.

The main motivation behind this is to alleviate (although not entirely
fix)
pathological compile time issues with huge types, like i4224. The
problem
we see is that the recursive splitting strategy combined with our messy
artifact combiner ends up with terribly long compiles as tons of
intermediate
artifacts are generated, and then attempted to be combined ad-nauseum.

Going directly from the large shifts to the destination types
short-circuits
a lot of these issues, but it's still an abuse of the backend and
front-ends
should never be doing this sort of thing.
2025-09-03 10:25:52 -07:00
Kane Wang
7d6e72f110
[RISCV][GlobalISel] Lower G_ATOMICRMW_SUB via G_ATOMICRMW_ADD (#155972)
RISCV does not provide a native atomic subtract instruction, so this
patch lowers `G_ATOMICRMW_SUB` by negating the RHS value and performing
an atomic add. The legalization rules in `RISCVLegalizerInfo` are
updated accordingly, with libcall fallbacks when `StdExtA` is not
available, and intrinsic legalization is extended to support
`riscv_masked_atomicrmw_sub`.

For example, lowering

`%1 = atomicrmw sub ptr %a, i32 1 seq_cst`

on riscv32a produces:

```
li      a1, -1
amoadd.w.aqrl   a0, a1, (a0)
```

On riscv64a, where the RHS type is narrower than XLEN, it currently
produces:

```
li      a1, 1
neg     a1, a1
amoadd.w.aqrl   a0, a1, (a0)
```

There is still a constant-folding or InstConbiner gap. For instance,
lowering

```
%b = sub i32 %x, %y
%1 = atomicrmw sub ptr %a, i32 %b seq_cst
```

generates:

```
subw    a1, a1, a2
neg     a1, a1
amoadd.w.aqrl   a0, a1, (a0)
```

This sequence could be optimized further to eliminate the redundant neg.
Addressing this may require improvements in the Combiner or Peephole
Optimizer in future work.

---------

Co-authored-by: Kane Wang <kanewang95@foxmail.com>
2025-09-03 08:42:31 -07:00
quic_hchandel
d0363815dd
[RISCV] Add changes to have better coverage for qc.insb and qc.insbi (#154135)
Before this patch, the selection for `QC_INSB` and `QC_INSBI` entirely
happens in C++, and does not support more than one non-constant input.

This patch seeks to rectify this shortcoming, by moving the C++ into a
target-specific DAGCombine, and adding `RISCV::QC_INSB`. One advantage
is this simplifies the code for handling `QC_INSBI`, as the C++ no
longer needs to choose between the two instructions based on the
inserted value (this is still done, but via ISel Patterns).

Another advantage of the DAGCombine is that this introduction can also
shift the inserted value to the `QC_INSB`, which our patterns need (and
were previously doing to the constant), and this shift can be
CSE'd/optimised with any prior shifts, if they exist. This allows the
inserted value to be variable, rather than a constant.
2025-09-03 12:35:38 +05:30
Craig Topper
8f50921cef
[RISCV] Add Zfh RUN lines to calling-conv-half.ll. NFC (#156562)
We had these RUN lines in our downstream and I couldn't tell for sure
that we had another Zfh calling convention test upstream.

Note we should fix the stack test to also exhaust the GPRs to make it
test the stack for ilp32f/lp64f. This was an existing issue in the
testing when F was enabled.
2025-09-02 21:53:35 -07:00
Mitch
cb89ffdd34
[RISCV] Fix incorrect folding of select on ctlz/cttz (#155231)
This patch tries to fix
[#155014](https://github.com/llvm/llvm-project/issues/155014). The
pattern of `ctlz`/`cttz` -> `icmp` -> `select` can occur when accounting
for targets which don't support `cttz(0)` or `ctlz(0)`. We can replace
this with a mask, but **only on power-of-2 bitwidths**.
2025-09-03 09:13:54 +08:00
Luke Lau
410764cff5
[RISCV] Commute True in foldVMergeToMask (#156499)
In order to fold a vmerge into a pseudo, the pseudo's passthru needs to
be the same as vmerge's false operand.

If they don't match we can try and commute the instruction if possible,
e.g. here we can commute v9 and v8 to fold the vmerge:

    vsetvli zero, a0, e32, m1, ta, ma
    vfmadd.vv v9, v10, v8
    vsetvli zero, zero, e32, m1, tu, ma
    vmerge.vvm v8, v8, v9, v0

    vsetvli zero, a0, e32, m1, tu, mu
    vfmacc.vv v8, v9, v10, v0.t

Previously this wasn't possible because we did the peephole in
SelectionDAG, but now that it's been migrated to MachineInstr in #144076
we can reuse the commuting infrastructure in TargetInstrInfo.

This fixes the extra vmv.v.v in the "mul" example here:
https://github.com/llvm/llvm-project/issues/123069#issuecomment-3137997141

It should also allow us to remove the isel patterns described in #141885
later.
2025-09-03 01:02:03 +00:00
Min-Yih Hsu
6c3db644ed
[RISCV] Use slideup to lower build_vector when all operand are (extract_element X, 0) (#154450)
The general lowering of build_vector starts with splatting the first
operand before sliding down other operands one-by-one. However, if the
every operands is an extract_element from the first vector element, we
could use the original _vector_ (source of extraction) from the last
build_vec operand as start value before sliding up other operands (in
reverse order) one-by-one. By doing so we can avoid the initial splat
and eliminate the vector to scalar movement later, which is something we
cannot do with vslidedown/vslide1down.

---------

Co-authored-by: Craig Topper <craig.topper@sifive.com>
Co-authored-by: Luke Lau <luke@igalia.com>
2025-09-02 09:45:45 -07:00
Jim Lin
2155427450 [RISCV] Split the attribute test for Qualcomm to attributes-qc.ll. NFC. 2025-09-02 09:01:55 +08:00
Jim Lin
32868480cd [RISCV] Split the attribute test for Andes to attributes-andes.ll. NFC. 2025-09-02 09:01:55 +08:00
UmeshKalappa
1debf23d7a
[RISC-V] Added the mips extension instructions like ehb,ihb and pause etc for MIPS RV64 P8700. (#155747)
Please refer the
https://mips.com/wp-content/uploads/2025/06/P8700_Programmers_Reference_Manual_Rev1.84_5-31-2025.pdf
for more information .

and files like RISCVInstrInfoXMips.td clang formatted .

No Regression found.

---------

Co-authored-by: Craig Topper <craig.topper@sifive.com>
2025-09-01 10:40:28 +02:00
Sudharsan Veeravalli
46dc8ef2d3
[RISCV] Compress shxadd to qc.c.muliadd when rd = rs2 (#155843)
Do this when Zba and Xqciac are both enabled.
2025-09-01 12:34:25 +05:30
Jim Lin
0fb1b56b2c [RISCV] Split the attribute test for THead to attributes-thead.ll. NFC. 2025-09-01 13:14:27 +08:00
Jianjian Guan
2ff7a4ccc9
[RISCV][NFC] Simplify some rvv regbankselect cases (#155961) 2025-09-01 10:59:54 +08:00
Philip Reames
b062aad57a
[CodeGen] Drop disjoint flag when reassociating (#156218)
This fixes a latent miscompile. To understand why the flag can't be
preserved, consider the case where a0=0, a1=0, a2=-1, and s3=-1.
2025-08-31 11:23:15 -07:00
Craig Topper
f3f717bbfa
[RISCV] Add computeKnownBitsForTargetNode for RISCVISD::SRAW. (#156191)
This node reads the lower 32 bits, shifts it right arithmetically
then sign extends to i64. If we know some of the lower 32 bits we
can propagate that information.
    
For the test case I had to find something that didn't get optimized
before type legalizaton and didn't get type legalized to a sign
extended value. The bswap gets type legalized to (lshr (bswap), 32).
2025-08-30 18:27:18 -07:00
Philip Reames
31c9198ea0 [RISCV] Add test coverage for reassociation with poison generating flags
The 'add' case is correct, the 'or' case is coverage for an upcoming
change to fix a bug w.r.t flag preservation.
2025-08-30 18:18:10 -07:00
Jim Lin
0a99348e96
[RISCV] Split the attribute test for xsfvfwmaccqqq to attributes-sifive.ll. NFC. (#155973) 2025-08-29 05:40:51 +00:00
Craig Topper
ff22071586
[RISCV] Add a conditional-cmv-fusion RUN line to select-binop-identity.ll. NFC (#155950)
Trying to clear out some test file changes from our downstream.
2025-08-28 19:35:58 -07:00
Philip Reames
552c0d14d1
[RISCV] Use XORI/SLLI/ADDI to when materializing select of constants (#155845)
This case is the inverse of the one introduced in #155644. The
complexity with the inversion is that we need to also invert the
condition before shifting it. I had originally planned to only do so
when the condition was "cheaply" invertible (i.e. didn't require the
xori), but when looking more closely at the diffs I noticed that while
the XORI prevents this from being an icount improvement, and actually
lengthens slightly the critical path, it does still reduce the number of
registers needed.
2025-08-28 10:49:46 -07:00
Djordje Todorovic
9a99896387
[TargetLoweringObjectFile] Handle riscv BE (#155166)
Add DWARF exception handling support for riscv big-endian targets.
More CodeGen changes related to riscvbe are coming.
2025-08-28 17:04:47 +02:00
Axel Sorenson
c249a9ab62
[GISel] Funnel shift combiner port from SelectionDAG ISel to GlobalISel (#135132)
The funnel shift combiner rule from
4a3708cd6b
is currently missing from GlobalISel. The following is a port of that
combiner to GlobalISel.
2025-08-27 21:50:40 -07:00
Shaoce SUN
a7451063b3
[RISCV][GISel] Lower G_SSHLSAT and G_USHLSAT (#155642) 2025-08-28 10:32:17 +08:00
Jim Lin
717771e13d
[RISCV] Implement MC support for Zvfbfa extension (#151106)
This patch adds MC support for Zvfbfa
https://github.com/aswaterman/riscv-misc/blob/main/isa/zvfbfa.adoc

Since Zvfbfa implies Zve32f, vector floating-point instructions can be
used directly with Zvfbfa extension.
2025-08-28 01:36:10 +00:00
Philip Reames
58df9b1a01
[RISCV] Enable LUi/AUIPC+ADDI/ADDIW reg alloc hint by default (#155693)
This block of code is currently conditional on the fusions being enabled
but as far as I can tell, does no harm to generally enable. The net
effect is the generically compiled code runs slightly better on machines
with this fusion.

The actual motivation is merely to stop confusing myself when I see the
sequence in code; the register allocators choice to sometimes blow two
registers instead of one is just generally weird, and my eyes spot it
when scanning disassembly.

(Note that this is just the regalloc hint; the scheduling changes remain
conditional, and probably should remain so.)
2025-08-27 15:59:08 -07:00
daniel-trujillo-bsc
658a931c5b
[CodeGen][RISCV] Add support of RISCV nontemporal to vector predication instructions. (#153033)
This PR adds support for VP intrinsics to be aware of the nontemporal
metadata information.
2025-08-27 15:48:33 -07:00
Philip Reames
811880a502
[RISCV] Use SLLI/ADDI to when materializing select of constants (#155644)
This avoids the need to materialize the difference explicitly, and thus
reduces register pressure when the condition val is otherwise unused.
2025-08-27 10:31:06 -07:00
Craig Topper
82917c8c99
[RISCV] Add SRAW to ComputeNumSignBitsForTargetNode. (#155564) 2025-08-27 09:25:13 -07:00