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/CallingConvLower.h"
19 #include "llvm/CodeGen/SelectionDAG.h"
20 #include "llvm/CodeGen/TargetLowering.h"
21 #include "llvm/TargetParser/RISCVTargetParser.h"
22 #include <optional>
23 
24 namespace llvm {
25 class RISCVSubtarget;
26 struct RISCVRegisterInfo;
27 namespace RISCVISD {
28 enum NodeType : unsigned {
29   FIRST_NUMBER = ISD::BUILTIN_OP_END,
30   RET_FLAG,
31   URET_FLAG,
32   SRET_FLAG,
33   MRET_FLAG,
34   CALL,
35   /// Select with condition operator - This selects between a true value and
36   /// a false value (ops #3 and #4) based on the boolean result of comparing
37   /// the lhs and rhs (ops #0 and #1) of a conditional expression with the
38   /// condition code in op #2, a XLenVT constant from the ISD::CondCode enum.
39   /// The lhs and rhs are XLenVT integers. The true and false values can be
40   /// integer or floating point.
41   SELECT_CC,
42   BR_CC,
43   BuildPairF64,
44   SplitF64,
45   TAIL,
46 
47   // Add the Lo 12 bits from an address. Selected to ADDI.
48   ADD_LO,
49   // Get the Hi 20 bits from an address. Selected to LUI.
50   HI,
51 
52   // Represents an AUIPC+ADDI pair. Selected to PseudoLLA.
53   LLA,
54 
55   // Selected as PseudoAddTPRel. Used to emit a TP-relative relocation.
56   ADD_TPREL,
57 
58   // Load address.
59   LA_TLS_GD,
60 
61   // Multiply high for signedxunsigned.
62   MULHSU,
63   // RV64I shifts, directly matching the semantics of the named RISC-V
64   // instructions.
65   SLLW,
66   SRAW,
67   SRLW,
68   // 32-bit operations from RV64M that can't be simply matched with a pattern
69   // at instruction selection time. These have undefined behavior for division
70   // by 0 or overflow (divw) like their target independent counterparts.
71   DIVW,
72   DIVUW,
73   REMUW,
74   // RV64IB rotates, directly matching the semantics of the named RISC-V
75   // instructions.
76   ROLW,
77   RORW,
78   // RV64IZbb bit counting instructions directly matching the semantics of the
79   // named RISC-V instructions.
80   CLZW,
81   CTZW,
82 
83   // RV64IZbb absolute value for i32. Expanded to (max (negw X), X) during isel.
84   ABSW,
85 
86   // FPR<->GPR transfer operations when the FPR is smaller than XLEN, needed as
87   // XLEN is the only legal integer width.
88   //
89   // FMV_H_X matches the semantics of the FMV.H.X.
90   // FMV_X_ANYEXTH is similar to FMV.X.H but has an any-extended result.
91   // FMV_X_SIGNEXTH is similar to FMV.X.H and has a sign-extended result.
92   // FMV_W_X_RV64 matches the semantics of the FMV.W.X.
93   // FMV_X_ANYEXTW_RV64 is similar to FMV.X.W but has an any-extended result.
94   //
95   // This is a more convenient semantic for producing dagcombines that remove
96   // unnecessary GPR->FPR->GPR moves.
97   FMV_H_X,
98   FMV_X_ANYEXTH,
99   FMV_X_SIGNEXTH,
100   FMV_W_X_RV64,
101   FMV_X_ANYEXTW_RV64,
102   // FP to XLen int conversions. Corresponds to fcvt.l(u).s/d/h on RV64 and
103   // fcvt.w(u).s/d/h on RV32. Unlike FP_TO_S/UINT these saturate out of
104   // range inputs. These are used for FP_TO_S/UINT_SAT lowering. Rounding mode
105   // is passed as a TargetConstant operand using the RISCVFPRndMode enum.
106   FCVT_X,
107   FCVT_XU,
108   // FP to 32 bit int conversions for RV64. These are used to keep track of the
109   // result being sign extended to 64 bit. These saturate out of range inputs.
110   // Used for FP_TO_S/UINT and FP_TO_S/UINT_SAT lowering. Rounding mode
111   // is passed as a TargetConstant operand using the RISCVFPRndMode enum.
112   FCVT_W_RV64,
113   FCVT_WU_RV64,
114 
115   // Rounds an FP value to its corresponding integer in the same FP format.
116   // First operand is the value to round, the second operand is the largest
117   // integer that can be represented exactly in the FP format. This will be
118   // expanded into multiple instructions and basic blocks with a custom
119   // inserter.
120   FROUND,
121 
122   // READ_CYCLE_WIDE - A read of the 64-bit cycle CSR on a 32-bit target
123   // (returns (Lo, Hi)). It takes a chain operand.
124   READ_CYCLE_WIDE,
125   // brev8, orc.b, zip, and unzip from Zbb and Zbkb. All operands are i32 or
126   // XLenVT.
127   BREV8,
128   ORC_B,
129   ZIP,
130   UNZIP,
131   // Vector Extension
132   // VMV_V_X_VL matches the semantics of vmv.v.x but includes an extra operand
133   // for the VL value to be used for the operation. The first operand is
134   // passthru operand.
135   VMV_V_X_VL,
136   // VFMV_V_F_VL matches the semantics of vfmv.v.f but includes an extra operand
137   // for the VL value to be used for the operation. The first operand is
138   // passthru operand.
139   VFMV_V_F_VL,
140   // VMV_X_S matches the semantics of vmv.x.s. The result is always XLenVT sign
141   // extended from the vector element size.
142   VMV_X_S,
143   // VMV_S_X_VL matches the semantics of vmv.s.x. It carries a VL operand.
144   VMV_S_X_VL,
145   // VFMV_S_F_VL matches the semantics of vfmv.s.f. It carries a VL operand.
146   VFMV_S_F_VL,
147   // Splats an 64-bit value that has been split into two i32 parts. This is
148   // expanded late to two scalar stores and a stride 0 vector load.
149   // The first operand is passthru operand.
150   SPLAT_VECTOR_SPLIT_I64_VL,
151   // Read VLENB CSR
152   READ_VLENB,
153   // Truncates a RVV integer vector by one power-of-two. Carries both an extra
154   // mask and VL operand.
155   TRUNCATE_VECTOR_VL,
156   // Matches the semantics of vslideup/vslidedown. The first operand is the
157   // pass-thru operand, the second is the source vector, the third is the
158   // XLenVT index (either constant or non-constant), the fourth is the mask
159   // and the fifth the VL.
160   VSLIDEUP_VL,
161   VSLIDEDOWN_VL,
162   // Matches the semantics of vslide1up/slide1down. The first operand is
163   // passthru operand, the second is source vector, third is the XLenVT scalar
164   // value. The fourth and fifth operands are the mask and VL operands.
165   VSLIDE1UP_VL,
166   VSLIDE1DOWN_VL,
167   // Matches the semantics of the vid.v instruction, with a mask and VL
168   // operand.
169   VID_VL,
170   // Matches the semantics of the vfcnvt.rod function (Convert double-width
171   // float to single-width float, rounding towards odd). Takes a double-width
172   // float vector and produces a single-width float vector. Also has a mask and
173   // VL operand.
174   VFNCVT_ROD_VL,
175   // These nodes match the semantics of the corresponding RVV vector reduction
176   // instructions. They produce a vector result which is the reduction
177   // performed over the second vector operand plus the first element of the
178   // third vector operand. The first operand is the pass-thru operand. The
179   // second operand is an unconstrained vector type, and the result, first, and
180   // third operand's types are expected to be the corresponding full-width
181   // LMUL=1 type for the second operand:
182   //   nxv8i8 = vecreduce_add nxv8i8, nxv32i8, nxv8i8
183   //   nxv2i32 = vecreduce_add nxv2i32, nxv8i32, nxv2i32
184   // The different in types does introduce extra vsetvli instructions but
185   // similarly it reduces the number of registers consumed per reduction.
186   // Also has a mask and VL operand.
187   VECREDUCE_ADD_VL,
188   VECREDUCE_UMAX_VL,
189   VECREDUCE_SMAX_VL,
190   VECREDUCE_UMIN_VL,
191   VECREDUCE_SMIN_VL,
192   VECREDUCE_AND_VL,
193   VECREDUCE_OR_VL,
194   VECREDUCE_XOR_VL,
195   VECREDUCE_FADD_VL,
196   VECREDUCE_SEQ_FADD_VL,
197   VECREDUCE_FMIN_VL,
198   VECREDUCE_FMAX_VL,
199 
200   // Vector binary ops with a merge as a third operand, a mask as a fourth
201   // operand, and VL as a fifth operand.
202   ADD_VL,
203   AND_VL,
204   MUL_VL,
205   OR_VL,
206   SDIV_VL,
207   SHL_VL,
208   SREM_VL,
209   SRA_VL,
210   SRL_VL,
211   SUB_VL,
212   UDIV_VL,
213   UREM_VL,
214   XOR_VL,
215   SMIN_VL,
216   SMAX_VL,
217   UMIN_VL,
218   UMAX_VL,
219 
220   SADDSAT_VL,
221   UADDSAT_VL,
222   SSUBSAT_VL,
223   USUBSAT_VL,
224 
225   MULHS_VL,
226   MULHU_VL,
227   FADD_VL,
228   FSUB_VL,
229   FMUL_VL,
230   FDIV_VL,
231   FMINNUM_VL,
232   FMAXNUM_VL,
233 
234   // Vector unary ops with a mask as a second operand and VL as a third operand.
235   FNEG_VL,
236   FABS_VL,
237   FSQRT_VL,
238   FCOPYSIGN_VL, // Has a merge operand
239   VFCVT_RTZ_X_F_VL,
240   VFCVT_RTZ_XU_F_VL,
241   VFCVT_X_F_VL,
242   VFCVT_XU_F_VL,
243   VFROUND_NOEXCEPT_VL,
244   VFCVT_RM_X_F_VL, // Has a rounding mode operand.
245   VFCVT_RM_XU_F_VL, // Has a rounding mode operand.
246   SINT_TO_FP_VL,
247   UINT_TO_FP_VL,
248   VFCVT_RM_F_X_VL, // Has a rounding mode operand.
249   VFCVT_RM_F_XU_VL, // Has a rounding mode operand.
250   FP_ROUND_VL,
251   FP_EXTEND_VL,
252 
253   // Vector FMA ops with a mask as a fourth operand and VL as a fifth operand.
254   VFMADD_VL,
255   VFNMADD_VL,
256   VFMSUB_VL,
257   VFNMSUB_VL,
258 
259   // Widening instructions with a merge value a third operand, a mask as a
260   // fourth operand, and VL as a fifth operand.
261   VWMUL_VL,
262   VWMULU_VL,
263   VWMULSU_VL,
264   VWADD_VL,
265   VWADDU_VL,
266   VWSUB_VL,
267   VWSUBU_VL,
268   VWADD_W_VL,
269   VWADDU_W_VL,
270   VWSUB_W_VL,
271   VWSUBU_W_VL,
272 
273   VNSRL_VL,
274 
275   // Vector compare producing a mask. Fourth operand is input mask. Fifth
276   // operand is VL.
277   SETCC_VL,
278 
279   // Vector select with an additional VL operand. This operation is unmasked.
280   VSELECT_VL,
281   // Vector select with operand #2 (the value when the condition is false) tied
282   // to the destination and an additional VL operand. This operation is
283   // unmasked.
284   VP_MERGE_VL,
285 
286   // Mask binary operators.
287   VMAND_VL,
288   VMOR_VL,
289   VMXOR_VL,
290 
291   // Set mask vector to all zeros or ones.
292   VMCLR_VL,
293   VMSET_VL,
294 
295   // Matches the semantics of vrgather.vx and vrgather.vv with extra operands
296   // for passthru and VL. Operands are (src, index, mask, passthru, vl).
297   VRGATHER_VX_VL,
298   VRGATHER_VV_VL,
299   VRGATHEREI16_VV_VL,
300 
301   // Vector sign/zero extend with additional mask & VL operands.
302   VSEXT_VL,
303   VZEXT_VL,
304 
305   //  vcpop.m with additional mask and VL operands.
306   VCPOP_VL,
307 
308   //  vfirst.m with additional mask and VL operands.
309   VFIRST_VL,
310 
311   // Reads value of CSR.
312   // The first operand is a chain pointer. The second specifies address of the
313   // required CSR. Two results are produced, the read value and the new chain
314   // pointer.
315   READ_CSR,
316   // Write value to CSR.
317   // The first operand is a chain pointer, the second specifies address of the
318   // required CSR and the third is the value to write. The result is the new
319   // chain pointer.
320   WRITE_CSR,
321   // Read and write value of CSR.
322   // The first operand is a chain pointer, the second specifies address of the
323   // required CSR and the third is the value to write. Two results are produced,
324   // the value read before the modification and the new chain pointer.
325   SWAP_CSR,
326 
327   // FP to 32 bit int conversions for RV64. These are used to keep track of the
328   // result being sign extended to 64 bit. These saturate out of range inputs.
329   STRICT_FCVT_W_RV64 = ISD::FIRST_TARGET_STRICTFP_OPCODE,
330   STRICT_FCVT_WU_RV64,
331 
332   // WARNING: Do not add anything in the end unless you want the node to
333   // have memop! In fact, starting from FIRST_TARGET_MEMORY_OPCODE all
334   // opcodes will be thought as target memory ops!
335 
336   // Load address.
337   LA = ISD::FIRST_TARGET_MEMORY_OPCODE,
338   LA_TLS_IE,
339 };
340 } // namespace RISCVISD
341 
342 class RISCVTargetLowering : public TargetLowering {
343   const RISCVSubtarget &Subtarget;
344 
345 public:
346   explicit RISCVTargetLowering(const TargetMachine &TM,
347                                const RISCVSubtarget &STI);
348 
getSubtarget()349   const RISCVSubtarget &getSubtarget() const { return Subtarget; }
350 
351   bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I,
352                           MachineFunction &MF,
353                           unsigned Intrinsic) const override;
354   bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty,
355                              unsigned AS,
356                              Instruction *I = nullptr) const override;
357   bool isLegalICmpImmediate(int64_t Imm) const override;
358   bool isLegalAddImmediate(int64_t Imm) const override;
359   bool isTruncateFree(Type *SrcTy, Type *DstTy) const override;
360   bool isTruncateFree(EVT SrcVT, EVT DstVT) const override;
361   bool isZExtFree(SDValue Val, EVT VT2) const override;
362   bool isSExtCheaperThanZExt(EVT SrcVT, EVT DstVT) const override;
363   bool signExtendConstant(const ConstantInt *CI) const override;
364   bool isCheapToSpeculateCttz(Type *Ty) const override;
365   bool isCheapToSpeculateCtlz(Type *Ty) const override;
366   bool isMaskAndCmp0FoldingBeneficial(const Instruction &AndI) const override;
367   bool hasAndNotCompare(SDValue Y) const override;
368   bool hasBitTest(SDValue X, SDValue Y) const override;
369   bool shouldProduceAndByConstByHoistingConstFromShiftsLHSOfAnd(
370       SDValue X, ConstantSDNode *XC, ConstantSDNode *CC, SDValue Y,
371       unsigned OldShiftOpcode, unsigned NewShiftOpcode,
372       SelectionDAG &DAG) const override;
373   /// Return true if the (vector) instruction I will be lowered to an instruction
374   /// with a scalar splat operand for the given Operand number.
375   bool canSplatOperand(Instruction *I, int Operand) const;
376   /// Return true if a vector instruction will lower to a target instruction
377   /// able to splat the given operand.
378   bool canSplatOperand(unsigned Opcode, int Operand) const;
379   bool shouldSinkOperands(Instruction *I,
380                           SmallVectorImpl<Use *> &Ops) const override;
381   bool shouldScalarizeBinop(SDValue VecOp) const override;
382   bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
383   bool isFPImmLegal(const APFloat &Imm, EVT VT,
384                     bool ForCodeSize) const override;
385   bool isExtractSubvectorCheap(EVT ResVT, EVT SrcVT,
386                                unsigned Index) const override;
387 
388   bool isIntDivCheap(EVT VT, AttributeList Attr) const override;
389 
390   bool preferScalarizeSplat(unsigned Opc) const override;
391 
softPromoteHalfType()392   bool softPromoteHalfType() const override { return true; }
393 
394   /// Return the register type for a given MVT, ensuring vectors are treated
395   /// as a series of gpr sized integers.
396   MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC,
397                                     EVT VT) const override;
398 
399   /// Return the number of registers for a given MVT, ensuring vectors are
400   /// treated as a series of gpr sized integers.
401   unsigned getNumRegistersForCallingConv(LLVMContext &Context,
402                                          CallingConv::ID CC,
403                                          EVT VT) const override;
404 
405   bool shouldFoldSelectWithIdentityConstant(unsigned BinOpcode,
406                                             EVT VT) const override;
407 
408   /// Return true if the given shuffle mask can be codegen'd directly, or if it
409   /// should be stack expanded.
410   bool isShuffleMaskLegal(ArrayRef<int> M, EVT VT) const override;
411 
412   bool hasBitPreservingFPLogic(EVT VT) const override;
413   bool
414   shouldExpandBuildVectorWithShuffles(EVT VT,
415                                       unsigned DefinedValues) const override;
416 
417   // Provide custom lowering hooks for some operations.
418   SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
419   void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
420                           SelectionDAG &DAG) const override;
421 
422   SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
423 
424   bool targetShrinkDemandedConstant(SDValue Op, const APInt &DemandedBits,
425                                     const APInt &DemandedElts,
426                                     TargetLoweringOpt &TLO) const override;
427 
428   void computeKnownBitsForTargetNode(const SDValue Op,
429                                      KnownBits &Known,
430                                      const APInt &DemandedElts,
431                                      const SelectionDAG &DAG,
432                                      unsigned Depth) const override;
433   unsigned ComputeNumSignBitsForTargetNode(SDValue Op,
434                                            const APInt &DemandedElts,
435                                            const SelectionDAG &DAG,
436                                            unsigned Depth) const override;
437 
438   const Constant *getTargetConstantFromLoad(LoadSDNode *LD) const override;
439 
440   // This method returns the name of a target specific DAG node.
441   const char *getTargetNodeName(unsigned Opcode) const override;
442 
443   ConstraintType getConstraintType(StringRef Constraint) const override;
444 
445   unsigned getInlineAsmMemConstraint(StringRef ConstraintCode) const override;
446 
447   std::pair<unsigned, const TargetRegisterClass *>
448   getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
449                                StringRef Constraint, MVT VT) const override;
450 
451   void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint,
452                                     std::vector<SDValue> &Ops,
453                                     SelectionDAG &DAG) const override;
454 
455   MachineBasicBlock *
456   EmitInstrWithCustomInserter(MachineInstr &MI,
457                               MachineBasicBlock *BB) const override;
458 
459   void AdjustInstrPostInstrSelection(MachineInstr &MI,
460                                      SDNode *Node) const override;
461 
462   EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
463                          EVT VT) const override;
464 
convertSetCCLogicToBitwiseLogic(EVT VT)465   bool convertSetCCLogicToBitwiseLogic(EVT VT) const override {
466     return VT.isScalarInteger();
467   }
convertSelectOfConstantsToMath(EVT VT)468   bool convertSelectOfConstantsToMath(EVT VT) const override { return true; }
469 
shouldInsertFencesForAtomic(const Instruction * I)470   bool shouldInsertFencesForAtomic(const Instruction *I) const override {
471     return isa<LoadInst>(I) || isa<StoreInst>(I);
472   }
473   Instruction *emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst,
474                                 AtomicOrdering Ord) const override;
475   Instruction *emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst,
476                                  AtomicOrdering Ord) const override;
477 
478   bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
479                                   EVT VT) const override;
480 
getExtendForAtomicOps()481   ISD::NodeType getExtendForAtomicOps() const override {
482     return ISD::SIGN_EXTEND;
483   }
484 
getExtendForAtomicCmpSwapArg()485   ISD::NodeType getExtendForAtomicCmpSwapArg() const override {
486     return ISD::SIGN_EXTEND;
487   }
488 
489   TargetLowering::ShiftLegalizationStrategy
preferredShiftLegalizationStrategy(SelectionDAG & DAG,SDNode * N,unsigned ExpansionFactor)490   preferredShiftLegalizationStrategy(SelectionDAG &DAG, SDNode *N,
491                                      unsigned ExpansionFactor) const override {
492     if (DAG.getMachineFunction().getFunction().hasMinSize())
493       return ShiftLegalizationStrategy::LowerToLibcall;
494     return TargetLowering::preferredShiftLegalizationStrategy(DAG, N,
495                                                               ExpansionFactor);
496   }
497 
498   bool isDesirableToCommuteWithShift(const SDNode *N,
499                                      CombineLevel Level) const override;
500 
501   /// If a physical register, this returns the register that receives the
502   /// exception address on entry to an EH pad.
503   Register
504   getExceptionPointerRegister(const Constant *PersonalityFn) const override;
505 
506   /// If a physical register, this returns the register that receives the
507   /// exception typeid on entry to a landing pad.
508   Register
509   getExceptionSelectorRegister(const Constant *PersonalityFn) const override;
510 
511   bool shouldExtendTypeInLibCall(EVT Type) const override;
512   bool shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const override;
513 
514   /// Returns the register with the specified architectural or ABI name. This
515   /// method is necessary to lower the llvm.read_register.* and
516   /// llvm.write_register.* intrinsics. Allocatable registers must be reserved
517   /// with the clang -ffixed-xX flag for access to be allowed.
518   Register getRegisterByName(const char *RegName, LLT VT,
519                              const MachineFunction &MF) const override;
520 
521   // Lower incoming arguments, copy physregs into vregs
522   SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
523                                bool IsVarArg,
524                                const SmallVectorImpl<ISD::InputArg> &Ins,
525                                const SDLoc &DL, SelectionDAG &DAG,
526                                SmallVectorImpl<SDValue> &InVals) const override;
527   bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
528                       bool IsVarArg,
529                       const SmallVectorImpl<ISD::OutputArg> &Outs,
530                       LLVMContext &Context) const override;
531   SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
532                       const SmallVectorImpl<ISD::OutputArg> &Outs,
533                       const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
534                       SelectionDAG &DAG) const override;
535   SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
536                     SmallVectorImpl<SDValue> &InVals) const override;
537 
538   bool shouldConvertConstantLoadToIntImm(const APInt &Imm,
539                                          Type *Ty) const override;
540   bool isUsedByReturnOnly(SDNode *N, SDValue &Chain) const override;
541   bool mayBeEmittedAsTailCall(const CallInst *CI) const override;
shouldConsiderGEPOffsetSplit()542   bool shouldConsiderGEPOffsetSplit() const override { return true; }
543 
544   bool decomposeMulByConstant(LLVMContext &Context, EVT VT,
545                               SDValue C) const override;
546 
547   bool isMulAddWithConstProfitable(SDValue AddNode,
548                                    SDValue ConstNode) const override;
549 
550   TargetLowering::AtomicExpansionKind
551   shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override;
552   Value *emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, AtomicRMWInst *AI,
553                                       Value *AlignedAddr, Value *Incr,
554                                       Value *Mask, Value *ShiftAmt,
555                                       AtomicOrdering Ord) const override;
556   TargetLowering::AtomicExpansionKind
557   shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *CI) const override;
558   Value *emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder,
559                                           AtomicCmpXchgInst *CI,
560                                           Value *AlignedAddr, Value *CmpVal,
561                                           Value *NewVal, Value *Mask,
562                                           AtomicOrdering Ord) const override;
563 
564   /// Returns true if the target allows unaligned memory accesses of the
565   /// specified type.
566   bool allowsMisalignedMemoryAccesses(
567       EVT VT, unsigned AddrSpace = 0, Align Alignment = Align(1),
568       MachineMemOperand::Flags Flags = MachineMemOperand::MONone,
569       unsigned *Fast = nullptr) const override;
570 
571   bool splitValueIntoRegisterParts(
572       SelectionDAG & DAG, const SDLoc &DL, SDValue Val, SDValue *Parts,
573       unsigned NumParts, MVT PartVT, std::optional<CallingConv::ID> CC)
574       const override;
575 
576   SDValue joinRegisterPartsIntoValue(
577       SelectionDAG & DAG, const SDLoc &DL, const SDValue *Parts,
578       unsigned NumParts, MVT PartVT, EVT ValueVT,
579       std::optional<CallingConv::ID> CC) const override;
580 
581   static RISCVII::VLMUL getLMUL(MVT VT);
computeVLMAX(unsigned VectorBits,unsigned EltSize,unsigned MinSize)582   inline static unsigned computeVLMAX(unsigned VectorBits, unsigned EltSize,
583                                       unsigned MinSize) {
584     // Original equation:
585     //   VLMAX = (VectorBits / EltSize) * LMUL
586     //   where LMUL = MinSize / RISCV::RVVBitsPerBlock
587     // The following equations have been reordered to prevent loss of precision
588     // when calculating fractional LMUL.
589     return ((VectorBits / EltSize) * MinSize) / RISCV::RVVBitsPerBlock;
590   };
591   static unsigned getRegClassIDForLMUL(RISCVII::VLMUL LMul);
592   static unsigned getSubregIndexByMVT(MVT VT, unsigned Index);
593   static unsigned getRegClassIDForVecVT(MVT VT);
594   static std::pair<unsigned, unsigned>
595   decomposeSubvectorInsertExtractToSubRegs(MVT VecVT, MVT SubVecVT,
596                                            unsigned InsertExtractIdx,
597                                            const RISCVRegisterInfo *TRI);
598   MVT getContainerForFixedLengthVector(MVT VT) const;
599 
600   bool shouldRemoveExtendFromGSIndex(EVT IndexVT, EVT DataVT) const override;
601 
602   bool isLegalElementTypeForRVV(Type *ScalarTy) const;
603 
604   bool shouldConvertFpToSat(unsigned Op, EVT FPVT, EVT VT) const override;
605 
606   unsigned getJumpTableEncoding() const override;
607 
608   const MCExpr *LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI,
609                                           const MachineBasicBlock *MBB,
610                                           unsigned uid,
611                                           MCContext &Ctx) const override;
612 
613   bool isVScaleKnownToBeAPowerOfTwo() const override;
614 
isLegalScaleForGatherScatter(uint64_t Scale,uint64_t ElemSize)615   bool isLegalScaleForGatherScatter(uint64_t Scale,
616                                     uint64_t ElemSize) const override {
617     // Scaled addressing not supported on indexed load/stores
618     return Scale == 1;
619   }
620 
621   /// If the target has a standard location for the stack protector cookie,
622   /// returns the address of that location. Otherwise, returns nullptr.
623   Value *getIRStackGuard(IRBuilderBase &IRB) const override;
624 
625 private:
626   /// RISCVCCAssignFn - This target-specific function extends the default
627   /// CCValAssign with additional information used to lower RISC-V calling
628   /// conventions.
629   typedef bool RISCVCCAssignFn(const DataLayout &DL, RISCVABI::ABI,
630                                unsigned ValNo, MVT ValVT, MVT LocVT,
631                                CCValAssign::LocInfo LocInfo,
632                                ISD::ArgFlagsTy ArgFlags, CCState &State,
633                                bool IsFixed, bool IsRet, Type *OrigTy,
634                                const RISCVTargetLowering &TLI,
635                                std::optional<unsigned> FirstMaskArgument);
636 
637   void analyzeInputArgs(MachineFunction &MF, CCState &CCInfo,
638                         const SmallVectorImpl<ISD::InputArg> &Ins, bool IsRet,
639                         RISCVCCAssignFn Fn) const;
640   void analyzeOutputArgs(MachineFunction &MF, CCState &CCInfo,
641                          const SmallVectorImpl<ISD::OutputArg> &Outs,
642                          bool IsRet, CallLoweringInfo *CLI,
643                          RISCVCCAssignFn Fn) const;
644 
645   template <class NodeTy>
646   SDValue getAddr(NodeTy *N, SelectionDAG &DAG, bool IsLocal = true) const;
647   SDValue getStaticTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG,
648                            bool UseGOT) const;
649   SDValue getDynamicTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG) const;
650 
651   SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
652   SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
653   SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
654   SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
655   SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
656   SDValue lowerSELECT(SDValue Op, SelectionDAG &DAG) const;
657   SDValue lowerBRCOND(SDValue Op, SelectionDAG &DAG) const;
658   SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const;
659   SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
660   SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
661   SDValue lowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const;
662   SDValue lowerShiftRightParts(SDValue Op, SelectionDAG &DAG, bool IsSRA) const;
663   SDValue lowerSPLAT_VECTOR_PARTS(SDValue Op, SelectionDAG &DAG) const;
664   SDValue lowerVectorMaskSplat(SDValue Op, SelectionDAG &DAG) const;
665   SDValue lowerVectorMaskExt(SDValue Op, SelectionDAG &DAG,
666                              int64_t ExtTrueVal) const;
667   SDValue lowerVectorMaskTruncLike(SDValue Op, SelectionDAG &DAG) const;
668   SDValue lowerVectorTruncLike(SDValue Op, SelectionDAG &DAG) const;
669   SDValue lowerVectorFPExtendOrRoundLike(SDValue Op, SelectionDAG &DAG) const;
670   SDValue lowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
671   SDValue lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
672   SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
673   SDValue LowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const;
674   SDValue LowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const;
675   SDValue lowerVPREDUCE(SDValue Op, SelectionDAG &DAG) const;
676   SDValue lowerVECREDUCE(SDValue Op, SelectionDAG &DAG) const;
677   SDValue lowerVectorMaskVecReduction(SDValue Op, SelectionDAG &DAG,
678                                       bool IsVP) const;
679   SDValue lowerFPVECREDUCE(SDValue Op, SelectionDAG &DAG) const;
680   SDValue lowerINSERT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const;
681   SDValue lowerEXTRACT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const;
682   SDValue lowerSTEP_VECTOR(SDValue Op, SelectionDAG &DAG) const;
683   SDValue lowerVECTOR_REVERSE(SDValue Op, SelectionDAG &DAG) const;
684   SDValue lowerVECTOR_SPLICE(SDValue Op, SelectionDAG &DAG) const;
685   SDValue lowerABS(SDValue Op, SelectionDAG &DAG) const;
686   SDValue lowerMaskedLoad(SDValue Op, SelectionDAG &DAG) const;
687   SDValue lowerMaskedStore(SDValue Op, SelectionDAG &DAG) const;
688   SDValue lowerFixedLengthVectorFCOPYSIGNToRVV(SDValue Op,
689                                                SelectionDAG &DAG) const;
690   SDValue lowerMaskedGather(SDValue Op, SelectionDAG &DAG) const;
691   SDValue lowerMaskedScatter(SDValue Op, SelectionDAG &DAG) const;
692   SDValue lowerFixedLengthVectorLoadToRVV(SDValue Op, SelectionDAG &DAG) const;
693   SDValue lowerFixedLengthVectorStoreToRVV(SDValue Op, SelectionDAG &DAG) const;
694   SDValue lowerFixedLengthVectorSetccToRVV(SDValue Op, SelectionDAG &DAG) const;
695   SDValue lowerFixedLengthVectorLogicOpToRVV(SDValue Op, SelectionDAG &DAG,
696                                              unsigned MaskOpc,
697                                              unsigned VecOpc) const;
698   SDValue lowerFixedLengthVectorShiftToRVV(SDValue Op, SelectionDAG &DAG) const;
699   SDValue lowerFixedLengthVectorSelectToRVV(SDValue Op,
700                                             SelectionDAG &DAG) const;
701   SDValue lowerToScalableOp(SDValue Op, SelectionDAG &DAG, unsigned NewOpc,
702                             bool HasMergeOp = false, bool HasMask = true) const;
703   SDValue lowerVPOp(SDValue Op, SelectionDAG &DAG, unsigned RISCVISDOpc,
704                     bool HasMergeOp = false) const;
705   SDValue lowerLogicVPOp(SDValue Op, SelectionDAG &DAG, unsigned MaskOpc,
706                          unsigned VecOpc) const;
707   SDValue lowerVPExtMaskOp(SDValue Op, SelectionDAG &DAG) const;
708   SDValue lowerVPSetCCMaskOp(SDValue Op, SelectionDAG &DAG) const;
709   SDValue lowerVPFPIntConvOp(SDValue Op, SelectionDAG &DAG,
710                              unsigned RISCVISDOpc) const;
711   SDValue lowerVPStridedLoad(SDValue Op, SelectionDAG &DAG) const;
712   SDValue lowerVPStridedStore(SDValue Op, SelectionDAG &DAG) const;
713   SDValue lowerFixedLengthVectorExtendToRVV(SDValue Op, SelectionDAG &DAG,
714                                             unsigned ExtendOpc) const;
715   SDValue lowerGET_ROUNDING(SDValue Op, SelectionDAG &DAG) const;
716   SDValue lowerSET_ROUNDING(SDValue Op, SelectionDAG &DAG) const;
717 
718   SDValue lowerEH_DWARF_CFA(SDValue Op, SelectionDAG &DAG) const;
719   SDValue lowerCTLZ_CTTZ_ZERO_UNDEF(SDValue Op, SelectionDAG &DAG) const;
720 
721   SDValue expandUnalignedRVVLoad(SDValue Op, SelectionDAG &DAG) const;
722   SDValue expandUnalignedRVVStore(SDValue Op, SelectionDAG &DAG) const;
723 
724   bool isEligibleForTailCallOptimization(
725       CCState &CCInfo, CallLoweringInfo &CLI, MachineFunction &MF,
726       const SmallVector<CCValAssign, 16> &ArgLocs) const;
727 
728   /// Generate error diagnostics if any register used by CC has been marked
729   /// reserved.
730   void validateCCReservedRegs(
731       const SmallVectorImpl<std::pair<llvm::Register, llvm::SDValue>> &Regs,
732       MachineFunction &MF) const;
733 
734   bool useRVVForFixedLengthVectorVT(MVT VT) const;
735 
736   MVT getVPExplicitVectorLengthTy() const override;
737 
738   /// RVV code generation for fixed length vectors does not lower all
739   /// BUILD_VECTORs. This makes BUILD_VECTOR legalisation a source of stores to
740   /// merge. However, merging them creates a BUILD_VECTOR that is just as
741   /// illegal as the original, thus leading to an infinite legalisation loop.
742   /// NOTE: Once BUILD_VECTOR can be custom lowered for all legal vector types,
743   /// this override can be removed.
744   bool mergeStoresAfterLegalization(EVT VT) const override;
745 
746   /// Disable normalizing
747   /// select(N0&N1, X, Y) => select(N0, select(N1, X, Y), Y) and
748   /// select(N0|N1, X, Y) => select(N0, select(N1, X, Y, Y))
749   /// RISCV doesn't have flags so it's better to perform the and/or in a GPR.
shouldNormalizeToSelectSequence(LLVMContext &,EVT)750   bool shouldNormalizeToSelectSequence(LLVMContext &, EVT) const override {
751     return false;
752   };
753 
754   /// For available scheduling models FDIV + two independent FMULs are much
755   /// faster than two FDIVs.
756   unsigned combineRepeatedFPDivisors() const override;
757 };
758 namespace RISCVVIntrinsicsTable {
759 
760 struct RISCVVIntrinsicInfo {
761   unsigned IntrinsicID;
762   uint8_t ScalarOperand;
763   uint8_t VLOperand;
hasScalarOperandRISCVVIntrinsicInfo764   bool hasScalarOperand() const {
765     // 0xF is not valid. See NoScalarOperand in IntrinsicsRISCV.td.
766     return ScalarOperand != 0xF;
767   }
hasVLOperandRISCVVIntrinsicInfo768   bool hasVLOperand() const {
769     // 0x1F is not valid. See NoVLOperand in IntrinsicsRISCV.td.
770     return VLOperand != 0x1F;
771   }
772 };
773 
774 using namespace RISCV;
775 
776 #define GET_RISCVVIntrinsicsTable_DECL
777 #include "RISCVGenSearchableTables.inc"
778 
779 } // end namespace RISCVVIntrinsicsTable
780 
781 } // end namespace llvm
782 
783 #endif
784