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