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