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