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