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