4545 Commits

Author SHA1 Message Date
Philipp van Kempen
f590963db8
[RISCV] Implement RISCVTTIImpl::getPreferredAddressingMode for HasVendorXCVmem (#120533)
For a simple matmult kernel this heuristic reduces the length of the
critical basic block from 15 to 20 instructions, resulting in a 20%
speedup.

**Without heuristic:**

```
       13688: 001b838b      cv.lb   t2, (s7), 0x1
       1368c: 09cdbcab      cv.lb   s9, t3(s11)
       13690: 089db62b      cv.lb   a2, s1(s11)
       13694: 092dbdab      cv.lb   s11, s2(s11)
       13698: 001d028b      cv.lb   t0, (s10), 0x1
       1369c: 00f282b3      add     t0, t0, a5
       136a0: 9072b52b      cv.mac  a0, t0, t2
       136a4: 9192bfab      cv.mac  t6, t0, s9
       136a8: 90c2beab      cv.mac  t4, t0, a2
       136ac: 91b2bf2b      cv.mac  t5, t0, s11
       136b0: fffc0c13      addi    s8, s8, -0x1
       136b4: 018e0633      add     a2, t3, s8
       136b8: 91b2b0ab      cv.mac  ra, t0, s11
       136bc: 000b8d93      mv      s11, s7
       136c0: fc0614e3      bnez    a2, 0x13688 <muriscv_nn_vec_mat_mult_t_s8+0x2f0>

       #instrs = 15
```

**With heuristic:**

```
        7bc0: 001c860b      cv.lb   a2, (s9), 0x1
        7bc4: 001e0d0b      cv.lb   s10, (t3), 0x1
        7bc8: 001e808b      cv.lb   ra, (t4), 0x1
        7bcc: 0015038b      cv.lb   t2, (a0), 0x1
        7bd0: 001c028b      cv.lb   t0, (s8), 0x1
        7bd4: 00f282b3      add     t0, t0, a5
        7bd8: 90c2bfab      cv.mac  t6, t0, a2
        7bdc: 91a2b92b      cv.mac  s2, t0, s10
        7be0: 9012b5ab      cv.mac  a1, t0, ra
        7be4: 9072b9ab      cv.mac  s3, t0, t2
        7be8: 9072b72b      cv.mac  a4, t0, t2
        7bec: fc851ae3      bne     a0, s0, 0x7bc0 <muriscv_nn_vec_mat_mult_t_s8+0x338>

        #instrs = 12

        improvement = 1 - 12/15 = 0.2 = 20%
```
2024-12-31 10:56:28 +08:00
Craig Topper
c557ce9f27 [RISCV] Use add_like_non_imm12 in XTheadba patterns to match Zba. 2024-12-29 12:39:37 -08:00
quic_hchandel
1557eeda73
[RISCV] Add Qualcomm uC Xqciac (Load-Store Adress calculation) extension (#121037)
This extension adds 3 instructions that perform load-store address
calculation.

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

This patch adds assembler only support.

---------

Co-authored-by: Harsh Chandel <hchandel@qti.qualcomm.com>
Co-authored-by: Sudharsan Veeravalli <quic_svs@quicinc.com>
2024-12-29 11:14:12 +05:30
Craig Topper
814902a03a [RISCV] Fix XTheadba patterns broken since cfc574a6cd13d2d0b77110b579c5cfcec744129f.
Adding an OperandTransform to CSImm12MulBy4 and CSImm12MulBy8 for
Zba broke these patterns. They should have been changed in the same,
but we lacked sufficient testing.
2024-12-26 21:50:35 -08:00
Craig Topper
cd3c1658ee [RISCV] Add more tests to rv*xtheadba.ll. NFC
XTheadba has similarities with Zba and shares some of the same
codegen code and has similar isel patterns. This patch makes the
testing more similar.
2024-12-26 21:46:19 -08:00
Alexey Bataev
b8952d4b1b
[RISCV][CG]Use processShuffleMasks for per-register shuffles
Patch adds usage of processShuffleMasks in in codegen
in lowerShuffleViaVRegSplitting. This function is already used for X86
shuffles estimations and in DAGTypeLegalizer::SplitVecRes_VECTOR_SHUFFLE
functions, unifies the code.

Reviewers: preames, topperc, lukel97, wangpc-pp

Reviewed By: wangpc-pp

Pull Request: https://github.com/llvm/llvm-project/pull/120803
2024-12-23 11:18:10 -05:00
Alexey Bataev
78ab771991 [RISCV][NFC]Add more test for shuffles with exact vlen, NFC 2024-12-20 14:27:43 -08:00
Luke Quinn
6ab8401f53
[RISCV][GISel] Port AddiPair optimization (#120463)
Check if (add r, imm) can be optimized to (ADDI (ADDI r, imm0), imm1),
in which imm = imm0 + imml and both imm0 and imm1 are simm12. We make
imm0 as large as possible and imm1 as small as possible so that we might
be able to use c.addi for the small immediate.
2024-12-20 11:32:27 -08:00
Craig Topper
d2b8acc104
[RISCV] Swap the order of SEWGreaterThanOrEqualAndLessThan64 and SEWGreaterThanOrEqual. (#120649)
SEWGreaterThanOrEqualAndLessThan64 is a stricter constraint so it should
have a higher value than SEWGreaterThanOrEqual.

Found by our random test generator.
2024-12-20 11:26:19 -08:00
Piotr Fusik
6e7312bda6
[RISCV] Select and/or/xor with certain constants to Zbb ANDN/ORN/XNOR (#120221)
(and X, (C<<12|0xfff)) -> (ANDN X, ~C<<12)
    (or  X, (C<<12|0xfff)) -> (ORN  X, ~C<<12)
    (xor X, (C<<12|0xfff)) -> (XNOR X, ~C<<12)

Emits better code, typically by avoiding an `ADDI HI, -1` instruction.

Co-authored-by: Craig Topper <craig.topper@sifive.com>
2024-12-19 21:38:20 +01:00
Michael Maitland
3710050566
[RISCV][VLOPT] Set CommonVL as the largest of the users (#120349)
Prior to this patch, we required that all users had the same VL in order
to optimize. But as the FIXME said, we can use the largest VL to
optimize, as long as we can determine what the largest is. This patch
implements the FIXME.
2024-12-19 13:22:31 -05:00
Piotr Fusik
01b96385fd [RISCV][test] Add zbb-logic-neg-imm.ll 2024-12-19 18:44:21 +01:00
Pengcheng Wang
2c782ab271
[RISCV] Add software pipeliner support (#117546)
This patch adds basic support of `MachinePipeliner` and disable
it by default.
    
The functionality should be OK and all llvm-test-suite tests have
passed.
2024-12-19 13:00:08 +08:00
Craig Topper
dc72ec808d
[RISCV] Custom legalize vp.merge for mask vectors. (#120479)
The default legalization uses vmslt with a vector of XLen to compute a
mask. This doesn't work if the type isn't legal. For fixed vectors it
will scalarize. For scalable vectors it crashes the compiler.

This patch uses an alternate strategy that promotes the i1 vector to an
i8 vector and does the merge. I don't claim this to be the best
lowering. I wrote it quickly almost 3 years ago when a crash was
reported in our downstream.

Fixes #120405.
2024-12-18 19:19:14 -08:00
Zhaoxin Yang
f334db92be
[llvm][CodeGen] Intrinsic llvm.powi.* code gen for vector arguments (#118242)
Scalarize vector FPOWI instead of promoting the type. This allows the
scalar FPOWIs to be visited and converted to libcalls before promoting
the type.

FIXME: This should be done in LegalizeVectorOps/LegalizeDAG, but call
lowering needs the unpromoted EVT.

Without this patch, in some backends, such as RISCV64 and LoongArch64,
the i32 type is illegal and will be promoted. This causes exponent type
check to fail when ISD::FPOWI node generates a libcall.

Fix https://github.com/llvm/llvm-project/issues/118079
2024-12-19 08:57:31 +08:00
Michael Maitland
a61eeaa748
[RISCV][VLOPT] Add vector indexed loads and stores to getOperandInfo (#119748)
Use `MO.getOperandNo() == 0` instead of `IsMODef` so naming is clear for the store, since the store should treat its operand 0 like that even though it is not a def.The load should treat its operand 0 def in the same way.
2024-12-17 23:51:45 -05:00
Michael Maitland
fb33268d2f
[RISCV][VLOPT] Add support for VID and VIOTA (#120331)
We already cover vid in `llvm/test/CodeGen/RISCV/rvv/vl-opt-op-info.mir`
so no need to add tests for that instruction.
2024-12-17 21:15:23 -05:00
Michael Maitland
169c32eb49
[RISCV][VLOPT] Enable the RISCVVLOptimizer by default (#119461)
Now that we have testing of all instructions in the isSupportedInstr
switch, and better coverage of getOperandInfo, I think it is a good time
to enable this by default.
2024-12-17 16:19:35 -05:00
Philip Reames
984cb791db
[RISCV] Use vmv.v.x to materialize masks in deinterleave2 lowering (#118500)
This is a follow up to 2af2634 to use vmv.v.x of i8 constants instead of
the prior vid/vand/vmsne sequence. The advantage of the vmv.v.x sequence
is that it's always m1 (so cheaper at high LMUL), and can be
rematerialized by the register allocator if needed to locally reduce
register pressure.
2024-12-17 12:50:09 -08:00
Michael Maitland
904849f297
[RISCV][VLOPT] Add support for more instructions in vl-opt-op-info.mir (#119416)
Specifically, some more where EMUL=LMUL and EEW=SEW.
2024-12-17 12:57:29 -05:00
Michael Maitland
345a35259c
[RISCV][VLOPT] Avoid crash when user produces scalar def (#120255)
I found this crash when trying to enable the VLOptimizer pass. We need
this patch before we can enable by default. The old assert was not
checking that USE and DEF were vector registers. The correct condition
is guarded at the callsite of tryReduceVL.
2024-12-17 12:07:29 -05:00
Benjamin Maxwell
a7dafea384
[SDAG] Allow folding stack slots into sincos/frexp in more cases (#118117)
This adds a new helper `canFoldStoreIntoLibCallOutputPointers()` to
check that it is safe to fold a store into a node that will expand to a
library call that takes output pointers. This requires checking for two
(independent) properties:

1. The store is not within a CALLSEQ_START..CALLSEQ_END pair
* If it is, the expansion would lead to nested call sequences (which is
invalid)
2. The node does not appear as a predecessor to the store
* If it does, attempting to merge the store into the call would result
in a cycle in the DAG

These two properties are checked as part of the same traversal in
`canFoldStoreIntoLibCallOutputPointers()`
2024-12-17 10:54:17 +00:00
Brendan Sweeney
bfe8a21bad
[RISCV][ISEL] Lowering to load-acquire/store-release for RISCV Zalasr (#82914)
Lowering to load-acquire/store-release for RISCV Zalasr.

Currently uses the psABI lowerings for WMO load-acquire/store-release
(which are identical to A.7). These are incompatable with the A.6
lowerings currently used by LLVM. This should be OK for now since Zalasr
is behind the enable experimental extensions flag, but needs to be fixed
before it is removed from that.

For TSO, it uses the standard Ztso mappings except for lowering seq_cst
loads/store to load-acquire/store-release, I had Andrea review that.
2024-12-17 00:19:45 -08:00
Craig Topper
43ede46898 [RISCV][GISel] Add legalization for more fp128 libcalls. 2024-12-16 23:39:09 -08:00
Shao-Ce SUN
d280a9c5e2
[NFC] [RISCV] Refactor class RISCVExtension (#120040)
I think typo can be avoided by reducing the number of times we re-enter
the extension name.
2024-12-16 19:53:23 +08:00
Craig Topper
54dac27c57
[GISel][RISCV] Use isSExtCheaperThanZExt when widening G_UMAX/G_UMIN. (#120041)
Similar to what we do for unsigned comparisons after #120032.
2024-12-15 23:16:58 -08:00
Craig Topper
115872902b
[GISel][RISCV] Use isSExtCheaperThanZExt when widening G_ICMP. (#120032)
Sign extending i32->i64 is more efficient than zero extend for RV64.
2024-12-15 22:55:58 -08:00
Craig Topper
de1a423c23
[GISel][RISCV][AArch64] Support legalizing G_SCMP/G_UCMP to sub(isgt,islt). (#119265)
Convert the LLT to EVT and call
TargetLowering::shouldExpandCmpUsingSelects to determine if we should do
this.

We don't have a getSetccResultType, so I'm boolean extending the
compares to the result type and using that. If the compares legalize to
the same type, these extends will get removed. Unfortunately, if the
compares legalize to a different type, we end up with truncates or
extends that might not be optimally placed.
2024-12-15 20:47:17 -08:00
Luke Quinn
537e0e1ff6
[RISCV][GISel] Added GISelPredicateCodes to LeadingOnes*Mask (#119886) 2024-12-13 14:23:16 -08:00
Craig Topper
82459ecf3e
[RISCV] Split OPERAND_SEW operand type for mask only instructions. (#119776)
Mask only instructions like vmand and vmsbf should always have 0 for
their Log2SEW operand.  Non-mask instructions should only have
3, 4, 5, or 6 for their Log2SEW operand.

Split the operand type so we can verify these cases separately.

I had to fix the SEW for whole register move to vmv.v.v copy
optimization and update an mir test. The vmv.v.v change isn't
functional since we have already done vsetvli insertion before and
nothing else uses the field after copy expansion. I can split these
changes off if desired.
2024-12-13 13:14:23 -08:00
Craig Topper
3b3394baec
[RISCV] Use Log2SEW=0 for VMNAND/VMSET created for riscv_vmsge(u) intrinsics. (#119767)
These instructions should always be created with Log2SEW=0 and an LMUL
based on SEW=8. This is used by the vsetvli pass to know these
instructions only care about the ratio and not the specific value.

Looks like I fixed riscv_vmsge(u)_mask intrinsics years ago, but forgot
the unmasked intrinsics.

I'm working on an enhancement to our MachineVerifier checks that will
require VMNAND and VMSET to have Log2SEW=0.
2024-12-13 11:00:12 -08:00
Sudharsan Veeravalli
668d9688ac
[RISCV] Add Qualcomm uC Xqcilsm (Load Store Multiple) extension (#119823)
This extension adds 6 instructions that can do multi-word load/store.

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

This patch adds assembler only support.
2024-12-14 00:06:58 +05:30
Craig Topper
0c94915d34
[RISCV] Use _B* suffix for vector mask logic pseudo instructions. (#119787)
Replace LMUL suffixes with _B1, _B2, etc. This matches what we do
for other mask only instructions like VCPOP_M, VFIRST_M, VMSBF_M,
VLM, VSM, etc.

Now all pseudoinstructions that use Log2SEW=0 will be consistently
named.
2024-12-12 21:11:01 -08:00
Craig Topper
88c18da37d
[RISCV] Rename suffixes on VCPOP/VMSBF/VMSET/etc pseudos. NFC (#119785)
These are suffixed with B1, B2, B4, B8, B16, B32, or B64 which I think
these were supposed to match the naming of the vbool types from C where
the number should be SEW/LMUL. So the smallest mask is 64 and the
largest is 1. This provides a compact syntax for describing the 7
possible ratios between LMUL and SEW.

We had the instruction names in the opposite order.
2024-12-12 16:17:21 -08:00
Michael Maitland
7442be68f7
[RISCV][VLOPT] Add vector mask producing integer instructions to isSupportedInstr and getOperandInfo (#119733) 2024-12-12 18:06:21 -05:00
Craig Topper
7ece560a50
[GISel] Support narrowing G_ICMP with more than 2 parts. (#119335)
This allows us to support i128 G_ICMP on RV32. I'm not sure how to test
the "left over" part of this as RISC-V always widens to a power of 2
before narrowing.
2024-12-12 09:50:26 -08:00
Michael Maitland
d99c9994db
[RISCV][VLOPT] Add support for mask-register logical instructions and set mask instructions (#112231)
We need to adjust getEMULEqualsEEWDivSEWTimesLMUL to account for the
fact that Log2EEW for mask instructions is 0 but their EMUL is
calculated using Log2EEW=3.
2024-12-12 12:24:52 -05:00
LiqinWeng
a611d67601
[RISCV][TTI] Add llvm.fmuladd and llvm.vp.fmuladd into canSplatOperand (#119508)
The first or second operand of fmuladd is a splat operand , it can help
fmuladd fold vv instructions to vf instructions.
2024-12-12 18:39:21 +08:00
Piotr Fusik
22d26ae304
[RISCV] Optimize (slli (srli (slli X, C1), C1), C2) -> (srli (slli X, C1), C1-C2) (#119567)
Masking out most significant bits can be done with shl followed by srl
with same shift amount. If this is followed by a shl, we could instead
srl by a smaller amount of bits.

This transform is already implemented in tablegen for masking out
32 most significant bits.

Emits better code for e.g.

    float *index(float *p, int i)
    {
        return p + (i & (1 << 30) - 1);
    }
2024-12-12 07:58:36 +01:00
quic_hchandel
0614c601b4
[RISCV] Add Qualcomm uC Xqcics(Conditional Select) extension (#119504)
The Qualcomm uC Xqcics extension adds 8 conditional select instructions.

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

This patch adds assembler only support.

---------

Co-authored-by: Harsh Chandel <hchandel@qti.qualcomm.com>
2024-12-12 11:12:09 +05:30
Luke Lau
088db868f3
[RISCV] Merge shuffle sources if lanes are disjoint (#119401)
In x264, there's a few kernels with shuffles like this:

    %41 = add nsw <16 x i32> %39, %40
    %42 = sub nsw <16 x i32> %39, %40
%43 = shufflevector <16 x i32> %41, <16 x i32> %42, <16 x i32> <i32 11,
i32 15, i32 7, i32 3, i32 26, i32 30, i32 22, i32 18, i32 9, i32 13, i32
5, i32 1, i32 24, i32 28, i32 20, i32 16>

Because this is a complex two-source shuffle, this will get lowered as
two vrgather.vvs that are blended together.

    vadd.vv v20, v16, v12
    vsub.vv v12, v16, v12
    vrgatherei16.vv v24, v20, v10
    vrgatherei16.vv v24, v12, v16, v0.t

However the indices coming from each source are disjoint, so we can
blend the two together and perform a single source shuffle instead:

    %41 = add nsw <16 x i32> %39, %40
    %42 = sub nsw <16 x i32> %39, %40
    %43 = select <0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1> %41, %42
%44 = shufflevector <16 x i32> %43, <16 x i32> poison, <16 x i32> <i32
11, i32 15, i32 7, i32 3, i32 10, i32 14, i32 6, i32 2, i32 9, i32 13,
i32 5, i32 1, i32 8, i32 12, i32 4, i32 0>

The select will likely get merged into the preceding instruction, and
then we only have to do one vrgather.vv:

    vadd.vv v20, v16, v12
    vsub.vv v20, v16, v12, v0.t
    vrgatherei16.vv v24, v20, v10

This patch bails if either of the sources are a broadcast/splat/identity
shuffle, since that will usually already have some sort of cheaper
lowering.

This improves performance on 525.x264_r by 4.12% with -O3 -flto
-march=rva22u64_v on the spacemit-x60.
2024-12-12 13:41:27 +08:00
Pengcheng Wang
da71203e6f
[MISched] Unify the way to specify scheduling direction (#119518)
For pre-ra scheduling, we use two options `-misched-topdown` and
`-misched-bottomup` to force the direction.

While for post-ra scheduling, we use `-misched-postra-direction`
with enumerated values (`topdown`, `bottomup` and `bidirectional`).

This is not unified and adds some mental burdens. Here we replace
these two options `-misched-topdown` and `-misched-bottomup` with
`-misched-prera-direction` with the same enumerated values.

To avoid the condition of `getNumOccurrences() > 0`, we add a new
enum value `Unspecified` and make it the default initial value.

These options are hidden, so we needn't keep the compatibility.
2024-12-12 11:24:07 +08:00
Philip Reames
ccfcc9117b [RISCV] Add coverage for zipeven/zipodd shuffles 2024-12-11 11:23:24 -08:00
Michael Maitland
6ce6b1d385 [RISCV][VLOPT] Use noreg where possible in vl-opt-op-info.mir 2024-12-11 11:13:24 -08:00
Michael Maitland
e7c626cdd1 [RISCV][VLOPT] Fix test case as a result of changes in #119602 2024-12-11 11:08:55 -08:00
Michael Maitland
412ab602f1
[RISCV][VLOPT] Add vector narrowing integer right shift instructions to isSupportedInstr (#119602) 2024-12-11 13:51:19 -05:00
Alex Bradbury
3787fbf040
[RISCV] Enable merging of external globals by default (#117880)
This follows up #115495 by enabling merging of external globals by
default, which had been left as a next step in order to make the
previous change more incremental and so we can more easily narrow down
on any identified regressions.

Enabling merging of external globals matches what Arm does (for non
mach-o targets), though AArch64 doesn't as there were [some
concerns](https://reviews.llvm.org/D61947) it might cause regressions in
some cases.

See https://github.com/llvm/llvm-project/pull/117880 for benchmark figures and discussion.
2024-12-11 16:06:49 +00:00
Michael Maitland
ad0fbb033d
[RISCV][VLOPT] Add vl-opt-op-info tests for unit strided and strided stores (#119465)
I don't include getOperandInfo for the loads, since they don't take a
vector use operand, and we don't include the loads in isSupportedInstr
so we will never call getOperandInfo on the vector destination of these
instructions.

Don't add support for VSM since we don't have any mask producing
instructions in isSupportedInstr at the moment.
2024-12-11 10:23:23 -05:00
Guillaume DI FATTA
a1ee1a9126
[CodeGen] @llvm.experimental.stackmap make operands immediate (#117932)
This pull request modifies the behavior of the
`@llvm.experimental.stackmap` intrinsic to require that its two first
operands (`id` and `numShadowBytes`) be **immediate values**. This
change ensures that variables cannot be passed as two first arguments to
this intrinsic.


Related Issue: https://github.com/llvm/llvm-project/issues/115733

### Testing
- Added new test cases to ensure errors are emitted for non-immediate
operands.
- Ran the full LLVM test suite to verify no regressions were introduced.
2024-12-11 17:41:19 +08:00
Craig Topper
839c8217b9
[LegalizeTypes][RISCV][X86] Legalize FP_ROUND to libcall in SoftPromoteHalfRes_FP_ROUND if the input type is softened. (#119481)
Previously we created an FP_TO_FP16 and legalized it in
SoftenFloatOp_FP_ROUND. This caused i16 to be sent to call lowering
instead of f16. This results in the ABI not being followed if f16 is
supposed to be passed in a different register than i16.

Looking at the libgcc binary for the library function it appears the value
is returned in xmm0 so the X86 test was being miscompiled before.

Fixes #107607.
2024-12-10 22:21:49 -08:00