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