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