4465 Commits

Author SHA1 Message Date
Craig Topper
3e0e1c13ce
[RISCV][GISel] Support fp128 arithmetic and conversion for RV64. (#118707)
We can support these via libcalls in libgcc/compiler-rt or integer
operations for fneg/fabs/fcopysign. fp128 values will be passed in two
64-bit GPRs according to the psABI.

Supporting RV32 requires sret which is not supported by libcall handling
in LegalizerHelper.cpp yet. It doesn't call canLowerReturn.
2024-12-04 21:43:29 -08:00
Philip Reames
758107f70a [RISCV] Improve spread(N) shuffle testing
Rework them now that spread(2) is special cased to ensure we still have
non-zero shift coverage.
2024-12-04 15:21:08 -08:00
Luke Quinn
261d4bbb3b
[RISCV] f32 roundeven pattern missed for Zfa (#118672)
f32 roundeven pattern was missing from RISCVInstrInfoZfa.td. Tests for
roundeven.f32/f16/f64 were missing.
2024-12-04 13:52:20 -08:00
Philip Reames
a6e7749ea9
[RISCV] Improve lowering of spread(2) shuffles (#118658)
A spread(2) shuffle is just a interleave with an undef lane. The
existing lowering was reusing the even lane for the undef value. This
was entirely legal, but non-optimal.
2024-12-04 12:21:08 -08:00
Craig Topper
4cf2cf18c9
[RISCV][GISel] Stop over promoting G_SITOFP/UITOFP libcalls on RV64. (#118597)
When we have legal instructions we want to promote to sXLen and let isel
pattern matching removing the and/sext_inreg.

When using a libcall we want to use a 'si' libcall for small types
instead of 'di'. To match the RV64 ABI, we need to sign extend `unsigned
int` arguments. We reuse the shouldSignExtendTypeInLibCall hook from
SelectionDAG.
2024-12-04 10:42:49 -08:00
Thorsten Schütt
148fdc519c
[GlobalISel] Add G_ABDS and G_ABDU instructions (#118122)
The DAG has the same instructions: the signed and unsigned absolute
difference of it's input. For AArch64, they map to uabd and sabd for
Neon and SVE. The Neon and SVE instructions will require custom
patterns.

They are pseudo opcodes and are not imported by the IRTranslator. We
need combines to create them.

PowerPC, ARM, and AArch64 have native instructions.

/// i.e trunc(abs(sext(Op0) - sext(Op1))) becomes abds(Op0, Op1) 
///  or trunc(abs(zext(Op0) - zext(Op1))) becomes abdu(Op0, Op1)

For GlobalISel, we are going to write the combines in MIR patterns.

see:
llvm/test/CodeGen/AArch64/abd-combine.ll

- [ ] combine into abd
- [ ] legalize and add td patterns
2024-12-04 12:53:15 +01:00
Brandon Wu
109e4a147f
[RISCV] Handle zeroinitializer of vector tuple Type (#113995)
It doesn't make sense to add a new generic ISD to handle riscv tuple
type. Instead we use `SPLAT_VECTOR` for ISD and further lower to
`VMV_V_X`.

Note: If there's `visitSPLAT_VECTOR` in generic DAG combiner, it needs
to skip riscv vector tuple type.

Stack on https://github.com/llvm/llvm-project/pull/114329
2024-12-04 13:40:02 +08:00
Philip Reames
f947d5afd9 [RISCV] Reduce redundancy in vnsrl tests
Triggered by discussion on pr118509.
2024-12-03 19:47:54 -08:00
Philip Reames
c1afcaf33b
[RISCV] Match deinterleave(4,8) shuffles to SHL/TRUNC when legal (#118509)
We can extend the existing SHL+TRUNC lowering used for deinterleave2 for
deinterleave4, and deinterleave8 when the result types are small enough
to allow the shift to be legal. On RV64, this means i8 and i16 results
for deinterleave4 and i8 results for deinterleave8.
2024-12-03 19:35:52 -08:00
Philip Reames
4dd5ac906f [RISCV] Improve coverage for spread(N) shuffles
I'd already included a few cases for spread(N) in the decompress(N) variants,
but rename for clarity and add a couple more edge cases.

i.e. spread(N, 0) produces a, undef, b, undef, ...
2024-12-03 10:42:17 -08:00
Craig Topper
9692242f51 [RISCV][GISel] Support f64->f32 fptrunc and f32->f64 fpext without D extension.
Add RUN lines to float-convert.ll and double-convert.ll without F
extension.
2024-12-02 23:50:32 -08:00
Philip Reames
2af2634c64
[RISCV] Use vcompress in deinterleave2 intrinsic lowering (#118325)
This is analogous to febbf91 which added shuffle lowering using
vcompress; we can do the same thing in the deinterleave2 lowering path
which is used for scalable vectors.

Note that we can further improve this for high lmul usage by adjusting
how we materialize the mask (whose result is at most m1 with a known bit
pattern). I am deliberately staging the work so that the changes to
reduce register pressure are more easily evaluated on their own merit.
2024-12-02 18:37:32 -08:00
Philip Reames
a2cb2088e7 [RISCV] Fix a typo in a deinterleave test
This was supposed to test a deinterleave Factor=4, Offset=1, but had an
off by one in the shuffle mask.
2024-12-02 17:02:47 -08:00
Luke Lau
f500ed5646
[RISCV][VLOPT] Add separate tests for getOperandInfo. NFC (#116170)
This adds separate tests for getOperandInfo to try and get better
coverage over all the possible operands.

It's done in MIR as it makes checking incompatible EEWs and EMULs
easier, which is difficult (but not impossible) to do in LLVM IR.

It tests each instruction "format", e.g. vop.vv/vwop.vv/vwop.wv etc.,
and for each format it tests the individual operands.

For each operand it tests when the EEW and EMUL match, when the EEW
doesn't match, and when the EMUL doesn't match.
2024-12-03 07:59:23 +08:00
Craig Topper
fdc7ccf543 [RISCV][GISel] Allow fp128 function arguments.
Add more testing for large arguments.
2024-12-02 15:38:46 -08:00
Philip Reames
56cb5cbfcd
[RISCV] Remove RISCVISD::VNSRL_VL and adjust deinterleave lowering to match (#118391)
Instead of directly lowering to vnsrl_vl and having custom pattern
matching for that case, we can just lower to a (legal) shift and
truncate, and let generic pattern matching produce the vnsrl.

The major motivation for this is that I'm going to reuse this logic to
handle e.g. deinterleave4 w/ i8 result.

The test changes aren't particularly interesting. They're minor code
improvements - I think because we do slightly better with the
insert_subvector patterns, but that's mostly irrelevant.
2024-12-02 13:39:12 -08:00
Craig Topper
a15400d05d
[RISCV][GISel] Support f32/f64 ldexp. (#117941)
The existing libcall lowering in LegalizerHelper.cpp did not account
for one operand being integer. Reuse the G_FPOWI code to fix this.
2024-12-02 13:30:46 -08:00
Luke Quinn
de6d0d2de0
[RISCV][GISel] Add FCLASS to onlyUsesFP for register bank selection (#118021)
Bug fix FCLASS instruction in RISCV. The bug is due the fact that FCLASS
has an input float register and output GPR this caused reg bank select
regression.
2024-12-02 11:19:08 -08:00
Luke Lau
c9fa3195f0
[RISCV] Use LiveIntervals to determine if AVL dominates when coalescing (#118285)
In order to coalesce a vsetvli with a register AVL into a previous
vsetvli, we need to make sure that the AVL register is reachable at the
previous vsetvli.

Back in pre-RA vsetvli insertion we just checked to see if the two
virtual registers were the same virtual register, and then this was
hacked around in the move to post-RA. We can instead use live intervals
to check that the reaching definition is the same at both instructions.

On its own this doesn't have much of an impact, but helps a lot in
#118283 and enables coalescing in about 60 of the test cases from that
PR.
2024-12-03 02:10:54 +08:00
Craig Topper
bee33b5291
[RISCV][GISel] Support f32/f64 powi. (#117937)
Need to force libcall legalization to treat the integer argument as
signed so that it can be promoted to XLen in call lowering for RV64.
Alternatively we could promote the operand before converting to libcall,
but going through call lowering is closer to what SelectionDAG does.
2024-12-02 09:06:38 -08:00
Craig Topper
73186546f0
[LegalizeTypes][RISCV] Call setTypeListBeforeSoften from ExpandIntRes_FP_TO_XINT if the FP type needs to be softened (#118269)
This avoids an unnecessary sext.w before the libcall.
2024-12-02 09:06:08 -08:00
LiqinWeng
ede570980a
[RISCV][TTI] Add llvm.vp.select into canSplatOperand. (#117982)
The second operand of llvm.vp.select is a splat operand , it can help
llvm.vp.select fold vv instructions to vx instructions.
2024-12-02 17:39:47 +08:00
Sudharsan Veeravalli
6881c6d2a6
[RISCV] Add Qualcomm uC Xqcia (Arithmetic) extension (#118113)
This extension adds 11 instructions that perform integer arithmetic.

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

This patch adds assembler only support.
2024-12-01 17:06:22 +05:30
Pengcheng Wang
01a15dca09
[RISCV] Set a barrier between mask producer and user of V0 (#114012)
Here we add a scheduling mutation in pre-ra scheduling, which will
add an artificial dependency edge between mask producer and its
previous nearest instruction that uses V0 register.

This prevents the overlap of live intervals of mask registers and
as a consequence we can reduce some spills/moves.

From the test changes, we can see some improvements and also some
regressions (more vtype toggles).

Partially fixes #113489.
2024-11-29 13:25:53 +08:00
Sudharsan Veeravalli
8fcbba82d6
[RISCV] Add Qualcomm uC Xqcisls (Scaled Load Store) extension (#117987)
This extension adds 8 load/store instructions with a scaled index
addressing mode.

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

This patch adds assembler only support.
2024-11-29 10:26:00 +05:30
Sudharsan Veeravalli
c4645ffeda
[RISCV] Add Qualcomm uC Xqcicsr (CSR) extension (#117169)
The Qualcomm uC Xqcicsr extension adds 2 instructions that can read and
write CSRs.

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

This patch adds assembler only support.
2024-11-28 12:46:15 +05:30
Pengcheng Wang
d36a4c0715
[RISCV] Rename some Feature* to Tune* (#117966)
These features should be tune features.
2024-11-28 15:01:49 +08:00
Felipe Magno de Almeida
e3fdc3aa81
[RISCV] Allow hoisting VXRM writes out of loops speculatively (#110044)
Change the intersect for the anticipated algorithm to ignore unknown
when anticipating. This effectively allows VXRM writes speculatively
because it could do a VXRM write even when there's branches where VXRM
is unneeded.

The importance of this change is because VXRM writes causes pipeline
flushes in some micro-architectures and so it makes sense to allow more
aggressive hoisting even if it causes some degradation for the slow
path.

An example is this code:
```
typedef unsigned char uint8_t;
__attribute__ ((noipa))
void foo (uint8_t *dst,  int i_dst_stride,
           uint8_t *src1, int i_src1_stride,
           uint8_t *src2, int i_src2_stride,
           int i_width, int i_height )
{
   for( int y = 0; y < i_height; y++ )
     {
       for( int x = 0; x < i_width; x++ )
         dst[x] = ( src1[x] + src2[x] + 1 ) >> 1;
       dst  += i_dst_stride;
       src1 += i_src1_stride;
       src2 += i_src2_stride;
     }
}
```
With this patch, the code above generates a hoisting VXRM writes out of
the outer loop.
2024-11-27 13:31:39 -08:00
Philip Reames
febbf9105f
[RISCV] Match vcompress during shuffle lowering (#117748)
This change matches a subset of vcompress patterns during shuffle
lowering. The subset implemented requires a contiguous prefix of
demanded elements followed by undefs. This subset was chosen for two
reasons: 1) which elements to spurious demand is a non-obvious problem,
and 2) my first several attempts at implementing the general case were
buggy. I decided to go with the simple case to start with.

vcompress scales better with LMUL than a general vrgather, and at least
the SpaceMit X60, has higher throughput even at m1. It also has the
advantage of requiring smaller vector constants at one bit per element
as opposed to vrgather which is a minimum of 8 bits per element. The
downside to using vcompress is that we can't fold a vselect into it, as
there is no masked vcompress variant.

For reference, here are the relevant throughputs from camel-cdr's data
table on BP3 (X60):
  vrgather.vv v8,v16,v24    4.0  16.0  64.0  256.0
  vcompress.vm v8,v16,v24   3.0  10.0  36.0  136.
  vmerge.vvm v8,v16,v24,v0  2.0  4.0   8.0   16.0

The largest concern with the extra vmerge is that we locally increase
register pressure. If we do have masking, we also have a passthru,
without the ability to fold that into the vcompress, we need to keep it
alive a bit longer. This can hurt at e.g. m8 where we have very few
architectural registers. As compared with the vrgather.vv sequence, this
is only one additional m1 VREG - since we no longer need the index
vector. It compares slightly worse against vrgatherie16.vv which can use
index vectors smaller than other operands. Note that we could
potentially fold the vmerge if only tail elements are being preserved; I
haven't investigated this.

It is unfortunately hard given our current lowering structure to know if
we're emitting a shuffle where masking will follow. Thankfully, it
doesn't seem to show up much in practice, so I think we can probably
ignore it.

This patch only handles single source compress idioms at the moment.
This is an effort to avoid interacting with other patches on review for
changing how we canonicalize length changing shuffles.
2024-11-27 13:23:18 -08:00
Craig Topper
175051b05e [RISCV][GISel] Support libcalls for f32/f64 acos/asin/atan/atan2/cosh/sinh/tanh. 2024-11-27 12:23:12 -08:00
Philip Reames
06246b2952 [RISCV] Add shrinkwrap test cases showing gaps in current impl
This covers multiple interactions reduced from larger workloads:
1) Rematerializing addi s0, x0, <imm> to avoid the need to spill a CSR, with
   the common user being a branch.  (i.e. branch on immediate idioms)
2) Rematerializing addi s0, a0, <imm> to avoid the need to spill a CSR, with
   the common user being a vector load or store.  (i.e. because we don't
   have (reg+imm) addressing on vector.)
3) Independent of the previous, we could still shrink wrap these by locally
   using a non-CSR, and deferring the move into csr into the non-shrink
   wrapped path.
4) Weirdly, MachineCSE is producing a different result when an edge is
   manually split.  This edge split should be irrelevant to the CSE?
2024-11-27 11:14:51 -08:00
Craig Topper
1bc9de2474 [RISCV] Add test cases for llvm.tan/asin/acos/atan/atan2/sinh/cosh/tanh. NFC 2024-11-27 10:24:34 -08:00
Craig Topper
d7643e8610 [RISCV][GISel] Support f32/f64 llvm.exp10 intrinsics. 2024-11-27 10:24:33 -08:00
Craig Topper
dae9cf3816 [RISCV] Move scalar llvm.exp10 tests into half/float/double-intrinsics.ll. NFC
Improves coverage for more configurations.
2024-11-27 10:24:33 -08:00
Craig Topper
50dfb0772b [RISCV] Support f32/f64 libcalls for sin/cos/pow/log/log2/log10/exp/exp2
Test cases copied from SelectionDAG.
2024-11-26 23:35:52 -08:00
Brandon Wu
4a7dbede6b
[RISCV] Support svukte extension (#115657)
This is the extension for "Address-Independent Latency of User-Mode
Faults to Supervisor Addresses".
Spec: https://github.com/riscv/riscv-isa-manual/pull/1564,
https://lf-riscv.atlassian.net/browse/RVS-2977
The spec states that the `svukte` depends on `sv39`, but we don't have
`sv39` yet, so I didn't add it to the implied list.
2024-11-27 10:54:57 +08:00
Craig Topper
38a3cce90a [RISCV][GISel] Copy fneg test cases from SelectionDAG into float/double-arith.ll. NFC
The test cases use fcmp which was not fully supported before
43b6b78771e9ab4da912b574664e713758c43110.
2024-11-26 18:20:56 -08:00
Craig Topper
43b6b78771
[RISCV][GISel] Use libcalls for f32/f64 G_FCMP without F/D extensions. (#117660)
LegalizerHelp only supported f128 libcalls and incorrectly assumed that
the destination register for the G_FCMP was s32.
2024-11-26 15:48:49 -08:00
Philip Reames
c55a080c08 [RISCV] Add shuffle coverage for compress, decompress, and repeat idioms
compress is intented to match vcompress from the ISA manual. Note that
  deinterleave is a subset of this, and is already tested elsewhere.

decompress is the synthetic pattern defined in same - though we can often
  do better than the mentioned iota/vrgather.  Note that some of these
  can also be expressed as interleave with at least one undef source,
  and is already tested elsewhere.

repeat repeats each input element N times in the output.  It can be
  described as as a interleave operations, but we can sometimes do
  better lowering wise.
2024-11-26 09:27:56 -08:00
Mark Goncharov
80df56e03b
Reapply "[RISCV] Implement tail call optimization in machine outliner" (#117700)
This MR fixes failed test `CodeGen/RISCV/compress-opt-select.ll`.

It was failed due to previously merged commit `[TTI][RISCV]
Unconditionally break critical edges to sink ADDI (PR #108889)`.

So, regenerated `compress-opt-select` test.
2024-11-26 23:39:45 +08:00
Mehdi Amini
f94bd3c933
Revert "[RISCV] Implement tail call optimization in machine outliner" (#117710)
Reverts llvm/llvm-project#115297
Bots are broken
2024-11-26 13:45:47 +01:00
Mark Goncharov
29062329f3
[RISCV] Implement tail call optimization in machine outliner (#115297)
Following up issue #89822, this patch adds opportunity to use tail call
in machine outliner pass.
Also it enables outline patterns with X5(T0) register.
2024-11-26 12:30:37 +03:00
Mark Goncharov
93caee17ad
[RISCV][SLEEF]: Support SLEEF vector library for RISC-V target. (#114014)
SLEEF math vector library now supports RISC-V target.
Commit: https://github.com/shibatch/sleef/pull/477

This patch enables the use of auto-vectorization with 
subsequent replacement by the corresponding SLEEF function.
2024-11-26 12:25:54 +03:00
Philip Reames
6657d4bd70
[TTI][RISCV] Unconditionally break critical edges to sink ADDI (#108889)
This looks like a rather weird change, so let me explain why this isn't
as unreasonable as it looks. Let's start with the problem it's solving.

```
define signext i32 @overlap_live_ranges(ptr %arg, i32 signext %arg1) { bb:
  %i = icmp eq i32 %arg1, 1
  br i1 %i, label %bb2, label %bb5

bb2:                                              ; preds = %bb
  %i3 = getelementptr inbounds nuw i8, ptr %arg, i64 4
  %i4 = load i32, ptr %i3, align 4
  br label %bb5

bb5:                                              ; preds = %bb2, %bb
  %i6 = phi i32 [ %i4, %bb2 ], [ 13, %bb ]
  ret i32 %i6
}
```

Right now, we codegen this as:

```
	li	a3, 1
	li	a2, 13
	bne	a1, a3, .LBB0_2
	lw	a2, 4(a0)
.LBB0_2:
	mv	a0, a2
	ret
```

In this example, we have two values which must be assigned to a0 per the
ABI (%arg, and the return value). SelectionDAG ensures that all values
used in a successor phi are defined before exit the predecessor block.
This creates an ADDI to materialize the immediate in the entry block.

Currently, this ADDI is not sunk into the tail block because we'd have
to split a critical edges to do so. Note that if our immediate was
anything large enough to require two instructions we *would* split this
critical edge.

Looking at other targets, we notice that they don't seem to have this
problem. They perform the sinking, and tail duplication that we don't.
Why? Well, it turns out for AArch64 that this is entirely an accident of
the existance of the gpr32all register class. The immediate is
materialized into the gpr32 class, and then copied into the gpr32all
register class. The existance of that copy puts us right back into the
two instruction case noted above.

This change essentially just bypasses this emergent behavior aspect of
the aarch64 behavior, and implements the same "always sink immediates"
behavior for RISCV as well.
2024-11-25 18:59:31 -08:00
Craig Topper
c2bb056482
[SelectionDAG][RISCV][AArch64] Allow f16 STRICT_FLDEXP to be promoted. Fix integer promotion of STRICT_FLDEXP in type legalizer. (#117633)
A special case in type legalization wasn't accounting for different
operand numbering between FLDEXP and STRICT_FLDEXP.

AArch64 already asked STRICT_FLDEXP to be promoted, but had no test for
it.
2024-11-25 16:12:45 -08:00
Philip Reames
c94d715867 [RISCV] Add coverage for immediate sinking in switch vs branch cases
This come up in the context of pr 108889.  We always end up sinking
the value in the phi if we dispatched via a switch, but not if we'd
dispatched via a branch.  This is purely an artifact of current
lowering.
2024-11-25 12:15:14 -08:00
Craig Topper
ed6749a405 [RISCV] Promote frexp with Zfh.
The default expansion tries to create an illegal integer type after
legalization.
2024-11-25 10:27:37 -08:00
Craig Topper
29828b26fa
[RISCV] Fix double counting scalar CSRs with Zcmp when emitting cfi_offset for RVV CSRs. (#117408)
getCalleeSavedStackSize() already contains RVPushStackSize. Don't
subtract it again.
2024-11-25 10:03:48 -08:00
Craig Topper
8ea78002c2 [RISCV] Add test case for RVV CSRs with cm.push.
The cfi_offset is incorrect for the RVV registers when cm.push
is used.
2024-11-25 09:45:20 -08:00
Craig Topper
20bd029a40
[RISCV] Promote fldexp with Zfh. (#117396)
The default expansion tries to create i16 operations after type
legalization.

Fixes #117349
2024-11-25 09:08:56 -08:00