1 //===-- RISCVISelLowering.h - RISCV 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 RISCV 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 "llvm/CodeGen/SelectionDAG.h" 19 #include "llvm/CodeGen/TargetLowering.h" 20 21 namespace llvm { 22 class RISCVSubtarget; 23 struct RISCVRegisterInfo; 24 namespace RISCVISD { 25 enum NodeType : unsigned { 26 FIRST_NUMBER = ISD::BUILTIN_OP_END, 27 RET_FLAG, 28 URET_FLAG, 29 SRET_FLAG, 30 MRET_FLAG, 31 CALL, 32 /// Select with condition operator - This selects between a true value and 33 /// a false value (ops #3 and #4) based on the boolean result of comparing 34 /// the lhs and rhs (ops #0 and #1) of a conditional expression with the 35 /// condition code in op #2, a XLenVT constant from the ISD::CondCode enum. 36 /// The lhs and rhs are XLenVT integers. The true and false values can be 37 /// integer or floating point. 38 SELECT_CC, 39 BR_CC, 40 BuildPairF64, 41 SplitF64, 42 TAIL, 43 // RV64I shifts, directly matching the semantics of the named RISC-V 44 // instructions. 45 SLLW, 46 SRAW, 47 SRLW, 48 // 32-bit operations from RV64M that can't be simply matched with a pattern 49 // at instruction selection time. These have undefined behavior for division 50 // by 0 or overflow (divw) like their target independent counterparts. 51 DIVW, 52 DIVUW, 53 REMUW, 54 // RV64IB rotates, directly matching the semantics of the named RISC-V 55 // instructions. 56 ROLW, 57 RORW, 58 // RV64IB/RV32IB funnel shifts, with the semantics of the named RISC-V 59 // instructions, but the same operand order as fshl/fshr intrinsics. 60 FSR, 61 FSL, 62 // RV64IB funnel shifts, with the semantics of the named RISC-V instructions, 63 // but the same operand order as fshl/fshr intrinsics. 64 FSRW, 65 FSLW, 66 // FPR<->GPR transfer operations when the FPR is smaller than XLEN, needed as 67 // XLEN is the only legal integer width. 68 // 69 // FMV_H_X matches the semantics of the FMV.H.X. 70 // FMV_X_ANYEXTH is similar to FMV.X.H but has an any-extended result. 71 // FMV_W_X_RV64 matches the semantics of the FMV.W.X. 72 // FMV_X_ANYEXTW_RV64 is similar to FMV.X.W but has an any-extended result. 73 // 74 // This is a more convenient semantic for producing dagcombines that remove 75 // unnecessary GPR->FPR->GPR moves. 76 FMV_H_X, 77 FMV_X_ANYEXTH, 78 FMV_W_X_RV64, 79 FMV_X_ANYEXTW_RV64, 80 // READ_CYCLE_WIDE - A read of the 64-bit cycle CSR on a 32-bit target 81 // (returns (Lo, Hi)). It takes a chain operand. 82 READ_CYCLE_WIDE, 83 // Generalized Reverse and Generalized Or-Combine - directly matching the 84 // semantics of the named RISC-V instructions. Lowered as custom nodes as 85 // TableGen chokes when faced with commutative permutations in deeply-nested 86 // DAGs. Each node takes an input operand and a TargetConstant immediate 87 // shift amount, and outputs a bit-manipulated version of input. All operands 88 // are of type XLenVT. 89 GREVI, 90 GREVIW, 91 GORCI, 92 GORCIW, 93 SHFLI, 94 // Vector Extension 95 // VMV_V_X_VL matches the semantics of vmv.v.x but includes an extra operand 96 // for the VL value to be used for the operation. 97 VMV_V_X_VL, 98 // VFMV_V_F_VL matches the semantics of vfmv.v.f but includes an extra operand 99 // for the VL value to be used for the operation. 100 VFMV_V_F_VL, 101 // VMV_X_S matches the semantics of vmv.x.s. The result is always XLenVT sign 102 // extended from the vector element size. 103 VMV_X_S, 104 // VMV_S_XF_VL matches the semantics of vmv.s.x/vmv.s.f, depending on the 105 // types of its operands. It carries a VL operand. 106 VMV_S_XF_VL, 107 // Splats an i64 scalar to a vector type (with element type i64) where the 108 // scalar is a sign-extended i32. 109 SPLAT_VECTOR_I64, 110 // Read VLENB CSR 111 READ_VLENB, 112 // Truncates a RVV integer vector by one power-of-two. Carries both an extra 113 // mask and VL operand. 114 TRUNCATE_VECTOR_VL, 115 // Unit-stride fault-only-first load 116 VLEFF, 117 VLEFF_MASK, 118 // Matches the semantics of vslideup/vslidedown. The first operand is the 119 // pass-thru operand, the second is the source vector, the third is the 120 // XLenVT index (either constant or non-constant), the fourth is the mask 121 // and the fifth the VL. 122 VSLIDEUP_VL, 123 VSLIDEDOWN_VL, 124 // Matches the semantics of vslide1up. The first operand is the source 125 // vector, the second is the XLenVT scalar value. The third and fourth 126 // operands are the mask and VL operands. 127 VSLIDE1UP_VL, 128 // Matches the semantics of the vid.v instruction, with a mask and VL 129 // operand. 130 VID_VL, 131 // Matches the semantics of the vfcnvt.rod function (Convert double-width 132 // float to single-width float, rounding towards odd). Takes a double-width 133 // float vector and produces a single-width float vector. Also has a mask and 134 // VL operand. 135 VFNCVT_ROD_VL, 136 // These nodes match the semantics of the corresponding RVV vector reduction 137 // instructions. They produce a vector result which is the reduction 138 // performed over the first vector operand plus the first element of the 139 // second vector operand. The first operand is an unconstrained vector type, 140 // and the result and second operand's types are expected to be the 141 // corresponding full-width LMUL=1 type for the first operand: 142 // nxv8i8 = vecreduce_add nxv32i8, nxv8i8 143 // nxv2i32 = vecreduce_add nxv8i32, nxv2i32 144 // The different in types does introduce extra vsetvli instructions but 145 // similarly it reduces the number of registers consumed per reduction. 146 // Also has a mask and VL operand. 147 VECREDUCE_ADD_VL, 148 VECREDUCE_UMAX_VL, 149 VECREDUCE_SMAX_VL, 150 VECREDUCE_UMIN_VL, 151 VECREDUCE_SMIN_VL, 152 VECREDUCE_AND_VL, 153 VECREDUCE_OR_VL, 154 VECREDUCE_XOR_VL, 155 VECREDUCE_FADD_VL, 156 VECREDUCE_SEQ_FADD_VL, 157 158 // Vector binary and unary ops with a mask as a third operand, and VL as a 159 // fourth operand. 160 // FIXME: Can we replace these with ISD::VP_*? 161 ADD_VL, 162 AND_VL, 163 MUL_VL, 164 OR_VL, 165 SDIV_VL, 166 SHL_VL, 167 SREM_VL, 168 SRA_VL, 169 SRL_VL, 170 SUB_VL, 171 UDIV_VL, 172 UREM_VL, 173 XOR_VL, 174 FADD_VL, 175 FSUB_VL, 176 FMUL_VL, 177 FDIV_VL, 178 FNEG_VL, 179 FABS_VL, 180 FSQRT_VL, 181 FMA_VL, 182 FCOPYSIGN_VL, 183 SMIN_VL, 184 SMAX_VL, 185 UMIN_VL, 186 UMAX_VL, 187 MULHS_VL, 188 MULHU_VL, 189 FP_TO_SINT_VL, 190 FP_TO_UINT_VL, 191 SINT_TO_FP_VL, 192 UINT_TO_FP_VL, 193 FP_ROUND_VL, 194 FP_EXTEND_VL, 195 196 // Vector compare producing a mask. Fourth operand is input mask. Fifth 197 // operand is VL. 198 SETCC_VL, 199 200 // Vector select with an additional VL operand. This operation is unmasked. 201 VSELECT_VL, 202 203 // Mask binary operators. 204 VMAND_VL, 205 VMOR_VL, 206 VMXOR_VL, 207 208 // Set mask vector to all zeros or ones. 209 VMCLR_VL, 210 VMSET_VL, 211 212 // Matches the semantics of vrgather.vx and vrgather.vv with an extra operand 213 // for VL. 214 VRGATHER_VX_VL, 215 VRGATHER_VV_VL, 216 VRGATHEREI16_VV_VL, 217 218 // Vector sign/zero extend with additional mask & VL operands. 219 VSEXT_VL, 220 VZEXT_VL, 221 222 // Memory opcodes start here. 223 VLE_VL = ISD::FIRST_TARGET_MEMORY_OPCODE, 224 VSE_VL, 225 226 // WARNING: Do not add anything in the end unless you want the node to 227 // have memop! In fact, starting from FIRST_TARGET_MEMORY_OPCODE all 228 // opcodes will be thought as target memory ops! 229 }; 230 } // namespace RISCVISD 231 232 class RISCVTargetLowering : public TargetLowering { 233 const RISCVSubtarget &Subtarget; 234 235 public: 236 explicit RISCVTargetLowering(const TargetMachine &TM, 237 const RISCVSubtarget &STI); 238 239 const RISCVSubtarget &getSubtarget() const { return Subtarget; } 240 241 bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I, 242 MachineFunction &MF, 243 unsigned Intrinsic) const override; 244 bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, 245 unsigned AS, 246 Instruction *I = nullptr) const override; 247 bool isLegalICmpImmediate(int64_t Imm) const override; 248 bool isLegalAddImmediate(int64_t Imm) const override; 249 bool isTruncateFree(Type *SrcTy, Type *DstTy) const override; 250 bool isTruncateFree(EVT SrcVT, EVT DstVT) const override; 251 bool isZExtFree(SDValue Val, EVT VT2) const override; 252 bool isSExtCheaperThanZExt(EVT SrcVT, EVT DstVT) const override; 253 bool isCheapToSpeculateCttz() const override; 254 bool isCheapToSpeculateCtlz() const override; 255 bool isFPImmLegal(const APFloat &Imm, EVT VT, 256 bool ForCodeSize) const override; 257 258 /// Return true if the given shuffle mask can be codegen'd directly, or if it 259 /// should be stack expanded. 260 bool isShuffleMaskLegal(ArrayRef<int> M, EVT VT) const override; 261 262 bool hasBitPreservingFPLogic(EVT VT) const override; 263 bool 264 shouldExpandBuildVectorWithShuffles(EVT VT, 265 unsigned DefinedValues) const override; 266 267 // Provide custom lowering hooks for some operations. 268 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; 269 void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results, 270 SelectionDAG &DAG) const override; 271 272 SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override; 273 274 bool targetShrinkDemandedConstant(SDValue Op, const APInt &DemandedBits, 275 const APInt &DemandedElts, 276 TargetLoweringOpt &TLO) const override; 277 278 void computeKnownBitsForTargetNode(const SDValue Op, 279 KnownBits &Known, 280 const APInt &DemandedElts, 281 const SelectionDAG &DAG, 282 unsigned Depth) const override; 283 unsigned ComputeNumSignBitsForTargetNode(SDValue Op, 284 const APInt &DemandedElts, 285 const SelectionDAG &DAG, 286 unsigned Depth) const override; 287 288 // This method returns the name of a target specific DAG node. 289 const char *getTargetNodeName(unsigned Opcode) const override; 290 291 ConstraintType getConstraintType(StringRef Constraint) const override; 292 293 unsigned getInlineAsmMemConstraint(StringRef ConstraintCode) const override; 294 295 std::pair<unsigned, const TargetRegisterClass *> 296 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, 297 StringRef Constraint, MVT VT) const override; 298 299 void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint, 300 std::vector<SDValue> &Ops, 301 SelectionDAG &DAG) const override; 302 303 MachineBasicBlock * 304 EmitInstrWithCustomInserter(MachineInstr &MI, 305 MachineBasicBlock *BB) const override; 306 307 EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, 308 EVT VT) const override; 309 310 bool convertSetCCLogicToBitwiseLogic(EVT VT) const override { 311 return VT.isScalarInteger(); 312 } 313 bool convertSelectOfConstantsToMath(EVT VT) const override { return true; } 314 315 bool shouldInsertFencesForAtomic(const Instruction *I) const override { 316 return isa<LoadInst>(I) || isa<StoreInst>(I); 317 } 318 Instruction *emitLeadingFence(IRBuilder<> &Builder, Instruction *Inst, 319 AtomicOrdering Ord) const override; 320 Instruction *emitTrailingFence(IRBuilder<> &Builder, Instruction *Inst, 321 AtomicOrdering Ord) const override; 322 323 bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, 324 EVT VT) const override; 325 326 ISD::NodeType getExtendForAtomicOps() const override { 327 return ISD::SIGN_EXTEND; 328 } 329 330 ISD::NodeType getExtendForAtomicCmpSwapArg() const override { 331 return ISD::SIGN_EXTEND; 332 } 333 334 bool shouldExpandShift(SelectionDAG &DAG, SDNode *N) const override { 335 if (DAG.getMachineFunction().getFunction().hasMinSize()) 336 return false; 337 return true; 338 } 339 bool isDesirableToCommuteWithShift(const SDNode *N, 340 CombineLevel Level) const override; 341 342 /// If a physical register, this returns the register that receives the 343 /// exception address on entry to an EH pad. 344 Register 345 getExceptionPointerRegister(const Constant *PersonalityFn) const override; 346 347 /// If a physical register, this returns the register that receives the 348 /// exception typeid on entry to a landing pad. 349 Register 350 getExceptionSelectorRegister(const Constant *PersonalityFn) const override; 351 352 bool shouldExtendTypeInLibCall(EVT Type) const override; 353 bool shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const override; 354 355 /// Returns the register with the specified architectural or ABI name. This 356 /// method is necessary to lower the llvm.read_register.* and 357 /// llvm.write_register.* intrinsics. Allocatable registers must be reserved 358 /// with the clang -ffixed-xX flag for access to be allowed. 359 Register getRegisterByName(const char *RegName, LLT VT, 360 const MachineFunction &MF) const override; 361 362 // Lower incoming arguments, copy physregs into vregs 363 SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, 364 bool IsVarArg, 365 const SmallVectorImpl<ISD::InputArg> &Ins, 366 const SDLoc &DL, SelectionDAG &DAG, 367 SmallVectorImpl<SDValue> &InVals) const override; 368 bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, 369 bool IsVarArg, 370 const SmallVectorImpl<ISD::OutputArg> &Outs, 371 LLVMContext &Context) const override; 372 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, 373 const SmallVectorImpl<ISD::OutputArg> &Outs, 374 const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL, 375 SelectionDAG &DAG) const override; 376 SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, 377 SmallVectorImpl<SDValue> &InVals) const override; 378 379 bool shouldConvertConstantLoadToIntImm(const APInt &Imm, 380 Type *Ty) const override { 381 return true; 382 } 383 bool mayBeEmittedAsTailCall(const CallInst *CI) const override; 384 bool shouldConsiderGEPOffsetSplit() const override { return true; } 385 386 bool decomposeMulByConstant(LLVMContext &Context, EVT VT, 387 SDValue C) const override; 388 389 TargetLowering::AtomicExpansionKind 390 shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override; 391 Value *emitMaskedAtomicRMWIntrinsic(IRBuilder<> &Builder, AtomicRMWInst *AI, 392 Value *AlignedAddr, Value *Incr, 393 Value *Mask, Value *ShiftAmt, 394 AtomicOrdering Ord) const override; 395 TargetLowering::AtomicExpansionKind 396 shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *CI) const override; 397 Value *emitMaskedAtomicCmpXchgIntrinsic(IRBuilder<> &Builder, 398 AtomicCmpXchgInst *CI, 399 Value *AlignedAddr, Value *CmpVal, 400 Value *NewVal, Value *Mask, 401 AtomicOrdering Ord) const override; 402 403 /// Returns true if the target allows unaligned memory accesses of the 404 /// specified type. 405 bool allowsMisalignedMemoryAccesses( 406 EVT VT, unsigned AddrSpace = 0, Align Alignment = Align(1), 407 MachineMemOperand::Flags Flags = MachineMemOperand::MONone, 408 bool *Fast = nullptr) const override; 409 410 bool splitValueIntoRegisterParts(SelectionDAG &DAG, const SDLoc &DL, 411 SDValue Val, SDValue *Parts, 412 unsigned NumParts, MVT PartVT, 413 Optional<CallingConv::ID> CC) const override; 414 415 SDValue 416 joinRegisterPartsIntoValue(SelectionDAG &DAG, const SDLoc &DL, 417 const SDValue *Parts, unsigned NumParts, 418 MVT PartVT, EVT ValueVT, 419 Optional<CallingConv::ID> CC) const override; 420 421 static RISCVVLMUL getLMUL(MVT VT); 422 static unsigned getRegClassIDForLMUL(RISCVVLMUL LMul); 423 static unsigned getSubregIndexByMVT(MVT VT, unsigned Index); 424 static unsigned getRegClassIDForVecVT(MVT VT); 425 static std::pair<unsigned, unsigned> 426 decomposeSubvectorInsertExtractToSubRegs(MVT VecVT, MVT SubVecVT, 427 unsigned InsertExtractIdx, 428 const RISCVRegisterInfo *TRI); 429 MVT getContainerForFixedLengthVector(MVT VT) const; 430 static MVT getContainerForFixedLengthVector(const TargetLowering &TLI, MVT VT, 431 const RISCVSubtarget &Subtarget); 432 static MVT getContainerForFixedLengthVector(SelectionDAG &DAG, MVT VT, 433 const RISCVSubtarget &Subtarget); 434 435 bool shouldRemoveExtendFromGSIndex(EVT VT) const override; 436 437 private: 438 void analyzeInputArgs(MachineFunction &MF, CCState &CCInfo, 439 const SmallVectorImpl<ISD::InputArg> &Ins, 440 bool IsRet) const; 441 void analyzeOutputArgs(MachineFunction &MF, CCState &CCInfo, 442 const SmallVectorImpl<ISD::OutputArg> &Outs, 443 bool IsRet, CallLoweringInfo *CLI) const; 444 445 template <class NodeTy> 446 SDValue getAddr(NodeTy *N, SelectionDAG &DAG, bool IsLocal = true) const; 447 448 SDValue getStaticTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG, 449 bool UseGOT) const; 450 SDValue getDynamicTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG) const; 451 452 SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; 453 SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; 454 SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const; 455 SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const; 456 SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; 457 SDValue lowerSELECT(SDValue Op, SelectionDAG &DAG) const; 458 SDValue lowerBRCOND(SDValue Op, SelectionDAG &DAG) const; 459 SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const; 460 SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; 461 SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const; 462 SDValue lowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const; 463 SDValue lowerShiftRightParts(SDValue Op, SelectionDAG &DAG, bool IsSRA) const; 464 SDValue lowerSPLAT_VECTOR_PARTS(SDValue Op, SelectionDAG &DAG) const; 465 SDValue lowerVectorMaskExt(SDValue Op, SelectionDAG &DAG, 466 int64_t ExtTrueVal) const; 467 SDValue lowerVectorMaskTrunc(SDValue Op, SelectionDAG &DAG) const; 468 SDValue lowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; 469 SDValue lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; 470 SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; 471 SDValue LowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const; 472 SDValue lowerVECREDUCE(SDValue Op, SelectionDAG &DAG) const; 473 SDValue lowerFPVECREDUCE(SDValue Op, SelectionDAG &DAG) const; 474 SDValue lowerINSERT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const; 475 SDValue lowerEXTRACT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const; 476 SDValue lowerVECTOR_REVERSE(SDValue Op, SelectionDAG &DAG) const; 477 SDValue lowerABS(SDValue Op, SelectionDAG &DAG) const; 478 SDValue lowerMLOAD(SDValue Op, SelectionDAG &DAG) const; 479 SDValue lowerMSTORE(SDValue Op, SelectionDAG &DAG) const; 480 SDValue lowerFixedLengthVectorFCOPYSIGNToRVV(SDValue Op, 481 SelectionDAG &DAG) const; 482 SDValue lowerMGATHER(SDValue Op, SelectionDAG &DAG) const; 483 SDValue lowerMSCATTER(SDValue Op, SelectionDAG &DAG) const; 484 SDValue lowerFixedLengthVectorLoadToRVV(SDValue Op, SelectionDAG &DAG) const; 485 SDValue lowerFixedLengthVectorStoreToRVV(SDValue Op, SelectionDAG &DAG) const; 486 SDValue lowerFixedLengthVectorSetccToRVV(SDValue Op, SelectionDAG &DAG) const; 487 SDValue lowerFixedLengthVectorLogicOpToRVV(SDValue Op, SelectionDAG &DAG, 488 unsigned MaskOpc, 489 unsigned VecOpc) const; 490 SDValue lowerFixedLengthVectorSelectToRVV(SDValue Op, 491 SelectionDAG &DAG) const; 492 SDValue lowerToScalableOp(SDValue Op, SelectionDAG &DAG, unsigned NewOpc, 493 bool HasMask = true) const; 494 SDValue lowerFixedLengthVectorExtendToRVV(SDValue Op, SelectionDAG &DAG, 495 unsigned ExtendOpc) const; 496 497 bool isEligibleForTailCallOptimization( 498 CCState &CCInfo, CallLoweringInfo &CLI, MachineFunction &MF, 499 const SmallVector<CCValAssign, 16> &ArgLocs) const; 500 501 /// Generate error diagnostics if any register used by CC has been marked 502 /// reserved. 503 void validateCCReservedRegs( 504 const SmallVectorImpl<std::pair<llvm::Register, llvm::SDValue>> &Regs, 505 MachineFunction &MF) const; 506 507 bool useRVVForFixedLengthVectorVT(MVT VT) const; 508 }; 509 510 namespace RISCV { 511 // We use 64 bits as the known part in the scalable vector types. 512 static constexpr unsigned RVVBitsPerBlock = 64; 513 } // namespace RISCV 514 515 namespace RISCVVIntrinsicsTable { 516 517 struct RISCVVIntrinsicInfo { 518 unsigned IntrinsicID; 519 uint8_t SplatOperand; 520 }; 521 522 using namespace RISCV; 523 524 #define GET_RISCVVIntrinsicsTable_DECL 525 #include "RISCVGenSearchableTables.inc" 526 527 } // end namespace RISCVVIntrinsicsTable 528 529 } // end namespace llvm 530 531 #endif 532