93 Commits

Author SHA1 Message Date
Luke Lau
e261f2895f
[RISCV] Add TSFlag for reading past VL behaviour. NFCI (#149704)
Currently we have a switch statement that checks if a vector instruction
may read elements past VL. However it currently doesn't account for
instructions in vendor extensions.

Handling all possible vendor instructions will result in quite a lot of
opcodes being added, so I've created a new TSFlag that we can declare in
TableGen, and added it to the existing instruction definitions.

I've tried to be conservative as possible here: All SiFive vendor vector
instructions should be covered by the flag, as well as all of
XRivosVizip, and ri.vextract from XRivosVisni.

For now this should be NFC because coincidentally, these instructions
aren't handled in getOperandInfo, so RISCVVLOptimizer should currently
avoid touching them despite them being liberally handled in
getMinimumVLForUser.

However in an upcoming patch we'll need to also bail in
getMinimumVLForUser, so this prepares for it.
2025-08-15 01:19:03 +00:00
Mikhail R. Gadelha
489a41d474
[RISCV][VLOPT] Added support for the zvbc and the remaining zvbb instructions (#153234)
Follow-up PR to #153071, adding the remaining zvbb instructions
(VBREV8_V and VREV8_V), plus the zvbc instruction (VCLMUL_VV, VCLMUL_VX,
VCLMULH_VV, VCLMULH_VX).
2025-08-13 14:43:25 +00:00
Mikhail R. Gadelha
d455d45654
[RISCV][VLOPT] Added support for several vector crypto instructions (#153071)
This PR adds support for the following instructions to the RISC-V
VLOptimizer: vandn.vx, vandn.vv, vbrev.v, vclz.v, vcpop.v, vctz.v,
vror.vi, vror.vx, vror.vv, vrol.vx, vrol.vv.
2025-08-12 12:05:03 -03:00
Luke Lau
fbd18642a9
[RISCV] Simplify EEW/EMUL check in VLOptimizer. NFC (#152100)
Currently when checking to see if two OperandInfos are compatible, we
check to see if the user operand only uses the first scalar and then do
two different checks depending on that.

However whether the user only uses the first scalar or not is already
encoded in OperandInfo, when EMUL is nullopt.

This removes the redundant check and keeps the logic in the OperandInfo
class to make the call site easier to reason about.
2025-08-05 16:53:41 +08:00
Luke Lau
bcca57b1f3
[RISCV] Simplify mask operand check in VLOptimizer. NFC (#150373)
We don't need to lookup the reg class because the MCInstDesc already
gives us this information.

With that we can remove some helper methods, and tighten the assert in
isCandidate because all pseudos at this stage should be defining virtual
registers.
2025-07-24 20:38:36 +08:00
Craig Topper
860ff8714b
[RISCV] Use empty() instead of size()==0. NFC (#149868)
Move the assert past the code that determines if the pass should run.
2025-07-21 13:16:38 -07:00
Luke Lau
b832c49cb4
[RISCV] Fix VLOptimizer assert, relax ElementsDependOn on viota/vms{b,i,o}f.m (#149698)
The previous assert wasn't passing the TSFlags but the opcode, so wasn't
working.

Fixing it reveals that it was actually triggering, because we're too
strict with viota and vmsxf.m We already reduce the VL on these
instructions because the result in each element doesn't depend on VL.
However, it does change if masked, so account for that.
2025-07-21 14:51:41 +08:00
Mikhail R. Gadelha
ececa87708
[RISCV][VLOPT] Add support for vrgather (#148249)
This PR adds support for the vrgather.vi, vrgather.vx, vrgather.vv,
vrgatherei16.vv instructions in the RISC-V VLOptimizer.

To support vrgatherei16.vv I also needed to add support for it in
getOperandLog2EEW.
2025-07-16 17:25:27 -03:00
Mikhail R. Gadelha
2435ea6975
[RISCV][VLOPT] Add support for vfclass.v (#148246)
This PR adds support for the vfclass.v instruction in the RISC-V
VLOptimizer.
2025-07-15 11:49:43 -03:00
Mikhail R. Gadelha
a606f4441a
[RISCV][VLOPT] Add support for vector integer add-with-carry/subtract-with-borrow instructions (#148247)
This PR adds support for the vmadc.vim, vmadc.vvm, vmadc.vxm, vmsbc.vvm,
vmsbc.vxm, vsbc.vvm, vsbc.vxm instructions in the RISC-V VLOptimizer.
2025-07-15 11:49:19 -03:00
Luke Lau
612afab512 [RISCV] Use MachineInstr::isFullCopy in a few places. NFC
Instead of checking that there's no subregisters.
2025-07-15 21:39:59 +08:00
Mikhail R. Gadelha
cc6a864788
[RISCV][VLOPT] Add support for vfrec7.v (#146918)
Add support for the vfrec7.v instruction in the RISC-V VLOptimizer.
2025-07-04 12:35:06 -03:00
Craig Topper
06c988cefd
[RISCV][VLOPT] Add support for vwsll.vx/vv. (#146998) 2025-07-04 00:07:47 -07:00
Luke Lau
5e31d4cdf2
[RISCV][VLOPT] Support v[f]slide1up.v{x,f} (#146716)
Similarly to #146710, for vslide1ups vl only determines the destination
elements written to so we can safely reduce their AVL.

We cannot do this for vslide1downs as the vl determines which lane the
new element is to be inserted in, so some negative tests have been
added.
2025-07-03 00:10:51 +01:00
Luke Lau
6550f28977
[RISCV][VLOPT] Support vslide{up,down} (#146710)
For vslideup and vslidedown, vl controls the elements which are written
just like other vector instructions. So unless I'm missing something it
should be safe to reduce them. For vslidedown, the specification states
that elements past vl may be read.

We already reduce vslideup and vslidedown in
RISCVVectorPeephole::tryToReduceVL where we just check for
RISCVII::elementsDependOnVL.

Eventually we should replace the whitelist with
RISCVII::elementsDependOnVL once we have test coverage. I've also added
an assert just to double check the instructions we currently support.

This helps reduce vl toggles for fixed-order recurrences vectorized with
EVL tail folding.
2025-07-02 23:30:25 +01:00
Luke Lau
c6abab2875
[RISCV][VLOPT] Add support for vfmerge.vfm and vfmv.v.f (#146692)
I noticed these were missing when seeing some extra vl toggles with EVL
tail folding.

This helps remove quite a few vsetvlis in llvm-test-suite
2025-07-02 23:29:48 +01:00
Kazu Hirata
54d836a080
[llvm] Use *Set::insert_range (NFC) (#138237) 2025-06-02 19:48:13 -07:00
Matt Arsenault
d79312b28c
RISCV: Remove faulty assert that ignored subregister uses (#141658)
This was asserting the raw virtual register class was a scalar
class, instead of computing the net result of the register class
plus the subregister index on the operand. The machine verifier
should be checking this was a valid combination in the first place,
so just drop the assert.
2025-05-27 23:34:47 +02:00
Piyou Chen
82b179ca66
[RISCV][VLOPT] Consider EMUL if it is unknown in EMULAndEEWAreEqual (#139670)
Fix https://github.com/llvm/llvm-project/issues/139288
2025-05-14 18:03:35 +08:00
Michael Maitland
f8416fcfec
[RISCV][VLOPT] Look through PHI instructions (#132236)
Similar to what we do for copies. We may reduce one of the PHI operands
and not the other, and thats perfectly okay.
2025-03-24 09:26:09 -04:00
Luke Lau
f4f7c71c55
[RISCV][VLOPT] Move mayReadPastVL check into getMinimumVLForUser. NFC (#127972)
checkUsers currently does two things, a) work out the minimum VL read by
every user and b) check that the operand info of the MI and users match.

getMinimumVLForUser handles most of a), with the exception of the check
for instructions that read past VL e.g. vrgather which is still in
checkUsers.

This moves it into getMinimumVLForUser to keep all that logic in one
place and simplifies an upcoming patch.
2025-02-20 20:17:18 +08:00
Luke Lau
44feae8695 [RISCV][VLOPT] Mark some methods + arguments as const. NFC 2025-02-20 17:37:27 +08:00
Luke Lau
c58011dc65
[RISCV][VLOPT] Peek through copies in checkUsers (#127656)
Currently if a user of an instruction isn't a vector pseudo we bail. For
simple non-subreg virtual COPYs, we can peek through their uses by using
a worklist.

This is extracted from a loop in TSVC2 (s273) that contains a fcmp +
select, which produces a copy that doesn't seem to be coalesced away.
2025-02-20 12:01:06 +08:00
LiqinWeng
fb394451ca
[RISCV][VLOPT] Add vfsqrt/vfrsqrt7 instruction to isSupportInstr (#127462) 2025-02-19 14:11:16 +08:00
Craig Topper
0cc532b79e
[RISCV] Move the RISCVII namespaced enums into RISCVVType namespace in RISCVTargetParser.h. NFC (#127585)
The VLMUL and policy enums originally lived in RISCVBaseInfo.h in the
backend which is where everything else in the RISCVII namespace is
defined.

RISCVTargetParser.h is used by much more of the compiler and it
doesn't really make sense to have 2 different namespaces exposed.
These enums are both associated with VTYPE so using the RISCVVType
namespace seems like a good home for them.
2025-02-18 08:27:25 -08:00
Luke Lau
36530414e3
[RISCV][VLOPT] Add support for Vector Fixed-Point Arithmetic Instructions (#126483)
This patch adds the remaining support for fixed-point arithmetic
instructions (we previously had support for averaging adds and
subtracts).

For saturating adds/subs/multiplies/clips, we can't change `vl` if
`vxsat` is used, since changing `vl` may change its value. So this patch
checks to see if it's dead before considering it a candidate.
2025-02-10 23:43:16 +08:00
Luke Lau
af2a228e0b
[RISCV][VLOPT] Fix passthru operand info for mixed-width instructions (#126504)
After #124066 we started allowing users that are passthrus. However for
widening/narrowing instructions we were returning the wrong operand info
for passthru operands since it originally assumed the operand would
never be a passthru. This fixes it by handling it in IsMODef.
2025-02-10 21:30:05 +08:00
Luke Lau
771f6b9f43
[RISCV][VLOPT] Add support for Widening Floating-Point Fused Multiply-Add Instructions (#126485)
We already had getOperandInfo support, so this marks the instructions as
supported in isCandidate. It also adds support for vfwmaccbf16.v{v,f}
from zvfbfwma
2025-02-10 19:55:22 +08:00
Luke Lau
19a41358ff
[RISCV][VLOPT] Add support for Single-Width Floating-Point Fused Multiply-Add Instructions (#125652)
These instructions have EEW=SEW for all operands.
2025-02-05 10:09:20 +08:00
Alex Bradbury
52c116218b [RISCV][VLOPT] Clear DemandedVLs for each invocation of runOnMachineFunction
I was running into failed assertions of `isCandidate(UserMI)` in
`getMinimumVLForUser`, but only occurring with
`-enable-machine-outliner=never`. I believe this is a red herring, and
it just so happens the memory allocation pattern on my machine exposed
the bug with that flag.

DemandedVLs is never cleared, which means it accumulates more
MachineInstr pointer keys over time, and it's possible that when e.g.
running on function 'b', a MachineInstr pointer points to the same
memory location used for a candidate in 'a'. This causes the assertion
to fail.

Comment left on #124530 with more information.
2025-02-02 18:05:13 +00:00
Craig Topper
bd95b57ef0
[RISCV][VLOpt] Move OperandInfo into anonymous namespace. Move getEMULEqualsEEWDivSEWTimesLMUL out of RISCVVType namespace. NFC (#125138)
We don't want OperandInfo to be visible outside of this translation
unit.

getEMULEqualsEEWDivSEWTimesLMUL is local to this file and declared
static. There's no reason to put it in a namespace.
2025-01-31 09:24:57 -08:00
Luke Lau
eb7e19998d
[RISCV][VLOPT] Allow users that are passthrus if tail elements aren't demanded (#124066)
The motivation for this to allow reducing the vl when a user is a
ternary pseudo, where the third operand is tied and also acts as a
passthru.

When checking the users of an instruction, we currently bail if the user
is used as a passthru because all of its elements past vl will be used
for the tail.

We can allow passthru users if we know the tail of their result isn't
used, which we will have computed beforehand after #124530

It's worth noting that this is all irrelevant of the tail policy,
because tail agnostic still ends up using the passthru.

I've checked that SPEC CPU 2017 + llvm-test-suite pass with this (on
qemu with rvv_ta_all_1s=true)

Fixes #123760
2025-01-30 23:45:24 +08:00
Luke Lau
8675cd3fac
[RISCV][VLOPT] Compute demanded VLs up front (#124530)
This replaces the worklist by instead computing what VL is demanded by
each instruction's users first, which is done via checkUsers.

The demanded VLs are stored in a DenseMap, and then we can just do a
single forward pass of tryReduceVL where we check if a candidate's
demanded VL is less than its VLOp.

This means the pass should now be linear in complexity, and allows us to
relax the restriction on tied operands in more easily as in #124066.
2025-01-29 12:39:38 +08:00
Luke Lau
ff271d04a2
[RISCV][VLOPT] Fix assertion failure across blocks (#124734)
Whilst adding a cross-block test, I encountered an assertion failure in
the second pass where we check the instruction popped off the worklist
is a candidate.

The leaf instruction %c in this case will be added to the worklist when
its VL is VLMAX, but during the first pass it will have its VL reduced
to 1.

Then in the second pass when its processed via the worklist, isCandidate
will no longer be true due to its VL == 1.

This fixes it by moving the VL == 1 check to tryReduceVL, keeping it
alongside the other VL check for bailing out early as an optimisation.
2025-01-29 11:00:50 +08:00
Luke Lau
c8d3ccfa16 [RISCV] Use llvm::reverse instead of make_range(rbegin, rend). NFC 2025-01-28 16:08:29 +08:00
Luke Lau
cb6f021af2
[RISCV][VLOPT] Remove unnecessary passthru restriction (#124549)
We currently check for passthrus in two places, on the instruction to
reduce in isCandidate, and on the users in checkUsers.

We cannot reduce the VL if an instruction has a user that's a passthru,
because the user will read elements past VL in the tail.

However it's fine to reduce an instruction if it itself contains a
non-undef passthru. Since the VL can only be reduced, not increased, the
previous tail will always remain the same.
2025-01-27 23:54:32 +08:00
Michael Maitland
bf258dbd57
[RISCV][VLOPT] support fp sign injection instructions (#124195) 2025-01-23 16:50:35 -05:00
Michael Maitland
f402e06e7d
[RISCV][VLOPT] Add vector fp min/max instructions to isSupportedInstr (#124196) 2025-01-23 16:47:14 -05:00
Luke Lau
ba3e6f0f0f
[RISCV][VLOPT] Remove dead passthru check in getOperandLog2EEW. NFC (#123911)
We already bail if the user is tied in checkUsers, which is true for all
passthrus. Remove the check in getOperandLog2EEW so that it only worries
about computing the OperandInfo, and leaves the passthru correctness to
checkUsers.
2025-01-23 10:17:39 +08:00
Philip Reames
27ccc99c4f
[RISCV][VLOpt] Minor worklist invariant cleanup [NFC] (#123989)
In retrospect, this probably should have been rolled into #123973. It
seemed more involved when I first decided to split. :)
2025-01-22 14:42:52 -08:00
Michael Maitland
1687aa2a99
[RISCV][VLOPT] Don't reduce the VL is the same as CommonVL (#123878)
This fixes the slowdown in #123862.
2025-01-22 13:49:54 -05:00
Philip Reames
589593254e
[RISCV][VLOpt] Reorganize visit order and worklist management (#123973)
This implements a suggestion by Craig in PR #123878. We can move the
worklist management out of the per-instruction work and do it once at
the end of scanning all the instructions. This should reduce repeat
visitation of the same instruction when no changes can be made.

Note that this does not remove the inherent O(N^2) in the algorithm.
We're still potentially visiiting every user of every def.

I also included a guard for unreachable blocks since that had been
mentioned as a possible cause. It seems we've rulled that out, but
guarding for this case is still a good idea.
2025-01-22 10:42:15 -08:00
Luke Lau
437e1a70ca
[RISCV][VLOPT] Handle tied pseudos in getOperandInfo (#123170)
For .wv widening instructions when checking if the opperand is vs1 or
vs2, we take into account whether or not it has a passthru. For tied
pseudos though their passthru is the vs2, and we weren't taking this
into account.
2025-01-16 23:00:13 +08:00
Michael Maitland
e44f03dd4e
[RISCV][VLOPT] Add floating point widening and narrowing bf16 convert support (#122353)
We already have getOperandInfo tests that cover this instruction.
2025-01-13 15:38:03 -05:00
Craig Topper
41e4018f9c
[RISCV][VLOPT] Simplify code by removing extra temporary variables. NFC (#122333)
Just do the conditional operator in the return statement.
2025-01-09 18:05:41 -08:00
Michael Maitland
d0373dbe7c
[RISCV][VLOPT] Add vadc to isSupportedInstr (#122345) 2025-01-09 19:44:40 -05:00
Michael Maitland
04e54cc19f
[RISCV][VLOPT] Add Vector Single-Width Averaging Add and Subtract to isSupportedInstr (#122351) 2025-01-09 19:39:12 -05:00
Michael Maitland
328c3a843f
[RISCV][VLOPT] Add vmerge to isSupportedInstr (#122340) 2025-01-09 16:10:40 -05:00
Craig Topper
b16777afb0
[RISCV] Return MILog2SEW for mask instructions getOperandLog2EEW. NFC (#122332)
The SEW operand for these instructions should have a value of 0. This
matches what was done for vcpop/vfirst.
2025-01-09 11:36:09 -08:00
Michael Maitland
5f70fea79f [RISCV][VLOPT] Add Vector Floating-Point Compare Instructions to getSupportedInstr 2025-01-09 10:50:32 -08:00