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 "llvm/CodeGen/MachineFrameInfo.h"
17 #include "llvm/IR/IntrinsicsRISCV.h"
18 #include "llvm/Support/Alignment.h"
19 #include "llvm/Support/Debug.h"
20 #include "llvm/Support/KnownBits.h"
21 #include "llvm/Support/MathExtras.h"
22 #include "llvm/Support/raw_ostream.h"
23 
24 using namespace llvm;
25 
26 #define DEBUG_TYPE "riscv-isel"
27 
28 namespace RISCVZvlssegTable {
29 struct RISCVZvlsseg {
30   unsigned IntrinsicID;
31   uint8_t SEW;
32   uint8_t LMUL;
33   uint8_t IndexLMUL;
34   uint16_t Pseudo;
35 };
36 
37 using namespace RISCV;
38 
39 #define GET_RISCVZvlssegTable_IMPL
40 #include "RISCVGenSearchableTables.inc"
41 
42 } // namespace RISCVZvlssegTable
43 
44 void RISCVDAGToDAGISel::PostprocessISelDAG() {
45   doPeepholeLoadStoreADDI();
46 }
47 
48 static SDNode *selectImm(SelectionDAG *CurDAG, const SDLoc &DL, int64_t Imm,
49                          MVT XLenVT) {
50   RISCVMatInt::InstSeq Seq;
51   RISCVMatInt::generateInstSeq(Imm, XLenVT == MVT::i64, Seq);
52 
53   SDNode *Result = nullptr;
54   SDValue SrcReg = CurDAG->getRegister(RISCV::X0, XLenVT);
55   for (RISCVMatInt::Inst &Inst : Seq) {
56     SDValue SDImm = CurDAG->getTargetConstant(Inst.Imm, DL, XLenVT);
57     if (Inst.Opc == RISCV::LUI)
58       Result = CurDAG->getMachineNode(RISCV::LUI, DL, XLenVT, SDImm);
59     else
60       Result = CurDAG->getMachineNode(Inst.Opc, DL, XLenVT, SrcReg, SDImm);
61 
62     // Only the first instruction has X0 as its source.
63     SrcReg = SDValue(Result, 0);
64   }
65 
66   return Result;
67 }
68 
69 static RISCVVLMUL getLMUL(MVT VT) {
70   switch (VT.getSizeInBits().getKnownMinValue() / 8) {
71   default:
72     llvm_unreachable("Invalid LMUL.");
73   case 1:
74     return RISCVVLMUL::LMUL_F8;
75   case 2:
76     return RISCVVLMUL::LMUL_F4;
77   case 4:
78     return RISCVVLMUL::LMUL_F2;
79   case 8:
80     return RISCVVLMUL::LMUL_1;
81   case 16:
82     return RISCVVLMUL::LMUL_2;
83   case 32:
84     return RISCVVLMUL::LMUL_4;
85   case 64:
86     return RISCVVLMUL::LMUL_8;
87   }
88 }
89 
90 static unsigned getRegClassIDForLMUL(RISCVVLMUL LMul) {
91   switch (LMul) {
92   default:
93     llvm_unreachable("Invalid LMUL.");
94   case RISCVVLMUL::LMUL_F8:
95   case RISCVVLMUL::LMUL_F4:
96   case RISCVVLMUL::LMUL_F2:
97   case RISCVVLMUL::LMUL_1:
98     return RISCV::VRRegClassID;
99   case RISCVVLMUL::LMUL_2:
100     return RISCV::VRM2RegClassID;
101   case RISCVVLMUL::LMUL_4:
102     return RISCV::VRM4RegClassID;
103   case RISCVVLMUL::LMUL_8:
104     return RISCV::VRM8RegClassID;
105   }
106 }
107 
108 static unsigned getSubregIndexByMVT(MVT VT, unsigned Index) {
109   RISCVVLMUL LMUL = getLMUL(VT);
110   if (LMUL == RISCVVLMUL::LMUL_F8 || LMUL == RISCVVLMUL::LMUL_F4 ||
111       LMUL == RISCVVLMUL::LMUL_F2 || LMUL == RISCVVLMUL::LMUL_1) {
112     static_assert(RISCV::sub_vrm1_7 == RISCV::sub_vrm1_0 + 7,
113                   "Unexpected subreg numbering");
114     return RISCV::sub_vrm1_0 + Index;
115   } else if (LMUL == RISCVVLMUL::LMUL_2) {
116     static_assert(RISCV::sub_vrm2_3 == RISCV::sub_vrm2_0 + 3,
117                   "Unexpected subreg numbering");
118     return RISCV::sub_vrm2_0 + Index;
119   } else if (LMUL == RISCVVLMUL::LMUL_4) {
120     static_assert(RISCV::sub_vrm4_1 == RISCV::sub_vrm4_0 + 1,
121                   "Unexpected subreg numbering");
122     return RISCV::sub_vrm4_0 + Index;
123   }
124   llvm_unreachable("Invalid vector type.");
125 }
126 
127 static SDValue createTupleImpl(SelectionDAG &CurDAG, ArrayRef<SDValue> Regs,
128                                unsigned RegClassID, unsigned SubReg0) {
129   assert(Regs.size() >= 2 && Regs.size() <= 8);
130 
131   SDLoc DL(Regs[0]);
132   SmallVector<SDValue, 8> Ops;
133 
134   Ops.push_back(CurDAG.getTargetConstant(RegClassID, DL, MVT::i32));
135 
136   for (unsigned I = 0; I < Regs.size(); ++I) {
137     Ops.push_back(Regs[I]);
138     Ops.push_back(CurDAG.getTargetConstant(SubReg0 + I, DL, MVT::i32));
139   }
140   SDNode *N =
141       CurDAG.getMachineNode(TargetOpcode::REG_SEQUENCE, DL, MVT::Untyped, Ops);
142   return SDValue(N, 0);
143 }
144 
145 static SDValue createM1Tuple(SelectionDAG &CurDAG, ArrayRef<SDValue> Regs,
146                              unsigned NF) {
147   static const unsigned RegClassIDs[] = {
148       RISCV::VRN2M1RegClassID, RISCV::VRN3M1RegClassID, RISCV::VRN4M1RegClassID,
149       RISCV::VRN5M1RegClassID, RISCV::VRN6M1RegClassID, RISCV::VRN7M1RegClassID,
150       RISCV::VRN8M1RegClassID};
151 
152   return createTupleImpl(CurDAG, Regs, RegClassIDs[NF - 2], RISCV::sub_vrm1_0);
153 }
154 
155 static SDValue createM2Tuple(SelectionDAG &CurDAG, ArrayRef<SDValue> Regs,
156                              unsigned NF) {
157   static const unsigned RegClassIDs[] = {RISCV::VRN2M2RegClassID,
158                                          RISCV::VRN3M2RegClassID,
159                                          RISCV::VRN4M2RegClassID};
160 
161   return createTupleImpl(CurDAG, Regs, RegClassIDs[NF - 2], RISCV::sub_vrm2_0);
162 }
163 
164 static SDValue createM4Tuple(SelectionDAG &CurDAG, ArrayRef<SDValue> Regs,
165                              unsigned NF) {
166   return createTupleImpl(CurDAG, Regs, RISCV::VRN2M4RegClassID,
167                          RISCV::sub_vrm4_0);
168 }
169 
170 static SDValue createTuple(SelectionDAG &CurDAG, ArrayRef<SDValue> Regs,
171                            unsigned NF, RISCVVLMUL LMUL) {
172   switch (LMUL) {
173   default:
174     llvm_unreachable("Invalid LMUL.");
175   case RISCVVLMUL::LMUL_F8:
176   case RISCVVLMUL::LMUL_F4:
177   case RISCVVLMUL::LMUL_F2:
178   case RISCVVLMUL::LMUL_1:
179     return createM1Tuple(CurDAG, Regs, NF);
180   case RISCVVLMUL::LMUL_2:
181     return createM2Tuple(CurDAG, Regs, NF);
182   case RISCVVLMUL::LMUL_4:
183     return createM4Tuple(CurDAG, Regs, NF);
184   }
185 }
186 
187 void RISCVDAGToDAGISel::selectVLSEG(SDNode *Node, unsigned IntNo, bool IsMasked,
188                                     bool IsStrided) {
189   SDLoc DL(Node);
190   unsigned NF = Node->getNumValues() - 1;
191   MVT VT = Node->getSimpleValueType(0);
192   unsigned ScalarSize = VT.getScalarSizeInBits();
193   MVT XLenVT = Subtarget->getXLenVT();
194   RISCVVLMUL LMUL = getLMUL(VT);
195   SDValue SEW = CurDAG->getTargetConstant(ScalarSize, DL, XLenVT);
196   unsigned CurOp = 2;
197   SmallVector<SDValue, 7> Operands;
198   if (IsMasked) {
199     SmallVector<SDValue, 8> Regs(Node->op_begin() + CurOp,
200                                  Node->op_begin() + CurOp + NF);
201     SDValue MaskedOff = createTuple(*CurDAG, Regs, NF, LMUL);
202     Operands.push_back(MaskedOff);
203     CurOp += NF;
204   }
205   Operands.push_back(Node->getOperand(CurOp++)); // Base pointer.
206   if (IsStrided)
207     Operands.push_back(Node->getOperand(CurOp++)); // Stride.
208   if (IsMasked)
209     Operands.push_back(Node->getOperand(CurOp++)); // Mask.
210   Operands.push_back(Node->getOperand(CurOp++));   // VL.
211   Operands.push_back(SEW);
212   Operands.push_back(Node->getOperand(0)); // Chain.
213   const RISCVZvlssegTable::RISCVZvlsseg *P = RISCVZvlssegTable::getPseudo(
214       IntNo, ScalarSize, static_cast<unsigned>(LMUL),
215       static_cast<unsigned>(RISCVVLMUL::LMUL_1));
216   SDNode *Load =
217       CurDAG->getMachineNode(P->Pseudo, DL, MVT::Untyped, MVT::Other, Operands);
218   SDValue SuperReg = SDValue(Load, 0);
219   for (unsigned I = 0; I < NF; ++I)
220     ReplaceUses(SDValue(Node, I),
221                 CurDAG->getTargetExtractSubreg(getSubregIndexByMVT(VT, I), DL,
222                                                VT, SuperReg));
223 
224   ReplaceUses(SDValue(Node, NF), SDValue(Load, 1));
225   CurDAG->RemoveDeadNode(Node);
226 }
227 
228 void RISCVDAGToDAGISel::selectVLSEGFF(SDNode *Node, bool IsMasked) {
229   SDLoc DL(Node);
230   unsigned IntNo = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue();
231   unsigned NF = Node->getNumValues() - 2; // Do not count VL and Chain.
232   MVT VT = Node->getSimpleValueType(0);
233   MVT XLenVT = Subtarget->getXLenVT();
234   unsigned ScalarSize = VT.getScalarSizeInBits();
235   RISCVVLMUL LMUL = getLMUL(VT);
236   SDValue SEW = CurDAG->getTargetConstant(ScalarSize, DL, XLenVT);
237 
238   unsigned CurOp = 2;
239   SmallVector<SDValue, 7> Operands;
240   if (IsMasked) {
241     SmallVector<SDValue, 8> Regs(Node->op_begin() + CurOp,
242                                  Node->op_begin() + CurOp + NF);
243     SDValue MaskedOff = createTuple(*CurDAG, Regs, NF, LMUL);
244     Operands.push_back(MaskedOff);
245     CurOp += NF;
246   }
247   Operands.push_back(Node->getOperand(CurOp++)); // Base pointer.
248   if (IsMasked)
249     Operands.push_back(Node->getOperand(CurOp++)); // Mask.
250   Operands.push_back(Node->getOperand(CurOp++));   // VL.
251   Operands.push_back(SEW);
252   Operands.push_back(Node->getOperand(0)); // Chain.
253   const RISCVZvlssegTable::RISCVZvlsseg *P = RISCVZvlssegTable::getPseudo(
254       IntNo, ScalarSize, static_cast<unsigned>(LMUL),
255       static_cast<unsigned>(RISCVVLMUL::LMUL_1));
256   SDNode *Load = CurDAG->getMachineNode(P->Pseudo, DL, MVT::Untyped, MVT::Other,
257                                         MVT::Glue, Operands);
258   SDNode *ReadVL = CurDAG->getMachineNode(RISCV::PseudoReadVL, DL, XLenVT,
259                                           /*Glue*/ SDValue(Load, 2));
260 
261   SDValue SuperReg = SDValue(Load, 0);
262   for (unsigned I = 0; I < NF; ++I)
263     ReplaceUses(SDValue(Node, I),
264                 CurDAG->getTargetExtractSubreg(getSubregIndexByMVT(VT, I), DL,
265                                                VT, SuperReg));
266 
267   ReplaceUses(SDValue(Node, NF), SDValue(ReadVL, 0));   // VL
268   ReplaceUses(SDValue(Node, NF + 1), SDValue(Load, 1)); // Chain
269   CurDAG->RemoveDeadNode(Node);
270 }
271 
272 void RISCVDAGToDAGISel::selectVLXSEG(SDNode *Node, unsigned IntNo,
273                                      bool IsMasked) {
274   SDLoc DL(Node);
275   unsigned NF = Node->getNumValues() - 1;
276   MVT VT = Node->getSimpleValueType(0);
277   unsigned ScalarSize = VT.getScalarSizeInBits();
278   MVT XLenVT = Subtarget->getXLenVT();
279   RISCVVLMUL LMUL = getLMUL(VT);
280   SDValue SEW = CurDAG->getTargetConstant(ScalarSize, DL, XLenVT);
281   unsigned CurOp = 2;
282   SmallVector<SDValue, 7> Operands;
283   if (IsMasked) {
284     SmallVector<SDValue, 8> Regs(Node->op_begin() + CurOp,
285                                  Node->op_begin() + CurOp + NF);
286     SDValue MaskedOff = createTuple(*CurDAG, Regs, NF, LMUL);
287     Operands.push_back(MaskedOff);
288     CurOp += NF;
289   }
290   Operands.push_back(Node->getOperand(CurOp++)); // Base pointer.
291   Operands.push_back(Node->getOperand(CurOp++)); // Index.
292   MVT IndexVT = Operands.back()->getSimpleValueType(0);
293   if (IsMasked)
294     Operands.push_back(Node->getOperand(CurOp++)); // Mask.
295   Operands.push_back(Node->getOperand(CurOp++));   // VL.
296   Operands.push_back(SEW);
297   Operands.push_back(Node->getOperand(0)); // Chain.
298 
299   RISCVVLMUL IndexLMUL = getLMUL(IndexVT);
300   unsigned IndexScalarSize = IndexVT.getScalarSizeInBits();
301   const RISCVZvlssegTable::RISCVZvlsseg *P = RISCVZvlssegTable::getPseudo(
302       IntNo, IndexScalarSize, static_cast<unsigned>(LMUL),
303       static_cast<unsigned>(IndexLMUL));
304   SDNode *Load =
305       CurDAG->getMachineNode(P->Pseudo, DL, MVT::Untyped, MVT::Other, Operands);
306   SDValue SuperReg = SDValue(Load, 0);
307   for (unsigned I = 0; I < NF; ++I)
308     ReplaceUses(SDValue(Node, I),
309                 CurDAG->getTargetExtractSubreg(getSubregIndexByMVT(VT, I), DL,
310                                                VT, SuperReg));
311 
312   ReplaceUses(SDValue(Node, NF), SDValue(Load, 1));
313   CurDAG->RemoveDeadNode(Node);
314 }
315 
316 void RISCVDAGToDAGISel::selectVSSEG(SDNode *Node, unsigned IntNo, bool IsMasked,
317                                     bool IsStrided) {
318   SDLoc DL(Node);
319   unsigned NF = Node->getNumOperands() - 4;
320   if (IsStrided)
321     NF--;
322   if (IsMasked)
323     NF--;
324   MVT VT = Node->getOperand(2)->getSimpleValueType(0);
325   unsigned ScalarSize = VT.getScalarSizeInBits();
326   MVT XLenVT = Subtarget->getXLenVT();
327   RISCVVLMUL LMUL = getLMUL(VT);
328   SDValue SEW = CurDAG->getTargetConstant(ScalarSize, DL, XLenVT);
329   SmallVector<SDValue, 8> Regs(Node->op_begin() + 2, Node->op_begin() + 2 + NF);
330   SDValue StoreVal = createTuple(*CurDAG, Regs, NF, LMUL);
331   SmallVector<SDValue, 7> Operands;
332   Operands.push_back(StoreVal);
333   unsigned CurOp = 2 + NF;
334   Operands.push_back(Node->getOperand(CurOp++)); // Base pointer.
335   if (IsStrided)
336     Operands.push_back(Node->getOperand(CurOp++)); // Stride.
337   if (IsMasked)
338     Operands.push_back(Node->getOperand(CurOp++)); // Mask.
339   Operands.push_back(Node->getOperand(CurOp++));   // VL.
340   Operands.push_back(SEW);
341   Operands.push_back(Node->getOperand(0)); // Chain.
342   const RISCVZvlssegTable::RISCVZvlsseg *P = RISCVZvlssegTable::getPseudo(
343       IntNo, ScalarSize, static_cast<unsigned>(LMUL),
344       static_cast<unsigned>(RISCVVLMUL::LMUL_1));
345   SDNode *Store =
346       CurDAG->getMachineNode(P->Pseudo, DL, Node->getValueType(0), Operands);
347   ReplaceNode(Node, Store);
348 }
349 
350 void RISCVDAGToDAGISel::selectVSXSEG(SDNode *Node, unsigned IntNo,
351                                      bool IsMasked) {
352   SDLoc DL(Node);
353   unsigned NF = Node->getNumOperands() - 5;
354   if (IsMasked)
355     --NF;
356   MVT VT = Node->getOperand(2)->getSimpleValueType(0);
357   unsigned ScalarSize = VT.getScalarSizeInBits();
358   MVT XLenVT = Subtarget->getXLenVT();
359   RISCVVLMUL LMUL = getLMUL(VT);
360   SDValue SEW = CurDAG->getTargetConstant(ScalarSize, DL, XLenVT);
361   SmallVector<SDValue, 7> Operands;
362   SmallVector<SDValue, 8> Regs(Node->op_begin() + 2, Node->op_begin() + 2 + NF);
363   SDValue StoreVal = createTuple(*CurDAG, Regs, NF, LMUL);
364   Operands.push_back(StoreVal);
365   unsigned CurOp = 2 + NF;
366   Operands.push_back(Node->getOperand(CurOp++)); // Base pointer.
367   Operands.push_back(Node->getOperand(CurOp++)); // Index.
368   MVT IndexVT = Operands.back()->getSimpleValueType(0);
369   if (IsMasked)
370     Operands.push_back(Node->getOperand(CurOp++)); // Mask.
371   Operands.push_back(Node->getOperand(CurOp++));   // VL.
372   Operands.push_back(SEW);
373   Operands.push_back(Node->getOperand(0)); // Chain.
374 
375   RISCVVLMUL IndexLMUL = getLMUL(IndexVT);
376   unsigned IndexScalarSize = IndexVT.getScalarSizeInBits();
377   const RISCVZvlssegTable::RISCVZvlsseg *P = RISCVZvlssegTable::getPseudo(
378       IntNo, IndexScalarSize, static_cast<unsigned>(LMUL),
379       static_cast<unsigned>(IndexLMUL));
380   SDNode *Store =
381       CurDAG->getMachineNode(P->Pseudo, DL, Node->getValueType(0), Operands);
382   ReplaceNode(Node, Store);
383 }
384 
385 void RISCVDAGToDAGISel::Select(SDNode *Node) {
386   // If we have a custom node, we have already selected.
387   if (Node->isMachineOpcode()) {
388     LLVM_DEBUG(dbgs() << "== "; Node->dump(CurDAG); dbgs() << "\n");
389     Node->setNodeId(-1);
390     return;
391   }
392 
393   // Instruction Selection not handled by the auto-generated tablegen selection
394   // should be handled here.
395   unsigned Opcode = Node->getOpcode();
396   MVT XLenVT = Subtarget->getXLenVT();
397   SDLoc DL(Node);
398   MVT VT = Node->getSimpleValueType(0);
399 
400   switch (Opcode) {
401   case ISD::ADD: {
402     // Optimize (add r, imm) to (addi (addi r, imm0) imm1) if applicable. The
403     // immediate must be in specific ranges and have a single use.
404     if (auto *ConstOp = dyn_cast<ConstantSDNode>(Node->getOperand(1))) {
405       if (!(ConstOp->hasOneUse()))
406         break;
407       // The imm must be in range [-4096,-2049] or [2048,4094].
408       int64_t Imm = ConstOp->getSExtValue();
409       if (!(-4096 <= Imm && Imm <= -2049) && !(2048 <= Imm && Imm <= 4094))
410         break;
411       // Break the imm to imm0+imm1.
412       const SDValue ImmOp0 = CurDAG->getTargetConstant(Imm - Imm / 2, DL, VT);
413       const SDValue ImmOp1 = CurDAG->getTargetConstant(Imm / 2, DL, VT);
414       auto *NodeAddi0 = CurDAG->getMachineNode(RISCV::ADDI, DL, VT,
415                                                Node->getOperand(0), ImmOp0);
416       auto *NodeAddi1 = CurDAG->getMachineNode(RISCV::ADDI, DL, VT,
417                                                SDValue(NodeAddi0, 0), ImmOp1);
418       ReplaceNode(Node, NodeAddi1);
419       return;
420     }
421     break;
422   }
423   case ISD::Constant: {
424     auto ConstNode = cast<ConstantSDNode>(Node);
425     if (VT == XLenVT && ConstNode->isNullValue()) {
426       SDValue New =
427           CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, RISCV::X0, XLenVT);
428       ReplaceNode(Node, New.getNode());
429       return;
430     }
431     int64_t Imm = ConstNode->getSExtValue();
432     if (XLenVT == MVT::i64) {
433       ReplaceNode(Node, selectImm(CurDAG, DL, Imm, XLenVT));
434       return;
435     }
436     break;
437   }
438   case ISD::FrameIndex: {
439     SDValue Imm = CurDAG->getTargetConstant(0, DL, XLenVT);
440     int FI = cast<FrameIndexSDNode>(Node)->getIndex();
441     SDValue TFI = CurDAG->getTargetFrameIndex(FI, VT);
442     ReplaceNode(Node, CurDAG->getMachineNode(RISCV::ADDI, DL, VT, TFI, Imm));
443     return;
444   }
445   case ISD::SRL: {
446     // Optimize (srl (and X, 0xffff), C) -> (srli (slli X, 16), 16 + C).
447     // Taking into account that the 0xffff may have had lower bits unset by
448     // SimplifyDemandedBits. This avoids materializing the 0xffff immediate.
449     // This pattern occurs when type legalizing i16 right shifts.
450     // FIXME: This could be extended to other AND masks.
451     auto *N1C = dyn_cast<ConstantSDNode>(Node->getOperand(1));
452     if (N1C) {
453       uint64_t ShAmt = N1C->getZExtValue();
454       SDValue N0 = Node->getOperand(0);
455       if (ShAmt < 16 && N0.getOpcode() == ISD::AND && N0.hasOneUse() &&
456           isa<ConstantSDNode>(N0.getOperand(1))) {
457         uint64_t Mask = N0.getConstantOperandVal(1);
458         Mask |= maskTrailingOnes<uint64_t>(ShAmt);
459         if (Mask == 0xffff) {
460           SDLoc DL(Node);
461           unsigned SLLOpc = Subtarget->is64Bit() ? RISCV::SLLIW : RISCV::SLLI;
462           unsigned SRLOpc = Subtarget->is64Bit() ? RISCV::SRLIW : RISCV::SRLI;
463           SDNode *SLLI =
464               CurDAG->getMachineNode(SLLOpc, DL, VT, N0->getOperand(0),
465                                      CurDAG->getTargetConstant(16, DL, VT));
466           SDNode *SRLI = CurDAG->getMachineNode(
467               SRLOpc, DL, VT, SDValue(SLLI, 0),
468               CurDAG->getTargetConstant(16 + ShAmt, DL, VT));
469           ReplaceNode(Node, SRLI);
470           return;
471         }
472       }
473     }
474 
475     break;
476   }
477   case ISD::INTRINSIC_W_CHAIN: {
478     unsigned IntNo = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue();
479     switch (IntNo) {
480       // By default we do not custom select any intrinsic.
481     default:
482       break;
483 
484     case Intrinsic::riscv_vsetvli:
485     case Intrinsic::riscv_vsetvlimax: {
486       if (!Subtarget->hasStdExtV())
487         break;
488 
489       bool VLMax = IntNo == Intrinsic::riscv_vsetvlimax;
490       unsigned Offset = VLMax ? 2 : 3;
491 
492       assert(Node->getNumOperands() == Offset + 2 &&
493              "Unexpected number of operands");
494 
495       RISCVVSEW VSEW =
496           static_cast<RISCVVSEW>(Node->getConstantOperandVal(Offset) & 0x7);
497       RISCVVLMUL VLMul = static_cast<RISCVVLMUL>(
498           Node->getConstantOperandVal(Offset + 1) & 0x7);
499 
500       unsigned VTypeI = RISCVVType::encodeVTYPE(
501           VLMul, VSEW, /*TailAgnostic*/ true, /*MaskAgnostic*/ false);
502       SDValue VTypeIOp = CurDAG->getTargetConstant(VTypeI, DL, XLenVT);
503 
504       SDValue VLOperand;
505       if (VLMax) {
506         VLOperand = CurDAG->getRegister(RISCV::X0, XLenVT);
507       } else {
508         VLOperand = Node->getOperand(2);
509 
510         if (auto *C = dyn_cast<ConstantSDNode>(VLOperand)) {
511           uint64_t AVL = C->getZExtValue();
512           if (isUInt<5>(AVL)) {
513             SDValue VLImm = CurDAG->getTargetConstant(AVL, DL, XLenVT);
514             ReplaceNode(
515                 Node, CurDAG->getMachineNode(RISCV::PseudoVSETIVLI, DL, XLenVT,
516                                              MVT::Other, VLImm, VTypeIOp,
517                                              /* Chain */ Node->getOperand(0)));
518             return;
519           }
520         }
521       }
522 
523       ReplaceNode(Node,
524                   CurDAG->getMachineNode(RISCV::PseudoVSETVLI, DL, XLenVT,
525                                          MVT::Other, VLOperand, VTypeIOp,
526                                          /* Chain */ Node->getOperand(0)));
527       return;
528     }
529     case Intrinsic::riscv_vlseg2:
530     case Intrinsic::riscv_vlseg3:
531     case Intrinsic::riscv_vlseg4:
532     case Intrinsic::riscv_vlseg5:
533     case Intrinsic::riscv_vlseg6:
534     case Intrinsic::riscv_vlseg7:
535     case Intrinsic::riscv_vlseg8: {
536       selectVLSEG(Node, IntNo, /*IsMasked*/ false, /*IsStrided*/ false);
537       return;
538     }
539     case Intrinsic::riscv_vlseg2_mask:
540     case Intrinsic::riscv_vlseg3_mask:
541     case Intrinsic::riscv_vlseg4_mask:
542     case Intrinsic::riscv_vlseg5_mask:
543     case Intrinsic::riscv_vlseg6_mask:
544     case Intrinsic::riscv_vlseg7_mask:
545     case Intrinsic::riscv_vlseg8_mask: {
546       selectVLSEG(Node, IntNo, /*IsMasked*/ true, /*IsStrided*/ false);
547       return;
548     }
549     case Intrinsic::riscv_vlsseg2:
550     case Intrinsic::riscv_vlsseg3:
551     case Intrinsic::riscv_vlsseg4:
552     case Intrinsic::riscv_vlsseg5:
553     case Intrinsic::riscv_vlsseg6:
554     case Intrinsic::riscv_vlsseg7:
555     case Intrinsic::riscv_vlsseg8: {
556       selectVLSEG(Node, IntNo, /*IsMasked*/ false, /*IsStrided*/ true);
557       return;
558     }
559     case Intrinsic::riscv_vlsseg2_mask:
560     case Intrinsic::riscv_vlsseg3_mask:
561     case Intrinsic::riscv_vlsseg4_mask:
562     case Intrinsic::riscv_vlsseg5_mask:
563     case Intrinsic::riscv_vlsseg6_mask:
564     case Intrinsic::riscv_vlsseg7_mask:
565     case Intrinsic::riscv_vlsseg8_mask: {
566       selectVLSEG(Node, IntNo, /*IsMasked*/ true, /*IsStrided*/ true);
567       return;
568     }
569     case Intrinsic::riscv_vloxseg2:
570     case Intrinsic::riscv_vloxseg3:
571     case Intrinsic::riscv_vloxseg4:
572     case Intrinsic::riscv_vloxseg5:
573     case Intrinsic::riscv_vloxseg6:
574     case Intrinsic::riscv_vloxseg7:
575     case Intrinsic::riscv_vloxseg8:
576     case Intrinsic::riscv_vluxseg2:
577     case Intrinsic::riscv_vluxseg3:
578     case Intrinsic::riscv_vluxseg4:
579     case Intrinsic::riscv_vluxseg5:
580     case Intrinsic::riscv_vluxseg6:
581     case Intrinsic::riscv_vluxseg7:
582     case Intrinsic::riscv_vluxseg8: {
583       selectVLXSEG(Node, IntNo, /*IsMasked*/ false);
584       return;
585     }
586     case Intrinsic::riscv_vloxseg2_mask:
587     case Intrinsic::riscv_vloxseg3_mask:
588     case Intrinsic::riscv_vloxseg4_mask:
589     case Intrinsic::riscv_vloxseg5_mask:
590     case Intrinsic::riscv_vloxseg6_mask:
591     case Intrinsic::riscv_vloxseg7_mask:
592     case Intrinsic::riscv_vloxseg8_mask:
593     case Intrinsic::riscv_vluxseg2_mask:
594     case Intrinsic::riscv_vluxseg3_mask:
595     case Intrinsic::riscv_vluxseg4_mask:
596     case Intrinsic::riscv_vluxseg5_mask:
597     case Intrinsic::riscv_vluxseg6_mask:
598     case Intrinsic::riscv_vluxseg7_mask:
599     case Intrinsic::riscv_vluxseg8_mask: {
600       selectVLXSEG(Node, IntNo, /*IsMasked*/ true);
601       return;
602     }
603     case Intrinsic::riscv_vlseg8ff:
604     case Intrinsic::riscv_vlseg7ff:
605     case Intrinsic::riscv_vlseg6ff:
606     case Intrinsic::riscv_vlseg5ff:
607     case Intrinsic::riscv_vlseg4ff:
608     case Intrinsic::riscv_vlseg3ff:
609     case Intrinsic::riscv_vlseg2ff: {
610       selectVLSEGFF(Node, /*IsMasked*/ false);
611       return;
612     }
613     case Intrinsic::riscv_vlseg8ff_mask:
614     case Intrinsic::riscv_vlseg7ff_mask:
615     case Intrinsic::riscv_vlseg6ff_mask:
616     case Intrinsic::riscv_vlseg5ff_mask:
617     case Intrinsic::riscv_vlseg4ff_mask:
618     case Intrinsic::riscv_vlseg3ff_mask:
619     case Intrinsic::riscv_vlseg2ff_mask: {
620       selectVLSEGFF(Node, /*IsMasked*/ true);
621       return;
622     }
623     }
624     break;
625   }
626   case ISD::INTRINSIC_VOID: {
627     unsigned IntNo = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue();
628     switch (IntNo) {
629     case Intrinsic::riscv_vsseg2:
630     case Intrinsic::riscv_vsseg3:
631     case Intrinsic::riscv_vsseg4:
632     case Intrinsic::riscv_vsseg5:
633     case Intrinsic::riscv_vsseg6:
634     case Intrinsic::riscv_vsseg7:
635     case Intrinsic::riscv_vsseg8: {
636       selectVSSEG(Node, IntNo, /*IsMasked*/ false, /*IsStrided*/ false);
637       return;
638     }
639     case Intrinsic::riscv_vsseg2_mask:
640     case Intrinsic::riscv_vsseg3_mask:
641     case Intrinsic::riscv_vsseg4_mask:
642     case Intrinsic::riscv_vsseg5_mask:
643     case Intrinsic::riscv_vsseg6_mask:
644     case Intrinsic::riscv_vsseg7_mask:
645     case Intrinsic::riscv_vsseg8_mask: {
646       selectVSSEG(Node, IntNo, /*IsMasked*/ true, /*IsStrided*/ false);
647       return;
648     }
649     case Intrinsic::riscv_vssseg2:
650     case Intrinsic::riscv_vssseg3:
651     case Intrinsic::riscv_vssseg4:
652     case Intrinsic::riscv_vssseg5:
653     case Intrinsic::riscv_vssseg6:
654     case Intrinsic::riscv_vssseg7:
655     case Intrinsic::riscv_vssseg8: {
656       selectVSSEG(Node, IntNo, /*IsMasked*/ false, /*IsStrided*/ true);
657       return;
658     }
659     case Intrinsic::riscv_vssseg2_mask:
660     case Intrinsic::riscv_vssseg3_mask:
661     case Intrinsic::riscv_vssseg4_mask:
662     case Intrinsic::riscv_vssseg5_mask:
663     case Intrinsic::riscv_vssseg6_mask:
664     case Intrinsic::riscv_vssseg7_mask:
665     case Intrinsic::riscv_vssseg8_mask: {
666       selectVSSEG(Node, IntNo, /*IsMasked*/ true, /*IsStrided*/ true);
667       return;
668     }
669     case Intrinsic::riscv_vsoxseg2:
670     case Intrinsic::riscv_vsoxseg3:
671     case Intrinsic::riscv_vsoxseg4:
672     case Intrinsic::riscv_vsoxseg5:
673     case Intrinsic::riscv_vsoxseg6:
674     case Intrinsic::riscv_vsoxseg7:
675     case Intrinsic::riscv_vsoxseg8:
676     case Intrinsic::riscv_vsuxseg2:
677     case Intrinsic::riscv_vsuxseg3:
678     case Intrinsic::riscv_vsuxseg4:
679     case Intrinsic::riscv_vsuxseg5:
680     case Intrinsic::riscv_vsuxseg6:
681     case Intrinsic::riscv_vsuxseg7:
682     case Intrinsic::riscv_vsuxseg8: {
683       selectVSXSEG(Node, IntNo, /*IsMasked*/ false);
684       return;
685     }
686     case Intrinsic::riscv_vsoxseg2_mask:
687     case Intrinsic::riscv_vsoxseg3_mask:
688     case Intrinsic::riscv_vsoxseg4_mask:
689     case Intrinsic::riscv_vsoxseg5_mask:
690     case Intrinsic::riscv_vsoxseg6_mask:
691     case Intrinsic::riscv_vsoxseg7_mask:
692     case Intrinsic::riscv_vsoxseg8_mask:
693     case Intrinsic::riscv_vsuxseg2_mask:
694     case Intrinsic::riscv_vsuxseg3_mask:
695     case Intrinsic::riscv_vsuxseg4_mask:
696     case Intrinsic::riscv_vsuxseg5_mask:
697     case Intrinsic::riscv_vsuxseg6_mask:
698     case Intrinsic::riscv_vsuxseg7_mask:
699     case Intrinsic::riscv_vsuxseg8_mask: {
700       selectVSXSEG(Node, IntNo, /*IsMasked*/ true);
701       return;
702     }
703     }
704     break;
705   }
706   case ISD::INSERT_SUBVECTOR: {
707     // Bail when not a "cast" like insert_subvector.
708     if (Node->getConstantOperandVal(2) != 0)
709       break;
710     if (!Node->getOperand(0).isUndef())
711       break;
712 
713     // Bail when normal isel should do the job.
714     MVT InVT = Node->getOperand(1).getSimpleValueType();
715     if (VT.isFixedLengthVector() || InVT.isScalableVector())
716       break;
717 
718     unsigned RegClassID;
719     if (VT.getVectorElementType() == MVT::i1)
720       RegClassID = RISCV::VRRegClassID;
721     else
722       RegClassID = getRegClassIDForLMUL(getLMUL(VT));
723 
724     SDValue V = Node->getOperand(1);
725     SDLoc DL(V);
726     SDValue RC =
727         CurDAG->getTargetConstant(RegClassID, DL, Subtarget->getXLenVT());
728     SDNode *NewNode =
729         CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, DL, VT, V, RC);
730     ReplaceNode(Node, NewNode);
731     return;
732   }
733   case ISD::EXTRACT_SUBVECTOR: {
734     // Bail when not a "cast" like extract_subvector.
735     if (Node->getConstantOperandVal(1) != 0)
736       break;
737 
738     // Bail when normal isel can do the job.
739     MVT InVT = Node->getOperand(0).getSimpleValueType();
740     if (VT.isScalableVector() || InVT.isFixedLengthVector())
741       break;
742 
743     unsigned RegClassID;
744     if (InVT.getVectorElementType() == MVT::i1)
745       RegClassID = RISCV::VRRegClassID;
746     else
747       RegClassID = getRegClassIDForLMUL(getLMUL(InVT));
748 
749     SDValue V = Node->getOperand(0);
750     SDLoc DL(V);
751     SDValue RC =
752         CurDAG->getTargetConstant(RegClassID, DL, Subtarget->getXLenVT());
753     SDNode *NewNode =
754         CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, DL, VT, V, RC);
755     ReplaceNode(Node, NewNode);
756     return;
757   }
758   }
759 
760   // Select the default instruction.
761   SelectCode(Node);
762 }
763 
764 bool RISCVDAGToDAGISel::SelectInlineAsmMemoryOperand(
765     const SDValue &Op, unsigned ConstraintID, std::vector<SDValue> &OutOps) {
766   switch (ConstraintID) {
767   case InlineAsm::Constraint_m:
768     // We just support simple memory operands that have a single address
769     // operand and need no special handling.
770     OutOps.push_back(Op);
771     return false;
772   case InlineAsm::Constraint_A:
773     OutOps.push_back(Op);
774     return false;
775   default:
776     break;
777   }
778 
779   return true;
780 }
781 
782 bool RISCVDAGToDAGISel::SelectAddrFI(SDValue Addr, SDValue &Base) {
783   if (auto *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
784     Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), Subtarget->getXLenVT());
785     return true;
786   }
787   return false;
788 }
789 
790 bool RISCVDAGToDAGISel::SelectBaseAddr(SDValue Addr, SDValue &Base) {
791   // If this is FrameIndex, select it directly. Otherwise just let it get
792   // selected to a register independently.
793   if (auto *FIN = dyn_cast<FrameIndexSDNode>(Addr))
794     Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), Subtarget->getXLenVT());
795   else
796     Base = Addr;
797   return true;
798 }
799 
800 bool RISCVDAGToDAGISel::selectShiftMask(SDValue N, unsigned ShiftWidth,
801                                         SDValue &ShAmt) {
802   // Shift instructions on RISCV only read the lower 5 or 6 bits of the shift
803   // amount. If there is an AND on the shift amount, we can bypass it if it
804   // doesn't affect any of those bits.
805   if (N.getOpcode() == ISD::AND && isa<ConstantSDNode>(N.getOperand(1))) {
806     const APInt &AndMask = N->getConstantOperandAPInt(1);
807 
808     // Since the max shift amount is a power of 2 we can subtract 1 to make a
809     // mask that covers the bits needed to represent all shift amounts.
810     assert(isPowerOf2_32(ShiftWidth) && "Unexpected max shift amount!");
811     APInt ShMask(AndMask.getBitWidth(), ShiftWidth - 1);
812 
813     if (ShMask.isSubsetOf(AndMask)) {
814       ShAmt = N.getOperand(0);
815       return true;
816     }
817 
818     // SimplifyDemandedBits may have optimized the mask so try restoring any
819     // bits that are known zero.
820     KnownBits Known = CurDAG->computeKnownBits(N->getOperand(0));
821     if (ShMask.isSubsetOf(AndMask | Known.Zero)) {
822       ShAmt = N.getOperand(0);
823       return true;
824     }
825   }
826 
827   ShAmt = N;
828   return true;
829 }
830 
831 // Match (srl (and val, mask), imm) where the result would be a
832 // zero-extended 32-bit integer. i.e. the mask is 0xffffffff or the result
833 // is equivalent to this (SimplifyDemandedBits may have removed lower bits
834 // from the mask that aren't necessary due to the right-shifting).
835 bool RISCVDAGToDAGISel::MatchSRLIW(SDNode *N) const {
836   assert(N->getOpcode() == ISD::SRL);
837   assert(N->getOperand(0).getOpcode() == ISD::AND);
838   assert(isa<ConstantSDNode>(N->getOperand(1)));
839   assert(isa<ConstantSDNode>(N->getOperand(0).getOperand(1)));
840 
841   // The IsRV64 predicate is checked after PatFrag predicates so we can get
842   // here even on RV32.
843   if (!Subtarget->is64Bit())
844     return false;
845 
846   SDValue And = N->getOperand(0);
847   uint64_t ShAmt = N->getConstantOperandVal(1);
848   uint64_t Mask = And.getConstantOperandVal(1);
849   return (Mask | maskTrailingOnes<uint64_t>(ShAmt)) == 0xffffffff;
850 }
851 
852 // Check that it is a SLLIUW (Shift Logical Left Immediate Unsigned i32
853 // on RV64).
854 // SLLIUW is the same as SLLI except for the fact that it clears the bits
855 // XLEN-1:32 of the input RS1 before shifting.
856 // A PatFrag has already checked that it has the right structure:
857 //
858 //  (AND (SHL RS1, VC2), VC1)
859 //
860 // We check that VC2, the shamt is less than 32, otherwise the pattern is
861 // exactly the same as SLLI and we give priority to that.
862 // Eventually we check that VC1, the mask used to clear the upper 32 bits
863 // of RS1, is correct:
864 //
865 //  VC1 == (0xFFFFFFFF << VC2)
866 //
867 bool RISCVDAGToDAGISel::MatchSLLIUW(SDNode *N) const {
868   assert(N->getOpcode() == ISD::AND);
869   assert(N->getOperand(0).getOpcode() == ISD::SHL);
870   assert(isa<ConstantSDNode>(N->getOperand(1)));
871   assert(isa<ConstantSDNode>(N->getOperand(0).getOperand(1)));
872 
873   // The IsRV64 predicate is checked after PatFrag predicates so we can get
874   // here even on RV32.
875   if (!Subtarget->is64Bit())
876     return false;
877 
878   SDValue Shl = N->getOperand(0);
879   uint64_t VC1 = N->getConstantOperandVal(1);
880   uint64_t VC2 = Shl.getConstantOperandVal(1);
881 
882   // Immediate range should be enforced by uimm5 predicate.
883   assert(VC2 < 32 && "Unexpected immediate");
884   return (VC1 >> VC2) == UINT64_C(0xFFFFFFFF);
885 }
886 
887 // X0 has special meaning for vsetvl/vsetvli.
888 //  rd | rs1 |   AVL value | Effect on vl
889 //--------------------------------------------------------------
890 // !X0 |  X0 |       VLMAX | Set vl to VLMAX
891 //  X0 |  X0 | Value in vl | Keep current vl, just change vtype.
892 bool RISCVDAGToDAGISel::selectVLOp(SDValue N, SDValue &VL) {
893   // If the VL value is a constant 0, manually select it to an ADDI with 0
894   // immediate to prevent the default selection path from matching it to X0.
895   auto *C = dyn_cast<ConstantSDNode>(N);
896   if (C && C->isNullValue())
897     VL = SDValue(selectImm(CurDAG, SDLoc(N), 0, Subtarget->getXLenVT()), 0);
898   else
899     VL = N;
900 
901   return true;
902 }
903 
904 bool RISCVDAGToDAGISel::selectVSplat(SDValue N, SDValue &SplatVal) {
905   if (N.getOpcode() != ISD::SPLAT_VECTOR &&
906       N.getOpcode() != RISCVISD::SPLAT_VECTOR_I64 &&
907       N.getOpcode() != RISCVISD::VMV_V_X_VL)
908     return false;
909   SplatVal = N.getOperand(0);
910   return true;
911 }
912 
913 bool RISCVDAGToDAGISel::selectVSplatSimm5(SDValue N, SDValue &SplatVal) {
914   if ((N.getOpcode() != ISD::SPLAT_VECTOR &&
915        N.getOpcode() != RISCVISD::SPLAT_VECTOR_I64 &&
916        N.getOpcode() != RISCVISD::VMV_V_X_VL) ||
917       !isa<ConstantSDNode>(N.getOperand(0)))
918     return false;
919 
920   int64_t SplatImm = cast<ConstantSDNode>(N.getOperand(0))->getSExtValue();
921 
922   // Both ISD::SPLAT_VECTOR and RISCVISD::SPLAT_VECTOR_I64 share semantics when
923   // the operand type is wider than the resulting vector element type: an
924   // implicit truncation first takes place. Therefore, perform a manual
925   // truncation/sign-extension in order to ignore any truncated bits and catch
926   // any zero-extended immediate.
927   // For example, we wish to match (i8 -1) -> (XLenVT 255) as a simm5 by first
928   // sign-extending to (XLenVT -1).
929   MVT XLenVT = Subtarget->getXLenVT();
930   assert(XLenVT == N.getOperand(0).getSimpleValueType() &&
931          "Unexpected splat operand type");
932   MVT EltVT = N.getSimpleValueType().getVectorElementType();
933   if (EltVT.bitsLT(XLenVT)) {
934     SplatImm = SignExtend64(SplatImm, EltVT.getSizeInBits());
935   }
936 
937   if (!isInt<5>(SplatImm))
938     return false;
939 
940   SplatVal = CurDAG->getTargetConstant(SplatImm, SDLoc(N), XLenVT);
941   return true;
942 }
943 
944 bool RISCVDAGToDAGISel::selectVSplatUimm5(SDValue N, SDValue &SplatVal) {
945   if ((N.getOpcode() != ISD::SPLAT_VECTOR &&
946        N.getOpcode() != RISCVISD::SPLAT_VECTOR_I64 &&
947        N.getOpcode() != RISCVISD::VMV_V_X_VL) ||
948       !isa<ConstantSDNode>(N.getOperand(0)))
949     return false;
950 
951   int64_t SplatImm = cast<ConstantSDNode>(N.getOperand(0))->getSExtValue();
952 
953   if (!isUInt<5>(SplatImm))
954     return false;
955 
956   SplatVal =
957       CurDAG->getTargetConstant(SplatImm, SDLoc(N), Subtarget->getXLenVT());
958 
959   return true;
960 }
961 
962 bool RISCVDAGToDAGISel::selectRVVSimm5(SDValue N, unsigned Width,
963                                        SDValue &Imm) {
964   if (auto *C = dyn_cast<ConstantSDNode>(N)) {
965     int64_t ImmVal = SignExtend64(C->getSExtValue(), Width);
966 
967     if (!isInt<5>(ImmVal))
968       return false;
969 
970     Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(N), Subtarget->getXLenVT());
971     return true;
972   }
973 
974   return false;
975 }
976 
977 bool RISCVDAGToDAGISel::selectRVVUimm5(SDValue N, unsigned Width,
978                                        SDValue &Imm) {
979   if (auto *C = dyn_cast<ConstantSDNode>(N)) {
980     int64_t ImmVal = C->getSExtValue();
981 
982     if (!isUInt<5>(ImmVal))
983       return false;
984 
985     Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(N), Subtarget->getXLenVT());
986     return true;
987   }
988 
989   return false;
990 }
991 
992 // Merge an ADDI into the offset of a load/store instruction where possible.
993 // (load (addi base, off1), off2) -> (load base, off1+off2)
994 // (store val, (addi base, off1), off2) -> (store val, base, off1+off2)
995 // This is possible when off1+off2 fits a 12-bit immediate.
996 void RISCVDAGToDAGISel::doPeepholeLoadStoreADDI() {
997   SelectionDAG::allnodes_iterator Position(CurDAG->getRoot().getNode());
998   ++Position;
999 
1000   while (Position != CurDAG->allnodes_begin()) {
1001     SDNode *N = &*--Position;
1002     // Skip dead nodes and any non-machine opcodes.
1003     if (N->use_empty() || !N->isMachineOpcode())
1004       continue;
1005 
1006     int OffsetOpIdx;
1007     int BaseOpIdx;
1008 
1009     // Only attempt this optimisation for I-type loads and S-type stores.
1010     switch (N->getMachineOpcode()) {
1011     default:
1012       continue;
1013     case RISCV::LB:
1014     case RISCV::LH:
1015     case RISCV::LW:
1016     case RISCV::LBU:
1017     case RISCV::LHU:
1018     case RISCV::LWU:
1019     case RISCV::LD:
1020     case RISCV::FLH:
1021     case RISCV::FLW:
1022     case RISCV::FLD:
1023       BaseOpIdx = 0;
1024       OffsetOpIdx = 1;
1025       break;
1026     case RISCV::SB:
1027     case RISCV::SH:
1028     case RISCV::SW:
1029     case RISCV::SD:
1030     case RISCV::FSH:
1031     case RISCV::FSW:
1032     case RISCV::FSD:
1033       BaseOpIdx = 1;
1034       OffsetOpIdx = 2;
1035       break;
1036     }
1037 
1038     if (!isa<ConstantSDNode>(N->getOperand(OffsetOpIdx)))
1039       continue;
1040 
1041     SDValue Base = N->getOperand(BaseOpIdx);
1042 
1043     // If the base is an ADDI, we can merge it in to the load/store.
1044     if (!Base.isMachineOpcode() || Base.getMachineOpcode() != RISCV::ADDI)
1045       continue;
1046 
1047     SDValue ImmOperand = Base.getOperand(1);
1048     uint64_t Offset2 = N->getConstantOperandVal(OffsetOpIdx);
1049 
1050     if (auto Const = dyn_cast<ConstantSDNode>(ImmOperand)) {
1051       int64_t Offset1 = Const->getSExtValue();
1052       int64_t CombinedOffset = Offset1 + Offset2;
1053       if (!isInt<12>(CombinedOffset))
1054         continue;
1055       ImmOperand = CurDAG->getTargetConstant(CombinedOffset, SDLoc(ImmOperand),
1056                                              ImmOperand.getValueType());
1057     } else if (auto GA = dyn_cast<GlobalAddressSDNode>(ImmOperand)) {
1058       // If the off1 in (addi base, off1) is a global variable's address (its
1059       // low part, really), then we can rely on the alignment of that variable
1060       // to provide a margin of safety before off1 can overflow the 12 bits.
1061       // Check if off2 falls within that margin; if so off1+off2 can't overflow.
1062       const DataLayout &DL = CurDAG->getDataLayout();
1063       Align Alignment = GA->getGlobal()->getPointerAlignment(DL);
1064       if (Offset2 != 0 && Alignment <= Offset2)
1065         continue;
1066       int64_t Offset1 = GA->getOffset();
1067       int64_t CombinedOffset = Offset1 + Offset2;
1068       ImmOperand = CurDAG->getTargetGlobalAddress(
1069           GA->getGlobal(), SDLoc(ImmOperand), ImmOperand.getValueType(),
1070           CombinedOffset, GA->getTargetFlags());
1071     } else if (auto CP = dyn_cast<ConstantPoolSDNode>(ImmOperand)) {
1072       // Ditto.
1073       Align Alignment = CP->getAlign();
1074       if (Offset2 != 0 && Alignment <= Offset2)
1075         continue;
1076       int64_t Offset1 = CP->getOffset();
1077       int64_t CombinedOffset = Offset1 + Offset2;
1078       ImmOperand = CurDAG->getTargetConstantPool(
1079           CP->getConstVal(), ImmOperand.getValueType(), CP->getAlign(),
1080           CombinedOffset, CP->getTargetFlags());
1081     } else {
1082       continue;
1083     }
1084 
1085     LLVM_DEBUG(dbgs() << "Folding add-immediate into mem-op:\nBase:    ");
1086     LLVM_DEBUG(Base->dump(CurDAG));
1087     LLVM_DEBUG(dbgs() << "\nN: ");
1088     LLVM_DEBUG(N->dump(CurDAG));
1089     LLVM_DEBUG(dbgs() << "\n");
1090 
1091     // Modify the offset operand of the load/store.
1092     if (BaseOpIdx == 0) // Load
1093       CurDAG->UpdateNodeOperands(N, Base.getOperand(0), ImmOperand,
1094                                  N->getOperand(2));
1095     else // Store
1096       CurDAG->UpdateNodeOperands(N, N->getOperand(0), Base.getOperand(0),
1097                                  ImmOperand, N->getOperand(3));
1098 
1099     // The add-immediate may now be dead, in which case remove it.
1100     if (Base.getNode()->use_empty())
1101       CurDAG->RemoveDeadNode(Base.getNode());
1102   }
1103 }
1104 
1105 // This pass converts a legalized DAG into a RISCV-specific DAG, ready
1106 // for instruction scheduling.
1107 FunctionPass *llvm::createRISCVISelDag(RISCVTargetMachine &TM) {
1108   return new RISCVDAGToDAGISel(TM);
1109 }
1110