1 //===-- RISCVISelDAGToDAG.cpp - A dag to dag inst selector for RISCV ------===//
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 an instruction selector for the RISCV target.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "RISCVISelDAGToDAG.h"
14 #include "MCTargetDesc/RISCVMCTargetDesc.h"
15 #include "MCTargetDesc/RISCVMatInt.h"
16 #include "RISCVISelLowering.h"
17 #include "llvm/CodeGen/MachineFrameInfo.h"
18 #include "llvm/IR/IntrinsicsRISCV.h"
19 #include "llvm/Support/Alignment.h"
20 #include "llvm/Support/Debug.h"
21 #include "llvm/Support/KnownBits.h"
22 #include "llvm/Support/MathExtras.h"
23 #include "llvm/Support/raw_ostream.h"
24 
25 using namespace llvm;
26 
27 #define DEBUG_TYPE "riscv-isel"
28 
29 namespace llvm {
30 namespace RISCV {
31 #define GET_RISCVVSSEGTable_IMPL
32 #define GET_RISCVVLSEGTable_IMPL
33 #define GET_RISCVVLXSEGTable_IMPL
34 #define GET_RISCVVSXSEGTable_IMPL
35 #define GET_RISCVVLETable_IMPL
36 #define GET_RISCVVSETable_IMPL
37 #define GET_RISCVVLXTable_IMPL
38 #define GET_RISCVVSXTable_IMPL
39 #include "RISCVGenSearchableTables.inc"
40 } // namespace RISCV
41 } // namespace llvm
42 
43 void RISCVDAGToDAGISel::PostprocessISelDAG() {
44   doPeepholeLoadStoreADDI();
45 }
46 
47 static SDNode *selectImm(SelectionDAG *CurDAG, const SDLoc &DL, int64_t Imm,
48                          MVT XLenVT) {
49   RISCVMatInt::InstSeq Seq = RISCVMatInt::generateInstSeq(Imm, XLenVT == MVT::i64);
50 
51   SDNode *Result = nullptr;
52   SDValue SrcReg = CurDAG->getRegister(RISCV::X0, XLenVT);
53   for (RISCVMatInt::Inst &Inst : Seq) {
54     SDValue SDImm = CurDAG->getTargetConstant(Inst.Imm, DL, XLenVT);
55     if (Inst.Opc == RISCV::LUI)
56       Result = CurDAG->getMachineNode(RISCV::LUI, DL, XLenVT, SDImm);
57     else
58       Result = CurDAG->getMachineNode(Inst.Opc, DL, XLenVT, SrcReg, SDImm);
59 
60     // Only the first instruction has X0 as its source.
61     SrcReg = SDValue(Result, 0);
62   }
63 
64   return Result;
65 }
66 
67 static SDValue createTupleImpl(SelectionDAG &CurDAG, ArrayRef<SDValue> Regs,
68                                unsigned RegClassID, unsigned SubReg0) {
69   assert(Regs.size() >= 2 && Regs.size() <= 8);
70 
71   SDLoc DL(Regs[0]);
72   SmallVector<SDValue, 8> Ops;
73 
74   Ops.push_back(CurDAG.getTargetConstant(RegClassID, DL, MVT::i32));
75 
76   for (unsigned I = 0; I < Regs.size(); ++I) {
77     Ops.push_back(Regs[I]);
78     Ops.push_back(CurDAG.getTargetConstant(SubReg0 + I, DL, MVT::i32));
79   }
80   SDNode *N =
81       CurDAG.getMachineNode(TargetOpcode::REG_SEQUENCE, DL, MVT::Untyped, Ops);
82   return SDValue(N, 0);
83 }
84 
85 static SDValue createM1Tuple(SelectionDAG &CurDAG, ArrayRef<SDValue> Regs,
86                              unsigned NF) {
87   static const unsigned RegClassIDs[] = {
88       RISCV::VRN2M1RegClassID, RISCV::VRN3M1RegClassID, RISCV::VRN4M1RegClassID,
89       RISCV::VRN5M1RegClassID, RISCV::VRN6M1RegClassID, RISCV::VRN7M1RegClassID,
90       RISCV::VRN8M1RegClassID};
91 
92   return createTupleImpl(CurDAG, Regs, RegClassIDs[NF - 2], RISCV::sub_vrm1_0);
93 }
94 
95 static SDValue createM2Tuple(SelectionDAG &CurDAG, ArrayRef<SDValue> Regs,
96                              unsigned NF) {
97   static const unsigned RegClassIDs[] = {RISCV::VRN2M2RegClassID,
98                                          RISCV::VRN3M2RegClassID,
99                                          RISCV::VRN4M2RegClassID};
100 
101   return createTupleImpl(CurDAG, Regs, RegClassIDs[NF - 2], RISCV::sub_vrm2_0);
102 }
103 
104 static SDValue createM4Tuple(SelectionDAG &CurDAG, ArrayRef<SDValue> Regs,
105                              unsigned NF) {
106   return createTupleImpl(CurDAG, Regs, RISCV::VRN2M4RegClassID,
107                          RISCV::sub_vrm4_0);
108 }
109 
110 static SDValue createTuple(SelectionDAG &CurDAG, ArrayRef<SDValue> Regs,
111                            unsigned NF, RISCVVLMUL LMUL) {
112   switch (LMUL) {
113   default:
114     llvm_unreachable("Invalid LMUL.");
115   case RISCVVLMUL::LMUL_F8:
116   case RISCVVLMUL::LMUL_F4:
117   case RISCVVLMUL::LMUL_F2:
118   case RISCVVLMUL::LMUL_1:
119     return createM1Tuple(CurDAG, Regs, NF);
120   case RISCVVLMUL::LMUL_2:
121     return createM2Tuple(CurDAG, Regs, NF);
122   case RISCVVLMUL::LMUL_4:
123     return createM4Tuple(CurDAG, Regs, NF);
124   }
125 }
126 
127 void RISCVDAGToDAGISel::addVectorLoadStoreOperands(
128     SDNode *Node, unsigned SEWImm, const SDLoc &DL, unsigned CurOp,
129     bool IsMasked, bool IsStridedOrIndexed, SmallVectorImpl<SDValue> &Operands,
130     MVT *IndexVT) {
131   SDValue Chain = Node->getOperand(0);
132   SDValue Glue;
133 
134   SDValue Base;
135   SelectBaseAddr(Node->getOperand(CurOp++), Base);
136   Operands.push_back(Base); // Base pointer.
137 
138   if (IsStridedOrIndexed) {
139     Operands.push_back(Node->getOperand(CurOp++)); // Index.
140     if (IndexVT)
141       *IndexVT = Operands.back()->getSimpleValueType(0);
142   }
143 
144   if (IsMasked) {
145     // Mask needs to be copied to V0.
146     SDValue Mask = Node->getOperand(CurOp++);
147     Chain = CurDAG->getCopyToReg(Chain, DL, RISCV::V0, Mask, SDValue());
148     Glue = Chain.getValue(1);
149     Operands.push_back(CurDAG->getRegister(RISCV::V0, Mask.getValueType()));
150   }
151   SDValue VL;
152   selectVLOp(Node->getOperand(CurOp++), VL);
153   Operands.push_back(VL);
154 
155   MVT XLenVT = Subtarget->getXLenVT();
156   SDValue SEW = CurDAG->getTargetConstant(SEWImm, DL, XLenVT);
157   Operands.push_back(SEW);
158 
159   Operands.push_back(Chain); // Chain.
160   if (Glue)
161     Operands.push_back(Glue);
162 }
163 
164 void RISCVDAGToDAGISel::selectVLSEG(SDNode *Node, bool IsMasked,
165                                     bool IsStrided) {
166   SDLoc DL(Node);
167   unsigned NF = Node->getNumValues() - 1;
168   MVT VT = Node->getSimpleValueType(0);
169   unsigned ScalarSize = VT.getScalarSizeInBits();
170   RISCVVLMUL LMUL = RISCVTargetLowering::getLMUL(VT);
171 
172   unsigned CurOp = 2;
173   SmallVector<SDValue, 8> Operands;
174   if (IsMasked) {
175     SmallVector<SDValue, 8> Regs(Node->op_begin() + CurOp,
176                                  Node->op_begin() + CurOp + NF);
177     SDValue MaskedOff = createTuple(*CurDAG, Regs, NF, LMUL);
178     Operands.push_back(MaskedOff);
179     CurOp += NF;
180   }
181 
182   addVectorLoadStoreOperands(Node, ScalarSize, DL, CurOp, IsMasked, IsStrided,
183                              Operands);
184 
185   const RISCV::VLSEGPseudo *P =
186       RISCV::getVLSEGPseudo(NF, IsMasked, IsStrided, /*FF*/ false, ScalarSize,
187                             static_cast<unsigned>(LMUL));
188   MachineSDNode *Load =
189       CurDAG->getMachineNode(P->Pseudo, DL, MVT::Untyped, MVT::Other, Operands);
190 
191   if (auto *MemOp = dyn_cast<MemSDNode>(Node))
192     CurDAG->setNodeMemRefs(Load, {MemOp->getMemOperand()});
193 
194   SDValue SuperReg = SDValue(Load, 0);
195   for (unsigned I = 0; I < NF; ++I) {
196     unsigned SubRegIdx = RISCVTargetLowering::getSubregIndexByMVT(VT, I);
197     ReplaceUses(SDValue(Node, I),
198                 CurDAG->getTargetExtractSubreg(SubRegIdx, DL, VT, SuperReg));
199   }
200 
201   ReplaceUses(SDValue(Node, NF), SDValue(Load, 1));
202   CurDAG->RemoveDeadNode(Node);
203 }
204 
205 void RISCVDAGToDAGISel::selectVLSEGFF(SDNode *Node, bool IsMasked) {
206   SDLoc DL(Node);
207   unsigned NF = Node->getNumValues() - 2; // Do not count VL and Chain.
208   MVT VT = Node->getSimpleValueType(0);
209   MVT XLenVT = Subtarget->getXLenVT();
210   unsigned ScalarSize = VT.getScalarSizeInBits();
211   RISCVVLMUL LMUL = RISCVTargetLowering::getLMUL(VT);
212 
213   unsigned CurOp = 2;
214   SmallVector<SDValue, 7> Operands;
215   if (IsMasked) {
216     SmallVector<SDValue, 8> Regs(Node->op_begin() + CurOp,
217                                  Node->op_begin() + CurOp + NF);
218     SDValue MaskedOff = createTuple(*CurDAG, Regs, NF, LMUL);
219     Operands.push_back(MaskedOff);
220     CurOp += NF;
221   }
222 
223   addVectorLoadStoreOperands(Node, ScalarSize, DL, CurOp, IsMasked,
224                              /*IsStridedOrIndexed*/ false, Operands);
225 
226   const RISCV::VLSEGPseudo *P =
227       RISCV::getVLSEGPseudo(NF, IsMasked, /*Strided*/ false, /*FF*/ true,
228                             ScalarSize, static_cast<unsigned>(LMUL));
229   MachineSDNode *Load = CurDAG->getMachineNode(P->Pseudo, DL, MVT::Untyped,
230                                                MVT::Other, MVT::Glue, Operands);
231   SDNode *ReadVL = CurDAG->getMachineNode(RISCV::PseudoReadVL, DL, XLenVT,
232                                           /*Glue*/ SDValue(Load, 2));
233 
234   if (auto *MemOp = dyn_cast<MemSDNode>(Node))
235     CurDAG->setNodeMemRefs(Load, {MemOp->getMemOperand()});
236 
237   SDValue SuperReg = SDValue(Load, 0);
238   for (unsigned I = 0; I < NF; ++I) {
239     unsigned SubRegIdx = RISCVTargetLowering::getSubregIndexByMVT(VT, I);
240     ReplaceUses(SDValue(Node, I),
241                 CurDAG->getTargetExtractSubreg(SubRegIdx, DL, VT, SuperReg));
242   }
243 
244   ReplaceUses(SDValue(Node, NF), SDValue(ReadVL, 0));   // VL
245   ReplaceUses(SDValue(Node, NF + 1), SDValue(Load, 1)); // Chain
246   CurDAG->RemoveDeadNode(Node);
247 }
248 
249 void RISCVDAGToDAGISel::selectVLXSEG(SDNode *Node, bool IsMasked,
250                                      bool IsOrdered) {
251   SDLoc DL(Node);
252   unsigned NF = Node->getNumValues() - 1;
253   MVT VT = Node->getSimpleValueType(0);
254   unsigned ScalarSize = VT.getScalarSizeInBits();
255   RISCVVLMUL LMUL = RISCVTargetLowering::getLMUL(VT);
256 
257   unsigned CurOp = 2;
258   SmallVector<SDValue, 8> Operands;
259   if (IsMasked) {
260     SmallVector<SDValue, 8> Regs(Node->op_begin() + CurOp,
261                                  Node->op_begin() + CurOp + NF);
262     SDValue MaskedOff = createTuple(*CurDAG, Regs, NF, LMUL);
263     Operands.push_back(MaskedOff);
264     CurOp += NF;
265   }
266 
267   MVT IndexVT;
268   addVectorLoadStoreOperands(Node, ScalarSize, DL, CurOp, IsMasked,
269                              /*IsStridedOrIndexed*/ true, Operands, &IndexVT);
270 
271   assert(VT.getVectorElementCount() == IndexVT.getVectorElementCount() &&
272          "Element count mismatch");
273 
274   RISCVVLMUL IndexLMUL = RISCVTargetLowering::getLMUL(IndexVT);
275   unsigned IndexScalarSize = IndexVT.getScalarSizeInBits();
276   const RISCV::VLXSEGPseudo *P = RISCV::getVLXSEGPseudo(
277       NF, IsMasked, IsOrdered, IndexScalarSize, static_cast<unsigned>(LMUL),
278       static_cast<unsigned>(IndexLMUL));
279   MachineSDNode *Load =
280       CurDAG->getMachineNode(P->Pseudo, DL, MVT::Untyped, MVT::Other, Operands);
281 
282   if (auto *MemOp = dyn_cast<MemSDNode>(Node))
283     CurDAG->setNodeMemRefs(Load, {MemOp->getMemOperand()});
284 
285   SDValue SuperReg = SDValue(Load, 0);
286   for (unsigned I = 0; I < NF; ++I) {
287     unsigned SubRegIdx = RISCVTargetLowering::getSubregIndexByMVT(VT, I);
288     ReplaceUses(SDValue(Node, I),
289                 CurDAG->getTargetExtractSubreg(SubRegIdx, DL, VT, SuperReg));
290   }
291 
292   ReplaceUses(SDValue(Node, NF), SDValue(Load, 1));
293   CurDAG->RemoveDeadNode(Node);
294 }
295 
296 void RISCVDAGToDAGISel::selectVSSEG(SDNode *Node, bool IsMasked,
297                                     bool IsStrided) {
298   SDLoc DL(Node);
299   unsigned NF = Node->getNumOperands() - 4;
300   if (IsStrided)
301     NF--;
302   if (IsMasked)
303     NF--;
304   MVT VT = Node->getOperand(2)->getSimpleValueType(0);
305   unsigned ScalarSize = VT.getScalarSizeInBits();
306   RISCVVLMUL LMUL = RISCVTargetLowering::getLMUL(VT);
307   SmallVector<SDValue, 8> Regs(Node->op_begin() + 2, Node->op_begin() + 2 + NF);
308   SDValue StoreVal = createTuple(*CurDAG, Regs, NF, LMUL);
309 
310   SmallVector<SDValue, 8> Operands;
311   Operands.push_back(StoreVal);
312   unsigned CurOp = 2 + NF;
313 
314   addVectorLoadStoreOperands(Node, ScalarSize, DL, CurOp, IsMasked, IsStrided,
315                              Operands);
316 
317   const RISCV::VSSEGPseudo *P = RISCV::getVSSEGPseudo(
318       NF, IsMasked, IsStrided, ScalarSize, static_cast<unsigned>(LMUL));
319   MachineSDNode *Store =
320       CurDAG->getMachineNode(P->Pseudo, DL, Node->getValueType(0), Operands);
321 
322   if (auto *MemOp = dyn_cast<MemSDNode>(Node))
323     CurDAG->setNodeMemRefs(Store, {MemOp->getMemOperand()});
324 
325   ReplaceNode(Node, Store);
326 }
327 
328 void RISCVDAGToDAGISel::selectVSXSEG(SDNode *Node, bool IsMasked,
329                                      bool IsOrdered) {
330   SDLoc DL(Node);
331   unsigned NF = Node->getNumOperands() - 5;
332   if (IsMasked)
333     --NF;
334   MVT VT = Node->getOperand(2)->getSimpleValueType(0);
335   unsigned ScalarSize = VT.getScalarSizeInBits();
336   RISCVVLMUL LMUL = RISCVTargetLowering::getLMUL(VT);
337   SmallVector<SDValue, 8> Regs(Node->op_begin() + 2, Node->op_begin() + 2 + NF);
338   SDValue StoreVal = createTuple(*CurDAG, Regs, NF, LMUL);
339 
340   SmallVector<SDValue, 8> Operands;
341   Operands.push_back(StoreVal);
342   unsigned CurOp = 2 + NF;
343 
344   MVT IndexVT;
345   addVectorLoadStoreOperands(Node, ScalarSize, DL, CurOp, IsMasked,
346                              /*IsStridedOrIndexed*/ true, Operands, &IndexVT);
347 
348   assert(VT.getVectorElementCount() == IndexVT.getVectorElementCount() &&
349          "Element count mismatch");
350 
351   RISCVVLMUL IndexLMUL = RISCVTargetLowering::getLMUL(IndexVT);
352   unsigned IndexScalarSize = IndexVT.getScalarSizeInBits();
353   const RISCV::VSXSEGPseudo *P = RISCV::getVSXSEGPseudo(
354       NF, IsMasked, IsOrdered, IndexScalarSize, static_cast<unsigned>(LMUL),
355       static_cast<unsigned>(IndexLMUL));
356   MachineSDNode *Store =
357       CurDAG->getMachineNode(P->Pseudo, DL, Node->getValueType(0), Operands);
358 
359   if (auto *MemOp = dyn_cast<MemSDNode>(Node))
360     CurDAG->setNodeMemRefs(Store, {MemOp->getMemOperand()});
361 
362   ReplaceNode(Node, Store);
363 }
364 
365 
366 void RISCVDAGToDAGISel::Select(SDNode *Node) {
367   // If we have a custom node, we have already selected.
368   if (Node->isMachineOpcode()) {
369     LLVM_DEBUG(dbgs() << "== "; Node->dump(CurDAG); dbgs() << "\n");
370     Node->setNodeId(-1);
371     return;
372   }
373 
374   // Instruction Selection not handled by the auto-generated tablegen selection
375   // should be handled here.
376   unsigned Opcode = Node->getOpcode();
377   MVT XLenVT = Subtarget->getXLenVT();
378   SDLoc DL(Node);
379   MVT VT = Node->getSimpleValueType(0);
380 
381   switch (Opcode) {
382   case ISD::Constant: {
383     auto *ConstNode = cast<ConstantSDNode>(Node);
384     if (VT == XLenVT && ConstNode->isNullValue()) {
385       SDValue New =
386           CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, RISCV::X0, XLenVT);
387       ReplaceNode(Node, New.getNode());
388       return;
389     }
390     ReplaceNode(Node, selectImm(CurDAG, DL, ConstNode->getSExtValue(), XLenVT));
391     return;
392   }
393   case ISD::FrameIndex: {
394     SDValue Imm = CurDAG->getTargetConstant(0, DL, XLenVT);
395     int FI = cast<FrameIndexSDNode>(Node)->getIndex();
396     SDValue TFI = CurDAG->getTargetFrameIndex(FI, VT);
397     ReplaceNode(Node, CurDAG->getMachineNode(RISCV::ADDI, DL, VT, TFI, Imm));
398     return;
399   }
400   case ISD::SRL: {
401     // We don't need this transform if zext.h is supported.
402     if (Subtarget->hasStdExtZbb() || Subtarget->hasStdExtZbp())
403       break;
404     // Optimize (srl (and X, 0xffff), C) ->
405     //          (srli (slli X, (XLen-16), (XLen-16) + C)
406     // Taking into account that the 0xffff may have had lower bits unset by
407     // SimplifyDemandedBits. This avoids materializing the 0xffff immediate.
408     // This pattern occurs when type legalizing i16 right shifts.
409     // FIXME: This could be extended to other AND masks.
410     auto *N1C = dyn_cast<ConstantSDNode>(Node->getOperand(1));
411     if (N1C) {
412       uint64_t ShAmt = N1C->getZExtValue();
413       SDValue N0 = Node->getOperand(0);
414       if (ShAmt < 16 && N0.getOpcode() == ISD::AND && N0.hasOneUse() &&
415           isa<ConstantSDNode>(N0.getOperand(1))) {
416         uint64_t Mask = N0.getConstantOperandVal(1);
417         Mask |= maskTrailingOnes<uint64_t>(ShAmt);
418         if (Mask == 0xffff) {
419           unsigned LShAmt = Subtarget->getXLen() - 16;
420           SDNode *SLLI =
421               CurDAG->getMachineNode(RISCV::SLLI, DL, VT, N0->getOperand(0),
422                                      CurDAG->getTargetConstant(LShAmt, DL, VT));
423           SDNode *SRLI = CurDAG->getMachineNode(
424               RISCV::SRLI, DL, VT, SDValue(SLLI, 0),
425               CurDAG->getTargetConstant(LShAmt + ShAmt, DL, VT));
426           ReplaceNode(Node, SRLI);
427           return;
428         }
429       }
430     }
431 
432     break;
433   }
434   case ISD::INTRINSIC_W_CHAIN: {
435     unsigned IntNo = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue();
436     switch (IntNo) {
437       // By default we do not custom select any intrinsic.
438     default:
439       break;
440 
441     case Intrinsic::riscv_vsetvli:
442     case Intrinsic::riscv_vsetvlimax: {
443       if (!Subtarget->hasStdExtV())
444         break;
445 
446       bool VLMax = IntNo == Intrinsic::riscv_vsetvlimax;
447       unsigned Offset = VLMax ? 2 : 3;
448 
449       assert(Node->getNumOperands() == Offset + 2 &&
450              "Unexpected number of operands");
451 
452       RISCVVSEW VSEW =
453           static_cast<RISCVVSEW>(Node->getConstantOperandVal(Offset) & 0x7);
454       RISCVVLMUL VLMul = static_cast<RISCVVLMUL>(
455           Node->getConstantOperandVal(Offset + 1) & 0x7);
456 
457       unsigned VTypeI = RISCVVType::encodeVTYPE(
458           VLMul, VSEW, /*TailAgnostic*/ true, /*MaskAgnostic*/ false);
459       SDValue VTypeIOp = CurDAG->getTargetConstant(VTypeI, DL, XLenVT);
460 
461       SDValue VLOperand;
462       if (VLMax) {
463         VLOperand = CurDAG->getRegister(RISCV::X0, XLenVT);
464       } else {
465         VLOperand = Node->getOperand(2);
466 
467         if (auto *C = dyn_cast<ConstantSDNode>(VLOperand)) {
468           uint64_t AVL = C->getZExtValue();
469           if (isUInt<5>(AVL)) {
470             SDValue VLImm = CurDAG->getTargetConstant(AVL, DL, XLenVT);
471             ReplaceNode(
472                 Node, CurDAG->getMachineNode(RISCV::PseudoVSETIVLI, DL, XLenVT,
473                                              MVT::Other, VLImm, VTypeIOp,
474                                              /* Chain */ Node->getOperand(0)));
475             return;
476           }
477         }
478       }
479 
480       ReplaceNode(Node,
481                   CurDAG->getMachineNode(RISCV::PseudoVSETVLI, DL, XLenVT,
482                                          MVT::Other, VLOperand, VTypeIOp,
483                                          /* Chain */ Node->getOperand(0)));
484       return;
485     }
486     case Intrinsic::riscv_vlseg2:
487     case Intrinsic::riscv_vlseg3:
488     case Intrinsic::riscv_vlseg4:
489     case Intrinsic::riscv_vlseg5:
490     case Intrinsic::riscv_vlseg6:
491     case Intrinsic::riscv_vlseg7:
492     case Intrinsic::riscv_vlseg8: {
493       selectVLSEG(Node, /*IsMasked*/ false, /*IsStrided*/ false);
494       return;
495     }
496     case Intrinsic::riscv_vlseg2_mask:
497     case Intrinsic::riscv_vlseg3_mask:
498     case Intrinsic::riscv_vlseg4_mask:
499     case Intrinsic::riscv_vlseg5_mask:
500     case Intrinsic::riscv_vlseg6_mask:
501     case Intrinsic::riscv_vlseg7_mask:
502     case Intrinsic::riscv_vlseg8_mask: {
503       selectVLSEG(Node, /*IsMasked*/ true, /*IsStrided*/ false);
504       return;
505     }
506     case Intrinsic::riscv_vlsseg2:
507     case Intrinsic::riscv_vlsseg3:
508     case Intrinsic::riscv_vlsseg4:
509     case Intrinsic::riscv_vlsseg5:
510     case Intrinsic::riscv_vlsseg6:
511     case Intrinsic::riscv_vlsseg7:
512     case Intrinsic::riscv_vlsseg8: {
513       selectVLSEG(Node, /*IsMasked*/ false, /*IsStrided*/ true);
514       return;
515     }
516     case Intrinsic::riscv_vlsseg2_mask:
517     case Intrinsic::riscv_vlsseg3_mask:
518     case Intrinsic::riscv_vlsseg4_mask:
519     case Intrinsic::riscv_vlsseg5_mask:
520     case Intrinsic::riscv_vlsseg6_mask:
521     case Intrinsic::riscv_vlsseg7_mask:
522     case Intrinsic::riscv_vlsseg8_mask: {
523       selectVLSEG(Node, /*IsMasked*/ true, /*IsStrided*/ true);
524       return;
525     }
526     case Intrinsic::riscv_vloxseg2:
527     case Intrinsic::riscv_vloxseg3:
528     case Intrinsic::riscv_vloxseg4:
529     case Intrinsic::riscv_vloxseg5:
530     case Intrinsic::riscv_vloxseg6:
531     case Intrinsic::riscv_vloxseg7:
532     case Intrinsic::riscv_vloxseg8:
533       selectVLXSEG(Node, /*IsMasked*/ false, /*IsOrdered*/ true);
534       return;
535     case Intrinsic::riscv_vluxseg2:
536     case Intrinsic::riscv_vluxseg3:
537     case Intrinsic::riscv_vluxseg4:
538     case Intrinsic::riscv_vluxseg5:
539     case Intrinsic::riscv_vluxseg6:
540     case Intrinsic::riscv_vluxseg7:
541     case Intrinsic::riscv_vluxseg8:
542       selectVLXSEG(Node, /*IsMasked*/ false, /*IsOrdered*/ false);
543       return;
544     case Intrinsic::riscv_vloxseg2_mask:
545     case Intrinsic::riscv_vloxseg3_mask:
546     case Intrinsic::riscv_vloxseg4_mask:
547     case Intrinsic::riscv_vloxseg5_mask:
548     case Intrinsic::riscv_vloxseg6_mask:
549     case Intrinsic::riscv_vloxseg7_mask:
550     case Intrinsic::riscv_vloxseg8_mask:
551       selectVLXSEG(Node, /*IsMasked*/ true, /*IsOrdered*/ true);
552       return;
553     case Intrinsic::riscv_vluxseg2_mask:
554     case Intrinsic::riscv_vluxseg3_mask:
555     case Intrinsic::riscv_vluxseg4_mask:
556     case Intrinsic::riscv_vluxseg5_mask:
557     case Intrinsic::riscv_vluxseg6_mask:
558     case Intrinsic::riscv_vluxseg7_mask:
559     case Intrinsic::riscv_vluxseg8_mask:
560       selectVLXSEG(Node, /*IsMasked*/ true, /*IsOrdered*/ false);
561       return;
562     case Intrinsic::riscv_vlseg8ff:
563     case Intrinsic::riscv_vlseg7ff:
564     case Intrinsic::riscv_vlseg6ff:
565     case Intrinsic::riscv_vlseg5ff:
566     case Intrinsic::riscv_vlseg4ff:
567     case Intrinsic::riscv_vlseg3ff:
568     case Intrinsic::riscv_vlseg2ff: {
569       selectVLSEGFF(Node, /*IsMasked*/ false);
570       return;
571     }
572     case Intrinsic::riscv_vlseg8ff_mask:
573     case Intrinsic::riscv_vlseg7ff_mask:
574     case Intrinsic::riscv_vlseg6ff_mask:
575     case Intrinsic::riscv_vlseg5ff_mask:
576     case Intrinsic::riscv_vlseg4ff_mask:
577     case Intrinsic::riscv_vlseg3ff_mask:
578     case Intrinsic::riscv_vlseg2ff_mask: {
579       selectVLSEGFF(Node, /*IsMasked*/ true);
580       return;
581     }
582     case Intrinsic::riscv_vloxei:
583     case Intrinsic::riscv_vloxei_mask:
584     case Intrinsic::riscv_vluxei:
585     case Intrinsic::riscv_vluxei_mask: {
586       bool IsMasked = IntNo == Intrinsic::riscv_vloxei_mask ||
587                       IntNo == Intrinsic::riscv_vluxei_mask;
588       bool IsOrdered = IntNo == Intrinsic::riscv_vloxei ||
589                        IntNo == Intrinsic::riscv_vloxei_mask;
590 
591       MVT VT = Node->getSimpleValueType(0);
592       unsigned ScalarSize = VT.getScalarSizeInBits();
593 
594       unsigned CurOp = 2;
595       SmallVector<SDValue, 8> Operands;
596       if (IsMasked)
597         Operands.push_back(Node->getOperand(CurOp++));
598 
599       MVT IndexVT;
600       addVectorLoadStoreOperands(Node, ScalarSize, DL, CurOp, IsMasked,
601                                  /*IsStridedOrIndexed*/ true, Operands,
602                                  &IndexVT);
603 
604       assert(VT.getVectorElementCount() == IndexVT.getVectorElementCount() &&
605              "Element count mismatch");
606 
607       RISCVVLMUL LMUL = RISCVTargetLowering::getLMUL(VT);
608       RISCVVLMUL IndexLMUL = RISCVTargetLowering::getLMUL(IndexVT);
609       unsigned IndexScalarSize = IndexVT.getScalarSizeInBits();
610       const RISCV::VLX_VSXPseudo *P = RISCV::getVLXPseudo(
611           IsMasked, IsOrdered, IndexScalarSize, static_cast<unsigned>(LMUL),
612           static_cast<unsigned>(IndexLMUL));
613       MachineSDNode *Load =
614           CurDAG->getMachineNode(P->Pseudo, DL, Node->getVTList(), Operands);
615 
616       if (auto *MemOp = dyn_cast<MemSDNode>(Node))
617         CurDAG->setNodeMemRefs(Load, {MemOp->getMemOperand()});
618 
619       ReplaceNode(Node, Load);
620       return;
621     }
622     case Intrinsic::riscv_vle1:
623     case Intrinsic::riscv_vle:
624     case Intrinsic::riscv_vle_mask:
625     case Intrinsic::riscv_vlse:
626     case Intrinsic::riscv_vlse_mask: {
627       bool IsMasked = IntNo == Intrinsic::riscv_vle_mask ||
628                       IntNo == Intrinsic::riscv_vlse_mask;
629       bool IsStrided =
630           IntNo == Intrinsic::riscv_vlse || IntNo == Intrinsic::riscv_vlse_mask;
631 
632       MVT VT = Node->getSimpleValueType(0);
633       unsigned ScalarSize = VT.getScalarSizeInBits();
634       // VLE1 uses an SEW of 8.
635       unsigned SEWImm = (IntNo == Intrinsic::riscv_vle1) ? 8 : ScalarSize;
636 
637       unsigned CurOp = 2;
638       SmallVector<SDValue, 8> Operands;
639       if (IsMasked)
640         Operands.push_back(Node->getOperand(CurOp++));
641 
642       addVectorLoadStoreOperands(Node, SEWImm, DL, CurOp, IsMasked, IsStrided,
643                                  Operands);
644 
645       RISCVVLMUL LMUL = RISCVTargetLowering::getLMUL(VT);
646       const RISCV::VLEPseudo *P =
647           RISCV::getVLEPseudo(IsMasked, IsStrided, /*FF*/ false, ScalarSize,
648                               static_cast<unsigned>(LMUL));
649       MachineSDNode *Load =
650           CurDAG->getMachineNode(P->Pseudo, DL, Node->getVTList(), Operands);
651 
652       if (auto *MemOp = dyn_cast<MemSDNode>(Node))
653         CurDAG->setNodeMemRefs(Load, {MemOp->getMemOperand()});
654 
655       ReplaceNode(Node, Load);
656       return;
657     }
658     case Intrinsic::riscv_vleff:
659     case Intrinsic::riscv_vleff_mask: {
660       bool IsMasked = IntNo == Intrinsic::riscv_vleff_mask;
661 
662       MVT VT = Node->getSimpleValueType(0);
663       unsigned ScalarSize = VT.getScalarSizeInBits();
664 
665       unsigned CurOp = 2;
666       SmallVector<SDValue, 7> Operands;
667       if (IsMasked)
668         Operands.push_back(Node->getOperand(CurOp++));
669 
670       addVectorLoadStoreOperands(Node, ScalarSize, DL, CurOp, IsMasked,
671                                  /*IsStridedOrIndexed*/ false, Operands);
672 
673       RISCVVLMUL LMUL = RISCVTargetLowering::getLMUL(VT);
674       const RISCV::VLEPseudo *P =
675           RISCV::getVLEPseudo(IsMasked, /*Strided*/ false, /*FF*/ true,
676                               ScalarSize, static_cast<unsigned>(LMUL));
677       MachineSDNode *Load =
678           CurDAG->getMachineNode(P->Pseudo, DL, Node->getValueType(0),
679                                  MVT::Other, MVT::Glue, Operands);
680       SDNode *ReadVL = CurDAG->getMachineNode(RISCV::PseudoReadVL, DL, XLenVT,
681                                               /*Glue*/ SDValue(Load, 2));
682 
683       if (auto *MemOp = dyn_cast<MemSDNode>(Node))
684         CurDAG->setNodeMemRefs(Load, {MemOp->getMemOperand()});
685 
686       ReplaceUses(SDValue(Node, 0), SDValue(Load, 0));
687       ReplaceUses(SDValue(Node, 1), SDValue(ReadVL, 0)); // VL
688       ReplaceUses(SDValue(Node, 2), SDValue(Load, 1));   // Chain
689       CurDAG->RemoveDeadNode(Node);
690       return;
691     }
692     }
693     break;
694   }
695   case ISD::INTRINSIC_VOID: {
696     unsigned IntNo = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue();
697     switch (IntNo) {
698     case Intrinsic::riscv_vsseg2:
699     case Intrinsic::riscv_vsseg3:
700     case Intrinsic::riscv_vsseg4:
701     case Intrinsic::riscv_vsseg5:
702     case Intrinsic::riscv_vsseg6:
703     case Intrinsic::riscv_vsseg7:
704     case Intrinsic::riscv_vsseg8: {
705       selectVSSEG(Node, /*IsMasked*/ false, /*IsStrided*/ false);
706       return;
707     }
708     case Intrinsic::riscv_vsseg2_mask:
709     case Intrinsic::riscv_vsseg3_mask:
710     case Intrinsic::riscv_vsseg4_mask:
711     case Intrinsic::riscv_vsseg5_mask:
712     case Intrinsic::riscv_vsseg6_mask:
713     case Intrinsic::riscv_vsseg7_mask:
714     case Intrinsic::riscv_vsseg8_mask: {
715       selectVSSEG(Node, /*IsMasked*/ true, /*IsStrided*/ false);
716       return;
717     }
718     case Intrinsic::riscv_vssseg2:
719     case Intrinsic::riscv_vssseg3:
720     case Intrinsic::riscv_vssseg4:
721     case Intrinsic::riscv_vssseg5:
722     case Intrinsic::riscv_vssseg6:
723     case Intrinsic::riscv_vssseg7:
724     case Intrinsic::riscv_vssseg8: {
725       selectVSSEG(Node, /*IsMasked*/ false, /*IsStrided*/ true);
726       return;
727     }
728     case Intrinsic::riscv_vssseg2_mask:
729     case Intrinsic::riscv_vssseg3_mask:
730     case Intrinsic::riscv_vssseg4_mask:
731     case Intrinsic::riscv_vssseg5_mask:
732     case Intrinsic::riscv_vssseg6_mask:
733     case Intrinsic::riscv_vssseg7_mask:
734     case Intrinsic::riscv_vssseg8_mask: {
735       selectVSSEG(Node, /*IsMasked*/ true, /*IsStrided*/ true);
736       return;
737     }
738     case Intrinsic::riscv_vsoxseg2:
739     case Intrinsic::riscv_vsoxseg3:
740     case Intrinsic::riscv_vsoxseg4:
741     case Intrinsic::riscv_vsoxseg5:
742     case Intrinsic::riscv_vsoxseg6:
743     case Intrinsic::riscv_vsoxseg7:
744     case Intrinsic::riscv_vsoxseg8:
745       selectVSXSEG(Node, /*IsMasked*/ false, /*IsOrdered*/ true);
746       return;
747     case Intrinsic::riscv_vsuxseg2:
748     case Intrinsic::riscv_vsuxseg3:
749     case Intrinsic::riscv_vsuxseg4:
750     case Intrinsic::riscv_vsuxseg5:
751     case Intrinsic::riscv_vsuxseg6:
752     case Intrinsic::riscv_vsuxseg7:
753     case Intrinsic::riscv_vsuxseg8:
754       selectVSXSEG(Node, /*IsMasked*/ false, /*IsOrdered*/ false);
755       return;
756     case Intrinsic::riscv_vsoxseg2_mask:
757     case Intrinsic::riscv_vsoxseg3_mask:
758     case Intrinsic::riscv_vsoxseg4_mask:
759     case Intrinsic::riscv_vsoxseg5_mask:
760     case Intrinsic::riscv_vsoxseg6_mask:
761     case Intrinsic::riscv_vsoxseg7_mask:
762     case Intrinsic::riscv_vsoxseg8_mask:
763       selectVSXSEG(Node, /*IsMasked*/ true, /*IsOrdered*/ true);
764       return;
765     case Intrinsic::riscv_vsuxseg2_mask:
766     case Intrinsic::riscv_vsuxseg3_mask:
767     case Intrinsic::riscv_vsuxseg4_mask:
768     case Intrinsic::riscv_vsuxseg5_mask:
769     case Intrinsic::riscv_vsuxseg6_mask:
770     case Intrinsic::riscv_vsuxseg7_mask:
771     case Intrinsic::riscv_vsuxseg8_mask:
772       selectVSXSEG(Node, /*IsMasked*/ true, /*IsOrdered*/ false);
773       return;
774     case Intrinsic::riscv_vsoxei:
775     case Intrinsic::riscv_vsoxei_mask:
776     case Intrinsic::riscv_vsuxei:
777     case Intrinsic::riscv_vsuxei_mask: {
778       bool IsMasked = IntNo == Intrinsic::riscv_vsoxei_mask ||
779                       IntNo == Intrinsic::riscv_vsuxei_mask;
780       bool IsOrdered = IntNo == Intrinsic::riscv_vsoxei ||
781                        IntNo == Intrinsic::riscv_vsoxei_mask;
782 
783       MVT VT = Node->getOperand(2)->getSimpleValueType(0);
784       unsigned ScalarSize = VT.getScalarSizeInBits();
785 
786       unsigned CurOp = 2;
787       SmallVector<SDValue, 8> Operands;
788       Operands.push_back(Node->getOperand(CurOp++)); // Store value.
789 
790       MVT IndexVT;
791       addVectorLoadStoreOperands(Node, ScalarSize, DL, CurOp, IsMasked,
792                                  /*IsStridedOrIndexed*/ true, Operands,
793                                  &IndexVT);
794 
795       assert(VT.getVectorElementCount() == IndexVT.getVectorElementCount() &&
796              "Element count mismatch");
797 
798       RISCVVLMUL LMUL = RISCVTargetLowering::getLMUL(VT);
799       RISCVVLMUL IndexLMUL = RISCVTargetLowering::getLMUL(IndexVT);
800       unsigned IndexScalarSize = IndexVT.getScalarSizeInBits();
801       const RISCV::VLX_VSXPseudo *P = RISCV::getVSXPseudo(
802           IsMasked, IsOrdered, IndexScalarSize, static_cast<unsigned>(LMUL),
803           static_cast<unsigned>(IndexLMUL));
804       MachineSDNode *Store =
805           CurDAG->getMachineNode(P->Pseudo, DL, Node->getVTList(), Operands);
806 
807       if (auto *MemOp = dyn_cast<MemSDNode>(Node))
808         CurDAG->setNodeMemRefs(Store, {MemOp->getMemOperand()});
809 
810       ReplaceNode(Node, Store);
811       return;
812     }
813     case Intrinsic::riscv_vse1:
814     case Intrinsic::riscv_vse:
815     case Intrinsic::riscv_vse_mask:
816     case Intrinsic::riscv_vsse:
817     case Intrinsic::riscv_vsse_mask: {
818       bool IsMasked = IntNo == Intrinsic::riscv_vse_mask ||
819                       IntNo == Intrinsic::riscv_vsse_mask;
820       bool IsStrided =
821           IntNo == Intrinsic::riscv_vsse || IntNo == Intrinsic::riscv_vsse_mask;
822 
823       MVT VT = Node->getOperand(2)->getSimpleValueType(0);
824       unsigned ScalarSize = VT.getScalarSizeInBits();
825       // VSE1 uses an SEW of 8.
826       unsigned SEWImm = (IntNo == Intrinsic::riscv_vse1) ? 8 : ScalarSize;
827 
828       unsigned CurOp = 2;
829       SmallVector<SDValue, 8> Operands;
830       Operands.push_back(Node->getOperand(CurOp++)); // Store value.
831 
832       addVectorLoadStoreOperands(Node, SEWImm, DL, CurOp, IsMasked, IsStrided,
833                                  Operands);
834 
835       RISCVVLMUL LMUL = RISCVTargetLowering::getLMUL(VT);
836       const RISCV::VSEPseudo *P = RISCV::getVSEPseudo(
837           IsMasked, IsStrided, ScalarSize, static_cast<unsigned>(LMUL));
838       MachineSDNode *Store =
839           CurDAG->getMachineNode(P->Pseudo, DL, Node->getVTList(), Operands);
840       if (auto *MemOp = dyn_cast<MemSDNode>(Node))
841         CurDAG->setNodeMemRefs(Store, {MemOp->getMemOperand()});
842 
843       ReplaceNode(Node, Store);
844       return;
845     }
846     }
847     break;
848   }
849   case ISD::BITCAST: {
850     MVT SrcVT = Node->getOperand(0).getSimpleValueType();
851     // Just drop bitcasts between vectors if both are fixed or both are
852     // scalable.
853     if ((VT.isScalableVector() && SrcVT.isScalableVector()) ||
854         (VT.isFixedLengthVector() && SrcVT.isFixedLengthVector())) {
855       ReplaceUses(SDValue(Node, 0), Node->getOperand(0));
856       CurDAG->RemoveDeadNode(Node);
857       return;
858     }
859     break;
860   }
861   case ISD::INSERT_SUBVECTOR: {
862     SDValue V = Node->getOperand(0);
863     SDValue SubV = Node->getOperand(1);
864     SDLoc DL(SubV);
865     auto Idx = Node->getConstantOperandVal(2);
866     MVT SubVecVT = SubV.getSimpleValueType();
867 
868     MVT SubVecContainerVT = SubVecVT;
869     // Establish the correct scalable-vector types for any fixed-length type.
870     if (SubVecVT.isFixedLengthVector())
871       SubVecContainerVT = RISCVTargetLowering::getContainerForFixedLengthVector(
872           *CurDAG, SubVecVT, *Subtarget);
873     if (VT.isFixedLengthVector())
874       VT = RISCVTargetLowering::getContainerForFixedLengthVector(*CurDAG, VT,
875                                                                  *Subtarget);
876 
877     const auto *TRI = Subtarget->getRegisterInfo();
878     unsigned SubRegIdx;
879     std::tie(SubRegIdx, Idx) =
880         RISCVTargetLowering::decomposeSubvectorInsertExtractToSubRegs(
881             VT, SubVecContainerVT, Idx, TRI);
882 
883     // If the Idx hasn't been completely eliminated then this is a subvector
884     // insert which doesn't naturally align to a vector register. These must
885     // be handled using instructions to manipulate the vector registers.
886     if (Idx != 0)
887       break;
888 
889     RISCVVLMUL SubVecLMUL = RISCVTargetLowering::getLMUL(SubVecContainerVT);
890     bool IsSubVecPartReg = SubVecLMUL == RISCVVLMUL::LMUL_F2 ||
891                            SubVecLMUL == RISCVVLMUL::LMUL_F4 ||
892                            SubVecLMUL == RISCVVLMUL::LMUL_F8;
893     (void)IsSubVecPartReg; // Silence unused variable warning without asserts.
894     assert((!IsSubVecPartReg || V.isUndef()) &&
895            "Expecting lowering to have created legal INSERT_SUBVECTORs when "
896            "the subvector is smaller than a full-sized register");
897 
898     // If we haven't set a SubRegIdx, then we must be going between
899     // equally-sized LMUL groups (e.g. VR -> VR). This can be done as a copy.
900     if (SubRegIdx == RISCV::NoSubRegister) {
901       unsigned InRegClassID = RISCVTargetLowering::getRegClassIDForVecVT(VT);
902       assert(RISCVTargetLowering::getRegClassIDForVecVT(SubVecContainerVT) ==
903                  InRegClassID &&
904              "Unexpected subvector extraction");
905       SDValue RC = CurDAG->getTargetConstant(InRegClassID, DL, XLenVT);
906       SDNode *NewNode = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
907                                                DL, VT, SubV, RC);
908       ReplaceNode(Node, NewNode);
909       return;
910     }
911 
912     SDValue Insert = CurDAG->getTargetInsertSubreg(SubRegIdx, DL, VT, V, SubV);
913     ReplaceNode(Node, Insert.getNode());
914     return;
915   }
916   case ISD::EXTRACT_SUBVECTOR: {
917     SDValue V = Node->getOperand(0);
918     auto Idx = Node->getConstantOperandVal(1);
919     MVT InVT = V.getSimpleValueType();
920     SDLoc DL(V);
921 
922     MVT SubVecContainerVT = VT;
923     // Establish the correct scalable-vector types for any fixed-length type.
924     if (VT.isFixedLengthVector())
925       SubVecContainerVT = RISCVTargetLowering::getContainerForFixedLengthVector(
926           *CurDAG, VT, *Subtarget);
927     if (InVT.isFixedLengthVector())
928       InVT = RISCVTargetLowering::getContainerForFixedLengthVector(
929           *CurDAG, InVT, *Subtarget);
930 
931     const auto *TRI = Subtarget->getRegisterInfo();
932     unsigned SubRegIdx;
933     std::tie(SubRegIdx, Idx) =
934         RISCVTargetLowering::decomposeSubvectorInsertExtractToSubRegs(
935             InVT, SubVecContainerVT, Idx, TRI);
936 
937     // If the Idx hasn't been completely eliminated then this is a subvector
938     // extract which doesn't naturally align to a vector register. These must
939     // be handled using instructions to manipulate the vector registers.
940     if (Idx != 0)
941       break;
942 
943     // If we haven't set a SubRegIdx, then we must be going between
944     // equally-sized LMUL types (e.g. VR -> VR). This can be done as a copy.
945     if (SubRegIdx == RISCV::NoSubRegister) {
946       unsigned InRegClassID = RISCVTargetLowering::getRegClassIDForVecVT(InVT);
947       assert(RISCVTargetLowering::getRegClassIDForVecVT(SubVecContainerVT) ==
948                  InRegClassID &&
949              "Unexpected subvector extraction");
950       SDValue RC = CurDAG->getTargetConstant(InRegClassID, DL, XLenVT);
951       SDNode *NewNode =
952           CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, DL, VT, V, RC);
953       ReplaceNode(Node, NewNode);
954       return;
955     }
956 
957     SDValue Extract = CurDAG->getTargetExtractSubreg(SubRegIdx, DL, VT, V);
958     ReplaceNode(Node, Extract.getNode());
959     return;
960   }
961   }
962 
963   // Select the default instruction.
964   SelectCode(Node);
965 }
966 
967 bool RISCVDAGToDAGISel::SelectInlineAsmMemoryOperand(
968     const SDValue &Op, unsigned ConstraintID, std::vector<SDValue> &OutOps) {
969   switch (ConstraintID) {
970   case InlineAsm::Constraint_m:
971     // We just support simple memory operands that have a single address
972     // operand and need no special handling.
973     OutOps.push_back(Op);
974     return false;
975   case InlineAsm::Constraint_A:
976     OutOps.push_back(Op);
977     return false;
978   default:
979     break;
980   }
981 
982   return true;
983 }
984 
985 bool RISCVDAGToDAGISel::SelectAddrFI(SDValue Addr, SDValue &Base) {
986   if (auto *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
987     Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), Subtarget->getXLenVT());
988     return true;
989   }
990   return false;
991 }
992 
993 bool RISCVDAGToDAGISel::SelectBaseAddr(SDValue Addr, SDValue &Base) {
994   // If this is FrameIndex, select it directly. Otherwise just let it get
995   // selected to a register independently.
996   if (auto *FIN = dyn_cast<FrameIndexSDNode>(Addr))
997     Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), Subtarget->getXLenVT());
998   else
999     Base = Addr;
1000   return true;
1001 }
1002 
1003 bool RISCVDAGToDAGISel::selectShiftMask(SDValue N, unsigned ShiftWidth,
1004                                         SDValue &ShAmt) {
1005   // Shift instructions on RISCV only read the lower 5 or 6 bits of the shift
1006   // amount. If there is an AND on the shift amount, we can bypass it if it
1007   // doesn't affect any of those bits.
1008   if (N.getOpcode() == ISD::AND && isa<ConstantSDNode>(N.getOperand(1))) {
1009     const APInt &AndMask = N->getConstantOperandAPInt(1);
1010 
1011     // Since the max shift amount is a power of 2 we can subtract 1 to make a
1012     // mask that covers the bits needed to represent all shift amounts.
1013     assert(isPowerOf2_32(ShiftWidth) && "Unexpected max shift amount!");
1014     APInt ShMask(AndMask.getBitWidth(), ShiftWidth - 1);
1015 
1016     if (ShMask.isSubsetOf(AndMask)) {
1017       ShAmt = N.getOperand(0);
1018       return true;
1019     }
1020 
1021     // SimplifyDemandedBits may have optimized the mask so try restoring any
1022     // bits that are known zero.
1023     KnownBits Known = CurDAG->computeKnownBits(N->getOperand(0));
1024     if (ShMask.isSubsetOf(AndMask | Known.Zero)) {
1025       ShAmt = N.getOperand(0);
1026       return true;
1027     }
1028   }
1029 
1030   ShAmt = N;
1031   return true;
1032 }
1033 
1034 bool RISCVDAGToDAGISel::selectSExti32(SDValue N, SDValue &Val) {
1035   if (N.getOpcode() == ISD::SIGN_EXTEND_INREG &&
1036       cast<VTSDNode>(N.getOperand(1))->getVT() == MVT::i32) {
1037     Val = N.getOperand(0);
1038     return true;
1039   }
1040   // FIXME: Should we just call computeNumSignBits here?
1041   if (N.getOpcode() == ISD::AssertSext &&
1042       cast<VTSDNode>(N->getOperand(1))->getVT().bitsLE(MVT::i32)) {
1043     Val = N;
1044     return true;
1045   }
1046   if (N.getOpcode() == ISD::AssertZext &&
1047       cast<VTSDNode>(N->getOperand(1))->getVT().bitsLT(MVT::i32)) {
1048     Val = N;
1049     return true;
1050   }
1051 
1052   return false;
1053 }
1054 
1055 bool RISCVDAGToDAGISel::selectZExti32(SDValue N, SDValue &Val) {
1056   if (N.getOpcode() == ISD::AND) {
1057     auto *C = dyn_cast<ConstantSDNode>(N.getOperand(1));
1058     if (C && C->getZExtValue() == UINT64_C(0xFFFFFFFF)) {
1059       Val = N.getOperand(0);
1060       return true;
1061     }
1062   }
1063   // FIXME: Should we just call computeKnownBits here?
1064   if (N.getOpcode() == ISD::AssertZext &&
1065       cast<VTSDNode>(N->getOperand(1))->getVT().bitsLE(MVT::i32)) {
1066     Val = N;
1067     return true;
1068   }
1069 
1070   return false;
1071 }
1072 
1073 // Check if (add r, imm) can be optimized to (ADDI (ADDI r, imm0), imm1),
1074 // in which imm = imm0 + imm1 and both imm0 and imm1 are simm12.
1075 bool RISCVDAGToDAGISel::selectAddiPair(SDValue N, SDValue &Val) {
1076   if (auto *ConstOp = dyn_cast<ConstantSDNode>(N)) {
1077     // The immediate operand must have only use.
1078     if (!(ConstOp->hasOneUse()))
1079       return false;
1080     // The immediate operand must be in range [-4096,-2049] or [2048,4094].
1081     int64_t Imm = ConstOp->getSExtValue();
1082     if ((-4096 <= Imm && Imm <= -2049) || (2048 <= Imm && Imm <= 4094)) {
1083       Val = N;
1084       return true;
1085     }
1086   }
1087   return false;
1088 }
1089 
1090 // Check that it is a SLLIUW (Shift Logical Left Immediate Unsigned i32
1091 // on RV64).
1092 // SLLIUW is the same as SLLI except for the fact that it clears the bits
1093 // XLEN-1:32 of the input RS1 before shifting.
1094 // A PatFrag has already checked that it has the right structure:
1095 //
1096 //  (AND (SHL RS1, VC2), VC1)
1097 //
1098 // We check that VC2, the shamt is less than 32, otherwise the pattern is
1099 // exactly the same as SLLI and we give priority to that.
1100 // Eventually we check that VC1, the mask used to clear the upper 32 bits
1101 // of RS1, is correct:
1102 //
1103 //  VC1 == (0xFFFFFFFF << VC2)
1104 //
1105 bool RISCVDAGToDAGISel::MatchSLLIUW(SDNode *N) const {
1106   assert(N->getOpcode() == ISD::AND);
1107   assert(N->getOperand(0).getOpcode() == ISD::SHL);
1108   assert(isa<ConstantSDNode>(N->getOperand(1)));
1109   assert(isa<ConstantSDNode>(N->getOperand(0).getOperand(1)));
1110 
1111   // The IsRV64 predicate is checked after PatFrag predicates so we can get
1112   // here even on RV32.
1113   if (!Subtarget->is64Bit())
1114     return false;
1115 
1116   SDValue Shl = N->getOperand(0);
1117   uint64_t VC1 = N->getConstantOperandVal(1);
1118   uint64_t VC2 = Shl.getConstantOperandVal(1);
1119 
1120   // Immediate range should be enforced by uimm5 predicate.
1121   assert(VC2 < 32 && "Unexpected immediate");
1122   return (VC1 >> VC2) == UINT64_C(0xFFFFFFFF);
1123 }
1124 
1125 // X0 has special meaning for vsetvl/vsetvli.
1126 //  rd | rs1 |   AVL value | Effect on vl
1127 //--------------------------------------------------------------
1128 // !X0 |  X0 |       VLMAX | Set vl to VLMAX
1129 //  X0 |  X0 | Value in vl | Keep current vl, just change vtype.
1130 bool RISCVDAGToDAGISel::selectVLOp(SDValue N, SDValue &VL) {
1131   // If the VL value is a constant 0, manually select it to an ADDI with 0
1132   // immediate to prevent the default selection path from matching it to X0.
1133   auto *C = dyn_cast<ConstantSDNode>(N);
1134   if (C && C->isNullValue())
1135     VL = SDValue(selectImm(CurDAG, SDLoc(N), 0, Subtarget->getXLenVT()), 0);
1136   else
1137     VL = N;
1138 
1139   return true;
1140 }
1141 
1142 bool RISCVDAGToDAGISel::selectVSplat(SDValue N, SDValue &SplatVal) {
1143   if (N.getOpcode() != ISD::SPLAT_VECTOR &&
1144       N.getOpcode() != RISCVISD::SPLAT_VECTOR_I64 &&
1145       N.getOpcode() != RISCVISD::VMV_V_X_VL)
1146     return false;
1147   SplatVal = N.getOperand(0);
1148   return true;
1149 }
1150 
1151 using ValidateFn = bool (*)(int64_t);
1152 
1153 static bool selectVSplatSimmHelper(SDValue N, SDValue &SplatVal,
1154                                    SelectionDAG &DAG,
1155                                    const RISCVSubtarget &Subtarget,
1156                                    ValidateFn ValidateImm) {
1157   if ((N.getOpcode() != ISD::SPLAT_VECTOR &&
1158        N.getOpcode() != RISCVISD::SPLAT_VECTOR_I64 &&
1159        N.getOpcode() != RISCVISD::VMV_V_X_VL) ||
1160       !isa<ConstantSDNode>(N.getOperand(0)))
1161     return false;
1162 
1163   int64_t SplatImm = cast<ConstantSDNode>(N.getOperand(0))->getSExtValue();
1164 
1165   // ISD::SPLAT_VECTOR, RISCVISD::SPLAT_VECTOR_I64 and RISCVISD::VMV_V_X_VL
1166   // share semantics when the operand type is wider than the resulting vector
1167   // element type: an implicit truncation first takes place. Therefore, perform
1168   // a manual truncation/sign-extension in order to ignore any truncated bits
1169   // and catch any zero-extended immediate.
1170   // For example, we wish to match (i8 -1) -> (XLenVT 255) as a simm5 by first
1171   // sign-extending to (XLenVT -1).
1172   MVT XLenVT = Subtarget.getXLenVT();
1173   assert(XLenVT == N.getOperand(0).getSimpleValueType() &&
1174          "Unexpected splat operand type");
1175   MVT EltVT = N.getSimpleValueType().getVectorElementType();
1176   if (EltVT.bitsLT(XLenVT))
1177     SplatImm = SignExtend64(SplatImm, EltVT.getSizeInBits());
1178 
1179   if (!ValidateImm(SplatImm))
1180     return false;
1181 
1182   SplatVal = DAG.getTargetConstant(SplatImm, SDLoc(N), XLenVT);
1183   return true;
1184 }
1185 
1186 bool RISCVDAGToDAGISel::selectVSplatSimm5(SDValue N, SDValue &SplatVal) {
1187   return selectVSplatSimmHelper(N, SplatVal, *CurDAG, *Subtarget,
1188                                 [](int64_t Imm) { return isInt<5>(Imm); });
1189 }
1190 
1191 bool RISCVDAGToDAGISel::selectVSplatSimm5Plus1(SDValue N, SDValue &SplatVal) {
1192   return selectVSplatSimmHelper(
1193       N, SplatVal, *CurDAG, *Subtarget,
1194       [](int64_t Imm) { return (isInt<5>(Imm) && Imm != -16) || Imm == 16; });
1195 }
1196 
1197 bool RISCVDAGToDAGISel::selectVSplatSimm5Plus1NonZero(SDValue N,
1198                                                       SDValue &SplatVal) {
1199   return selectVSplatSimmHelper(
1200       N, SplatVal, *CurDAG, *Subtarget, [](int64_t Imm) {
1201         return Imm != 0 && ((isInt<5>(Imm) && Imm != -16) || Imm == 16);
1202       });
1203 }
1204 
1205 bool RISCVDAGToDAGISel::selectVSplatUimm5(SDValue N, SDValue &SplatVal) {
1206   if ((N.getOpcode() != ISD::SPLAT_VECTOR &&
1207        N.getOpcode() != RISCVISD::SPLAT_VECTOR_I64 &&
1208        N.getOpcode() != RISCVISD::VMV_V_X_VL) ||
1209       !isa<ConstantSDNode>(N.getOperand(0)))
1210     return false;
1211 
1212   int64_t SplatImm = cast<ConstantSDNode>(N.getOperand(0))->getSExtValue();
1213 
1214   if (!isUInt<5>(SplatImm))
1215     return false;
1216 
1217   SplatVal =
1218       CurDAG->getTargetConstant(SplatImm, SDLoc(N), Subtarget->getXLenVT());
1219 
1220   return true;
1221 }
1222 
1223 bool RISCVDAGToDAGISel::selectRVVSimm5(SDValue N, unsigned Width,
1224                                        SDValue &Imm) {
1225   if (auto *C = dyn_cast<ConstantSDNode>(N)) {
1226     int64_t ImmVal = SignExtend64(C->getSExtValue(), Width);
1227 
1228     if (!isInt<5>(ImmVal))
1229       return false;
1230 
1231     Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(N), Subtarget->getXLenVT());
1232     return true;
1233   }
1234 
1235   return false;
1236 }
1237 
1238 bool RISCVDAGToDAGISel::selectRVVUimm5(SDValue N, unsigned Width,
1239                                        SDValue &Imm) {
1240   if (auto *C = dyn_cast<ConstantSDNode>(N)) {
1241     int64_t ImmVal = C->getSExtValue();
1242 
1243     if (!isUInt<5>(ImmVal))
1244       return false;
1245 
1246     Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(N), Subtarget->getXLenVT());
1247     return true;
1248   }
1249 
1250   return false;
1251 }
1252 
1253 // Merge an ADDI into the offset of a load/store instruction where possible.
1254 // (load (addi base, off1), off2) -> (load base, off1+off2)
1255 // (store val, (addi base, off1), off2) -> (store val, base, off1+off2)
1256 // This is possible when off1+off2 fits a 12-bit immediate.
1257 void RISCVDAGToDAGISel::doPeepholeLoadStoreADDI() {
1258   SelectionDAG::allnodes_iterator Position(CurDAG->getRoot().getNode());
1259   ++Position;
1260 
1261   while (Position != CurDAG->allnodes_begin()) {
1262     SDNode *N = &*--Position;
1263     // Skip dead nodes and any non-machine opcodes.
1264     if (N->use_empty() || !N->isMachineOpcode())
1265       continue;
1266 
1267     int OffsetOpIdx;
1268     int BaseOpIdx;
1269 
1270     // Only attempt this optimisation for I-type loads and S-type stores.
1271     switch (N->getMachineOpcode()) {
1272     default:
1273       continue;
1274     case RISCV::LB:
1275     case RISCV::LH:
1276     case RISCV::LW:
1277     case RISCV::LBU:
1278     case RISCV::LHU:
1279     case RISCV::LWU:
1280     case RISCV::LD:
1281     case RISCV::FLH:
1282     case RISCV::FLW:
1283     case RISCV::FLD:
1284       BaseOpIdx = 0;
1285       OffsetOpIdx = 1;
1286       break;
1287     case RISCV::SB:
1288     case RISCV::SH:
1289     case RISCV::SW:
1290     case RISCV::SD:
1291     case RISCV::FSH:
1292     case RISCV::FSW:
1293     case RISCV::FSD:
1294       BaseOpIdx = 1;
1295       OffsetOpIdx = 2;
1296       break;
1297     }
1298 
1299     if (!isa<ConstantSDNode>(N->getOperand(OffsetOpIdx)))
1300       continue;
1301 
1302     SDValue Base = N->getOperand(BaseOpIdx);
1303 
1304     // If the base is an ADDI, we can merge it in to the load/store.
1305     if (!Base.isMachineOpcode() || Base.getMachineOpcode() != RISCV::ADDI)
1306       continue;
1307 
1308     SDValue ImmOperand = Base.getOperand(1);
1309     uint64_t Offset2 = N->getConstantOperandVal(OffsetOpIdx);
1310 
1311     if (auto *Const = dyn_cast<ConstantSDNode>(ImmOperand)) {
1312       int64_t Offset1 = Const->getSExtValue();
1313       int64_t CombinedOffset = Offset1 + Offset2;
1314       if (!isInt<12>(CombinedOffset))
1315         continue;
1316       ImmOperand = CurDAG->getTargetConstant(CombinedOffset, SDLoc(ImmOperand),
1317                                              ImmOperand.getValueType());
1318     } else if (auto *GA = dyn_cast<GlobalAddressSDNode>(ImmOperand)) {
1319       // If the off1 in (addi base, off1) is a global variable's address (its
1320       // low part, really), then we can rely on the alignment of that variable
1321       // to provide a margin of safety before off1 can overflow the 12 bits.
1322       // Check if off2 falls within that margin; if so off1+off2 can't overflow.
1323       const DataLayout &DL = CurDAG->getDataLayout();
1324       Align Alignment = GA->getGlobal()->getPointerAlignment(DL);
1325       if (Offset2 != 0 && Alignment <= Offset2)
1326         continue;
1327       int64_t Offset1 = GA->getOffset();
1328       int64_t CombinedOffset = Offset1 + Offset2;
1329       ImmOperand = CurDAG->getTargetGlobalAddress(
1330           GA->getGlobal(), SDLoc(ImmOperand), ImmOperand.getValueType(),
1331           CombinedOffset, GA->getTargetFlags());
1332     } else if (auto *CP = dyn_cast<ConstantPoolSDNode>(ImmOperand)) {
1333       // Ditto.
1334       Align Alignment = CP->getAlign();
1335       if (Offset2 != 0 && Alignment <= Offset2)
1336         continue;
1337       int64_t Offset1 = CP->getOffset();
1338       int64_t CombinedOffset = Offset1 + Offset2;
1339       ImmOperand = CurDAG->getTargetConstantPool(
1340           CP->getConstVal(), ImmOperand.getValueType(), CP->getAlign(),
1341           CombinedOffset, CP->getTargetFlags());
1342     } else {
1343       continue;
1344     }
1345 
1346     LLVM_DEBUG(dbgs() << "Folding add-immediate into mem-op:\nBase:    ");
1347     LLVM_DEBUG(Base->dump(CurDAG));
1348     LLVM_DEBUG(dbgs() << "\nN: ");
1349     LLVM_DEBUG(N->dump(CurDAG));
1350     LLVM_DEBUG(dbgs() << "\n");
1351 
1352     // Modify the offset operand of the load/store.
1353     if (BaseOpIdx == 0) // Load
1354       CurDAG->UpdateNodeOperands(N, Base.getOperand(0), ImmOperand,
1355                                  N->getOperand(2));
1356     else // Store
1357       CurDAG->UpdateNodeOperands(N, N->getOperand(0), Base.getOperand(0),
1358                                  ImmOperand, N->getOperand(3));
1359 
1360     // The add-immediate may now be dead, in which case remove it.
1361     if (Base.getNode()->use_empty())
1362       CurDAG->RemoveDeadNode(Base.getNode());
1363   }
1364 }
1365 
1366 // This pass converts a legalized DAG into a RISCV-specific DAG, ready
1367 // for instruction scheduling.
1368 FunctionPass *llvm::createRISCVISelDag(RISCVTargetMachine &TM) {
1369   return new RISCVDAGToDAGISel(TM);
1370 }
1371