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