4734 Commits

Author SHA1 Message Date
Daniel Paoliello
16e051f0b9
[win] NFC: Rename EHCatchret to EHCont to allow for EH Continuation targets that aren't catchret instructions (#129953)
This change splits out the renaming and comment updates from #129612 as a non-functional change.
2025-03-06 09:28:44 -08:00
quic_hchandel
6e7e46cafe
[RISCV] Add Qualcomm uC Xqcibm (Bit Manipulation) extension (#129504)
This extension adds thirty eight  bit manipulation instructions.

The current spec can be found at:
https://github.com/quic/riscv-unified-db/releases/tag/Xqci-0.6

This patch adds assembler only support.

Co-authored-by: Sudharsan Veeravalli <quic_svs@quicinc.com>
2025-03-06 12:01:53 +05:30
Jim Lin
316f68f7f2
[RISCV] Remove the TODO for folding bswap and shift from the test. (NFC) (#129972)
https://reviews.llvm.org/D122655 has supported it.
2025-03-06 13:02:17 +08:00
Jim Lin
463a0964f4
[RISCV] Remove the TODO for fmaximum/fminimum from the tests. (NFC) (#129969)
https://reviews.llvm.org/D156069 has supported it.
2025-03-06 13:01:58 +08:00
Sam Elliott
e49180d84c
[RISCV] Xqccmp Code Generation (#128815)
This adds support for Xqccmp to the following passes:
- Prolog Epilog Insertion - reusing much of the existing push/pop logic,
but extending it to cope with frame pointers and reorder the CFI
information correctly.
- Move Merger - extending it to support the `qc.` variants of the
double-move instructions.
- Push/Pop Optimizer - extending it to support the `qc.` variants of the
pop instructions.

The testing is based on existing Zcmp tests, but I have put them in
separate files as some of the Zcmp tests were getting quite long.
2025-03-05 10:59:45 -08:00
Philip Reames
6e749f597f
[RISCV] Adjust RISCVVectorMaskDAGMutation to look for copy to V0 (#129296)
This mutation was introduced in 01a15dca0 with the goal of avoiding many
copies from V1-v31 to v0 immediately before a mask consuming
instruction. I noticed in a workload that this was not applying to
vmv.s.x (which we use for short vector masks). We'd had a whitelist of
instructions. Instead, we can directly inspect the user of the current
node to see if it's a copy to V0. This isn't quite precise (as the mask
producing instruction could already be scheduled fairly far from it's
single use), but is probably good enough.

As with all schedule changes, results are mixed. Some significant
improvements, some regressions.
2025-03-05 08:56:09 -08:00
Alex Bradbury
dd662d8028
[RISCV] Handle ADD in RISCVInstrInfo::isCopyInstrImpl (#81123)
Split out from #77610 and features a test, as a buggy version of this
caused a regression when landing that patch (the previous version had a
typo picking the wrong register as the source).

This is also motivated by future changes to MachineCopyPropagation which will use this information to determine if we have been left with a nop mv.
2025-03-05 12:29:04 +00:00
Jim Lin
a0a904e946
[RISCV] Collect shuffle mask for the lane not by createSequentialMask (#129830)
If there are the shuffle mask <1, u, u, u, 2, u, u, u> with factor 4. we
should have the shuffle mask <1, 2> for lane 0 and <u, u> for lane 1,
and so on. Since we use createSequentialMask to create the shuffle mask,
the shuffle mask for lane 1 would be <u, 0>(dervied from <u, u+1>). This
leads to poor code generation.
2025-03-05 15:31:16 +08:00
Sam Elliott
ee4bc5a8ca
[RISCV] Remove Last Traces of User Interrupts (#129300)
These were left over from when Craig removed
`__attribute__((interrupt("user")))` support in
05d0caef6081e1a6cb23a5a5afe43dc82e8ca558.

The tests change "interrupt"="user" into "interrupt"="machine" as they
are still intending to be interrupt tests. ISelLowering will now reject
"interrupt"="user". The docs no longer mention "user" as a possible
interrupt attribute argument.
2025-03-04 11:36:16 -08:00
Akshat Oke
af4ec59f8d
[CodeGen][NPM] Port ExpandPostRAPseudos to NPM (#129509) 2025-03-04 11:49:09 +05:30
Petr Penzin
b44fbdee00
[RISCV] Tune flag for fast vrgather.vv (#124664)
Add tune knob for N*Log2(N) vrgather.vv cost.
2025-03-03 16:04:49 -08:00
Brendan Sweeney
4fd5d935a3
[RISCV] Emitting proper atomic ABI tag when Zalasr is enabled (#121017)
When Zalasr is enabled, it will emit the A7 atomic ABI tag. Zalasr is
the load-acquire and store-release extension, and the reason A7 (and
A6S) exists is to support it.

The A7 atomic ABI is compatible with A6S (which is what is currently
emitted as the tag), but A7 is not compatible with A6C, while A6C and
A6S are compatible.


https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-atomic.adoc#risc-v-atomics-mappings


https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#tag_riscv_atomic_abi-14-uleb128version
2025-03-03 11:34:52 -08:00
Sergey Kachkov
3dc799162f
[RISCV] Add DAG combine to convert (iN reduce.add (zext (vXi1 A to vXiN)) into vcpop.m (#127497)
This patch combines (iN vector.reduce.add (zext (vXi1 A to vXiN)) into
vcpop.m instruction (similarly to bitcast + ctpop pattern). It can be
useful for counting number of set bits in scalable vector types, which
can't be expressed with bitcast + ctpop (this was previously discussed
here: https://github.com/llvm/llvm-project/pull/74294).
2025-03-03 16:27:52 +03:00
Sergey Kachkov
a55786170d [RISCV][NFC] Add pre-commit test 2025-03-03 13:55:04 +03:00
Akshat Oke
77f44a9642
[CodeGen][NewPM] Port MachineSink to NPM (#115434)
Targets can set the EnableSinkAndFold option in CGPassBuilderOptions for
the NPM pipeline in buildCodeGenPipeline(... &Opts, ...)
2025-03-03 15:49:37 +05:30
Jim Lin
e42ab4c54e
[RISCV] Handle zvbb instructions in getVectorLowDemandedScalarBits. (#129011) 2025-03-03 11:27:34 +08:00
Jim Lin
94f6b6d538
[SelectionDAG][RISCV] Promote VECREDUCE_{FMAX,FMIN,FMAXIMUM,FMINIMUM} (#128800)
This patch also adds the tests for VP_REDUCE_{FMAX,FMIN,FMAXIMUM,FMINIMUM}, which have been supported for a while.
2025-02-28 23:13:30 +08:00
Sam Elliott
5066d7b601
[RISCV] Add Xqccmp 0.1 Assembly Support (#128731)
Xqccmp is a new spec by Qualcomm that makes a vendor-specific effort to
solve the push/pop + frame pointers issue. Broadly, it takes the Zcmp
instructions and reverse the order they push/pop registers in, which
ends up matching the frame pointer convention.

This extension adds a new instruction not present in Zcmp,
`qc.cm.pushfp`, which will set `fp` to the incoming `sp` value after it
has pushed the registers.

This change duplicates the Zcmp implementation, with minor changes to
mnemonics (for the `qc.` prefix), predicates, and the addition of
`qc.cm.pushfp`. There is also new logic to prevent combining Xqccmp and
Zcmp. Xqccmp is kept separate to Xqci for decoding/encoding etc, as the
specs are separate today.

Specification:
https://github.com/quic/riscv-unified-db/releases/tag/Xqccmp_extension-0.1.0
2025-02-26 20:03:02 -08:00
Luke Lau
35bf925f7e [RISCV] Delete dead COPYs to vmv0 during vmv0 elimination
This fixes a crash reported at
https://github.com/llvm/llvm-project/pull/126850#issuecomment-2685166388,
where we may leave around a COPY to vmv0 after peeking through it.
Even though the COPY is dead, there's no pass between vmv0 elimination
and regalloc that will delete it so regalloc will try to allocate
something for it.

The test showcasing this is added in vmv0-elimination.mir. Removing
the dead COPY results in changes in spills in the >= LMUL 16 VP tests,
but it's worth noting that these tests are very noisy and not
representative of real world code.
2025-02-26 23:09:50 +08:00
Luke Quinn
aace6a2f9d
[RISCV] Xqcia 0.4 The spec was recently updated, this changes the name in the TD files associated and increments the Extension number in the clang driver. This is mostly a MC change as there is no other generated code for these instructions yet.
Signed-off-by: Luke Quinn <quic_lquinn@quicinc.com>
2025-02-26 08:09:20 -05:00
Jim Lin
a565f9eb29 [RISCV] The test for vp.reduce.fminimum/fmaximum with fixed-length should stay in fixed-vectors-reduction-fp-vp.ll. (NFC) 2025-02-26 10:32:57 +08:00
Jim Lin
439de05848 [RISCV] Rename function name to start with prefix vpreduce for consistency. (NFC) 2025-02-26 10:32:57 +08:00
Craig Topper
4f18f3f09a
[RISCV] Use addiw for or_is_add when or input is sign extended. (#128635)
We prefer to emit addi instead of ori because its more compressible, but
this can pessimize the sext.w removal pass.

If the input to the OR is known to be a sign extended 32 bit value, we
can use addiw instead of addi which will give more power to the sext.w
removal pass. As it is known to produce sign a sign extended value and
only consume the lower 32 bits.

Fixes #128468.
2025-02-25 10:04:57 -08:00
quic_hchandel
538b898a83
[RISCV] Add Qualcomm uC Xqcilia (Large Immediate Arithmetic) extension (#124706)
This extension adds eight 48 bit large arithmetic instructions.

The current spec can be found at:
https://github.com/quic/riscv-unified-db/releases/latest

This patch adds assembler only support.
2025-02-24 08:04:29 -08:00
Simon Pilgrim
7de64925da
[DAG] shouldReduceLoadWidth - hasOneUse should check just the loaded value - not the chain (#128167)
The hasOneUse check was failing in any case where the load was part of a chain - we should only be checking if the loaded value has one use, and any updates to the chain should be handled by the fold calling shouldReduceLoadWidth.

I've updated the x86 implementation to match, although it has no effect here yet (I'm still looking at how to improve the x86 implementation) as the inner for loop was discarding chain uses anyway.

By using SDValue::hasOneUse instead this patch exposes a missing dependency on the LLVMSelectionDAG library in a lot of tools + unittests, which resulted in having to make SDNode::hasNUsesOfValue inline.

Noticed while fighting the x86 regressions in #122671
2025-02-24 11:09:41 +00:00
Craig Topper
bac6e7b651
[RISCV][VLOpt] Put vmclr/vmset back in the RISCVVPseudo table. (#128293)
This allows them to be supported by the VLOptimizer.
2025-02-22 15:30:35 -08:00
Luke Lau
e23ab73335
[VPlan] Don't convert widen recipes to VP intrinsics in EVL transform (#127180)
This is a copy of #126177, since it was automatically and permanently
closed because I messed up the source branch on my remote

This patch proposes to avoid converting widening recipes to VP
intrinsics during the EVL transform.

IIUC we initially did this to avoid `vl` toggles on RISC-V. However we
now have the RISCVVLOptimizer pass which mostly makes this redundant.

Emitting regular IR instead of VP intrinsics allows more generic
optimisations, both in the middle end and DAGCombiner, and we generally
have better patterns in the RISC-V backend for non-VP nodes. Sticking to
regular IR instructions is likely a lot less work than reimplementing
all of these optimisations for VP intrinsics, and on SPEC CPU 2017 we get
noticeably better code generation.
2025-02-22 19:38:11 +08:00
Sudharsan Veeravalli
6757cf4e6f
[RISCV] [MachineOutliner] Analyze all candidates (#127659)
#117700 made a change from analyzing all the candidates to analyzing
just the first candidate before deciding to either delete or keep all of
them.

Even though the candidates all have the same instructions, the basic
blocks in which they are present are different and we will need to check
each of them before deciding whether to keep or erase them.
Particularly, `isAvailableAcrossAndOutOfSeq` checks to see if the
register (x5 in this case) is available from the end of the MBB to the
beginning of the candidate and not checking this for each candidate led
to incorrect candidates being outlined resulting in correctness issues
in a few downstream benchmarks.

Similarly, deleting all the candidates if the first one is not viable
will result in missed outlining opportunities.
2025-02-21 12:53:13 +05:30
Philip Reames
43f2968a02
[RISCV] Recognize VLA shift pairs from shuffle masks (#127710)
If we have a shuffle mask which can be represented as two slides + some
conditional masking, we can emit a VLA sequence which is at most
O(2*LMUL). This is essentially a generalization of the existing
isElementRotate, but is staged to only introduce the new match for the
moment. A follow up change will start consolidating code - see the notes
below.

A couple of notes:
1) I'm excluding bit rotates mostly to keep the diffs manageable. 
2) The existing isElementRotate logic is nearly redundant after this
   change.  However, we have some intersection between the bit rotate
   and element rotate matching.  To keep things simple, I left that in
   place for now, and will merge/cleanup in a separate change.
3) The individual asVSlideup and asVSlidedown are closely related, but
the former looks through extracts and the later changes VL. I'm leaving
these in place for now, but hope to common them up a bit as well.
2025-02-20 07:50:49 -08:00
Piotr Fusik
0a8341fdb2
[RISCV] Avoid VMNOT by swapping VMERGE operands for mask extensions (#126751)
Fold:

    (select (not m),  1, 0) -> (select m, 0,  1)
    (select (not m), -1, 0) -> (select m, 0, -1)
2025-02-20 13:53:21 +01:00
Piotr Fusik
9787240912 [RISCV][test] Add tests for extending negated mask 2025-02-20 11:37:03 +01:00
Luke Lau
df96b56b9f
[RISCV] Move VMV0 elimination past machine SSA opts (#126850)
This is the follow up to #125026 that keeps mask operands in virtual
register form for as long as possible throughout the backend.

The diffs in this patch are from MachineCSE/MachineSink/RISCVVLOptimizer
kicking in.

The invariant that the mask COPY never has a subreg no longer holds
after MachineCSE (it coalesces some copies), so it needed to be relaxed.
2025-02-20 12:41:05 +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
Craig Topper
b0e24d17f2
[RISCV] Use opaque pointers in some tests. NFC (#127906) 2025-02-19 15:16:09 -08:00
Craig Topper
26e375046d Recommit "[RISCV] Add a pass to remove ADDI by reassociating to fold into load/store address. (#127151)"
Tests have been re-generated with recent scheduler changes.

Original message:

SelectionDAG will not reassociate adds to the end of a chain if
there are multiple users of later additions. This prevents isel
from folding the immediate into a load/store address.

One easy way to see this is accessing an array in a struct with
two different indices. An ADDI will be used to get to the start
of the array then 2 different SHXADD instructions will be used to
add the scaled indices. Finally the SHXADD will be used by different
load instructions. We can remove the ADDI by folding the offset into
each load.

This patch adds a new pass that analyzes how an ADDI constant
propagates through address arithmetic. If the arithmetic is only
used by a load/store and the offset is small enough, we can adjust
the load/store offset and remove the ADDI.

This pass is placed before MachineCSE to allow cleanups if some
instructions become common after removing offsets from their inputs.

This pass gives ~3% improvement on dynamic instruction count on
541.leela_r and 544.nab_r from SPEC2017 for the train data set. There's
a ~1% improvement on 557.xz_r.
2025-02-19 12:11:00 -08:00
Craig Topper
37d0f20593 Revert "[RISCV] Add a pass to remove ADDI by reassociating to fold into load/store address. (#127151)"
This reverts commit c3ebbfd7368ec3e4737427eef602296a868a4ecd.

Seeing some test failures on the build bot.
2025-02-19 11:57:53 -08:00
Craig Topper
c3ebbfd736
[RISCV] Add a pass to remove ADDI by reassociating to fold into load/store address. (#127151)
SelectionDAG will not reassociate adds to the end of a chain if
there are multiple users of later additions. This prevents isel
from folding the immediate into a load/store address.
    
One easy way to see this is accessing an array in a struct with
two different indices. An ADDI will be used to get to the start
of the array then 2 different SHXADD instructions will be used to
add the scaled indices. Finally the SHXADD will be used by different
load instructions. We can remove the ADDI by folding the offset into
each load.
    
This patch adds a new pass that analyzes how an ADDI constant
propagates through address arithmetic. If the arithmetic is only
used by a load/store and the offset is small enough, we can adjust
the load/store offset and remove the ADDI.
    
This pass is placed before MachineCSE to allow cleanups if some
instructions become common after removing offsets from their inputs.

This pass gives ~3% improvement on dynamic instruction count on
541.leela_r and 544.nab_r from SPEC2017 for the train data set. There's
a ~1% improvement on 557.xz_r.
2025-02-19 11:30:55 -08:00
Vladislav Belov
b9a1e58b2c
[RISCVISel] Compute leading zeros for RISCVISD::VCPOP_VL node (#127705)
This patch adds handling of the RISCVISD::VCPOP_VL node in
RISCVTargetLowering::computeKnownBitsForTargetNode. It eliminates
redundant zero-extension instructions.
2025-02-19 11:39:55 +03:00
LiqinWeng
fb394451ca
[RISCV][VLOPT] Add vfsqrt/vfrsqrt7 instruction to isSupportInstr (#127462) 2025-02-19 14:11:16 +08:00
Craig Topper
9516f44f6b
[RISCV] Add policy operand to masked vector compare pseudos. Remove ForceTailAgnostic. NFC (#127575)
Add a policy operand to set the tail agnostic policy instead of using
ForceTailAgnostic. The masked to unmasked transforms had to be updated
to drop the policy operand when converting to unmasked.
2025-02-18 07:05:05 -08:00
Pengcheng Wang
6b2e511aed
[RISCV] Implement isHighLatencyDef() (#127476)
And returns true for div/rem/sqrt/... operations.

This is an alternative if we don't support generic scheduling model.
2025-02-18 14:24:20 +08:00
Craig Topper
9b7282e545
[RISCV] Recognize de-interleave shuffles with 2 sources. (#127272)
We can use vnsrl+trunc on each source and concatenate the results
with vslideup.
    
For low LMUL it would be better to concat first, but I'm leaving
this for later.
2025-02-16 20:40:09 -08:00
Craig Topper
63113cfc98
[RISCV] Remove what appears to be an unnecessary check for LMUL_8 in getSingleShuffleSrc. (#127250)
I think this dates to a time when we used to use a type twice as large
as necessary for the input to the vnsrl. This was changed in #118509
when factor 4 and 8 were added.

The existing test for this regresses because it uses a lot of undef
elements and we previously figured out we could reduce its size and then
try the vnsrl again. We now match it before we try to reduce the width
so we miss this opportunity.

I've added a second test that doesn't have any undef elements in the
first half. Prior to this patch we used a vcompress lowering instead of
vnsrl.
2025-02-14 19:32:53 -08:00
Philip Reames
25e43334a8
[RISCV] Lower shuffle which splats a single span (without exact VLEN) (#127108)
If we have a shuffle which repeats the same pattern of elements, all of
which come from the first register in the source register group, we can
lower this to a single vrgather at m1 to perform the element
rearrangement, and reuse that for each register in the result vector
register group.
2025-02-14 17:09:27 -08:00
Philip Reames
059722da5e Revert "[RISCV] Default to MicroOpBufferSize = 1 for scheduling purposes (#126608)" and follow up commit.
This reverts commit 9cc8442a2b438962883bbbfd8ff62ad4b1a2b95d.
This reverts commit 859c871184bdfdebb47b5c7ec5e59348e0534e0b.

A performance regression was reported on the original review.  There appears
to have been an unexpected interaction here.  Reverting during investigation.
2025-02-13 09:57:33 -08:00
Philip Reames
859c871184
[RISCV] Default to MicroOpBufferSize = 1 for scheduling purposes (#126608)
This change introduces a default schedule model for the RISCV target
which leaves everything unchanged except the MicroOpBufferSize. The
default value of this flag in NoSched is 0. Both configurations
represent in order cores (i.e. no reorder window), the difference
between them comes down to whether heuristics other than latency are
allowed to apply. (Implementation details below)

I left the processor models which explicitly set MicroOpBufferSize=0
unchanged in this patch, but strongly suspect we should change those
too. Honestly, I think the LLVM wide default for this flag should be
changed, but don't have the energy to manage the updates for all
targets.

Implementation wise, the effect of this change is that schedule units
which are ready to run *except that* one of their predecessors may not
have completed yet are added to the Available list, not the Pending one.
The result of this is that it becomes possible to chose to schedule a
node before it's ready cycle if the heuristics prefer. This is
essentially chosing to insert a resource stall instead of e.g.
increasing register pressure.

Note that I was initially concerned there might be a correctness aspect
(as in some kind of exposed pipeline design), but the generic scheduler
doesn't seem to know how to insert noop instructions. Without that, a
program wouldn't be guaranteed to schedule on an exposed pipeline
depending on the program and schedule model in question.

The effect of this is that we sometimes prefer register pressure in
codegen results. This is mostly churn (or small wins) on scalar because
we have many more registers, but is of major importance on vector -
particularly high LMUL - because we effectively have many fewer
registers and the relative cost of spilling is much higher. This is a
significant improvement on high LMUL code quality for default rva23u
configurations - or any non -mcpu vector configuration for that matter.

Fixes #107532
2025-02-12 12:31:39 -08:00
Philip Reames
9478822f4f
[RISCV] Decompose single source shuffles (without exact VLEN) (#126951)
(This is a re-apply for what was 8374d42. The bug there was fairly 
major - despite the comments and review description, the code was 
using each register in the source register group, not only the first 
register. This was completely wrong.)

This is a continuation of the work started in
https://github.com/llvm/llvm-project/pull/125735 to lower selected VLA
shuffles in linear m1 components instead of generating O(LMUL^2) or
O(LMUL*Log2(LMUL) high LMUL shuffles.

This pattern focuses on shuffles where all the elements being used
across the entire destination register group come from a single register
in the source register group. Such cases come up fairly frequently via
e.g. spread(N), and repeat(N) idioms.

One subtlety to this patch is the handling of the index vector for
vrgatherei16.vv. Because the index and source registers can have
different EEW, the index vector for the Nth chunk of the destination is
not guaranteed to be register aligned. In fact, it is common for e.g. an
EEW=64 shuffle to have EEW=16 indices which are four chunks per source
register. Given this, we have to pay a cost for extracting these chunks
into the low position before performing each shuffle.

I'd initially expressed this as a naive extract sub-vector for each data
parallel piece. However, at high LMUL, this quickly caused register
pressure problems since we could at worst need 4x the temporary
registers for the index. Instead, this patch uses a repeating slidedown
chained from previous iterations. This increases critical path by at
worst 3 slides (SEW=64 is the worst case), but reduces register pressure
to at worst 2x - and only if the original index vector is reused
elsewhere. I view this as arguably a bit of a workaround (since our
scheduling should have done better with the plain extract variant), but
a probably necessary one.
2025-02-12 12:10:35 -08:00
Philip Reames
c77d202759 Revert "[RISCV] Decompose single source shuffles (without exact VLEN) (#126108)"
This reverts commit 8374d421861cd3d47e21ae7889ba0b4c498e8d85.  A miscompile
was reported against the review thread, reverting while we investigate.
2025-02-12 08:33:20 -08:00
Philip Reames
ff8f6abe20 Reapply "[RISCV] Allow undef prefix for local repeating VLA shuffle lowering (#126097)"
(With a fix to recently added code.)

Implement the first TODO from #125735, and minorly cleanup code using
same style as the recently landed strict prefix case.
2025-02-12 07:40:13 -08:00
Akshat Oke
7b60e03d73
Reland "CodeGen][NewPM] Port MachineScheduler to NPM. (#125703)" (#126684)
`RegisterClassInfo` was supposed to be kept alive between pass runs,
which wasn't being done leading to recomputations increasing the compile
time.

Now the Impl class is a member of the legacy and new passes so that it
is not reconstructed on every pass run.

---------

Co-authored-by: Christudasan Devadasan <christudasan.devadasan@amd.com>
2025-02-12 18:54:39 +05:30