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/MathExtras.h"
21 #include "llvm/Support/raw_ostream.h"
22 
23 using namespace llvm;
24 
25 #define DEBUG_TYPE "riscv-isel"
26 
27 void RISCVDAGToDAGISel::PostprocessISelDAG() {
28   doPeepholeLoadStoreADDI();
29 }
30 
31 static SDNode *selectImm(SelectionDAG *CurDAG, const SDLoc &DL, int64_t Imm,
32                          MVT XLenVT) {
33   RISCVMatInt::InstSeq Seq;
34   RISCVMatInt::generateInstSeq(Imm, XLenVT == MVT::i64, Seq);
35 
36   SDNode *Result = nullptr;
37   SDValue SrcReg = CurDAG->getRegister(RISCV::X0, XLenVT);
38   for (RISCVMatInt::Inst &Inst : Seq) {
39     SDValue SDImm = CurDAG->getTargetConstant(Inst.Imm, DL, XLenVT);
40     if (Inst.Opc == RISCV::LUI)
41       Result = CurDAG->getMachineNode(RISCV::LUI, DL, XLenVT, SDImm);
42     else
43       Result = CurDAG->getMachineNode(Inst.Opc, DL, XLenVT, SrcReg, SDImm);
44 
45     // Only the first instruction has X0 as its source.
46     SrcReg = SDValue(Result, 0);
47   }
48 
49   return Result;
50 }
51 
52 void RISCVDAGToDAGISel::Select(SDNode *Node) {
53   // If we have a custom node, we have already selected.
54   if (Node->isMachineOpcode()) {
55     LLVM_DEBUG(dbgs() << "== "; Node->dump(CurDAG); dbgs() << "\n");
56     Node->setNodeId(-1);
57     return;
58   }
59 
60   // Instruction Selection not handled by the auto-generated tablegen selection
61   // should be handled here.
62   unsigned Opcode = Node->getOpcode();
63   MVT XLenVT = Subtarget->getXLenVT();
64   SDLoc DL(Node);
65   EVT VT = Node->getValueType(0);
66 
67   switch (Opcode) {
68   case ISD::ADD: {
69     // Optimize (add r, imm) to (addi (addi r, imm0) imm1) if applicable. The
70     // immediate must be in specific ranges and have a single use.
71     if (auto *ConstOp = dyn_cast<ConstantSDNode>(Node->getOperand(1))) {
72       if (!(ConstOp->hasOneUse()))
73         break;
74       // The imm must be in range [-4096,-2049] or [2048,4094].
75       int64_t Imm = ConstOp->getSExtValue();
76       if (!(-4096 <= Imm && Imm <= -2049) && !(2048 <= Imm && Imm <= 4094))
77         break;
78       // Break the imm to imm0+imm1.
79       EVT VT = Node->getValueType(0);
80       const SDValue ImmOp0 = CurDAG->getTargetConstant(Imm - Imm / 2, DL, VT);
81       const SDValue ImmOp1 = CurDAG->getTargetConstant(Imm / 2, DL, VT);
82       auto *NodeAddi0 = CurDAG->getMachineNode(RISCV::ADDI, DL, VT,
83                                                Node->getOperand(0), ImmOp0);
84       auto *NodeAddi1 = CurDAG->getMachineNode(RISCV::ADDI, DL, VT,
85                                                SDValue(NodeAddi0, 0), ImmOp1);
86       ReplaceNode(Node, NodeAddi1);
87       return;
88     }
89     break;
90   }
91   case ISD::Constant: {
92     auto ConstNode = cast<ConstantSDNode>(Node);
93     if (VT == XLenVT && ConstNode->isNullValue()) {
94       SDValue New =
95           CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, RISCV::X0, XLenVT);
96       ReplaceNode(Node, New.getNode());
97       return;
98     }
99     int64_t Imm = ConstNode->getSExtValue();
100     if (XLenVT == MVT::i64) {
101       ReplaceNode(Node, selectImm(CurDAG, DL, Imm, XLenVT));
102       return;
103     }
104     break;
105   }
106   case ISD::FrameIndex: {
107     SDValue Imm = CurDAG->getTargetConstant(0, DL, XLenVT);
108     int FI = cast<FrameIndexSDNode>(Node)->getIndex();
109     SDValue TFI = CurDAG->getTargetFrameIndex(FI, VT);
110     ReplaceNode(Node, CurDAG->getMachineNode(RISCV::ADDI, DL, VT, TFI, Imm));
111     return;
112   }
113   case ISD::INTRINSIC_W_CHAIN: {
114     unsigned IntNo = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue();
115     switch (IntNo) {
116       // By default we do not custom select any intrinsic.
117     default:
118       break;
119 
120     case Intrinsic::riscv_vsetvli: {
121       if (!Subtarget->hasStdExtV())
122         break;
123 
124       assert(Node->getNumOperands() == 5);
125 
126       RISCVVSEW VSEW =
127           static_cast<RISCVVSEW>(Node->getConstantOperandVal(3) & 0x7);
128       RISCVVLMUL VLMul =
129           static_cast<RISCVVLMUL>(Node->getConstantOperandVal(4) & 0x7);
130 
131       unsigned VTypeI = RISCVVType::encodeVTYPE(
132           VLMul, VSEW, /*TailAgnostic*/ true, /*MaskAgnostic*/ false);
133       SDValue VTypeIOp = CurDAG->getTargetConstant(VTypeI, DL, XLenVT);
134 
135       SDValue VLOperand = Node->getOperand(2);
136       if (auto *C = dyn_cast<ConstantSDNode>(VLOperand)) {
137         if (C->isNullValue()) {
138           VLOperand = SDValue(
139               CurDAG->getMachineNode(RISCV::ADDI, DL, XLenVT,
140                                      CurDAG->getRegister(RISCV::X0, XLenVT),
141                                      CurDAG->getTargetConstant(0, DL, XLenVT)),
142               0);
143         }
144       }
145 
146       ReplaceNode(Node,
147                   CurDAG->getMachineNode(RISCV::PseudoVSETVLI, DL, XLenVT,
148                                          MVT::Other, VLOperand, VTypeIOp,
149                                          /* Chain */ Node->getOperand(0)));
150       return;
151     }
152     case Intrinsic::riscv_vsetvlimax: {
153       if (!Subtarget->hasStdExtV())
154         break;
155 
156       assert(Node->getNumOperands() == 4);
157 
158       RISCVVSEW VSEW =
159           static_cast<RISCVVSEW>(Node->getConstantOperandVal(2) & 0x7);
160       RISCVVLMUL VLMul =
161           static_cast<RISCVVLMUL>(Node->getConstantOperandVal(3) & 0x7);
162 
163       unsigned VTypeI = RISCVVType::encodeVTYPE(
164           VLMul, VSEW, /*TailAgnostic*/ true, /*MaskAgnostic*/ false);
165       SDValue VTypeIOp = CurDAG->getTargetConstant(VTypeI, DL, XLenVT);
166 
167       SDValue VLOperand = CurDAG->getRegister(RISCV::X0, XLenVT);
168       ReplaceNode(Node,
169                   CurDAG->getMachineNode(RISCV::PseudoVSETVLI, DL, XLenVT,
170                                          MVT::Other, VLOperand, VTypeIOp,
171                                          /* Chain */ Node->getOperand(0)));
172       return;
173     }
174     }
175     break;
176   }
177   }
178 
179   // Select the default instruction.
180   SelectCode(Node);
181 }
182 
183 bool RISCVDAGToDAGISel::SelectInlineAsmMemoryOperand(
184     const SDValue &Op, unsigned ConstraintID, std::vector<SDValue> &OutOps) {
185   switch (ConstraintID) {
186   case InlineAsm::Constraint_m:
187     // We just support simple memory operands that have a single address
188     // operand and need no special handling.
189     OutOps.push_back(Op);
190     return false;
191   case InlineAsm::Constraint_A:
192     OutOps.push_back(Op);
193     return false;
194   default:
195     break;
196   }
197 
198   return true;
199 }
200 
201 bool RISCVDAGToDAGISel::SelectAddrFI(SDValue Addr, SDValue &Base) {
202   if (auto FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
203     Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), Subtarget->getXLenVT());
204     return true;
205   }
206   return false;
207 }
208 
209 // Match (srl (and val, mask), imm) where the result would be a
210 // zero-extended 32-bit integer. i.e. the mask is 0xffffffff or the result
211 // is equivalent to this (SimplifyDemandedBits may have removed lower bits
212 // from the mask that aren't necessary due to the right-shifting).
213 bool RISCVDAGToDAGISel::MatchSRLIW(SDNode *N) const {
214   assert(N->getOpcode() == ISD::SRL);
215   assert(N->getOperand(0).getOpcode() == ISD::AND);
216   assert(isa<ConstantSDNode>(N->getOperand(1)));
217   assert(isa<ConstantSDNode>(N->getOperand(0).getOperand(1)));
218 
219   // The IsRV64 predicate is checked after PatFrag predicates so we can get
220   // here even on RV32.
221   if (!Subtarget->is64Bit())
222     return false;
223 
224   SDValue And = N->getOperand(0);
225   uint64_t ShAmt = N->getConstantOperandVal(1);
226   uint64_t Mask = And.getConstantOperandVal(1);
227   return (Mask | maskTrailingOnes<uint64_t>(ShAmt)) == 0xffffffff;
228 }
229 
230 // Check that it is a SLOI (Shift Left Ones Immediate). A PatFrag has already
231 // determined it has the right structure:
232 //
233 //  (OR (SHL RS1, VC2), VC1)
234 //
235 // Check that VC1, the mask used to fill with ones, is compatible
236 // with VC2, the shamt:
237 //
238 //  VC1 == maskTrailingOnes(VC2)
239 //
240 bool RISCVDAGToDAGISel::MatchSLOI(SDNode *N) const {
241   assert(N->getOpcode() == ISD::OR);
242   assert(N->getOperand(0).getOpcode() == ISD::SHL);
243   assert(isa<ConstantSDNode>(N->getOperand(1)));
244   assert(isa<ConstantSDNode>(N->getOperand(0).getOperand(1)));
245 
246   SDValue Shl = N->getOperand(0);
247   if (Subtarget->is64Bit()) {
248     uint64_t VC1 = N->getConstantOperandVal(1);
249     uint64_t VC2 = Shl.getConstantOperandVal(1);
250     return VC1 == maskTrailingOnes<uint64_t>(VC2);
251   }
252 
253   uint32_t VC1 = N->getConstantOperandVal(1);
254   uint32_t VC2 = Shl.getConstantOperandVal(1);
255   return VC1 == maskTrailingOnes<uint32_t>(VC2);
256 }
257 
258 // Check that it is a SROI (Shift Right Ones Immediate). A PatFrag has already
259 // determined it has the right structure:
260 //
261 //  (OR (SRL RS1, VC2), VC1)
262 //
263 // Check that VC1, the mask used to fill with ones, is compatible
264 // with VC2, the shamt:
265 //
266 //  VC1 == maskLeadingOnes(VC2)
267 //
268 bool RISCVDAGToDAGISel::MatchSROI(SDNode *N) const {
269   assert(N->getOpcode() == ISD::OR);
270   assert(N->getOperand(0).getOpcode() == ISD::SRL);
271   assert(isa<ConstantSDNode>(N->getOperand(1)));
272   assert(isa<ConstantSDNode>(N->getOperand(0).getOperand(1)));
273 
274   SDValue Srl = N->getOperand(0);
275   if (Subtarget->is64Bit()) {
276     uint64_t VC1 = N->getConstantOperandVal(1);
277     uint64_t VC2 = Srl.getConstantOperandVal(1);
278     return VC1 == maskLeadingOnes<uint64_t>(VC2);
279   }
280 
281   uint32_t VC1 = N->getConstantOperandVal(1);
282   uint32_t VC2 = Srl.getConstantOperandVal(1);
283   return VC1 == maskLeadingOnes<uint32_t>(VC2);
284 }
285 
286 // Check that it is a SROIW (Shift Right Ones Immediate i32 on RV64). A PatFrag
287 // has already determined it has the right structure:
288 //
289 //  (OR (SRL RS1, VC2), VC1)
290 //
291 // and then we check that VC1, the mask used to fill with ones, is compatible
292 // with VC2, the shamt:
293 //
294 //  VC2 < 32
295 //  VC1 == maskTrailingZeros<uint64_t>(32 - VC2)
296 //
297 bool RISCVDAGToDAGISel::MatchSROIW(SDNode *N) const {
298   assert(N->getOpcode() == ISD::OR);
299   assert(N->getOperand(0).getOpcode() == ISD::SRL);
300   assert(isa<ConstantSDNode>(N->getOperand(1)));
301   assert(isa<ConstantSDNode>(N->getOperand(0).getOperand(1)));
302 
303   // The IsRV64 predicate is checked after PatFrag predicates so we can get
304   // here even on RV32.
305   if (!Subtarget->is64Bit())
306     return false;
307 
308   SDValue Srl = N->getOperand(0);
309   uint64_t VC1 = N->getConstantOperandVal(1);
310   uint64_t VC2 = Srl.getConstantOperandVal(1);
311 
312   // Immediate range should be enforced by uimm5 predicate.
313   assert(VC2 < 32 && "Unexpected immediate");
314   return VC1 == maskTrailingZeros<uint64_t>(32 - VC2);
315 }
316 
317 // Check that it is a SLLIUW (Shift Logical Left Immediate Unsigned i32
318 // on RV64).
319 // SLLIUW is the same as SLLI except for the fact that it clears the bits
320 // XLEN-1:32 of the input RS1 before shifting.
321 // A PatFrag has already checked that it has the right structure:
322 //
323 //  (AND (SHL RS1, VC2), VC1)
324 //
325 // We check that VC2, the shamt is less than 32, otherwise the pattern is
326 // exactly the same as SLLI and we give priority to that.
327 // Eventually we check that VC1, the mask used to clear the upper 32 bits
328 // of RS1, is correct:
329 //
330 //  VC1 == (0xFFFFFFFF << VC2)
331 //
332 bool RISCVDAGToDAGISel::MatchSLLIUW(SDNode *N) const {
333   assert(N->getOpcode() == ISD::AND);
334   assert(N->getOperand(0).getOpcode() == ISD::SHL);
335   assert(isa<ConstantSDNode>(N->getOperand(1)));
336   assert(isa<ConstantSDNode>(N->getOperand(0).getOperand(1)));
337 
338   // The IsRV64 predicate is checked after PatFrag predicates so we can get
339   // here even on RV32.
340   if (!Subtarget->is64Bit())
341     return false;
342 
343   SDValue Shl = N->getOperand(0);
344   uint64_t VC1 = N->getConstantOperandVal(1);
345   uint64_t VC2 = Shl.getConstantOperandVal(1);
346 
347   // Immediate range should be enforced by uimm5 predicate.
348   assert(VC2 < 32 && "Unexpected immediate");
349   return VC1 == ((uint64_t)0xFFFFFFFF << VC2);
350 }
351 
352 bool RISCVDAGToDAGISel::selectVSplat(SDValue N, SDValue &SplatVal) {
353   if (N.getOpcode() != ISD::SPLAT_VECTOR &&
354       N.getOpcode() != RISCVISD::SPLAT_VECTOR_I64)
355     return false;
356   SplatVal = N.getOperand(0);
357   return true;
358 }
359 
360 bool RISCVDAGToDAGISel::selectVSplatSimm5(SDValue N, SDValue &SplatVal) {
361   if ((N.getOpcode() != ISD::SPLAT_VECTOR &&
362        N.getOpcode() != RISCVISD::SPLAT_VECTOR_I64) ||
363       !isa<ConstantSDNode>(N.getOperand(0)))
364     return false;
365 
366   int64_t SplatImm = cast<ConstantSDNode>(N.getOperand(0))->getSExtValue();
367 
368   // Both ISD::SPLAT_VECTOR and RISCVISD::SPLAT_VECTOR_I64 share semantics when
369   // the operand type is wider than the resulting vector element type: an
370   // implicit truncation first takes place. Therefore, perform a manual
371   // truncation/sign-extension in order to ignore any truncated bits and catch
372   // any zero-extended immediate.
373   // For example, we wish to match (i8 -1) -> (XLenVT 255) as a simm5 by first
374   // sign-extending to (XLenVT -1).
375   auto XLenVT = Subtarget->getXLenVT();
376   assert(XLenVT == N.getOperand(0).getSimpleValueType() &&
377          "Unexpected splat operand type");
378   auto EltVT = N.getValueType().getVectorElementType();
379   if (EltVT.bitsLT(XLenVT)) {
380     SplatImm = SignExtend64(SplatImm, EltVT.getSizeInBits());
381   }
382 
383   if (!isInt<5>(SplatImm))
384     return false;
385 
386   SplatVal = CurDAG->getTargetConstant(SplatImm, SDLoc(N), XLenVT);
387   return true;
388 }
389 
390 bool RISCVDAGToDAGISel::selectVSplatUimm5(SDValue N, SDValue &SplatVal) {
391   if ((N.getOpcode() != ISD::SPLAT_VECTOR &&
392        N.getOpcode() != RISCVISD::SPLAT_VECTOR_I64) ||
393       !isa<ConstantSDNode>(N.getOperand(0)))
394     return false;
395 
396   int64_t SplatImm = cast<ConstantSDNode>(N.getOperand(0))->getSExtValue();
397 
398   if (!isUInt<5>(SplatImm))
399     return false;
400 
401   SplatVal =
402       CurDAG->getTargetConstant(SplatImm, SDLoc(N), Subtarget->getXLenVT());
403 
404   return true;
405 }
406 
407 // Merge an ADDI into the offset of a load/store instruction where possible.
408 // (load (addi base, off1), off2) -> (load base, off1+off2)
409 // (store val, (addi base, off1), off2) -> (store val, base, off1+off2)
410 // This is possible when off1+off2 fits a 12-bit immediate.
411 void RISCVDAGToDAGISel::doPeepholeLoadStoreADDI() {
412   SelectionDAG::allnodes_iterator Position(CurDAG->getRoot().getNode());
413   ++Position;
414 
415   while (Position != CurDAG->allnodes_begin()) {
416     SDNode *N = &*--Position;
417     // Skip dead nodes and any non-machine opcodes.
418     if (N->use_empty() || !N->isMachineOpcode())
419       continue;
420 
421     int OffsetOpIdx;
422     int BaseOpIdx;
423 
424     // Only attempt this optimisation for I-type loads and S-type stores.
425     switch (N->getMachineOpcode()) {
426     default:
427       continue;
428     case RISCV::LB:
429     case RISCV::LH:
430     case RISCV::LW:
431     case RISCV::LBU:
432     case RISCV::LHU:
433     case RISCV::LWU:
434     case RISCV::LD:
435     case RISCV::FLH:
436     case RISCV::FLW:
437     case RISCV::FLD:
438       BaseOpIdx = 0;
439       OffsetOpIdx = 1;
440       break;
441     case RISCV::SB:
442     case RISCV::SH:
443     case RISCV::SW:
444     case RISCV::SD:
445     case RISCV::FSH:
446     case RISCV::FSW:
447     case RISCV::FSD:
448       BaseOpIdx = 1;
449       OffsetOpIdx = 2;
450       break;
451     }
452 
453     if (!isa<ConstantSDNode>(N->getOperand(OffsetOpIdx)))
454       continue;
455 
456     SDValue Base = N->getOperand(BaseOpIdx);
457 
458     // If the base is an ADDI, we can merge it in to the load/store.
459     if (!Base.isMachineOpcode() || Base.getMachineOpcode() != RISCV::ADDI)
460       continue;
461 
462     SDValue ImmOperand = Base.getOperand(1);
463     uint64_t Offset2 = N->getConstantOperandVal(OffsetOpIdx);
464 
465     if (auto Const = dyn_cast<ConstantSDNode>(ImmOperand)) {
466       int64_t Offset1 = Const->getSExtValue();
467       int64_t CombinedOffset = Offset1 + Offset2;
468       if (!isInt<12>(CombinedOffset))
469         continue;
470       ImmOperand = CurDAG->getTargetConstant(CombinedOffset, SDLoc(ImmOperand),
471                                              ImmOperand.getValueType());
472     } else if (auto GA = dyn_cast<GlobalAddressSDNode>(ImmOperand)) {
473       // If the off1 in (addi base, off1) is a global variable's address (its
474       // low part, really), then we can rely on the alignment of that variable
475       // to provide a margin of safety before off1 can overflow the 12 bits.
476       // Check if off2 falls within that margin; if so off1+off2 can't overflow.
477       const DataLayout &DL = CurDAG->getDataLayout();
478       Align Alignment = GA->getGlobal()->getPointerAlignment(DL);
479       if (Offset2 != 0 && Alignment <= Offset2)
480         continue;
481       int64_t Offset1 = GA->getOffset();
482       int64_t CombinedOffset = Offset1 + Offset2;
483       ImmOperand = CurDAG->getTargetGlobalAddress(
484           GA->getGlobal(), SDLoc(ImmOperand), ImmOperand.getValueType(),
485           CombinedOffset, GA->getTargetFlags());
486     } else if (auto CP = dyn_cast<ConstantPoolSDNode>(ImmOperand)) {
487       // Ditto.
488       Align Alignment = CP->getAlign();
489       if (Offset2 != 0 && Alignment <= Offset2)
490         continue;
491       int64_t Offset1 = CP->getOffset();
492       int64_t CombinedOffset = Offset1 + Offset2;
493       ImmOperand = CurDAG->getTargetConstantPool(
494           CP->getConstVal(), ImmOperand.getValueType(), CP->getAlign(),
495           CombinedOffset, CP->getTargetFlags());
496     } else {
497       continue;
498     }
499 
500     LLVM_DEBUG(dbgs() << "Folding add-immediate into mem-op:\nBase:    ");
501     LLVM_DEBUG(Base->dump(CurDAG));
502     LLVM_DEBUG(dbgs() << "\nN: ");
503     LLVM_DEBUG(N->dump(CurDAG));
504     LLVM_DEBUG(dbgs() << "\n");
505 
506     // Modify the offset operand of the load/store.
507     if (BaseOpIdx == 0) // Load
508       CurDAG->UpdateNodeOperands(N, Base.getOperand(0), ImmOperand,
509                                  N->getOperand(2));
510     else // Store
511       CurDAG->UpdateNodeOperands(N, N->getOperand(0), Base.getOperand(0),
512                                  ImmOperand, N->getOperand(3));
513 
514     // The add-immediate may now be dead, in which case remove it.
515     if (Base.getNode()->use_empty())
516       CurDAG->RemoveDeadNode(Base.getNode());
517   }
518 }
519 
520 // This pass converts a legalized DAG into a RISCV-specific DAG, ready
521 // for instruction scheduling.
522 FunctionPass *llvm::createRISCVISelDag(RISCVTargetMachine &TM) {
523   return new RISCVDAGToDAGISel(TM);
524 }
525