brintos

brintos / llvm-project-archived public Read only

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