1//===- RISCVTargetTransformInfo.h - RISC-V specific TTI ---------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file defines a TargetTransformInfoImplBase conforming object specific
10/// to the RISC-V target machine. It uses the target's detailed information to
11/// provide more precise answers to certain TTI queries, while letting the
12/// target independent and default TTI implementations handle the rest.
13///
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_LIB_TARGET_RISCV_RISCVTARGETTRANSFORMINFO_H
17#define LLVM_LIB_TARGET_RISCV_RISCVTARGETTRANSFORMINFO_H
18
19#include "RISCVSubtarget.h"
20#include "RISCVTargetMachine.h"
21#include "llvm/Analysis/TargetTransformInfo.h"
22#include "llvm/CodeGen/BasicTTIImpl.h"
23#include "llvm/IR/Function.h"
24#include <optional>
25
26namespace llvm {
27
28class RISCVTTIImpl final : public BasicTTIImplBase<RISCVTTIImpl> {
29 using BaseT = BasicTTIImplBase<RISCVTTIImpl>;
30 using TTI = TargetTransformInfo;
31
32 friend BaseT;
33
34 const RISCVSubtarget *ST;
35 const RISCVTargetLowering *TLI;
36
37 const RISCVSubtarget *getST() const { return ST; }
38 const RISCVTargetLowering *getTLI() const { return TLI; }
39
40 /// This function returns an estimate for VL to be used in VL based terms
41 /// of the cost model. For fixed length vectors, this is simply the
42 /// vector length. For scalable vectors, we return results consistent
43 /// with getVScaleForTuning under the assumption that clients are also
44 /// using that when comparing costs between scalar and vector representation.
45 /// This does unfortunately mean that we can both undershoot and overshot
46 /// the true cost significantly if getVScaleForTuning is wildly off for the
47 /// actual target hardware.
48 unsigned getEstimatedVLFor(VectorType *Ty) const;
49
50 /// This function calculates the costs for one or more RVV opcodes based
51 /// on the vtype and the cost kind.
52 /// \param Opcodes A list of opcodes of the RVV instruction to evaluate.
53 /// \param VT The MVT of vtype associated with the RVV instructions.
54 /// For widening/narrowing instructions where the result and source types
55 /// differ, it is important to check the spec to determine whether the vtype
56 /// refers to the result or source type.
57 /// \param CostKind The type of cost to compute.
58 InstructionCost getRISCVInstructionCost(ArrayRef<unsigned> OpCodes, MVT VT,
59 TTI::TargetCostKind CostKind) const;
60
61 // Return the cost of generating a PC relative address
62 InstructionCost
63 getStaticDataAddrGenerationCost(const TTI::TargetCostKind CostKind) const;
64
65 /// Return the cost of accessing a constant pool entry of the specified
66 /// type.
67 InstructionCost getConstantPoolLoadCost(Type *Ty,
68 TTI::TargetCostKind CostKind) const;
69
70 /// If this shuffle can be lowered as a masked slide pair (at worst),
71 /// return a cost for it.
72 InstructionCost getSlideCost(FixedVectorType *Tp, ArrayRef<int> Mask,
73 TTI::TargetCostKind CostKind) const;
74
75 /// Return the type used to cost vzip.vv, whose LMUL represents the
76 /// interleaved destination EMUL. Return an invalid MVT if illegal.
77 MVT getZvzipVZIPCostVT(MVT InterleavedVT) const;
78
79 /// Return the type used to cost vunzipe.v/vunzipo.v, whose LMUL represents
80 /// the interleaved source EMUL. Return an invalid MVT if illegal.
81 MVT getZvzipVUNZIPCostVT(MVT InterleavedVT) const;
82
83 /// If a fixed-length shuffle can be lowered to a vzip.vv instruction,
84 /// return its cost.
85 InstructionCost getVZIPCost(TTI::ShuffleKind Kind, VectorType *DstTy,
86 VectorType *SrcTy, ArrayRef<int> Mask,
87 TTI::TargetCostKind CostKind) const;
88
89public:
90 explicit RISCVTTIImpl(const RISCVTargetMachine *TM, const Function &F)
91 : BaseT(TM, F.getDataLayout()), ST(TM->getSubtargetImpl(F)),
92 TLI(ST->getTargetLowering()) {}
93
94 /// Return the cost of materializing an immediate for a value operand of
95 /// a store instruction.
96 InstructionCost getStoreImmCost(Type *VecTy, TTI::OperandValueInfo OpInfo,
97 TTI::TargetCostKind CostKind) const;
98
99 InstructionCost getIntImmCost(const APInt &Imm, Type *Ty,
100 TTI::TargetCostKind CostKind) const override;
101 InstructionCost getIntImmCostInst(unsigned Opcode, unsigned Idx,
102 const APInt &Imm, Type *Ty,
103 TTI::TargetCostKind CostKind,
104 Instruction *Inst = nullptr) const override;
105 InstructionCost
106 getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx, const APInt &Imm,
107 Type *Ty, TTI::TargetCostKind CostKind) const override;
108
109 /// \name EVL Support for predicated vectorization.
110 /// Whether the target supports the %evl parameter of VP intrinsic efficiently
111 /// in hardware. (see LLVM Language Reference - "Vector Predication
112 /// Intrinsics",
113 /// https://llvm.org/docs/LangRef.html#vector-predication-intrinsics and
114 /// "IR-level VP intrinsics",
115 /// https://llvm.org/docs/Proposals/VectorPredication.html#ir-level-vp-intrinsics).
116 bool hasActiveVectorLength() const override;
117
118 TargetTransformInfo::PopcntSupportKind
119 getPopcntSupport(unsigned TyWidth) const override;
120
121 InstructionCost getPartialReductionCost(
122 unsigned Opcode, Type *InputTypeA, Type *InputTypeB, Type *AccumType,
123 ElementCount VF, TTI::PartialReductionExtendKind OpAExtend,
124 TTI::PartialReductionExtendKind OpBExtend, std::optional<unsigned> BinOp,
125 TTI::TargetCostKind CostKind,
126 std::optional<FastMathFlags> FMF) const override;
127
128 bool shouldExpandReduction(const IntrinsicInst *II) const override;
129 bool supportsScalableVectors() const override {
130 // VLEN=32 support is incomplete.
131 return ST->hasVInstructions() &&
132 (ST->getRealMinVLen() >= RISCV::RVVBitsPerBlock);
133 }
134 bool enableOrderedReductions() const override { return true; }
135 bool enableScalableVectorization() const override {
136 return ST->hasVInstructions();
137 }
138 bool preferTailFoldingOverEpilogue(TailFoldingInfo *TFI) const override {
139 return ST->hasVInstructions();
140 }
141 TailFoldingStyle getPreferredTailFoldingStyle() const override {
142 return ST->hasVInstructions() ? TailFoldingStyle::DataWithEVL
143 : TailFoldingStyle::None;
144 }
145 std::optional<unsigned> getVScaleForTuning() const override;
146
147 TypeSize
148 getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const override;
149
150 unsigned getRegUsageForType(Type *Ty) const override;
151
152 unsigned getMaximumVF(unsigned ElemWidth, unsigned Opcode) const override;
153
154 bool preferAlternateOpcodeVectorization() const override;
155
156 bool preferEpilogueVectorization(ElementCount Iters) const override {
157 // Epilogue vectorization is usually unprofitable - tail folding or
158 // a smaller VF would have been better. This a blunt hammer - we
159 // should re-examine this once vectorization is better tuned.
160 return false;
161 }
162
163 bool shouldConsiderVectorizationRegPressure() const override { return true; }
164
165 InstructionCost
166 getMemIntrinsicInstrCost(const MemIntrinsicCostAttributes &MICA,
167 TTI::TargetCostKind CostKind) const override;
168
169 InstructionCost getMaskedMemoryOpCost(const MemIntrinsicCostAttributes &MICA,
170 TTI::TargetCostKind CostKind) const;
171
172 InstructionCost
173 getPointersChainCost(ArrayRef<const Value *> Ptrs, const Value *Base,
174 const TTI::PointersChainInfo &Info, Type *AccessTy,
175 const TTI::TargetCostKind CostKind) const override;
176
177 void getUnrollingPreferences(Loop *L, ScalarEvolution &SE,
178 TTI::UnrollingPreferences &UP,
179 OptimizationRemarkEmitter *ORE) const override;
180
181 void getPeelingPreferences(Loop *L, ScalarEvolution &SE,
182 TTI::PeelingPreferences &PP) const override;
183
184 bool getTgtMemIntrinsic(IntrinsicInst *Inst,
185 MemIntrinsicInfo &Info) const override;
186
187 unsigned getMinVectorRegisterBitWidth() const override {
188 return ST->useRVVForFixedLengthVectors() ? 16 : 0;
189 }
190
191 InstructionCost
192 getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy,
193 TTI::TargetCostKind CostKind, ArrayRef<int> Mask, int Index,
194 VectorType *SubTp, ArrayRef<const Value *> Args = {},
195 const Instruction *CtxI = nullptr,
196 TTI::VectorInstrContext VIC =
197 TTI::VectorInstrContext::None) const override;
198
199 InstructionCost
200 getScalarizationOverhead(VectorType *Ty, const APInt &DemandedElts,
201 bool Insert, bool Extract,
202 TTI::TargetCostKind CostKind,
203 bool ForPoisonSrc = true, ArrayRef<Value *> VL = {},
204 TTI::VectorInstrContext VIC =
205 TTI::VectorInstrContext::None) const override;
206
207 InstructionCost
208 getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
209 TTI::TargetCostKind CostKind) const override;
210
211 InstructionCost
212 getAddressComputationCost(Type *PTy, ScalarEvolution *SE, const SCEV *Ptr,
213 TTI::TargetCostKind CostKind) const override;
214
215 InstructionCost getInterleavedMemoryOpCost(
216 unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
217 Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
218 bool UseMaskForCond = false, bool UseMaskForGaps = false) const override;
219
220 InstructionCost getGatherScatterOpCost(const MemIntrinsicCostAttributes &MICA,
221 TTI::TargetCostKind CostKind) const;
222
223 InstructionCost
224 getExpandCompressMemoryOpCost(const MemIntrinsicCostAttributes &MICA,
225 TTI::TargetCostKind CostKind) const;
226
227 InstructionCost getStridedMemoryOpCost(const MemIntrinsicCostAttributes &MICA,
228 TTI::TargetCostKind CostKind) const;
229
230 InstructionCost
231 getCostOfKeepingLiveOverCall(ArrayRef<Type *> Tys) const override;
232
233 InstructionCost
234 getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
235 TTI::CastContextHint CCH, TTI::TargetCostKind CostKind,
236 const Instruction *I = nullptr) const override;
237
238 InstructionCost
239 getMinMaxReductionCost(Intrinsic::ID IID, VectorType *Ty, FastMathFlags FMF,
240 TTI::TargetCostKind CostKind) const override;
241
242 std::optional<InstructionCost> getCombinedArithmeticInstructionCost(
243 unsigned ISDOpcode, Type *Ty, TTI::TargetCostKind CostKind,
244 TTI::OperandValueInfo Opd1Info, TTI::OperandValueInfo Opd2Info,
245 ArrayRef<const Value *> Args, const Instruction *CtxI) const;
246
247 InstructionCost
248 getArithmeticReductionCost(unsigned Opcode, VectorType *Ty,
249 std::optional<FastMathFlags> FMF,
250 TTI::TargetCostKind CostKind) const override;
251
252 InstructionCost
253 getExtendedReductionCost(unsigned Opcode, bool IsUnsigned, Type *ResTy,
254 VectorType *ValTy, std::optional<FastMathFlags> FMF,
255 TTI::TargetCostKind CostKind) const override;
256
257 InstructionCost getMemoryOpCost(
258 unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace,
259 TTI::TargetCostKind CostKind,
260 TTI::OperandValueInfo OpdInfo = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
261 const Instruction *I = nullptr) const override;
262
263 InstructionCost getCmpSelInstrCost(
264 unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred,
265 TTI::TargetCostKind CostKind,
266 TTI::OperandValueInfo Op1Info = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
267 TTI::OperandValueInfo Op2Info = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
268 const Instruction *I = nullptr) const override;
269
270 InstructionCost getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind,
271 const Instruction *I = nullptr) const override;
272
273 using BaseT::getVectorInstrCost;
274 InstructionCost
275 getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind,
276 unsigned Index, const Value *Op0, const Value *Op1,
277 TTI::VectorInstrContext VIC =
278 TTI::VectorInstrContext::None) const override;
279
280 InstructionCost
281 getIndexedVectorInstrCostFromEnd(unsigned Opcode, Type *Val,
282 TTI::TargetCostKind CostKind,
283 unsigned Index) const override;
284
285 InstructionCost getArithmeticInstrCost(
286 unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
287 TTI::OperandValueInfo Op1Info = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
288 TTI::OperandValueInfo Op2Info = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
289 ArrayRef<const Value *> Args = {},
290 const Instruction *CtxI = nullptr) const override;
291
292 bool isElementTypeLegalForScalableVector(Type *Ty) const override {
293 return TLI->isLegalElementTypeForRVV(ScalarTy: TLI->getValueType(DL, Ty));
294 }
295
296 bool isLegalMaskedLoadStore(Type *DataType, Align Alignment) const {
297 if (!ST->hasVInstructions())
298 return false;
299
300 EVT DataTypeVT = TLI->getValueType(DL, Ty: DataType);
301
302 // Only support fixed vectors if we know the minimum vector size.
303 if (DataTypeVT.isFixedLengthVector() && !ST->useRVVForFixedLengthVectors())
304 return false;
305
306 EVT ElemType = DataTypeVT.getScalarType();
307 if (!ST->enableUnalignedVectorMem() && Alignment < ElemType.getStoreSize())
308 return false;
309
310 return TLI->isLegalElementTypeForRVV(ScalarTy: ElemType);
311 }
312
313 bool isLegalMaskedLoad(Type *DataType, Align Alignment,
314 unsigned /*AddressSpace*/,
315 TTI::MaskKind /*MaskKind*/) const override {
316 return isLegalMaskedLoadStore(DataType, Alignment);
317 }
318 bool isLegalMaskedStore(Type *DataType, Align Alignment,
319 unsigned /*AddressSpace*/,
320 TTI::MaskKind /*MaskKind*/) const override {
321 return isLegalMaskedLoadStore(DataType, Alignment);
322 }
323
324 bool isLegalMaskedGatherScatter(Type *DataType, Align Alignment) const {
325 if (!ST->hasVInstructions())
326 return false;
327
328 EVT DataTypeVT = TLI->getValueType(DL, Ty: DataType);
329
330 // Only support fixed vectors if we know the minimum vector size.
331 if (DataTypeVT.isFixedLengthVector() && !ST->useRVVForFixedLengthVectors())
332 return false;
333
334 // We also need to check if the vector of address is valid.
335 EVT PointerTypeVT = EVT(TLI->getPointerTy(DL));
336 if (DataTypeVT.isScalableVector() &&
337 !TLI->isLegalElementTypeForRVV(ScalarTy: PointerTypeVT))
338 return false;
339
340 EVT ElemType = DataTypeVT.getScalarType();
341 if (!ST->enableUnalignedVectorMem() && Alignment < ElemType.getStoreSize())
342 return false;
343
344 return TLI->isLegalElementTypeForRVV(ScalarTy: ElemType);
345 }
346
347 bool isLegalMaskedGather(Type *DataType, Align Alignment) const override {
348 return isLegalMaskedGatherScatter(DataType, Alignment);
349 }
350 bool isLegalMaskedScatter(Type *DataType, Align Alignment) const override {
351 return isLegalMaskedGatherScatter(DataType, Alignment);
352 }
353
354 bool forceScalarizeMaskedGather(VectorType *VTy,
355 Align Alignment) const override {
356 // Scalarize masked gather for RV64 if EEW=64 indices aren't supported.
357 return ST->is64Bit() && !ST->hasVInstructionsI64();
358 }
359
360 bool forceScalarizeMaskedScatter(VectorType *VTy,
361 Align Alignment) const override {
362 // Scalarize masked scatter for RV64 if EEW=64 indices aren't supported.
363 return ST->is64Bit() && !ST->hasVInstructionsI64();
364 }
365
366 bool isLegalStridedLoadStore(Type *DataType, Align Alignment) const override {
367 EVT DataTypeVT = TLI->getValueType(DL, Ty: DataType);
368 return TLI->isLegalStridedLoadStore(DataType: DataTypeVT, Alignment);
369 }
370
371 bool isLegalInterleavedAccessType(VectorType *VTy, unsigned Factor,
372 Align Alignment,
373 unsigned AddrSpace) const override {
374 return TLI->isLegalInterleavedAccessType(VTy, Factor, Alignment, AddrSpace,
375 DL);
376 }
377
378 bool isLegalMaskedExpandLoad(Type *DataType, Align Alignment) const override;
379
380 bool isLegalMaskedCompressStore(Type *DataTy, Align Alignment) const override;
381
382 bool isLegalBroadcastLoad(Type *ElementTy,
383 ElementCount NumElements) const override;
384
385 /// \returns How the target needs this vector-predicated operation to be
386 /// transformed.
387 TargetTransformInfo::VPLegalization
388 getVPLegalizationStrategy(const VPIntrinsic &PI) const override {
389 using VPLegalization = TargetTransformInfo::VPLegalization;
390 static const Intrinsic::ID Supported[] = {
391 Intrinsic::experimental_vp_strided_load,
392 Intrinsic::experimental_vp_strided_store,
393 Intrinsic::experimental_vp_reverse,
394 Intrinsic::experimental_vp_splice,
395 Intrinsic::vp_cttz_elts,
396 Intrinsic::vp_gather,
397 Intrinsic::vp_load,
398 Intrinsic::vp_load_ff,
399 Intrinsic::vp_merge,
400 Intrinsic::vp_reduce_add,
401 Intrinsic::vp_reduce_and,
402 Intrinsic::vp_reduce_fadd,
403 Intrinsic::vp_reduce_fmax,
404 Intrinsic::vp_reduce_fmaximum,
405 Intrinsic::vp_reduce_fmin,
406 Intrinsic::vp_reduce_fminimum,
407 Intrinsic::vp_reduce_fmul,
408 Intrinsic::vp_reduce_mul,
409 Intrinsic::vp_reduce_or,
410 Intrinsic::vp_reduce_smax,
411 Intrinsic::vp_reduce_smin,
412 Intrinsic::vp_reduce_umax,
413 Intrinsic::vp_reduce_umin,
414 Intrinsic::vp_reduce_xor,
415 Intrinsic::vp_scatter,
416 Intrinsic::vp_sdiv,
417 Intrinsic::vp_srem,
418 Intrinsic::vp_store,
419 Intrinsic::vp_udiv,
420 Intrinsic::vp_urem};
421 if (!ST->hasVInstructions() ||
422 (PI.getIntrinsicID() == Intrinsic::vp_reduce_mul &&
423 cast<VectorType>(Val: PI.getArgOperand(i: 1)->getType())
424 ->getElementType()
425 ->getIntegerBitWidth() != 1) ||
426 !is_contained(Range: Supported, Element: PI.getIntrinsicID()))
427 return VPLegalization(VPLegalization::Discard, VPLegalization::Convert);
428 return VPLegalization(VPLegalization::Legal, VPLegalization::Legal);
429 }
430
431 bool isLegalToVectorizeReduction(const RecurrenceDescriptor &RdxDesc,
432 ElementCount VF) const override {
433 if (!VF.isScalable())
434 return true;
435
436 Type *Ty = RdxDesc.getRecurrenceType();
437 if (!TLI->isLegalElementTypeForRVV(ScalarTy: TLI->getValueType(DL, Ty)))
438 return false;
439
440 switch (RdxDesc.getRecurrenceKind()) {
441 case RecurKind::Add:
442 case RecurKind::Sub:
443 case RecurKind::AddChainWithSubs:
444 case RecurKind::And:
445 case RecurKind::Or:
446 case RecurKind::Xor:
447 case RecurKind::SMin:
448 case RecurKind::SMax:
449 case RecurKind::UMin:
450 case RecurKind::UMax:
451 case RecurKind::FMin:
452 case RecurKind::FMax:
453 case RecurKind::FindIV:
454 case RecurKind::FindLast:
455 return true;
456 case RecurKind::AnyOf:
457 case RecurKind::FAdd:
458 case RecurKind::FSub:
459 case RecurKind::FMulAdd:
460 // We can't promote f16/bf16 fadd reductions and scalable vectors can't be
461 // expanded.
462 if (Ty->isBFloatTy() || (Ty->isHalfTy() && !ST->hasVInstructionsF16()))
463 return false;
464 return true;
465 case RecurKind::Mul:
466 case RecurKind::FMul:
467 case RecurKind::FMinNum:
468 case RecurKind::FMaxNum:
469 case RecurKind::FMinimum:
470 case RecurKind::FMaximum:
471 case RecurKind::FMinimumNum:
472 case RecurKind::FMaximumNum:
473 case RecurKind::FAddChainWithSubs:
474 return false;
475 case RecurKind::None:
476 llvm_unreachable("Unknown reduction kind.");
477 }
478 }
479
480 unsigned getMaxInterleaveFactor(ElementCount VF,
481 bool HasUnorderedReductions) const override {
482 // Don't interleave if the loop has been vectorized with scalable vectors.
483 if (VF.isScalable())
484 return 1;
485 // If the loop will not be vectorized, don't interleave the loop.
486 // Let regular unroll to unroll the loop.
487 return VF.isScalar() ? 1 : ST->getMaxInterleaveFactor();
488 }
489
490 bool enableInterleavedAccessVectorization() const override { return true; }
491
492 bool enableMaskedInterleavedAccessVectorization() const override {
493 return ST->hasVInstructions();
494 }
495
496 unsigned getMinTripCountTailFoldingThreshold() const override;
497
498 enum RISCVRegisterClass { GPRRC, FPRRC, VRRC };
499 unsigned getNumberOfRegisters(unsigned ClassID) const override {
500 switch (ClassID) {
501 case RISCVRegisterClass::GPRRC:
502 // 31 = 32 GPR - x0 (zero register)
503 // FIXME: Should we exclude fixed registers like SP, TP or GP?
504 return 31;
505 case RISCVRegisterClass::FPRRC:
506 if (ST->hasStdExtF())
507 return 32;
508 return 0;
509 case RISCVRegisterClass::VRRC:
510 // Although there are 32 vector registers, v0 is special in that it is the
511 // only register that can be used to hold a mask.
512 // FIXME: Should we conservatively return 31 as the number of usable
513 // vector registers?
514 return ST->hasVInstructions() ? 32 : 0;
515 }
516 llvm_unreachable("unknown register class");
517 }
518
519 TTI::AddressingModeKind
520 getPreferredAddressingMode(const Loop *L, ScalarEvolution *SE) const override;
521
522 unsigned getRegisterClassForType(bool Vector,
523 Type *Ty = nullptr) const override {
524 if (Vector)
525 return RISCVRegisterClass::VRRC;
526 if (!Ty)
527 return RISCVRegisterClass::GPRRC;
528
529 Type *ScalarTy = Ty->getScalarType();
530 if ((ScalarTy->isHalfTy() && ST->hasStdExtZfhmin()) ||
531 (ScalarTy->isFloatTy() && ST->hasStdExtF()) ||
532 (ScalarTy->isDoubleTy() && ST->hasStdExtD())) {
533 return RISCVRegisterClass::FPRRC;
534 }
535
536 return RISCVRegisterClass::GPRRC;
537 }
538
539 const char *getRegisterClassName(unsigned ClassID) const override {
540 switch (ClassID) {
541 case RISCVRegisterClass::GPRRC:
542 return "RISCV::GPRRC";
543 case RISCVRegisterClass::FPRRC:
544 return "RISCV::FPRRC";
545 case RISCVRegisterClass::VRRC:
546 return "RISCV::VRRC";
547 }
548 llvm_unreachable("unknown register class");
549 }
550
551 bool isLSRCostLess(const TargetTransformInfo::LSRCost &C1,
552 const TargetTransformInfo::LSRCost &C2) const override;
553
554 bool shouldConsiderAddressTypePromotion(
555 const Instruction &I,
556 bool &AllowPromotionWithoutCommonHeader) const override;
557 std::optional<unsigned> getMinPageSize() const override { return 4096; }
558 /// Return true if the (vector) instruction I will be lowered to an
559 /// instruction with a scalar splat operand for the given Operand number.
560 bool canSplatOperand(Instruction *I, int Operand) const;
561 /// Return true if a vector instruction will lower to a target instruction
562 /// able to splat the given operand.
563 bool canSplatOperand(unsigned Opcode, int Operand,
564 Intrinsic::ID IntrinsicID) const;
565
566 TargetTransformInfo::VectorInstrContext getBuildVectorContextHint(
567 ArrayRef<int> Mask, ArrayRef<Value *> Scalars,
568 function_ref<
569 bool(SmallVectorImpl<TargetTransformInfo::BuildVectorUseOp> &)>
570 GatherUseOps) const override;
571
572 bool isProfitableToSinkOperands(Instruction *I,
573 SmallVectorImpl<Use *> &Ops) const override;
574
575 TTI::MemCmpExpansionOptions
576 enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const override;
577
578 bool enableSelectOptimize() const override {
579 return ST->enableSelectOptimize();
580 }
581
582 bool shouldTreatInstructionLikeSelect(const Instruction *I) const override;
583
584 bool
585 shouldCopyAttributeWhenOutliningFrom(const Function *Caller,
586 const Attribute &Attr) const override;
587
588 std::optional<Instruction *>
589 instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const override;
590};
591
592} // end namespace llvm
593
594#endif // LLVM_LIB_TARGET_RISCV_RISCVTARGETTRANSFORMINFO_H
595