367 Commits

Author SHA1 Message Date
Ramkumar Ramachandra
5d4e1e0c84
[RISCV] Fix build failure in getIntrinsicInstrCost (#151210)
bd66fd0 ([CostModel/RISCV] Fix costs of vector [l](lrint|lround))
introduced buildbot failures by using a temporary ArrayRef when a
SmallVector should have been used. Fix this.

Failure: https://lab.llvm.org/buildbot/#/builders/186/builds/11133
2025-07-29 20:42:54 +01:00
Ramkumar Ramachandra
bd66fd0d01
[CostModel/RISCV] Fix costs of vector [l](lrint|lround) (#146058)
Take the actual instruction cost into account, and don't fallthrough to
code that doesn't apply to [l]lrint. Also strip invalid costs for
[b]f16, as a companion to #146507, and unify it with [l]lround costs as
a companion to #147713.
2025-07-29 19:22:11 +01:00
Alex Bradbury
5294793bdc Revert "[RISCV][TTI] Enable masked interleave access for scalable vector (#149981)"
This reverts commit ee3a7714b7a69ac9aae4b79f4c67adc38bc6876b.

Causes an assertion for the zvl1024b RISC-V build configuration. See
comment with reproducer at
<https://github.com/llvm/llvm-project/pull/149981#issuecomment-3118482801>
2025-07-25 16:14:10 +01:00
Mel Chen
ee3a7714b7
[RISCV][TTI] Enable masked interleave access for scalable vector (#149981)
Now that support for masked loads/stores of interleave groups has
landed, we can enable the loop vectorizer to generate masked interleave
access where applicable.

This improves vectorization in several ways:
* Internal predication support: This enables interleave group
vectorization for loops with internal control flow predication, provided
all members of the group share the same predicate. Gaps in interleave
groups are still not efficiently handled by masking, so masking for gaps
remains disabled for now.
* Tail folding: This allows tail folding of loops with interleave groups
by using masking. Without this, vectorized loops with interleaves would
fall back to using separate gather/scatter accesses, which can be
significantly less efficient.
* Scalable vector support: Currently, only scalable vector types are
supported for masked interleave lowering. Fixed-length vector support
will be enabled in the future.

As interleave access is not yet supported with tail folding by EVL, that
functionality is temporarily disabled. We are going to create another
patch to support it.

Co-authored-by: Philip Reames <preames@rivosinc.com>

---------

Co-authored-by: Philip Reames <preames@rivosinc.com>
2025-07-25 17:53:08 +08:00
Elvis Wang
324773e238
[RISCV][TTI] Implement vector costs for llvm.fpto{u|s}i.sat(). (#143655)
This patch implement vector costs for `llvm.fptoui.sat()` in RISCV TTI.
2025-07-23 09:52:33 +08:00
Luke Lau
da8d7f49ff
[RISCV] Unify non-vp and vp rounding intrinsic costing (#147872)
Currently we have slightly different costing for the vp and non-vp
version of the rounding intrinsics.

We can delete this code and use the generic BasicTTIImpl code for the vp
intrinsics which falls back to the non-vp versions.

I'm not sure if the zvfh costing is correct, this should probably be
fixed in a follow up patch. At the moment the non-vp cost is more
important since it is what the loop vectorizer will use.
2025-07-10 15:46:05 +08:00
Luke Lau
20becf373e
[TTI] Move vp.{select,merge} costing from RISCV to BasicTTIImpl. NFC (#147870)
Move the costing to the generic implementation in BasicTTIImpl since it
just falls back to the non-vp costing.

Also pass through the OperandValueInfo if using value based costing, but
I don't believe this affects the result for any in-tree target
currently.
2025-07-10 14:30:52 +08:00
David Green
77941eba7f
[CostModel] Add a DstTy to getShuffleCost (#141634)
A shuffle will take two input vectors and a mask, to produce a new
vector of size <MaskElts x SrcEltTy>. Historically it has been assumed
that the SrcTy and the DstTy are the same for getShuffleCost, with that
being relaxed in recent years. If the Tp passed to getShuffleCost is the
SrcTy, then the DstTy can be calculated from the Mask elts and the src
elt size, but the Mask is not always provided and the Tp is not reliably
always the SrcTy. This has led to situations notably in the SLP
vectorizer but also in the generic cost routines where assumption about
how vectors will be legalized are built into the generic cost routines -
for example whether they will widen or promote, with the cost modelling
assuming they will widen but the default lowering to promote for integer
vectors.

This patch attempts to start improving that - it originally tried to
alter more of the cost model but that too quickly became too many
changes at once, so this patch just plumbs in a DstTy to getShuffleCost
so that DstTy and SrcTy can be reliably distinguished. The callers of
getShuffleCost have been updated to try and include a DstTy that is more
accurate. Otherwise it tries to be fairly non-functional, keeping the
SrcTy used as the primary type used in shuffle cost routines, only using
DstTy where it was in the past (for InsertSubVector for example).

Some asserts have been added that help to check for consistent values
when a Mask and a DstTy are provided to getShuffleCost. Some of them
took a while to get right, and some non-mask calls might still be
incorrect. Hopefully this will provide a useful base to build more
shuffles that alter size.
2025-06-21 12:29:29 +01:00
Philip Reames
b96370131d
[TTI] Plumb CostKind through getPartialReductionCost (#144953)
Purely for the sake of being idiomatic with other TTI costing routines,
no direct motivation beyond that.
2025-06-19 15:29:56 -07:00
Florian Hahn
071a6feabd
[TTI] Remove PPC hasActiveVectorLength impl, simplify interface (NFC). (#142310)
PPCTTIImpl defines hasActiveVectorLength and also getVPMemoryOpCost, but
they appear unused (i.e. no changes to tests).

Remove them, as they complicate the interface for hasActiveVectorLength.
This simplifies the only use in LV as now no placeholder values need to
be passed.

PR: https://github.com/llvm/llvm-project/pull/142310
2025-06-18 19:02:17 +01:00
Pengcheng Wang
ca29c632f0
[RISCV] Support non-power-of-2 types when expanding memcmp
We can convert non-power-of-2 types into extended value types
and then they will be widen.

Reviewers: lukel97

Reviewed By: lukel97

Pull Request: https://github.com/llvm/llvm-project/pull/114971
2025-06-18 16:11:18 +08:00
Philip Reames
391dafd8af
[RISCV] Consolidate both copies of getLMUL1VT [nfc] (#144568)
Put one copy on RISCVTargetLowering as a static function so that both
locations can use it, and rename the method to getM1VT for slightly
improved readability.
2025-06-17 11:28:43 -07:00
Craig Topper
a3d35b87ea
[RISCV] Use RISCV::RVVBitsPerBlock instead of 64 in getLMUL1VT. NFC (#144401) 2025-06-16 11:24:33 -07:00
Philip Reames
90d62e0ae3
[RISCV][TTI] Refine reverse shuffle costing for high LMUL (#144155)
This contains two closely related changes:
1) Explicitly recurse on the i1 case - "3" happens to be the right
   magic constant at m1, but is not otherwise correct, and we're
   better off deferring this to existing logic.
2) Match the lowering for high LMUL shuffles - we've switched to using
   a linear number of m1 vrgather instead of a single big vrgather.
   This results in substantially faster (but also larger) code for
   reverse shuffles larger than m1.  Note that fixed vectors need
   a slide at the end, but scalable ones don't.

This will have the effect of biasing the vectorizer towards larger
(particularly scalable larger) vector factors. This increases VF for the
s112 and s1112 loops from TSVC_2 (in all configurations).

We could refine the high LMUL estimates a bit more, but I think getting
the linear scaling right is probably close enough for the moment.
2025-06-16 10:20:09 -07:00
Pengcheng Wang
4903c11a7e
[RISCV] Support memcmp expansion for vectors
This patch adds the support of generating vector instructions for
`memcmp`. This implementation is inspired by X86's.

We convert integer comparisons (eq/ne only) into vector comparisons
and do a vector reduction and to get the result.

The range of supported load sizes is (XLEN, VLEN * LMUL8] and
non-power-of-2 types are not supported.

Fixes #143294.

Reviewers: lukel97, asb, preames, topperc, dtcxzyw

Reviewed By: topperc, lukel97

Pull Request: https://github.com/llvm/llvm-project/pull/114517
2025-06-13 14:31:48 +08:00
Philip Reames
3a2bcd96e2
[RISCV][TTI] Allow partial reduce with mismatched extends (#143608)
This depends on the recently add partial_reduce_sumla node for lowering
but at this point, we have all the parts.
2025-06-10 15:26:54 -07:00
Philip Reames
8eb4ada181
[RISCV][TTI] Discount slide cost if ri.vinsert/ri.vextract are available (#142036)
If we have the ri.vinsert/vextract instructions from xrivosvisni, we can
do an element insert or extract without needing a vslide or a vector
temporary register. Adjust the TTI cost to reflect this.
2025-05-30 11:06:28 -07:00
Philip Reames
041d189f01
[RISCV][TTI] Adjust costing in getPartialReductionCost for zvqdotq (#141430)
Two changes:

1) Handle fixed vector cases now that 77a3f8 has landed. 
2) Fix a mistake in the original costing - the VF passed in is the
   input VF, not the output VF.  Given that we should be costing the
   accumulator type with VF/4.

Note that (2) does not cause any visible test differences as the
vectorizer (outside of maximize-bandwidth mode) does not consider wide
enough VF for the costing difference to matter.
2025-05-26 08:23:56 -07:00
Philip Reames
a21fb74c0c
[RISCV][TTI] Implement getPartialReductionCost for the vqdotq cases (#140974)
Doing so tells the loop vectorizer that the partial.reduce intrinsic is
profitable to use over the plain extend/multiply/reduce.add sequence.
2025-05-23 07:15:06 -07:00
David Green
abd2c07e39
[CostModel] Make Op0 and Op1 const in getVectorInstrCost. NFC (#137631)
This does not alter much at the moment, but allows const pointers to be
passed as Op0 and Op1, simplifying later patches
2025-05-01 15:55:08 +01:00
Jonas Paulsson
f5c8c1eedb
[SLPVectorizer] Move X86 specific handling into X86TTIImpl. (#137830)
`ad9909d "[SLP]Fix perfect diamond match with extractelements in scalars" `
changed SLPVectorizer getScalarizationOverhead() to call
TTI.getVectorInstrCost() instead of TTI.getScalarizationOverhead() in some
cases. This was due to X86 specific handlings in these (overridden) methods,
and unfortunately the general preference of TTI.getScalarizationOverhead()
was dropped. If VL is available it should always be preferred to use
getScalarizationOverhead(), and this is indeed the case for SystemZ which
has a special insertion instruction that can insert two GPR64s.

Then ` 33af951 "[SLP]Synchronize cost of gather/buildvector nodes with
codegen"` reworked SLPVectorizer getGatherCost() which together with
ad9909d caused the SystemZ test vec-elt-insertion.ll to fail.

This patch restores the SystemZ test and reverts the change in SLPVectorizer
getScalarizationOverhead() so that TTI.getScalarizationOverhead() is always
called again. The ForPoisonSrc argument is now passed on to the TTI method
so that X86 can handle this as required.

Fixes: #135346
2025-04-30 17:11:27 +02:00
MingYan
e43d64ebe9
[RISCV] Sink vp.splat operands of VP intrinsic. (#133245)
This patch introduces a `vp.splat` matching method for VP support by
sinking the `vp.splat` operand of VP operations back into the same basic
block as the VP operation, facilitating the generation of .vx
instructions to reduce vector register pressure.

---------

Co-authored-by: yanming <ming.yan@terapines.com>
2025-04-27 15:42:49 +08:00
David Green
98b6f8dc69
[CostModel] Remove optional from InstructionCost::getValue() (#135596)
InstructionCost is already an optional value, containing an Invalid
state that can be checked with isValid(). There is little point in
returning another optional from getValue(). Most uses do not make use of
it being a std::optional, dereferencing the value directly (either
isValid has been checked previously or the Cost is assumed to be valid).
The one case that does in AMDGPU used value_or which has been replaced
by a isValid() check.
2025-04-23 07:46:27 +01:00
Philip Reames
7c4cb0e836 Fix build error introduced by 1c722fc
The change built before merge, but apparently a constness change landed
since I posted this for review.
2025-04-22 11:05:24 -07:00
Philip Reames
1c722fc8f5
[RISCV][TTI] Use processShuffleMask for shuffle legalization estimate (#136191)
We had some code which tried to estimate legalization costs for
illegally typed shuffles, but it only handled the case of a widening
shuffle, and used a somewhat adhoc heuristic. We can reuse the
processShuffleMask utility (which we already use for individual vector
register splitting when exact VLEN is known) to perform the same
splitting given the legal vector type as the unit of split instead. This
makes the costing both simpler and more robust.

Note that this swings costs for illegal shuffles pretty wildly as we
were previously sometimes hitting the adhoc code, and sometimes falling
through into generic scalarization costing. I don't know that any of the
costs for the individual tests in tree are significant, but the test
which which triggered me finding this was reported to me by Alexey
reduced from something triggering a bad choice in SLP for x264. So this
has the potential to be somewhat high impact.
2025-04-22 10:50:20 -07:00
Sergei Barannikov
3334c3597d
[TTI] Fix discrepancies in prototypes between interface and implementations (NFCI) (#136655)
These are not diagnosed because implementations hide the methods of the base class rather than overriding them.
This works as long as a hiding function is callable with the same arguments as the same function from the base class.

Pull Request: https://github.com/llvm/llvm-project/pull/136655
2025-04-22 11:40:12 +03:00
Sergei Barannikov
0014b49482
[TTI] Make all interface methods const (NFCI) (#136598)
Making `TargetTransformInfo::Model::Impl` `const` makes sure all
interface methods are `const`, in `BasicTTIImpl`, its bases, and in all
derived classes.

Pull Request: https://github.com/llvm/llvm-project/pull/136598
2025-04-22 06:27:29 +03:00
Sergei Barannikov
e0c1e23b99
[TTI] Constify BasicTTIImplBase::thisT() (NFCI) (#136575)
The main change is making `thisT` method `const`, the rest of the
changes is fixing compilation errors (*).

(*) There are two tricky methods, `getVectorInstrCost()` and
`getIntImmCost()`.
They have several overloads; some of these overloads are typically
pulled in to derived classes using the `using` directive, and then
hidden by methods in the derived class.
The compiler does not complain if the hiding methods are not marked as
`const`, which means that clients will use the methods from the base
class. If after this change your target fails cost model tests, this
must be the reason. To resolve the issue you need  to make all hiding
overloads `const`. See the second commit in this PR.

Pull Request: https://github.com/llvm/llvm-project/pull/136575
2025-04-21 21:42:40 +03:00
Luke Lau
053451cb35 [RISCV] Handle scalarized reductions in getArithmeticReductionCost
This fixes a crash reported at
https://github.com/llvm/llvm-project/pull/114250#issuecomment-2813686061

If the vector type isn't legal at all, e.g. bfloat with +zvfbfmin,
then the legalized type will be scalarized. So use getScalarType()
instead of getVectorElement() when checking for f16/bf16.
2025-04-21 16:07:15 +08:00
Philip Reames
31c37a4a5e
[RISCV][TTI] Adjust VLS shuffle costing to account for sub-mask reuse (#129793)
If we have a shuffle which can be split via VLA where two or more of the
destinations have exactly the same elements, then we only need to
account for them once in costing. The duplicate copies are are (at
worst) whole register moves.

Note that this change only handles the single source case. Doing the
multiple source case seemed a bit more complicated, and I didn't have a
motivating test case.
2025-03-29 15:18:44 -07:00
Pengcheng Wang
f5f4da6db6
[RISCV] Don't vectorize for loops with small trip count (#132176)
Inspired by https://reviews.llvm.org/D130755.

I don't know the logic behind the value 5, it is copied from AArch64.

For some tests, I have to change the trip count so that we don't
break what they are testing.
2025-03-28 15:51:29 +08:00
Elvis Wang
6dba5f6595
[TTI] Align optional FMFs in getExtendedReductionCost() to getArithmeticReductionCost(). (#131968)
In the implementation of the getExtendedReductionCost(), it ofter calls
getArithmeticReductionCost() with FMFs. But we shouldn't call
getArithmeticReductionCost() with FMFs for non-floating-point reductions
which will return the wrong cost.

This patch makes FMFs in getExtendedReductionCost() optional and align
to the getArithmeticReductionCost(). So the TTI will return the correct
cost for non-FP extended-reductions query without FMFs.

This patch is not quite NFC but it's hard to test from the CostModel
side.

Split from #113903.
2025-03-19 18:53:38 +08:00
Piotr Fusik
35cd6a4c11
[RISCV] Sink NOT to be fold into ANDN/ORN/XNOR/VANDN (#131632)
Undoes a negation being hoisted out of a loop, so that it can be fold
into an inverted bitwise operation in the loop.

Implements #108840 on RISC-V
2025-03-19 06:06:13 +01:00
Philip Reames
42429fedf9
[RISCV] Simplify costShuffleViaVRegSplitting [nfc] (#129766)
This code goes to some length to cost the subvector extracts, but by
construction, all of the subvector extracts are subregister extracts
from a vector register group and thus have zero cost. As a result, none
of this code is needed.
2025-03-04 13:35:52 -08:00
Philip Reames
c8dd8522fa [RISCV][TTI] Use early return to simplify costShuffleViaVRegSplitting [nfc] 2025-03-04 12:27:37 -08:00
Philip Reames
863260523f [RISCV][TTI] Simplify code using getRealVLen() [NFC] 2025-03-04 09:48:06 -08:00
Philip Reames
248be98418 Reapply "[RISCV][TTI] Add shuffle costing for masked slide lowering (#128537)"
With a fix for fully undef masks.  These can't reach the lowering code, but
can reach the costing code via e.g. SLP.

This change adds the TTI costing corresponding to the recently added
isMaskedSlidePair lowering for vector shuffles. However, since the
existing costing code hadn't covered either slideup, slidedown, or the
(now removed) isElementRotate, the impact is larger in scope than just
that new lowering.

---------

Co-authored-by: Alexey Bataev <a.bataev@gmx.com>
Co-authored-by: Luke Lau <luke_lau@icloud.com>
2025-02-28 08:02:27 -08:00
Philip Reames
b2152823e0 Revert "[RISCV][TTI] Add shuffle costing for masked slide lowering (#128537)"
This reverts commit 4904728cab8596320a77a895cb712fba07ea7bb1.  Downstream
test failed, reverting during investigation.
2025-02-27 22:03:18 -08:00
Philip Reames
4904728cab
[RISCV][TTI] Add shuffle costing for masked slide lowering (#128537)
This change adds the TTI costing corresponding to the recently added
isMaskedSlidePair lowering for vector shuffles. However, since the
existing costing code hadn't covered either slideup, slidedown, or the
(now removed) isElementRotate, the impact is larger in scope than just
that new lowering.

---------

Co-authored-by: Alexey Bataev <a.bataev@gmx.com>
Co-authored-by: Luke Lau <luke_lau@icloud.com>
2025-02-27 18:58:42 -08:00
Philip Reames
1bd13bceec
[RISCV][TTI] Fix a misuse of the getShuffleCost API [NFC] (#129137)
The getShuffleCost api, in concept, expects to only deal with non-length
changing shuffles. We were failing to extend the mask appropriately
before invoking it. This came up in
https://github.com/llvm/llvm-project/pull/128537 in discussion of a
potential invariant, but is otherwise unrelated.
2025-02-27 18:53:49 -08:00
Gergely Futo
c11e3dafcf
[RISCV] Correct RISCVTTIImpl::getIntImmCostInst for Zba (#128174)
zext.w is only available on RV64.

We also never hoist UINT64_C(0xffffffff) on RV32, since the AND is
deleted by SelectionDAG after type legalization splits it.
2025-02-27 08:48:55 +01:00
Philip Reames
529b3d16da [RISCV][TTI] Remove SK_Select from manual splitting in getShuffleCost
We have general splitting logic for this kind just below, which to my
knowledge is both correct and precise.  Given no test changes, either
a) the adhoc logic works out the same, or b) we have no coverage. I
did not investigate which.
2025-02-24 07:53:53 -08:00
Matt Arsenault
971fc42254
TargetTransformInfo: Add missing consts to a couple of methods (#128492) 2025-02-24 19:08:22 +07:00
Philip Reames
a7d578dcce [RISCV][TTI] Avoid complicated fallthrough in getShuffleCost [nfc]
Just making the control flow easier to follow.
2025-02-22 15:16:59 -08:00
Philip Reames
f5f55ade3a [RISCV][TTI] Common a check in getShufleCost [nfc]
None of the vector costings apply if we're scalarizing.  Pull that check
into an early guard instead.
2025-02-22 15:00:18 -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
Mikhail R. Gadelha
053e033321
[RISCV] Generalize cost model for vp_fneg. NFC. (#126915)
Move the cost model for vp_fneg from the riscv-specific implementation to the generic TTI layer.
This ensures consistent handling of vp_fneg across targets
2025-02-14 10:58:18 -03:00
Mikhail R. Gadelha
83fa117f76
[RISCV] Add cost model for fma (#126076)
This change builds on PR #125683, which added a cost model for fmuladd.

To ensure completeness, this patch extends the cost model to also cover fma, using the same costing approach as fmuladd.

I plan to send a follow-up patch that includes the cost model vp_fma and vp_fmuladd, and their tests.
2025-02-10 10:11:28 -03:00
Sudharsan Veeravalli
83783e8bec
[RISCV] Fix typos discovered by codespell (NFC) (#126191)
Found using https://github.com/codespell-project/codespell

```
codespell RISCV --write-changes \
       --ignore-words-list=FPR,fpr,VAs,ORE,WorstCase,hart,sie,MIs,FLE,fle,CarryIn,vor,OLT,VILL,vill,bu,pass-thru 
```
2025-02-07 13:35:30 +05:30
Mikhail R. Gadelha
e78be31639
[RISCV] Added cost model for fmuladd (#125683)
This patch updates the cost model for fmuladd on vector types to scale with LMUL. This was found when analyzing a hot loop in 519.lbm_r that was unprofitably vectorized, but doesn't directly impact that case and is split off so it doesn't get forgotten.

Unlike other FP arithmetic ops, it's not scaled by 2 because the scalar cost isn't scaled by 2.
2025-02-05 09:33:24 -03:00