1//===-- RISCVISelLowering.h - RISC-V DAG Lowering Interface -----*- 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//
9// This file defines the interfaces that RISC-V uses to lower LLVM code into a
10// selection DAG.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_LIB_TARGET_RISCV_RISCVISELLOWERING_H
15#define LLVM_LIB_TARGET_RISCV_RISCVISELLOWERING_H
16
17#include "RISCV.h"
18#include "RISCVCallingConv.h"
19#include "llvm/CodeGen/CallingConvLower.h"
20#include "llvm/CodeGen/SelectionDAG.h"
21#include "llvm/CodeGen/TargetLowering.h"
22#include <optional>
23
24namespace llvm {
25class InstructionCost;
26class RISCVSubtarget;
27struct RISCVRegisterInfo;
28
29class RISCVTargetLowering : public TargetLowering {
30 const RISCVSubtarget &Subtarget;
31
32public:
33 explicit RISCVTargetLowering(const TargetMachine &TM,
34 const RISCVSubtarget &STI);
35
36 const RISCVSubtarget &getSubtarget() const { return Subtarget; }
37
38 void getTgtMemIntrinsic(SmallVectorImpl<IntrinsicInfo> &Infos,
39 const CallBase &I, MachineFunction &MF,
40 unsigned Intrinsic) const override;
41 bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty,
42 unsigned AS,
43 Instruction *I = nullptr) const override;
44 bool isLegalICmpImmediate(int64_t Imm) const override;
45 bool isLegalAddImmediate(int64_t Imm) const override;
46 bool isTruncateFree(Type *SrcTy, Type *DstTy) const override;
47 bool isTruncateFree(EVT SrcVT, EVT DstVT) const override;
48 bool isTruncateFree(SDValue Val, EVT VT2) const override;
49 bool isZExtFree(SDValue Val, EVT VT2) const override;
50 bool isSExtCheaperThanZExt(EVT SrcVT, EVT DstVT) const override;
51 bool signExtendConstant(const ConstantInt *CI) const override;
52 bool isCheapToSpeculateCttz(Type *Ty) const override;
53 bool isCheapToSpeculateCtlz(Type *Ty) const override;
54 bool isMaskAndCmp0FoldingBeneficial(const Instruction &AndI) const override;
55 bool hasAndNotCompare(SDValue Y) const override;
56 bool hasAndNot(SDValue Y) const override;
57 bool hasBitTest(SDValue X, SDValue Y) const override;
58 bool shouldProduceAndByConstByHoistingConstFromShiftsLHSOfAnd(
59 SDValue X, ConstantSDNode *XC, ConstantSDNode *CC, SDValue Y,
60 unsigned OldShiftOpcode, unsigned NewShiftOpcode,
61 SelectionDAG &DAG) const override;
62 bool shouldScalarizeBinop(SDValue VecOp) const override;
63 bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
64 int getLegalZfaFPImm(const APFloat &Imm, EVT VT) const;
65 bool isFPImmLegal(const APFloat &Imm, EVT VT,
66 bool ForCodeSize) const override;
67 ExtractSubvectorCost getExtractSubvectorCost(EVT ResVT, EVT SrcVT,
68 unsigned Index) const override;
69
70 bool isIntDivCheap(EVT VT, AttributeList Attr) const override;
71
72 bool preferScalarizeSplat(SDNode *N) const override;
73
74 void finalizeLowering(MachineFunction &MF) const override;
75
76 /// Customize the preferred legalization strategy for certain types.
77 LegalizeTypeAction getPreferredVectorAction(MVT VT) const override;
78
79 /// Return the register type for a given MVT, ensuring vectors are treated
80 /// as a series of gpr sized integers.
81 MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC,
82 EVT VT) const override;
83
84 /// Return the number of registers for a given MVT, for inline assembly
85 unsigned
86 getNumRegisters(LLVMContext &Context, EVT VT,
87 std::optional<MVT> RegisterVT = std::nullopt) const override;
88
89 /// Return the number of registers for a given MVT, ensuring vectors are
90 /// treated as a series of gpr sized integers.
91 unsigned getNumRegistersForCallingConv(LLVMContext &Context,
92 CallingConv::ID CC,
93 EVT VT) const override;
94
95 bool shouldFoldSelectWithIdentityConstant(unsigned BinOpcode, EVT VT,
96 unsigned SelectOpcode, SDValue X,
97 SDValue Y) const override;
98
99 /// Return true if the given shuffle mask can be codegen'd directly, or if it
100 /// should be stack expanded.
101 bool isShuffleMaskLegal(ArrayRef<int> M, EVT VT) const override;
102
103 bool isVectorClearMaskLegal(ArrayRef<int> M, EVT VT) const override;
104
105 bool isMultiStoresCheaperThanBitsMerge(EVT LTy, EVT HTy) const override {
106 // If the pair to store is a mixture of float and int values, we will
107 // save two bitwise instructions and one float-to-int instruction and
108 // increase one store instruction. There is potentially a more
109 // significant benefit because it avoids the float->int domain switch
110 // for input value. So It is more likely a win.
111 if ((LTy.isFloatingPoint() && HTy.isInteger()) ||
112 (LTy.isInteger() && HTy.isFloatingPoint()))
113 return true;
114 // If the pair only contains int values, we will save two bitwise
115 // instructions and increase one store instruction (costing one more
116 // store buffer). Since the benefit is more blurred we leave such a pair
117 // out until we get testcase to prove it is a win.
118 return false;
119 }
120
121 bool
122 shouldExpandBuildVectorWithShuffles(EVT VT,
123 unsigned DefinedValues) const override;
124
125 /// Return the cost of LMUL for linear operations.
126 InstructionCost getLMULCost(MVT VT) const;
127
128 InstructionCost getVRGatherVVCost(MVT VT) const;
129 InstructionCost getVRGatherVICost(MVT VT) const;
130 InstructionCost getVSlideVXCost(MVT VT) const;
131 InstructionCost getVSlideVICost(MVT VT) const;
132
133 // Provide custom lowering hooks for some operations.
134 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
135 void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
136 SelectionDAG &DAG) const override;
137
138 SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
139
140 bool targetShrinkDemandedConstant(SDValue Op, const APInt &DemandedBits,
141 const APInt &DemandedElts,
142 TargetLoweringOpt &TLO) const override;
143
144 void computeKnownBitsForTargetNode(const SDValue Op,
145 KnownBits &Known,
146 const APInt &DemandedElts,
147 const SelectionDAG &DAG,
148 unsigned Depth) const override;
149
150 void computeKnownBitsForTargetInstr(GISelValueTracking &Analysis, Register R,
151 KnownBits &Known,
152 const APInt &DemandedElts,
153 const MachineRegisterInfo &MRI,
154 unsigned Depth = 0) const override;
155 unsigned ComputeNumSignBitsForTargetNode(SDValue Op,
156 const APInt &DemandedElts,
157 const SelectionDAG &DAG,
158 unsigned Depth) const override;
159
160 bool SimplifyDemandedBitsForTargetNode(SDValue Op, const APInt &DemandedBits,
161 const APInt &DemandedElts,
162 KnownBits &Known,
163 TargetLoweringOpt &TLO,
164 unsigned Depth) const override;
165
166 bool canCreateUndefOrPoisonForTargetNode(
167 SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
168 UndefPoisonKind Kind, bool ConsiderFlags, unsigned Depth) const override;
169
170 const Constant *getTargetConstantFromLoad(LoadSDNode *LD) const override;
171
172 MachineMemOperand::Flags
173 getTargetMMOFlags(const Instruction &I) const override;
174
175 MachineMemOperand::Flags
176 getTargetMMOFlags(const MemSDNode &Node) const override;
177
178 bool
179 areTwoSDNodeTargetMMOFlagsMergeable(const MemSDNode &NodeX,
180 const MemSDNode &NodeY) const override;
181
182 ConstraintType getConstraintType(StringRef Constraint) const override;
183
184 InlineAsm::ConstraintCode
185 getInlineAsmMemConstraint(StringRef ConstraintCode) const override;
186
187 std::pair<unsigned, const TargetRegisterClass *>
188 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
189 StringRef Constraint, MVT VT) const override;
190
191 void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint,
192 std::vector<SDValue> &Ops,
193 SelectionDAG &DAG) const override;
194
195 MachineBasicBlock *
196 EmitInstrWithCustomInserter(MachineInstr &MI,
197 MachineBasicBlock *BB) const override;
198
199 void AdjustInstrPostInstrSelection(MachineInstr &MI,
200 SDNode *Node) const override;
201
202 EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
203 EVT VT) const override;
204
205 CondMergingParams
206 getJumpConditionMergingParams(Instruction::BinaryOps Opc, const Value *LHS,
207 const Value *RHS,
208 const Function *F) const override;
209
210 bool shouldFormOverflowOp(unsigned Opcode, EVT VT,
211 bool MathUsed) const override {
212 if (VT == MVT::i8 || VT == MVT::i16)
213 return false;
214
215 return TargetLowering::shouldFormOverflowOp(Opcode, VT, MathUsed);
216 }
217
218 bool storeOfVectorConstantIsCheap(bool IsZero, EVT MemVT, unsigned NumElem,
219 unsigned AddrSpace) const override {
220 // Replacing 4 or more element stores is a net reduction in instructions
221 // even after accounting for the vmv.v.i needed to materialize the zero
222 // vector. MemVT may already be a vector, since memset lowers to LMUL1
223 // stores that we rely on this merge to widen, so use the total element
224 // count.
225 unsigned NumMemElts = MemVT.isVector() ? MemVT.getVectorNumElements() : 1;
226 if (IsZero)
227 return NumElem * NumMemElts >= 4;
228
229 // Materializing a non-zero vector constant isn't free (it may need
230 // several instructions like li + vmv.v.x or a constant-pool load), so stay
231 // conservative and only merge when replacing 4 or more stores.
232 return NumElem >= 4;
233 }
234
235 bool convertSetCCLogicToBitwiseLogic(EVT VT) const override {
236 return VT.isScalarInteger();
237 }
238 bool convertSelectOfConstantsToMath(EVT VT) const override { return true; }
239
240 bool isCtpopFast(EVT VT) const override;
241
242 unsigned getCustomCtpopCost(EVT VT, ISD::CondCode Cond) const override;
243
244 bool preferZeroCompareBranch() const override { return true; }
245
246 // Note that one specific case requires fence insertion for an
247 // AtomicCmpXchgInst but is handled via the RISCVZacasABIFix pass rather
248 // than this hook due to limitations in the interface here.
249 bool shouldInsertFencesForAtomic(const Instruction *I) const override;
250
251 Instruction *emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst,
252 AtomicOrdering Ord) const override;
253 Instruction *emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst,
254 AtomicOrdering Ord) const override;
255
256 bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
257 EVT VT) const override;
258
259 ISD::NodeType getExtendForAtomicOps() const override {
260 return ISD::SIGN_EXTEND;
261 }
262
263 ISD::NodeType getExtendForAtomicCmpSwapArg() const override;
264 ISD::NodeType getExtendForAtomicRMWArg(unsigned Op) const override;
265
266 bool shouldTransformSignedTruncationCheck(EVT XVT,
267 unsigned KeptBits) const override;
268
269 TargetLowering::ShiftLegalizationStrategy
270 preferredShiftLegalizationStrategy(SelectionDAG &DAG, SDNode *N,
271 unsigned ExpansionFactor) const override {
272 if (DAG.getMachineFunction().getFunction().hasMinSize())
273 return ShiftLegalizationStrategy::LowerToLibcall;
274 return TargetLowering::preferredShiftLegalizationStrategy(DAG, N,
275 ExpansionFactor);
276 }
277
278 bool isDesirableToCommuteWithShift(const SDNode *N,
279 CombineLevel Level) const override;
280
281 /// If a physical register, this returns the register that receives the
282 /// exception address on entry to an EH pad.
283 Register
284 getExceptionPointerRegister(ExceptionHandling EH,
285 const Constant *PersonalityFn) const override;
286
287 /// If a physical register, this returns the register that receives the
288 /// exception typeid on entry to a landing pad.
289 Register
290 getExceptionSelectorRegister(ExceptionHandling EH,
291 const Constant *PersonalityFn) const override;
292
293 bool shouldExtendTypeInLibCall(EVT Type) const override;
294 bool shouldSignExtendTypeInLibCall(Type *Ty, bool IsSigned) const override;
295
296 /// Returns the register with the specified architectural or ABI name. This
297 /// method is necessary to lower the llvm.read_register.* and
298 /// llvm.write_register.* intrinsics. Allocatable registers must be reserved
299 /// with the clang -ffixed-xX flag for access to be allowed.
300 Register getRegisterByName(const char *RegName, LLT VT,
301 const MachineFunction &MF) const override;
302
303 // Lower incoming arguments, copy physregs into vregs
304 SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
305 bool IsVarArg,
306 const SmallVectorImpl<ISD::InputArg> &Ins,
307 const SDLoc &DL, SelectionDAG &DAG,
308 SmallVectorImpl<SDValue> &InVals) const override;
309 bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
310 bool IsVarArg,
311 const SmallVectorImpl<ISD::OutputArg> &Outs,
312 LLVMContext &Context, const Type *RetTy) const override;
313 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
314 const SmallVectorImpl<ISD::OutputArg> &Outs,
315 const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
316 SelectionDAG &DAG) const override;
317 SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
318 SmallVectorImpl<SDValue> &InVals) const override;
319
320 bool shouldConvertConstantLoadToIntImm(const APInt &Imm,
321 Type *Ty) const override;
322 bool isUsedByReturnOnly(SDNode *N, SDValue &Chain) const override;
323 bool mayBeEmittedAsTailCall(const CallInst *CI) const override;
324 bool shouldConsiderGEPOffsetSplit() const override { return true; }
325
326 bool decomposeMulByConstant(LLVMContext &Context, EVT VT,
327 SDValue C) const override;
328
329 bool isMulAddWithConstProfitable(SDValue AddNode,
330 SDValue ConstNode) const override;
331
332 TargetLowering::AtomicExpansionKind
333 shouldExpandAtomicRMWInIR(const AtomicRMWInst *AI) const override;
334 Value *emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, AtomicRMWInst *AI,
335 Value *AlignedAddr, Value *Incr,
336 Value *Mask, Value *ShiftAmt,
337 AtomicOrdering Ord) const override;
338 TargetLowering::AtomicExpansionKind
339 shouldExpandAtomicCmpXchgInIR(const AtomicCmpXchgInst *CI) const override;
340 Value *emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder,
341 AtomicCmpXchgInst *CI,
342 Value *AlignedAddr, Value *CmpVal,
343 Value *NewVal, Value *Mask,
344 AtomicOrdering Ord) const override;
345
346 /// Returns true if the target allows unaligned memory accesses of the
347 /// specified type.
348 bool allowsMisalignedMemoryAccesses(
349 EVT VT, unsigned AddrSpace = 0, Align Alignment = Align(1),
350 MachineMemOperand::Flags Flags = MachineMemOperand::MONone,
351 unsigned *Fast = nullptr) const override;
352
353 bool allowsMisalignedMemoryAccesses(
354 LLT Ty, unsigned AddrSpace = 0, Align Alignment = Align(1),
355 MachineMemOperand::Flags Flags = MachineMemOperand::MONone,
356 unsigned *Fast = nullptr) const override;
357
358 EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op,
359 const AttributeList &FuncAttributes) const override;
360
361 bool splitValueIntoRegisterParts(
362 SelectionDAG & DAG, const SDLoc &DL, SDValue Val, SDValue *Parts,
363 unsigned NumParts, MVT PartVT, std::optional<CallingConv::ID> CC)
364 const override;
365
366 SDValue joinRegisterPartsIntoValue(
367 SelectionDAG & DAG, const SDLoc &DL, const SDValue *Parts,
368 unsigned NumParts, MVT PartVT, EVT ValueVT,
369 std::optional<CallingConv::ID> CC) const override;
370
371 // Return the value of VLMax for the given vector type (i.e. SEW and LMUL)
372 SDValue computeVLMax(MVT VecVT, const SDLoc &DL, SelectionDAG &DAG) const;
373
374 static RISCVVType::VLMUL getLMUL(MVT VT);
375 inline static unsigned computeVLMAX(unsigned VectorBits, unsigned EltSize,
376 unsigned MinSize) {
377 // Original equation:
378 // VLMAX = (VectorBits / EltSize) * LMUL
379 // where LMUL = MinSize / RISCV::RVVBitsPerBlock
380 // The following equations have been reordered to prevent loss of precision
381 // when calculating fractional LMUL.
382 return ((VectorBits / EltSize) * MinSize) / RISCV::RVVBitsPerBlock;
383 }
384
385 // Return inclusive (low, high) bounds on the value of VLMAX for the
386 // given scalable container type given known bounds on VLEN.
387 static std::pair<unsigned, unsigned>
388 computeVLMAXBounds(MVT ContainerVT, const RISCVSubtarget &Subtarget);
389
390 /// Given a vector (either fixed or scalable), return the scalable vector
391 /// corresponding to a vector register (i.e. an m1 register group).
392 static MVT getM1VT(MVT VT) {
393 unsigned EltSizeInBits = VT.getVectorElementType().getSizeInBits();
394 assert(EltSizeInBits <= RISCV::RVVBitsPerBlock && "Unexpected vector MVT");
395 return MVT::getScalableVectorVT(VT: VT.getVectorElementType(),
396 NumElements: RISCV::RVVBitsPerBlock / EltSizeInBits);
397 }
398
399 static unsigned getRegClassIDForLMUL(RISCVVType::VLMUL LMul);
400 static unsigned getSubregIndexByMVT(MVT VT, unsigned Index);
401 static unsigned getRegClassIDForVecVT(MVT VT);
402 static std::pair<unsigned, unsigned>
403 decomposeSubvectorInsertExtractToSubRegs(MVT VecVT, MVT SubVecVT,
404 unsigned InsertExtractIdx,
405 const RISCVRegisterInfo *TRI);
406 MVT getContainerForFixedLengthVector(MVT VT) const;
407
408 bool shouldRemoveExtendFromGSIndex(SDValue Extend, EVT DataVT) const override;
409
410 bool isLegalElementTypeForRVV(EVT ScalarTy) const;
411
412 bool shouldConvertFpToSat(unsigned Op, EVT FPVT, EVT VT) const override;
413
414 unsigned getJumpTableEncoding() const override;
415
416 const MCExpr *LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI,
417 const MachineBasicBlock *MBB,
418 unsigned uid,
419 MCContext &Ctx) const override;
420
421 bool getIndexedAddressParts(SDNode *Op, SDValue &Base, SDValue &Offset,
422 ISD::MemIndexedMode &AM, SelectionDAG &DAG) const;
423 bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset,
424 ISD::MemIndexedMode &AM,
425 SelectionDAG &DAG) const override;
426 bool getPostIndexedAddressParts(SDNode *N, SDNode *Op, SDValue &Base,
427 SDValue &Offset, ISD::MemIndexedMode &AM,
428 SelectionDAG &DAG) const override;
429
430 bool isLegalScaleForGatherScatter(uint64_t Scale,
431 uint64_t ElemSize) const override {
432 // Scaled addressing not supported on indexed load/stores
433 return Scale == 1;
434 }
435
436 /// If the target has a standard location for the stack protector cookie,
437 /// returns the address of that location. Otherwise, returns nullptr.
438 Value *getIRStackGuard(IRBuilderBase &IRB,
439 const LibcallLoweringInfo &Libcalls) const override;
440
441 /// Returns whether or not generating a interleaved load/store intrinsic for
442 /// this type will be legal.
443 bool isLegalInterleavedAccessType(VectorType *VTy, unsigned Factor,
444 Align Alignment, unsigned AddrSpace,
445 const DataLayout &) const;
446
447 /// Return true if a stride load store of the given result type and
448 /// alignment is legal.
449 bool isLegalStridedLoadStore(EVT DataType, Align Alignment) const;
450
451 /// Return true if a fault-only-first load of the given result type and
452 /// alignment is legal.
453 bool isLegalFirstFaultLoad(EVT DataType, Align Alignment) const;
454
455 unsigned getMaxSupportedInterleaveFactor() const override { return 8; }
456
457 bool fallBackToDAGISel(const Instruction &Inst) const override;
458
459 bool lowerInterleavedLoad(Instruction *Load, Value *Mask,
460 ArrayRef<ShuffleVectorInst *> Shuffles,
461 ArrayRef<unsigned> Indices, unsigned Factor,
462 const APInt &GapMask) const override;
463
464 bool lowerInterleavedStore(Instruction *Store, Value *Mask,
465 ShuffleVectorInst *SVI, unsigned Factor,
466 const APInt &GapMask) const override;
467
468 bool lowerDeinterleaveIntrinsicToLoad(Instruction *Load, Value *Mask,
469 IntrinsicInst *DI,
470 const APInt &GapMask) const override;
471
472 bool lowerInterleaveIntrinsicToStore(
473 Instruction *Store, Value *Mask,
474 ArrayRef<Value *> InterleaveValues) const override;
475
476 bool supportKCFIBundles() const override { return true; }
477
478 SDValue expandIndirectJTBranch(const SDLoc &dl, SDValue Value, SDValue Addr,
479 int JTI, SelectionDAG &DAG) const override;
480
481 MachineInstr *EmitKCFICheck(MachineBasicBlock &MBB,
482 MachineBasicBlock::instr_iterator &MBBI,
483 const TargetInstrInfo *TII) const override;
484
485 /// True if stack clash protection is enabled for this functions.
486 bool hasInlineStackProbe(const MachineFunction &MF) const override;
487
488 unsigned getStackProbeSize(const MachineFunction &MF, Align StackAlign) const;
489
490 MachineBasicBlock *emitDynamicProbedAlloc(MachineInstr &MI,
491 MachineBasicBlock *MBB) const;
492
493 ArrayRef<MCPhysReg> getRoundingControlRegisters() const override;
494
495 bool shouldFoldMaskToVariableShiftPair(SDValue Y) const override;
496
497 /// Control the following reassociation of operands: (op (op x, c1), y) -> (op
498 /// (op x, y), c1) where N0 is (op x, c1) and N1 is y.
499 bool isReassocProfitable(SelectionDAG &DAG, SDValue N0,
500 SDValue N1) const override;
501
502 /// Match a mask which "spreads" the leading elements of a vector evenly
503 /// across the result. Factor is the spread amount, and Index is the
504 /// offset applied.
505 static bool isSpreadMask(ArrayRef<int> Mask, unsigned Factor,
506 unsigned &Index);
507
508private:
509 template <class NodeTy>
510 SDValue getAddr(NodeTy *N, SelectionDAG &DAG, bool IsLocal = true,
511 bool IsExternWeak = false) const;
512 SDValue getStaticTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG,
513 bool UseGOT) const;
514 SDValue getDynamicTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG) const;
515 SDValue getTLSDescAddr(GlobalAddressSDNode *N, SelectionDAG &DAG) const;
516
517 SDValue lowerConstantFP(SDValue Op, SelectionDAG &DAG) const;
518 SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
519 SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
520 SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
521 SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
522 SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
523 SDValue lowerSELECT(SDValue Op, SelectionDAG &DAG) const;
524 SDValue lowerBRCOND(SDValue Op, SelectionDAG &DAG) const;
525 SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const;
526 SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
527 SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
528 SDValue lowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const;
529 SDValue lowerShiftRightParts(SDValue Op, SelectionDAG &DAG, bool IsSRA) const;
530 SDValue lowerSPLAT_VECTOR_PARTS(SDValue Op, SelectionDAG &DAG) const;
531 SDValue lowerVectorMaskSplat(SDValue Op, SelectionDAG &DAG) const;
532 SDValue lowerVectorMaskExt(SDValue Op, SelectionDAG &DAG,
533 int64_t ExtTrueVal) const;
534 SDValue lowerVectorMaskTrunc(SDValue Op, SelectionDAG &DAG) const;
535 SDValue lowerVectorTrunc(SDValue Op, SelectionDAG &DAG) const;
536 SDValue lowerVectorFPExtendOrRound(SDValue Op, SelectionDAG &DAG) const;
537 SDValue lowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
538 SDValue lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
539 SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
540 SDValue LowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const;
541 SDValue LowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const;
542 SDValue lowerVPREDUCE(SDValue Op, SelectionDAG &DAG) const;
543 SDValue lowerVECREDUCE(SDValue Op, SelectionDAG &DAG) const;
544 SDValue lowerVectorMaskVecReduction(SDValue Op, SelectionDAG &DAG,
545 bool IsVP) const;
546 SDValue lowerFPVECREDUCE(SDValue Op, SelectionDAG &DAG) const;
547 SDValue lowerINSERT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const;
548 SDValue lowerEXTRACT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const;
549 SDValue lowerVECTOR_DEINTERLEAVE(SDValue Op, SelectionDAG &DAG) const;
550 SDValue lowerVECTOR_INTERLEAVE(SDValue Op, SelectionDAG &DAG) const;
551 SDValue lowerSTEP_VECTOR(SDValue Op, SelectionDAG &DAG) const;
552 SDValue lowerVECTOR_REVERSE(SDValue Op, SelectionDAG &DAG) const;
553 SDValue lowerVECTOR_SPLICE(SDValue Op, SelectionDAG &DAG) const;
554 SDValue lowerABS(SDValue Op, SelectionDAG &DAG) const;
555 SDValue lowerMaskedLoad(SDValue Op, SelectionDAG &DAG) const;
556 SDValue lowerLoadFF(SDValue Op, SelectionDAG &DAG) const;
557 SDValue lowerMaskedStore(SDValue Op, SelectionDAG &DAG) const;
558 SDValue lowerVectorCompress(SDValue Op, SelectionDAG &DAG) const;
559 SDValue lowerMaskedGather(SDValue Op, SelectionDAG &DAG) const;
560 SDValue lowerMaskedScatter(SDValue Op, SelectionDAG &DAG) const;
561 SDValue lowerFixedLengthVectorLoadToRVV(SDValue Op, SelectionDAG &DAG) const;
562 SDValue lowerFixedLengthVectorStoreToRVV(SDValue Op, SelectionDAG &DAG) const;
563 SDValue lowerToScalableOp(SDValue Op, SelectionDAG &DAG) const;
564 SDValue LowerIS_FPCLASS(SDValue Op, SelectionDAG &DAG) const;
565 SDValue lowerVPOp(SDValue Op, SelectionDAG &DAG) const;
566 SDValue lowerVPMergeMask(SDValue Op, SelectionDAG &DAG) const;
567 SDValue lowerVPSpliceExperimental(SDValue Op, SelectionDAG &DAG) const;
568 SDValue lowerVPReverseExperimental(SDValue Op, SelectionDAG &DAG) const;
569 SDValue lowerVPStridedLoad(SDValue Op, SelectionDAG &DAG) const;
570 SDValue lowerVPStridedStore(SDValue Op, SelectionDAG &DAG) const;
571 SDValue lowerVPCttzElements(SDValue Op, SelectionDAG &DAG) const;
572 SDValue lowerGET_ROUNDING(SDValue Op, SelectionDAG &DAG) const;
573 SDValue lowerSET_ROUNDING(SDValue Op, SelectionDAG &DAG) const;
574 SDValue lowerGET_FPENV(SDValue Op, SelectionDAG &DAG) const;
575 SDValue lowerSET_FPENV(SDValue Op, SelectionDAG &DAG) const;
576 SDValue lowerRESET_FPENV(SDValue Op, SelectionDAG &DAG) const;
577 SDValue lowerGET_FPMODE(SDValue Op, SelectionDAG &DAG) const;
578 SDValue lowerSET_FPMODE(SDValue Op, SelectionDAG &DAG) const;
579 SDValue lowerRESET_FPMODE(SDValue Op, SelectionDAG &DAG) const;
580
581 SDValue lowerEH_DWARF_CFA(SDValue Op, SelectionDAG &DAG) const;
582 SDValue lowerCTLZ_CTTZ_ZERO_POISON(SDValue Op, SelectionDAG &DAG) const;
583
584 SDValue lowerStrictFPExtendOrRoundLike(SDValue Op, SelectionDAG &DAG) const;
585
586 SDValue lowerVectorStrictFSetcc(SDValue Op, SelectionDAG &DAG) const;
587
588 SDValue lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
589
590 SDValue expandUnalignedRVVLoad(SDValue Op, SelectionDAG &DAG) const;
591 SDValue expandUnalignedRVVStore(SDValue Op, SelectionDAG &DAG) const;
592
593 SDValue expandUnalignedVPLoad(SDValue Op, SelectionDAG &DAG) const;
594 SDValue expandUnalignedVPStore(SDValue Op, SelectionDAG &DAG) const;
595
596 SDValue lowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const;
597 SDValue lowerADJUST_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const;
598 SDValue lowerPARTIAL_REDUCE_MLA(SDValue Op, SelectionDAG &DAG) const;
599 SDValue lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const;
600
601 SDValue lowerXAndesBfHCvtBFloat16Load(SDValue Op, SelectionDAG &DAG) const;
602 SDValue lowerXAndesBfHCvtBFloat16Store(SDValue Op, SelectionDAG &DAG) const;
603
604 bool isEligibleForTailCallOptimization(
605 CCState &CCInfo, CallLoweringInfo &CLI, MachineFunction &MF,
606 const SmallVector<CCValAssign, 16> &ArgLocs) const;
607
608 /// Generate error diagnostics if any register used by CC has been marked
609 /// reserved.
610 void validateCCReservedRegs(
611 const SmallVectorImpl<std::pair<llvm::Register, llvm::SDValue>> &Regs,
612 MachineFunction &MF) const;
613
614 bool useRVVForFixedLengthVectorVT(MVT VT) const;
615
616 MVT getVPExplicitVectorLengthTy() const override;
617
618 bool shouldExpandGetVectorLength(EVT TripCountVT, unsigned VF,
619 bool IsScalable) const override;
620
621 bool isProfitableToFoldVScaleAdd(SDValue N) const override;
622
623 /// RVV code generation for fixed length vectors does not lower all
624 /// BUILD_VECTORs. This makes BUILD_VECTOR legalisation a source of stores to
625 /// merge. However, merging them creates a BUILD_VECTOR that is just as
626 /// illegal as the original, thus leading to an infinite legalisation loop.
627 /// NOTE: Once BUILD_VECTOR can be custom lowered for all legal vector types,
628 /// this override can be removed.
629 bool mergeStoresAfterLegalization(EVT VT) const override;
630
631 /// Disable normalizing
632 /// select(N0&N1, X, Y) => select(N0, select(N1, X, Y), Y) and
633 /// select(N0|N1, X, Y) => select(N0, select(N1, X, Y, Y))
634 /// RISC-V doesn't have flags so it's better to perform the and/or in a GPR.
635 bool shouldNormalizeToSelectSequence(LLVMContext &, EVT, EVT) const override {
636 return false;
637 }
638
639 /// Disables storing and loading vectors by default when there are function
640 /// calls between the load and store, since these are more expensive than just
641 /// using scalars
642 bool shouldMergeStoreOfLoadsOverCall(EVT SrcVT, EVT MergedVT) const override {
643 return !MergedVT.isVector() || SrcVT.isVector();
644 }
645
646 /// For available scheduling models FDIV + two independent FMULs are much
647 /// faster than two FDIVs.
648 unsigned combineRepeatedFPDivisors() const override;
649
650 SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG,
651 SmallVectorImpl<SDNode *> &Created) const override;
652
653 bool shouldFoldSelectWithSingleBitTest(EVT VT,
654 const APInt &AndMask) const override;
655
656 unsigned getMinimumJumpTableEntries() const override;
657
658 SDValue emitFlushICache(SelectionDAG &DAG, SDValue InChain, SDValue Start,
659 SDValue End, SDValue Flags, SDLoc DL) const;
660
661 std::pair<const TargetRegisterClass *, uint8_t>
662 findRepresentativeClass(const TargetRegisterInfo *TRI, MVT VT) const override;
663};
664
665namespace RISCVVIntrinsicsTable {
666
667struct RISCVVIntrinsicInfo {
668 unsigned IntrinsicID;
669 uint8_t ScalarOperand;
670 uint8_t VLOperand;
671 bool IsFPIntrinsic;
672 bool hasScalarOperand() const {
673 // 0xF is not valid. See NoScalarOperand in IntrinsicsRISCV.td.
674 return ScalarOperand != 0xF;
675 }
676 bool hasVLOperand() const {
677 // 0x1F is not valid. See NoVLOperand in IntrinsicsRISCV.td.
678 return VLOperand != 0x1F;
679 }
680};
681
682using namespace RISCV;
683
684#define GET_RISCVVIntrinsicsTable_DECL
685#include "RISCVGenSearchableTables.inc"
686#undef GET_RISCVVIntrinsicsTable_DECL
687
688} // end namespace RISCVVIntrinsicsTable
689
690} // end namespace llvm
691
692#endif
693