7692 Commits

Author SHA1 Message Date
Sam Elliott
49c052363b
[RISCV] Use ADDD for GPR Pair Move with P (#180671) 2026-02-10 12:59:06 -08:00
Craig Topper
f134b802ee
[RISCV] Refactor the MC layer SiFive VCIX classes. (#180433)
My initial goal was to name bits {19-15} as either rs1, vs1, or imm as
appropriate.

The VCIX instructions effectively have 3 properties that are combined:
the type of bits 19-15 (determined by funct3), how many vector registers
are sources (determined by funct6), and whether vd is a written or not
(determined by vm).

I found the VCIXInfo class very hard to read and understand. This patch
breaks it up into simpler steps and moves some properties to flags in
the existing VCIXType classs. A new VCIXRs1Info class is added to
contain the properties for bits 19-15. The VCIXInfo now combines the
properties from these 2 classes and the HaveOutputDst flag to create the
various things needed to build the final instruction. To reduce the
number of template arguments, the VCIXInfo is passed all the way down to
the base class.

Much of the refactoring in this patch was accomplished with AI. I have
looked at the diffs in the output tablegen files to verify it works as
expected. RISCVGenInstrInfo.inc only changes line number comments.
RISCVGenDisassembler.inc doesn't change at all as expected.
RISCVGenMCCodeEmitter.inc changes due to the different field names and
orders in the record.
2026-02-10 12:34:15 -08:00
Craig Topper
f668c9ff2b
[RISCV] Add (BSETI x0, 11) to isLoadImm for optimizeCondBranch (#180820)
optimizeCondBranch is looking for immediates that are 1 apart to rewrite
the branch by sharing a constant. BSETI x0, 11 can be used to produce
2048 which is one more than the largest positive constant produced by
addi.
2026-02-10 12:32:36 -08:00
Pengcheng Wang
8c5f31b365
[RISCV] Enable select optimization by default (#178394)
And we add `TuneEnableSelectOptimize` to:
* `generic`
* `generic-ooo`
* `sifive-p550`
* `spacemit-x60`
2026-02-10 16:19:01 +08:00
Craig Topper
f33ea53451
[RISCV] Remove redundant czero in multi-word comparisons (#180485)
When comparing multi-word integers with Zicond, we generate:
  (or (czero_eqz (lo1 < lo2), (hi1 == hi2)),
      (czero_nez (hi1 < hi2), (hi1 == hi2)))

The czero_nez is redundant because when hi1 == hi2 is true, hi1 < hi2 is
already 0. This patch adds a DAG combine to recognize:
  czero_nez (setcc X, Y, CC), (setcc X, Y, eq) -> (setcc X, Y, CC)
when CC is a strict inequality (lt, gt, ult, ugt).

This saves one instruction in 128-bit comparisons on RV64 with Zicond.

Note the czero_nez becomes a czero.eqz in the final assembly because the
seteq is replaced by an xor that produces 0 when the values are equal.

Part of #179584

Assisted-by: claude
2026-02-09 21:48:14 -08:00
Pengcheng Wang
776297b0a6
[RISCV] Rename FeatureEnableSelectOptimize to TuneEnableSelectOptimize (#180496)
It should be a tune feature just like others.
2026-02-10 10:43:25 +08:00
Jim Lin
6bce3fc1a9
[RISCV] Generate 8alt/16alt version error message for zvfofp8min (#180450) 2026-02-10 09:43:51 +08:00
Ryan Buchner
d69ccf3b34
[RISCV] Combine shuffle of shuffles to a single shuffle (#178095)
Compressing to a single shuffle doesn't remove any information and the backend can better apply specific optimizations to a single shuffle.

Addresses #176218.

---------

Co-authored-by: Luke Lau <luke_lau@igalia.com>
2026-02-09 14:48:31 -08:00
Craig Topper
e6a72a1d42
[RISCV] Combine ADDD+WMULSU to WMACCSU (#180454)
Extend the existing combineADDDToWMACC DAG combine to also match
RISCVISD::WMULSU and produce RISCVISD::WMACCSU. This is similar to
how ADDD+UMUL_LOHI is combined to WMACCU and ADDD+SMUL_LOHI is
combined to WMACC.

This patch was generated by AI, but I reviewed it.
2026-02-09 08:51:27 -08:00
Luke Lau
f2d5b3952b
[RISCV] Add cost for @llvm.vector.splice.{left,right} (#179219)
Currently vector splice intrinsics are costed through getShuffleCost
when the offset is fixed. When the offset is variable though we can't
use a shuffle mask so it currently returns invalid.

This implements the cost in RISCVTTIImpl::getIntrinsicInstrCost as the
cost of a slideup and a slidedown, which matches the codegen.

It also implements the type based cost whenever the offset argument
isn't available.

It may be possible to reduce the cost in future when one of the vector
operands is known to be poison, in which case we only generate a single
slideup or slidedown.
2026-02-09 16:11:15 +08:00
Pengcheng Wang
e16f35493c
[RISCV][TTI] Adjust the cost of llvm.abs intrinsic when Zvabd exists
When `Zvabd` exists, `llvm.abs` is lowered to `vabs.v` so the cost
is 1.

Reviewers: mshockwave, topperc, lukel97, skachkov-sc, preames

Reviewed By: topperc

Pull Request: https://github.com/llvm/llvm-project/pull/180146
2026-02-09 15:50:14 +08:00
Pengcheng Wang
972e73b812
[RISCV][CodeGen] Lower ISD::ABS to Zvabd instructions
We add pseudos/patterns for `vabs.v` instruction and handle the
lowering in `RISCVTargetLowering::lowerABS`.

Reviewers: topperc, 4vtomat, mshockwave, preames, lukel97, tclin914

Reviewed By: mshockwave

Pull Request: https://github.com/llvm/llvm-project/pull/180142
2026-02-09 15:21:25 +08:00
Pengcheng Wang
e992593341
[RISCV][CodeGen] Lower abds/abdu to Zvabd instructions
We directly lower `ISD::ABDS`/`ISD::ABDU` to `Zvabd` instructions.

Note that we only support SEW=8/16 for `vabd.vv`/`vabdu.vv`.

Reviewers: mshockwave, lukel97, topperc, preames, tclin914, 4vtomat

Reviewed By: lukel97, topperc

Pull Request: https://github.com/llvm/llvm-project/pull/180141
2026-02-09 15:12:22 +08:00
Pengcheng Wang
151fadecd1
[RISCV][MC] Support experimental Zvabd instructions
The `Zvabd` is for `RISC-V Integer Vector Absolute Difference` and
it provides 5 instructions:

* `vabs.v`: Vector Signed Integer Absolute.
* `vabd.vv`: Vector Signed Integer Absolute Difference.
* `vabdu.vv`: Vector Unsigned Integer Absolute Difference.
* `vwabda.vv`: Vector Signed Integer Absolute Difference And Accumulate.
* `vwabdau.vv`: Vector Unsigned Integer Absolute Difference And Accumulate.

Doc: https://github.com/riscv/integer-vector-absolute-difference

Reviewers: topperc, lukel97, preames, tclin914, asb, kito-cheng, mshockwave

Pull Request: https://github.com/llvm/llvm-project/pull/180139
2026-02-09 14:18:39 +08:00
Mark Zhuang
bd4784a913
[RISCV] Add SpacemiT X100 base scheduling model (#178189)
SpacemiT X100 is a 4-issue, out-of-order, RVA23 processor. This patch
introduces the base scheduling model for scalar instructions. The
scheduling model for RVV will be added in a future update.
2026-02-09 11:36:45 +08:00
Jim Lin
84b5e9f8db
[RISCV] Add used callee-saved registers as implicit/implicit-def registers to save/restore call (#180133)
We should add used callee-saved registers as implicit used to save
libcall and as implicit defined to restore libcall. It likes what we did
for CM_PUSH/CM_POPRET. That can help to construct correct dataflow. In
entry bb, save libcall implicitly uses the callee-saved registers which
live in. And in return bb, restore libcall implicitly defines the
callee-saved registers which live out.
2026-02-09 10:00:32 +08:00
Craig Topper
769b734c02
[RISCV] Combine ADDD with UMUL_LOHI/SMUL_LOHI into WMACCU/WMACC (#180383)
Combine the pattern:
  ADDD(addlo, addhi, UMUL_LOHI(x, y).0, UMUL_LOHI(x, y).1)
into:
  WMACCU(x, y, addlo, addhi)

And similarly for SMUL_LOHI -> WMACC.


This patch was written with AI, but I reviewed it carefully.
2026-02-08 13:39:32 -08:00
Craig Topper
5c826f5172
[RISCV] Emit MULHU/MULHS/UMUL_LOHI/SMUL_LOHI from our custom XLen*2 expansion. (#180379)
We already do all the checks necessary in order to prioritize
MULHU/MULHS/UMUL_LOHI/SMUL_LOHI over MULHSU/WMULSU. We might as
well just emit the nodes instead of letting generic type legalization
redo the checks.

This is slightly different than the default legalization because we
don't have access to ExpandInteger so we have to emit TRUNCATES and
BUILD_PAIR. Not sure if this will result in any differences in practice.
2026-02-08 13:39:15 -08:00
Craig Topper
a563e6bb7e
[RISCV] Add support for forming WMULSU during type legalization. (#180331)
Add a DAG combine to turn it into MULHSU if the lower half result
is unused.
2026-02-08 12:38:56 -08:00
Craig Topper
370764c8cb
[RISCV] Use addd/subd for i64 add/sub for RV32+P. (#180129)
Add RISCVISD opcodes and custom type legalize to them.
2026-02-06 12:42:11 -08:00
Craig Topper
caee8f015e
[RISCV] Add ppair.e and ppaire.w as aliases for pack on RV32 and RV64 respectively (#180100)
Based on this note from
https://jhauser.us/RISCV/ext-P/RVP-baseInstrs-018.pdf

(*1) For RV32, PPAIRE.H is a pseudoinstruction for PACK.
(*2) For RV64, PPAIRE.W is a pseudoinstruction for PACK.
2026-02-06 08:49:47 -08:00
Brandon Wu
d99f1cdd66
[RISCV][llvm] Support INSERT_VECTOR_ELT codegen for P extension (#179471)
Add custom lowering for INSERT_VECTOR_ELT on P extension vector types
using the MVM instruction.

TODO: Handle <4 x i8> on RV64 which is constructed to extract_vector_elt
+ build_vector instead of insert_vector_elt.
2026-02-06 14:12:18 +08:00
Craig Topper
22c5c2583d
[RISCV] Reorder the operands for RISCVISD::PPAIRE_DB. NFC (#180111)
Order the operands so the the low and high part of the rs1 regpair are
first, followed by the low and high part of the rs2 regpair.

Also change the type to use v4i8 for the result so that it's only
shuffling elements not combining elements into a larger elment.

I'm planning to add ADDD and SUBD opcodes that will be defined with the
same operand order allowing RISCVISelDAGToDAG.cpp code to be shared.
2026-02-05 21:35:47 -08:00
Kito Cheng
46423d8169
[RISCV] Fix P-extension instruction names per spec 0.19 (#179961)
Fix instruction naming to match P-extension specification 0.19:
- pnsari.b -> pnsrari.b (Packed Narrowing Shift Right Arithmetic
Rounding)
- pnsari.h -> pnsrari.h
- nsari -> nsrari
- paax.dhx -> paas.dhx (Packed Average Add/Sub, not Add/Add-Cross)

The instruction encodings remain unchanged as they were already correct.

Ref: https://www.jhauser.us/RISCV/ext-P/RVP-baseInstrs-Sail-019.txt
2026-02-06 10:35:24 +08:00
Craig Topper
1ad20b9428
[RISCV] Rename RISCVISD::PPACK_DH->PPAIRE_DB. NFC (#180089)
The instruction was renamed, but we hadn't renamed the ISD opcode.
2026-02-05 17:35:12 -08:00
Craig Topper
313d9ac1cf
[RISCV] Add wmul(u) codegen for RV32+P (#180032)
mulh tests are to make sure we continue to use mulh when only the
upper half is used.
2026-02-05 17:34:25 -08:00
Craig Topper
6c37aa8ffd
[RISCV] Remove P from RISCVISD::PASUB(U)/PMULHSU/PMULHR(U)/PMULHRSU. NFC (#180064)
There's a good chance we'll want to use these for scalar too.

Drop vector type from SDTypeProfile. Remove PMULHSU since we already
have RISCVISD::MULHSU for scalars in the base ISA.
2026-02-05 17:33:35 -08:00
Min-Yih Hsu
6441f1c9d5
[RISCV] Introduce a new syntax for processor-specific tuning feature strings (#175063)
This patch proposes new a tuning feature string format that helps users
to build a performance model by "configuring" an existing tune CPU,
along with its scheduling model. For example, this string
```
"sifive-x280:single-element-vec-fp64"
```
takes ``sifive-x280`` as the "base" tune CPU and configured it with
``single-element-vec-fp64``. This gives us a performance model that
looks exactly like that of ``sifive-x280``, except some of the 64-bit
vector floating point instructions now produce only a single element per
cycle due to ``single-element-vec-fp64``.

This string could eventually be used in places like ``-mtune`` at the
frontend. Right now, this patch only implements the parser part, which
is put under the TargetParser library.

The grammar for this string is:
```
    tune-cpu      ::= 'tuning CPU name in lower case'
    directive     ::= "[a-zA-Z0-9_-]+"
    tune-features ::= directive ["," directive]*
```
A *directive* can and can only _enable_ or _disable_ a certain tuning
feature from the tuning CPU. A **positive directive**, like the
``single-element-vec-fp64`` we just saw, enables an additional tuning
feature in the associated tuning model.

A **negative directive**, on the other hand, removes a certain tuning
feature. For example, ``sifive-x390`` already has the
``single-element-vec-fp64`` feature, and we can use
"sifive-x390:no-single-element-vec-fp64" to create a new performance
model that looks nearly the same as ``sifive-x390`` except
``single-element-vec-fp64`` being cut out. In this case,
``no-single-element-vec-fp64`` is a negative directive.

There are additional restrictions on what we can put in the list of
directives, please refer to the documentations for more details.

Right now, this string only accepts directives that are explicitly
supported by the tune CPU. For example, "sifive-x280:prefer-w-inst" is
not a valide string as ``prefer-w-inst`` is not supported by
``sifive-x280`` at this moment. Vendors of these processors are expected
to maintain the compatibility of their supported directives across
different versions.

---------

Co-authored-by: Sam Elliott <aelliott@qti.qualcomm.com>
2026-02-05 15:22:07 -08:00
Jameson Nash
d762cc2f03
[GlobalISel] Add SVE support for alloca (#178976)
Complementary to the same handling code in SelectionDAG:

f3d81d4110/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp (L160-L165)

f3d81d4110/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (L4613-L4623)

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-05 14:00:34 -05:00
Luke Lau
63918f51aa
[RISCV] Fold vmerge into op with undef passthru by using vmerge's vl (#179862)
Currently we only fold an op into vmerge if we know the smaller of the
two vls, because we can't increase the vl.

However if the op's passthru is undef, then we can just use vmerge's vl
because the lanes past op's vl were undef anyway. We need to make sure
that the op doesn't access memory though. Other instructions where the
result depends on the VL should already be handled by the
RISCVII::elementsDependOnVL check below.

This is probably always profitable because even though we increase vl,
we remove a vmerge which needs to process vl elements anyway.

This removes some regressions in #179622.
2026-02-06 00:13:14 +08:00
Luke Lau
9ed7ba87c4
[RISCV] Remove redundant vand.vi with fpto*i to i1 (#179876)
If the source of an fpto*i doesn't fit in the destination type, the
result is poison. For i1 destinations, this means the result needs to be
0 or 1/-1, so we can just compare the result to 0 directly instead of
truncating.

The VP lowering for fpto*i already does this.
2026-02-06 00:06:32 +08:00
Craig Topper
bfbbed1327
[RISCV] Call updateCZceFeatureImplications from RISCVAsmParser::setFeatureBits. (#179870) 2026-02-05 07:03:26 -08:00
Jim Lin
79a26b9d65
[RISCV] Update Andes45 vector integer arithmetic scheduling info (#174538)
This PR adds latency/throughput for all RVV integer arithmetic to the
andes45 series scheduling model.
2026-02-05 13:07:33 +08:00
Craig Topper
fc56916a5d
[RISCV] Correct lowering of ISD::SETGE/SETULE/SETLE/SETUGE in lowerVPSetCCMaskOp. (#179801)
XOR should be OR to match the comment.

Found while reviewing #179622 which deletes this function. I would like
to commit this first so we have a correct baseline for reviewing that
patch.
2026-02-04 20:25:13 -08:00
Sam Elliott
0cac3e381d
[CodeGen][TII] Delete analyzeSelect hook (#175828)
The only caller of this function (`PeepholeOptimizer::optimizeSelect`)
did not use most of the parameters, was broadly equivalent to
`MI->isSelect()`, and the `optimizeSelect` hook can return `nullptr`
anyway.

Update `optimizeSelect` to return `nullptr` by default rather than
asserting when not implemented.
2026-02-04 14:14:45 -08:00
Craig Topper
861d2e2dd3
[RISCV] Deprecate RISCVSubtarget::hasStdExtCOrZcd() and hasStdExtCOrZcfOrZce(). (#179762)
Replace with hasStdExtZcd() and hastStdExtZcf().

Creation of RISCVSubtarget/MCSubtargetInfo handles implication of Zcf
and Zcd now. The exception is .option arch handling which will require
+zcf and +zcd to be listed explicitly. I'll try to fix this in a follow
up. #155035 had the same issue.

I've left the error messages mentioning both Zcf and C+F/D. We can
consider changing that in a follow up.
2026-02-04 13:00:21 -08:00
weiguozhi
9a47c3bcba
[RegAlloc] Change the computation of CSRCost (#177226)
This patch fixes https://github.com/llvm/llvm-project/issues/150737.

The original computed CSRCost is too small, so the optimization of
spilling instead of using CSR is rarely triggered.
    
Also the original cost model is too difficult to be understood and too
hard to be tuned by backend developers and users.
    
So this patch changes the CSRCost to be

        CSRCost = TRI->getCSRFirstUseCost() * EntryFreq * Scale
    
TRI->getCSRFirstUseCost() is the raw cost of save/restore a CSR. Usually
we don't need to tune this number.
   EntryFreq is the BlockFrequency of the entry block.
Scale is used to scale down the CSRCost, because we usually prefer a CSR
register instead of spilling if we have similar CSRCost and spill cost,
so it should be less than 100%. We usually tune this number.
    
Another problem is the original function RAGreedy::calcSpillCost()
actually computes a cost for block split, so this patch also implements
a correct RAGreedy::calcSpillCost() function.

This new behavior is not enabled by default. This optimization is used
by 3 targets (AArch64 / AMDGPU / RISCV), I will change them one by one
in following patches.
2026-02-04 10:08:57 -08:00
Craig Topper
6d96ae6aa8
[RISCV] Add tied destination constraint to CustomSiFiveVMACC. (#179567)
As the name suggess, these are multiply-accumulate instructions and
thus they have 3 sources.
2026-02-04 17:58:07 +00:00
Craig Topper
7083354fd6
[RISCV] Remove deprecated RISCVSubtarget::hasStdExtCOrZca(). NFC (#179616) 2026-02-04 09:49:44 -08:00
Craig Topper
265a994f4d
[RISCV] Add C/Zcf/Zcd/Zce implication rules to subtarget construction. (#179615)
This ensures the feature bits and RISCVSubtarget flags match what
RISCVISAInfo would do.

I'm not excited about the code duplication, but I need to set the
RISCVSubtarget flags along with calling ToggleFeature. I'll think about
how to improve this.
2026-02-04 09:32:11 -08:00
serge-sans-paille
802fd8c92a
[perf] Replace copy-assign by move-assign in llvm/lib/Target (#179464) 2026-02-04 13:47:01 +00:00
Juan Manuel Martinez Caamaño
49bf907c83
[NFC][LLVM] Make MachineInstrBuilder::constrainAllUses return void (#179632)
This function always returns `true`; so we can transform it to return
`void` and simplify the code.

Follow up of https://github.com/llvm/llvm-project/pull/179501 .
2026-02-04 12:06:10 +01:00
Juan Manuel Martinez Caamaño
04c56505f8
[NFC][LLVM] Make constrainSelectedInstRegOperands return void (#179501)
`constrainSelectedInstRegOperands` always returns `true`; so it can be
safely transformed to return `void` instead.

A follow-up patch should update `MachineInstrBuilder::constrainAllUses`.
2026-02-04 08:59:16 +01:00
Luke Lau
3794b83ae5
[RISCV] Don't emit VP_SETCC in combineVectorSizedSetCCEquality. NFC (#179479)
This is part of the work to remove trivial VP intrinsics.

In the combineVectorSizedSetCCEquality combine, used for the compares
that ExpandMemcmp generates, we currently emit a VP_SETCC. We can just
emit a regular SETCC and let RISCVVLOptimizer take care of reducing the
VL.
2026-02-04 06:59:27 +00:00
Craig Topper
ed2aa304ca
[RISCV] Use RVInstVV as the base for CustomSiFiveVMACC. NFC (#179565)
This correctly names the operands vd, vs1, and vs2 instead of rd, rs1,
and rs2. RVInstVCCustom2 is now only used for VCIX which has its own
operand naming problems.

I'm considering using named operand indices in
RISCVAsmParser::validateInstruction for the RVVConstraints, but first I
would have to make vs1, vs2 named correctly across all vector
instructions.
2026-02-03 22:42:05 -08:00
Mark Zhuang
b10d6a501e
[RISCV] Add macro fusion support for spacemit-x100 (#178594)
New fusion types:
- AND(I)/OR(I)/XOR(I) + AND(I)/OR(I)/XOR(I) (3 variants)
- MUL(W)+ADD(W)
- ADD + LOAD/STORE
- SLLI + SRLI/SRAI
2026-02-04 14:25:52 +08:00
Min-Yih Hsu
0d11f68a8a
[RISCV] Run VLOptimizer right after ISel (#179377)
When working on #177238 I found some cases where machine SSA
optimizations (or any optimizations that run before the current
VLOptimizer, really) can benefit from reduced VL operands. In addition,
by running VLOptimizer early, in the future we can further remove the
mini VL reduction currently in RISCVVectorPeephole, once we teach
VLOptimizer some corner cases (e.g. handle vector stores).
This patch therefore moves VLOptimizer to be (basically) right after the
ISel phase.
2026-02-03 22:15:41 -08:00
Craig Topper
7b2190c458
[RISCV] Enable SelectCompressOpt with HasStdExtZca. (#179601)
This removes the last use of HasStdExtC in tablegen so I've removed it as
well.
2026-02-03 21:56:48 -08:00
Craig Topper
6e2048e06a
[RISCV] Add isel patterns to form vwsll.vx/vi when the LHS is an any_extend. (#179571)
If we know the shift amount is greater than or equal to the
incoming EEW, the zext will have been converted to an anyext by
SimplifyDemandedBits. Treat this case the same as zext.
2026-02-03 19:22:00 -08:00
Craig Topper
aa00a34976
[RISCV] Sink some encoding related lets into class/def bodies. NFC (#179544)
Rather than using lets around classes/defs, override them in the class
def/body.

Some of these lets were around single class/def were I thought it was
better to be inside. Some were around multiple unrelated classes where
it seemed better not to link their encodings like that.

For vmv, I added a multiclass to better encapsulate them but still kept
the let scope to avoid repetition. The encodings are closely related
enough that I thought this was ok.
2026-02-03 15:05:35 -08:00