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 "RISCVMachineFunctionInfo.h" 18 #include "llvm/CodeGen/MachineFrameInfo.h" 19 #include "llvm/IR/IntrinsicsRISCV.h" 20 #include "llvm/Support/Alignment.h" 21 #include "llvm/Support/Debug.h" 22 #include "llvm/Support/KnownBits.h" 23 #include "llvm/Support/MathExtras.h" 24 #include "llvm/Support/raw_ostream.h" 25 26 using namespace llvm; 27 28 #define DEBUG_TYPE "riscv-isel" 29 30 namespace llvm { 31 namespace RISCV { 32 #define GET_RISCVVSSEGTable_IMPL 33 #define GET_RISCVVLSEGTable_IMPL 34 #define GET_RISCVVLXSEGTable_IMPL 35 #define GET_RISCVVSXSEGTable_IMPL 36 #define GET_RISCVVLETable_IMPL 37 #define GET_RISCVVSETable_IMPL 38 #define GET_RISCVVLXTable_IMPL 39 #define GET_RISCVVSXTable_IMPL 40 #include "RISCVGenSearchableTables.inc" 41 } // namespace RISCV 42 } // namespace llvm 43 44 void RISCVDAGToDAGISel::PreprocessISelDAG() { 45 for (SelectionDAG::allnodes_iterator I = CurDAG->allnodes_begin(), 46 E = CurDAG->allnodes_end(); 47 I != E;) { 48 SDNode *N = &*I++; // Preincrement iterator to avoid invalidation issues. 49 50 // Lower SPLAT_VECTOR_SPLIT_I64 to two scalar stores and a stride 0 vector 51 // load. Done after lowering and combining so that we have a chance to 52 // optimize this to VMV_V_X_VL when the upper bits aren't needed. 53 if (N->getOpcode() != RISCVISD::SPLAT_VECTOR_SPLIT_I64_VL) 54 continue; 55 56 assert(N->getNumOperands() == 3 && "Unexpected number of operands"); 57 MVT VT = N->getSimpleValueType(0); 58 SDValue Lo = N->getOperand(0); 59 SDValue Hi = N->getOperand(1); 60 SDValue VL = N->getOperand(2); 61 assert(VT.getVectorElementType() == MVT::i64 && VT.isScalableVector() && 62 Lo.getValueType() == MVT::i32 && Hi.getValueType() == MVT::i32 && 63 "Unexpected VTs!"); 64 MachineFunction &MF = CurDAG->getMachineFunction(); 65 RISCVMachineFunctionInfo *FuncInfo = MF.getInfo<RISCVMachineFunctionInfo>(); 66 SDLoc DL(N); 67 68 // We use the same frame index we use for moving two i32s into 64-bit FPR. 69 // This is an analogous operation. 70 int FI = FuncInfo->getMoveF64FrameIndex(MF); 71 MachinePointerInfo MPI = MachinePointerInfo::getFixedStack(MF, FI); 72 const TargetLowering &TLI = CurDAG->getTargetLoweringInfo(); 73 SDValue StackSlot = 74 CurDAG->getFrameIndex(FI, TLI.getPointerTy(CurDAG->getDataLayout())); 75 76 SDValue Chain = CurDAG->getEntryNode(); 77 Lo = CurDAG->getStore(Chain, DL, Lo, StackSlot, MPI, Align(8)); 78 79 SDValue OffsetSlot = 80 CurDAG->getMemBasePlusOffset(StackSlot, TypeSize::Fixed(4), DL); 81 Hi = CurDAG->getStore(Chain, DL, Hi, OffsetSlot, MPI.getWithOffset(4), 82 Align(8)); 83 84 Chain = CurDAG->getNode(ISD::TokenFactor, DL, MVT::Other, Lo, Hi); 85 86 SDVTList VTs = CurDAG->getVTList({VT, MVT::Other}); 87 SDValue IntID = 88 CurDAG->getTargetConstant(Intrinsic::riscv_vlse, DL, MVT::i64); 89 SDValue Ops[] = {Chain, IntID, StackSlot, 90 CurDAG->getRegister(RISCV::X0, MVT::i64), VL}; 91 92 SDValue Result = CurDAG->getMemIntrinsicNode( 93 ISD::INTRINSIC_W_CHAIN, DL, VTs, Ops, MVT::i64, MPI, Align(8), 94 MachineMemOperand::MOLoad); 95 96 // We're about to replace all uses of the SPLAT_VECTOR_SPLIT_I64 with the 97 // vlse we created. This will cause general havok on the dag because 98 // anything below the conversion could be folded into other existing nodes. 99 // To avoid invalidating 'I', back it up to the convert node. 100 --I; 101 CurDAG->ReplaceAllUsesOfValueWith(SDValue(N, 0), Result); 102 103 // Now that we did that, the node is dead. Increment the iterator to the 104 // next node to process, then delete N. 105 ++I; 106 CurDAG->DeleteNode(N); 107 } 108 } 109 110 void RISCVDAGToDAGISel::PostprocessISelDAG() { 111 SelectionDAG::allnodes_iterator Position = CurDAG->allnodes_end(); 112 113 bool MadeChange = false; 114 while (Position != CurDAG->allnodes_begin()) { 115 SDNode *N = &*--Position; 116 // Skip dead nodes and any non-machine opcodes. 117 if (N->use_empty() || !N->isMachineOpcode()) 118 continue; 119 120 MadeChange |= doPeepholeSExtW(N); 121 MadeChange |= doPeepholeLoadStoreADDI(N); 122 } 123 124 if (MadeChange) 125 CurDAG->RemoveDeadNodes(); 126 } 127 128 static SDNode *selectImm(SelectionDAG *CurDAG, const SDLoc &DL, int64_t Imm, 129 const RISCVSubtarget &Subtarget) { 130 MVT XLenVT = Subtarget.getXLenVT(); 131 RISCVMatInt::InstSeq Seq = 132 RISCVMatInt::generateInstSeq(Imm, Subtarget.getFeatureBits()); 133 134 SDNode *Result = nullptr; 135 SDValue SrcReg = CurDAG->getRegister(RISCV::X0, XLenVT); 136 for (RISCVMatInt::Inst &Inst : Seq) { 137 SDValue SDImm = CurDAG->getTargetConstant(Inst.Imm, DL, XLenVT); 138 if (Inst.Opc == RISCV::LUI) 139 Result = CurDAG->getMachineNode(RISCV::LUI, DL, XLenVT, SDImm); 140 else if (Inst.Opc == RISCV::ADDUW) 141 Result = CurDAG->getMachineNode(RISCV::ADDUW, DL, XLenVT, SrcReg, 142 CurDAG->getRegister(RISCV::X0, XLenVT)); 143 else 144 Result = CurDAG->getMachineNode(Inst.Opc, DL, XLenVT, SrcReg, SDImm); 145 146 // Only the first instruction has X0 as its source. 147 SrcReg = SDValue(Result, 0); 148 } 149 150 return Result; 151 } 152 153 static SDValue createTupleImpl(SelectionDAG &CurDAG, ArrayRef<SDValue> Regs, 154 unsigned RegClassID, unsigned SubReg0) { 155 assert(Regs.size() >= 2 && Regs.size() <= 8); 156 157 SDLoc DL(Regs[0]); 158 SmallVector<SDValue, 8> Ops; 159 160 Ops.push_back(CurDAG.getTargetConstant(RegClassID, DL, MVT::i32)); 161 162 for (unsigned I = 0; I < Regs.size(); ++I) { 163 Ops.push_back(Regs[I]); 164 Ops.push_back(CurDAG.getTargetConstant(SubReg0 + I, DL, MVT::i32)); 165 } 166 SDNode *N = 167 CurDAG.getMachineNode(TargetOpcode::REG_SEQUENCE, DL, MVT::Untyped, Ops); 168 return SDValue(N, 0); 169 } 170 171 static SDValue createM1Tuple(SelectionDAG &CurDAG, ArrayRef<SDValue> Regs, 172 unsigned NF) { 173 static const unsigned RegClassIDs[] = { 174 RISCV::VRN2M1RegClassID, RISCV::VRN3M1RegClassID, RISCV::VRN4M1RegClassID, 175 RISCV::VRN5M1RegClassID, RISCV::VRN6M1RegClassID, RISCV::VRN7M1RegClassID, 176 RISCV::VRN8M1RegClassID}; 177 178 return createTupleImpl(CurDAG, Regs, RegClassIDs[NF - 2], RISCV::sub_vrm1_0); 179 } 180 181 static SDValue createM2Tuple(SelectionDAG &CurDAG, ArrayRef<SDValue> Regs, 182 unsigned NF) { 183 static const unsigned RegClassIDs[] = {RISCV::VRN2M2RegClassID, 184 RISCV::VRN3M2RegClassID, 185 RISCV::VRN4M2RegClassID}; 186 187 return createTupleImpl(CurDAG, Regs, RegClassIDs[NF - 2], RISCV::sub_vrm2_0); 188 } 189 190 static SDValue createM4Tuple(SelectionDAG &CurDAG, ArrayRef<SDValue> Regs, 191 unsigned NF) { 192 return createTupleImpl(CurDAG, Regs, RISCV::VRN2M4RegClassID, 193 RISCV::sub_vrm4_0); 194 } 195 196 static SDValue createTuple(SelectionDAG &CurDAG, ArrayRef<SDValue> Regs, 197 unsigned NF, RISCVII::VLMUL LMUL) { 198 switch (LMUL) { 199 default: 200 llvm_unreachable("Invalid LMUL."); 201 case RISCVII::VLMUL::LMUL_F8: 202 case RISCVII::VLMUL::LMUL_F4: 203 case RISCVII::VLMUL::LMUL_F2: 204 case RISCVII::VLMUL::LMUL_1: 205 return createM1Tuple(CurDAG, Regs, NF); 206 case RISCVII::VLMUL::LMUL_2: 207 return createM2Tuple(CurDAG, Regs, NF); 208 case RISCVII::VLMUL::LMUL_4: 209 return createM4Tuple(CurDAG, Regs, NF); 210 } 211 } 212 213 void RISCVDAGToDAGISel::addVectorLoadStoreOperands( 214 SDNode *Node, unsigned Log2SEW, const SDLoc &DL, unsigned CurOp, 215 bool IsMasked, bool IsStridedOrIndexed, SmallVectorImpl<SDValue> &Operands, 216 MVT *IndexVT) { 217 SDValue Chain = Node->getOperand(0); 218 SDValue Glue; 219 220 SDValue Base; 221 SelectBaseAddr(Node->getOperand(CurOp++), Base); 222 Operands.push_back(Base); // Base pointer. 223 224 if (IsStridedOrIndexed) { 225 Operands.push_back(Node->getOperand(CurOp++)); // Index. 226 if (IndexVT) 227 *IndexVT = Operands.back()->getSimpleValueType(0); 228 } 229 230 if (IsMasked) { 231 // Mask needs to be copied to V0. 232 SDValue Mask = Node->getOperand(CurOp++); 233 Chain = CurDAG->getCopyToReg(Chain, DL, RISCV::V0, Mask, SDValue()); 234 Glue = Chain.getValue(1); 235 Operands.push_back(CurDAG->getRegister(RISCV::V0, Mask.getValueType())); 236 } 237 SDValue VL; 238 selectVLOp(Node->getOperand(CurOp++), VL); 239 Operands.push_back(VL); 240 241 MVT XLenVT = Subtarget->getXLenVT(); 242 SDValue SEWOp = CurDAG->getTargetConstant(Log2SEW, DL, XLenVT); 243 Operands.push_back(SEWOp); 244 245 Operands.push_back(Chain); // Chain. 246 if (Glue) 247 Operands.push_back(Glue); 248 } 249 250 void RISCVDAGToDAGISel::selectVLSEG(SDNode *Node, bool IsMasked, 251 bool IsStrided) { 252 SDLoc DL(Node); 253 unsigned NF = Node->getNumValues() - 1; 254 MVT VT = Node->getSimpleValueType(0); 255 unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits()); 256 RISCVII::VLMUL LMUL = RISCVTargetLowering::getLMUL(VT); 257 258 unsigned CurOp = 2; 259 SmallVector<SDValue, 8> Operands; 260 if (IsMasked) { 261 SmallVector<SDValue, 8> Regs(Node->op_begin() + CurOp, 262 Node->op_begin() + CurOp + NF); 263 SDValue MaskedOff = createTuple(*CurDAG, Regs, NF, LMUL); 264 Operands.push_back(MaskedOff); 265 CurOp += NF; 266 } 267 268 addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked, IsStrided, 269 Operands); 270 271 const RISCV::VLSEGPseudo *P = 272 RISCV::getVLSEGPseudo(NF, IsMasked, IsStrided, /*FF*/ false, Log2SEW, 273 static_cast<unsigned>(LMUL)); 274 MachineSDNode *Load = 275 CurDAG->getMachineNode(P->Pseudo, DL, MVT::Untyped, MVT::Other, Operands); 276 277 if (auto *MemOp = dyn_cast<MemSDNode>(Node)) 278 CurDAG->setNodeMemRefs(Load, {MemOp->getMemOperand()}); 279 280 SDValue SuperReg = SDValue(Load, 0); 281 for (unsigned I = 0; I < NF; ++I) { 282 unsigned SubRegIdx = RISCVTargetLowering::getSubregIndexByMVT(VT, I); 283 ReplaceUses(SDValue(Node, I), 284 CurDAG->getTargetExtractSubreg(SubRegIdx, DL, VT, SuperReg)); 285 } 286 287 ReplaceUses(SDValue(Node, NF), SDValue(Load, 1)); 288 CurDAG->RemoveDeadNode(Node); 289 } 290 291 void RISCVDAGToDAGISel::selectVLSEGFF(SDNode *Node, bool IsMasked) { 292 SDLoc DL(Node); 293 unsigned NF = Node->getNumValues() - 2; // Do not count VL and Chain. 294 MVT VT = Node->getSimpleValueType(0); 295 MVT XLenVT = Subtarget->getXLenVT(); 296 unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits()); 297 RISCVII::VLMUL LMUL = RISCVTargetLowering::getLMUL(VT); 298 299 unsigned CurOp = 2; 300 SmallVector<SDValue, 7> Operands; 301 if (IsMasked) { 302 SmallVector<SDValue, 8> Regs(Node->op_begin() + CurOp, 303 Node->op_begin() + CurOp + NF); 304 SDValue MaskedOff = createTuple(*CurDAG, Regs, NF, LMUL); 305 Operands.push_back(MaskedOff); 306 CurOp += NF; 307 } 308 309 addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked, 310 /*IsStridedOrIndexed*/ false, Operands); 311 312 const RISCV::VLSEGPseudo *P = 313 RISCV::getVLSEGPseudo(NF, IsMasked, /*Strided*/ false, /*FF*/ true, 314 Log2SEW, static_cast<unsigned>(LMUL)); 315 MachineSDNode *Load = CurDAG->getMachineNode(P->Pseudo, DL, MVT::Untyped, 316 MVT::Other, MVT::Glue, Operands); 317 SDNode *ReadVL = CurDAG->getMachineNode(RISCV::PseudoReadVL, DL, XLenVT, 318 /*Glue*/ SDValue(Load, 2)); 319 320 if (auto *MemOp = dyn_cast<MemSDNode>(Node)) 321 CurDAG->setNodeMemRefs(Load, {MemOp->getMemOperand()}); 322 323 SDValue SuperReg = SDValue(Load, 0); 324 for (unsigned I = 0; I < NF; ++I) { 325 unsigned SubRegIdx = RISCVTargetLowering::getSubregIndexByMVT(VT, I); 326 ReplaceUses(SDValue(Node, I), 327 CurDAG->getTargetExtractSubreg(SubRegIdx, DL, VT, SuperReg)); 328 } 329 330 ReplaceUses(SDValue(Node, NF), SDValue(ReadVL, 0)); // VL 331 ReplaceUses(SDValue(Node, NF + 1), SDValue(Load, 1)); // Chain 332 CurDAG->RemoveDeadNode(Node); 333 } 334 335 void RISCVDAGToDAGISel::selectVLXSEG(SDNode *Node, bool IsMasked, 336 bool IsOrdered) { 337 SDLoc DL(Node); 338 unsigned NF = Node->getNumValues() - 1; 339 MVT VT = Node->getSimpleValueType(0); 340 unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits()); 341 RISCVII::VLMUL LMUL = RISCVTargetLowering::getLMUL(VT); 342 343 unsigned CurOp = 2; 344 SmallVector<SDValue, 8> Operands; 345 if (IsMasked) { 346 SmallVector<SDValue, 8> Regs(Node->op_begin() + CurOp, 347 Node->op_begin() + CurOp + NF); 348 SDValue MaskedOff = createTuple(*CurDAG, Regs, NF, LMUL); 349 Operands.push_back(MaskedOff); 350 CurOp += NF; 351 } 352 353 MVT IndexVT; 354 addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked, 355 /*IsStridedOrIndexed*/ true, Operands, &IndexVT); 356 357 assert(VT.getVectorElementCount() == IndexVT.getVectorElementCount() && 358 "Element count mismatch"); 359 360 RISCVII::VLMUL IndexLMUL = RISCVTargetLowering::getLMUL(IndexVT); 361 unsigned IndexLog2EEW = Log2_32(IndexVT.getScalarSizeInBits()); 362 const RISCV::VLXSEGPseudo *P = RISCV::getVLXSEGPseudo( 363 NF, IsMasked, IsOrdered, IndexLog2EEW, static_cast<unsigned>(LMUL), 364 static_cast<unsigned>(IndexLMUL)); 365 MachineSDNode *Load = 366 CurDAG->getMachineNode(P->Pseudo, DL, MVT::Untyped, MVT::Other, Operands); 367 368 if (auto *MemOp = dyn_cast<MemSDNode>(Node)) 369 CurDAG->setNodeMemRefs(Load, {MemOp->getMemOperand()}); 370 371 SDValue SuperReg = SDValue(Load, 0); 372 for (unsigned I = 0; I < NF; ++I) { 373 unsigned SubRegIdx = RISCVTargetLowering::getSubregIndexByMVT(VT, I); 374 ReplaceUses(SDValue(Node, I), 375 CurDAG->getTargetExtractSubreg(SubRegIdx, DL, VT, SuperReg)); 376 } 377 378 ReplaceUses(SDValue(Node, NF), SDValue(Load, 1)); 379 CurDAG->RemoveDeadNode(Node); 380 } 381 382 void RISCVDAGToDAGISel::selectVSSEG(SDNode *Node, bool IsMasked, 383 bool IsStrided) { 384 SDLoc DL(Node); 385 unsigned NF = Node->getNumOperands() - 4; 386 if (IsStrided) 387 NF--; 388 if (IsMasked) 389 NF--; 390 MVT VT = Node->getOperand(2)->getSimpleValueType(0); 391 unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits()); 392 RISCVII::VLMUL LMUL = RISCVTargetLowering::getLMUL(VT); 393 SmallVector<SDValue, 8> Regs(Node->op_begin() + 2, Node->op_begin() + 2 + NF); 394 SDValue StoreVal = createTuple(*CurDAG, Regs, NF, LMUL); 395 396 SmallVector<SDValue, 8> Operands; 397 Operands.push_back(StoreVal); 398 unsigned CurOp = 2 + NF; 399 400 addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked, IsStrided, 401 Operands); 402 403 const RISCV::VSSEGPseudo *P = RISCV::getVSSEGPseudo( 404 NF, IsMasked, IsStrided, Log2SEW, static_cast<unsigned>(LMUL)); 405 MachineSDNode *Store = 406 CurDAG->getMachineNode(P->Pseudo, DL, Node->getValueType(0), Operands); 407 408 if (auto *MemOp = dyn_cast<MemSDNode>(Node)) 409 CurDAG->setNodeMemRefs(Store, {MemOp->getMemOperand()}); 410 411 ReplaceNode(Node, Store); 412 } 413 414 void RISCVDAGToDAGISel::selectVSXSEG(SDNode *Node, bool IsMasked, 415 bool IsOrdered) { 416 SDLoc DL(Node); 417 unsigned NF = Node->getNumOperands() - 5; 418 if (IsMasked) 419 --NF; 420 MVT VT = Node->getOperand(2)->getSimpleValueType(0); 421 unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits()); 422 RISCVII::VLMUL LMUL = RISCVTargetLowering::getLMUL(VT); 423 SmallVector<SDValue, 8> Regs(Node->op_begin() + 2, Node->op_begin() + 2 + NF); 424 SDValue StoreVal = createTuple(*CurDAG, Regs, NF, LMUL); 425 426 SmallVector<SDValue, 8> Operands; 427 Operands.push_back(StoreVal); 428 unsigned CurOp = 2 + NF; 429 430 MVT IndexVT; 431 addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked, 432 /*IsStridedOrIndexed*/ true, Operands, &IndexVT); 433 434 assert(VT.getVectorElementCount() == IndexVT.getVectorElementCount() && 435 "Element count mismatch"); 436 437 RISCVII::VLMUL IndexLMUL = RISCVTargetLowering::getLMUL(IndexVT); 438 unsigned IndexLog2EEW = Log2_32(IndexVT.getScalarSizeInBits()); 439 const RISCV::VSXSEGPseudo *P = RISCV::getVSXSEGPseudo( 440 NF, IsMasked, IsOrdered, IndexLog2EEW, static_cast<unsigned>(LMUL), 441 static_cast<unsigned>(IndexLMUL)); 442 MachineSDNode *Store = 443 CurDAG->getMachineNode(P->Pseudo, DL, Node->getValueType(0), Operands); 444 445 if (auto *MemOp = dyn_cast<MemSDNode>(Node)) 446 CurDAG->setNodeMemRefs(Store, {MemOp->getMemOperand()}); 447 448 ReplaceNode(Node, Store); 449 } 450 451 452 void RISCVDAGToDAGISel::Select(SDNode *Node) { 453 // If we have a custom node, we have already selected. 454 if (Node->isMachineOpcode()) { 455 LLVM_DEBUG(dbgs() << "== "; Node->dump(CurDAG); dbgs() << "\n"); 456 Node->setNodeId(-1); 457 return; 458 } 459 460 // Instruction Selection not handled by the auto-generated tablegen selection 461 // should be handled here. 462 unsigned Opcode = Node->getOpcode(); 463 MVT XLenVT = Subtarget->getXLenVT(); 464 SDLoc DL(Node); 465 MVT VT = Node->getSimpleValueType(0); 466 467 switch (Opcode) { 468 case ISD::Constant: { 469 auto *ConstNode = cast<ConstantSDNode>(Node); 470 if (VT == XLenVT && ConstNode->isZero()) { 471 SDValue New = 472 CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, RISCV::X0, XLenVT); 473 ReplaceNode(Node, New.getNode()); 474 return; 475 } 476 int64_t Imm = ConstNode->getSExtValue(); 477 // If the upper XLen-16 bits are not used, try to convert this to a simm12 478 // by sign extending bit 15. 479 if (isUInt<16>(Imm) && isInt<12>(SignExtend64(Imm, 16)) && 480 hasAllHUsers(Node)) 481 Imm = SignExtend64(Imm, 16); 482 // If the upper 32-bits are not used try to convert this into a simm32 by 483 // sign extending bit 32. 484 if (!isInt<32>(Imm) && isUInt<32>(Imm) && hasAllWUsers(Node)) 485 Imm = SignExtend64(Imm, 32); 486 487 ReplaceNode(Node, selectImm(CurDAG, DL, Imm, *Subtarget)); 488 return; 489 } 490 case ISD::FrameIndex: { 491 SDValue Imm = CurDAG->getTargetConstant(0, DL, XLenVT); 492 int FI = cast<FrameIndexSDNode>(Node)->getIndex(); 493 SDValue TFI = CurDAG->getTargetFrameIndex(FI, VT); 494 ReplaceNode(Node, CurDAG->getMachineNode(RISCV::ADDI, DL, VT, TFI, Imm)); 495 return; 496 } 497 case ISD::SRL: { 498 // We don't need this transform if zext.h is supported. 499 if (Subtarget->hasStdExtZbb() || Subtarget->hasStdExtZbp()) 500 break; 501 // Optimize (srl (and X, 0xffff), C) -> 502 // (srli (slli X, (XLen-16), (XLen-16) + C) 503 // Taking into account that the 0xffff may have had lower bits unset by 504 // SimplifyDemandedBits. This avoids materializing the 0xffff immediate. 505 // This pattern occurs when type legalizing i16 right shifts. 506 // FIXME: This could be extended to other AND masks. 507 auto *N1C = dyn_cast<ConstantSDNode>(Node->getOperand(1)); 508 if (N1C) { 509 uint64_t ShAmt = N1C->getZExtValue(); 510 SDValue N0 = Node->getOperand(0); 511 if (ShAmt < 16 && N0.getOpcode() == ISD::AND && N0.hasOneUse() && 512 isa<ConstantSDNode>(N0.getOperand(1))) { 513 uint64_t Mask = N0.getConstantOperandVal(1); 514 Mask |= maskTrailingOnes<uint64_t>(ShAmt); 515 if (Mask == 0xffff) { 516 unsigned LShAmt = Subtarget->getXLen() - 16; 517 SDNode *SLLI = 518 CurDAG->getMachineNode(RISCV::SLLI, DL, VT, N0->getOperand(0), 519 CurDAG->getTargetConstant(LShAmt, DL, VT)); 520 SDNode *SRLI = CurDAG->getMachineNode( 521 RISCV::SRLI, DL, VT, SDValue(SLLI, 0), 522 CurDAG->getTargetConstant(LShAmt + ShAmt, DL, VT)); 523 ReplaceNode(Node, SRLI); 524 return; 525 } 526 } 527 } 528 529 break; 530 } 531 case ISD::AND: { 532 auto *N1C = dyn_cast<ConstantSDNode>(Node->getOperand(1)); 533 if (!N1C) 534 break; 535 536 SDValue N0 = Node->getOperand(0); 537 538 bool LeftShift = N0.getOpcode() == ISD::SHL; 539 if (!LeftShift && N0.getOpcode() != ISD::SRL) 540 break; 541 542 auto *C = dyn_cast<ConstantSDNode>(N0.getOperand(1)); 543 if (!C) 544 break; 545 uint64_t C2 = C->getZExtValue(); 546 unsigned XLen = Subtarget->getXLen(); 547 if (!C2 || C2 >= XLen) 548 break; 549 550 uint64_t C1 = N1C->getZExtValue(); 551 552 // Keep track of whether this is a andi, zext.h, or zext.w. 553 bool ZExtOrANDI = isInt<12>(N1C->getSExtValue()); 554 if (C1 == UINT64_C(0xFFFF) && 555 (Subtarget->hasStdExtZbb() || Subtarget->hasStdExtZbp())) 556 ZExtOrANDI = true; 557 if (C1 == UINT64_C(0xFFFFFFFF) && Subtarget->hasStdExtZba()) 558 ZExtOrANDI = true; 559 560 // Clear irrelevant bits in the mask. 561 if (LeftShift) 562 C1 &= maskTrailingZeros<uint64_t>(C2); 563 else 564 C1 &= maskTrailingOnes<uint64_t>(XLen - C2); 565 566 // Some transforms should only be done if the shift has a single use or 567 // the AND would become (srli (slli X, 32), 32) 568 bool OneUseOrZExtW = N0.hasOneUse() || C1 == UINT64_C(0xFFFFFFFF); 569 570 SDValue X = N0.getOperand(0); 571 572 // Turn (and (srl x, c2) c1) -> (srli (slli x, c3-c2), c3) if c1 is a mask 573 // with c3 leading zeros. 574 if (!LeftShift && isMask_64(C1)) { 575 uint64_t C3 = XLen - (64 - countLeadingZeros(C1)); 576 if (C2 < C3) { 577 // If the number of leading zeros is C2+32 this can be SRLIW. 578 if (C2 + 32 == C3) { 579 SDNode *SRLIW = 580 CurDAG->getMachineNode(RISCV::SRLIW, DL, XLenVT, X, 581 CurDAG->getTargetConstant(C2, DL, XLenVT)); 582 ReplaceNode(Node, SRLIW); 583 return; 584 } 585 586 // (and (srl (sexti32 Y), c2), c1) -> (srliw (sraiw Y, 31), c3 - 32) if 587 // c1 is a mask with c3 leading zeros and c2 >= 32 and c3-c2==1. 588 // 589 // This pattern occurs when (i32 (srl (sra 31), c3 - 32)) is type 590 // legalized and goes through DAG combine. 591 SDValue Y; 592 if (C2 >= 32 && (C3 - C2) == 1 && N0.hasOneUse() && 593 selectSExti32(X, Y)) { 594 SDNode *SRAIW = 595 CurDAG->getMachineNode(RISCV::SRAIW, DL, XLenVT, Y, 596 CurDAG->getTargetConstant(31, DL, XLenVT)); 597 SDNode *SRLIW = CurDAG->getMachineNode( 598 RISCV::SRLIW, DL, XLenVT, SDValue(SRAIW, 0), 599 CurDAG->getTargetConstant(C3 - 32, DL, XLenVT)); 600 ReplaceNode(Node, SRLIW); 601 return; 602 } 603 604 // (srli (slli x, c3-c2), c3). 605 if (OneUseOrZExtW && !ZExtOrANDI) { 606 SDNode *SLLI = CurDAG->getMachineNode( 607 RISCV::SLLI, DL, XLenVT, X, 608 CurDAG->getTargetConstant(C3 - C2, DL, XLenVT)); 609 SDNode *SRLI = 610 CurDAG->getMachineNode(RISCV::SRLI, DL, XLenVT, SDValue(SLLI, 0), 611 CurDAG->getTargetConstant(C3, DL, XLenVT)); 612 ReplaceNode(Node, SRLI); 613 return; 614 } 615 } 616 } 617 618 // Turn (and (shl x, c2), c1) -> (srli (slli c2+c3), c3) if c1 is a mask 619 // shifted by c2 bits with c3 leading zeros. 620 if (LeftShift && isShiftedMask_64(C1)) { 621 uint64_t C3 = XLen - (64 - countLeadingZeros(C1)); 622 623 if (C2 + C3 < XLen && 624 C1 == (maskTrailingOnes<uint64_t>(XLen - (C2 + C3)) << C2)) { 625 // Use slli.uw when possible. 626 if ((XLen - (C2 + C3)) == 32 && Subtarget->hasStdExtZba()) { 627 SDNode *SLLIUW = 628 CurDAG->getMachineNode(RISCV::SLLIUW, DL, XLenVT, X, 629 CurDAG->getTargetConstant(C2, DL, XLenVT)); 630 ReplaceNode(Node, SLLIUW); 631 return; 632 } 633 634 // (srli (slli c2+c3), c3) 635 if (OneUseOrZExtW && !ZExtOrANDI) { 636 SDNode *SLLI = CurDAG->getMachineNode( 637 RISCV::SLLI, DL, XLenVT, X, 638 CurDAG->getTargetConstant(C2 + C3, DL, XLenVT)); 639 SDNode *SRLI = 640 CurDAG->getMachineNode(RISCV::SRLI, DL, XLenVT, SDValue(SLLI, 0), 641 CurDAG->getTargetConstant(C3, DL, XLenVT)); 642 ReplaceNode(Node, SRLI); 643 return; 644 } 645 } 646 } 647 648 // Turn (and (shr x, c2), c1) -> (slli (srli x, c2+c3), c3) if c1 is a 649 // shifted mask with c2 leading zeros and c3 trailing zeros. 650 if (!LeftShift && isShiftedMask_64(C1)) { 651 uint64_t Leading = XLen - (64 - countLeadingZeros(C1)); 652 uint64_t C3 = countTrailingZeros(C1); 653 if (Leading == C2 && C2 + C3 < XLen && OneUseOrZExtW && !ZExtOrANDI) { 654 SDNode *SRLI = CurDAG->getMachineNode( 655 RISCV::SRLI, DL, XLenVT, X, 656 CurDAG->getTargetConstant(C2 + C3, DL, XLenVT)); 657 SDNode *SLLI = 658 CurDAG->getMachineNode(RISCV::SLLI, DL, XLenVT, SDValue(SRLI, 0), 659 CurDAG->getTargetConstant(C3, DL, XLenVT)); 660 ReplaceNode(Node, SLLI); 661 return; 662 } 663 // If the leading zero count is C2+32, we can use SRLIW instead of SRLI. 664 if (Leading > 32 && (Leading - 32) == C2 && C2 + C3 < 32 && 665 OneUseOrZExtW && !ZExtOrANDI) { 666 SDNode *SRLIW = CurDAG->getMachineNode( 667 RISCV::SRLIW, DL, XLenVT, X, 668 CurDAG->getTargetConstant(C2 + C3, DL, XLenVT)); 669 SDNode *SLLI = 670 CurDAG->getMachineNode(RISCV::SLLI, DL, XLenVT, SDValue(SRLIW, 0), 671 CurDAG->getTargetConstant(C3, DL, XLenVT)); 672 ReplaceNode(Node, SLLI); 673 return; 674 } 675 } 676 677 // Turn (and (shl x, c2), c1) -> (slli (srli x, c3-c2), c3) if c1 is a 678 // shifted mask with no leading zeros and c3 trailing zeros. 679 if (LeftShift && isShiftedMask_64(C1)) { 680 uint64_t Leading = XLen - (64 - countLeadingZeros(C1)); 681 uint64_t C3 = countTrailingZeros(C1); 682 if (Leading == 0 && C2 < C3 && OneUseOrZExtW && !ZExtOrANDI) { 683 SDNode *SRLI = CurDAG->getMachineNode( 684 RISCV::SRLI, DL, XLenVT, X, 685 CurDAG->getTargetConstant(C3 - C2, DL, XLenVT)); 686 SDNode *SLLI = 687 CurDAG->getMachineNode(RISCV::SLLI, DL, XLenVT, SDValue(SRLI, 0), 688 CurDAG->getTargetConstant(C3, DL, XLenVT)); 689 ReplaceNode(Node, SLLI); 690 return; 691 } 692 } 693 694 break; 695 } 696 case ISD::INTRINSIC_WO_CHAIN: { 697 unsigned IntNo = Node->getConstantOperandVal(0); 698 switch (IntNo) { 699 // By default we do not custom select any intrinsic. 700 default: 701 break; 702 case Intrinsic::riscv_vmsgeu: 703 case Intrinsic::riscv_vmsge: { 704 SDValue Src1 = Node->getOperand(1); 705 SDValue Src2 = Node->getOperand(2); 706 // Only custom select scalar second operand. 707 if (Src2.getValueType() != XLenVT) 708 break; 709 // Small constants are handled with patterns. 710 if (auto *C = dyn_cast<ConstantSDNode>(Src2)) { 711 int64_t CVal = C->getSExtValue(); 712 if (CVal >= -15 && CVal <= 16) 713 break; 714 } 715 bool IsUnsigned = IntNo == Intrinsic::riscv_vmsgeu; 716 MVT Src1VT = Src1.getSimpleValueType(); 717 unsigned VMSLTOpcode, VMNANDOpcode; 718 switch (RISCVTargetLowering::getLMUL(Src1VT)) { 719 default: 720 llvm_unreachable("Unexpected LMUL!"); 721 case RISCVII::VLMUL::LMUL_F8: 722 VMSLTOpcode = 723 IsUnsigned ? RISCV::PseudoVMSLTU_VX_MF8 : RISCV::PseudoVMSLT_VX_MF8; 724 VMNANDOpcode = RISCV::PseudoVMNAND_MM_MF8; 725 break; 726 case RISCVII::VLMUL::LMUL_F4: 727 VMSLTOpcode = 728 IsUnsigned ? RISCV::PseudoVMSLTU_VX_MF4 : RISCV::PseudoVMSLT_VX_MF4; 729 VMNANDOpcode = RISCV::PseudoVMNAND_MM_MF4; 730 break; 731 case RISCVII::VLMUL::LMUL_F2: 732 VMSLTOpcode = 733 IsUnsigned ? RISCV::PseudoVMSLTU_VX_MF2 : RISCV::PseudoVMSLT_VX_MF2; 734 VMNANDOpcode = RISCV::PseudoVMNAND_MM_MF2; 735 break; 736 case RISCVII::VLMUL::LMUL_1: 737 VMSLTOpcode = 738 IsUnsigned ? RISCV::PseudoVMSLTU_VX_M1 : RISCV::PseudoVMSLT_VX_M1; 739 VMNANDOpcode = RISCV::PseudoVMNAND_MM_M1; 740 break; 741 case RISCVII::VLMUL::LMUL_2: 742 VMSLTOpcode = 743 IsUnsigned ? RISCV::PseudoVMSLTU_VX_M2 : RISCV::PseudoVMSLT_VX_M2; 744 VMNANDOpcode = RISCV::PseudoVMNAND_MM_M2; 745 break; 746 case RISCVII::VLMUL::LMUL_4: 747 VMSLTOpcode = 748 IsUnsigned ? RISCV::PseudoVMSLTU_VX_M4 : RISCV::PseudoVMSLT_VX_M4; 749 VMNANDOpcode = RISCV::PseudoVMNAND_MM_M4; 750 break; 751 case RISCVII::VLMUL::LMUL_8: 752 VMSLTOpcode = 753 IsUnsigned ? RISCV::PseudoVMSLTU_VX_M8 : RISCV::PseudoVMSLT_VX_M8; 754 VMNANDOpcode = RISCV::PseudoVMNAND_MM_M8; 755 break; 756 } 757 SDValue SEW = CurDAG->getTargetConstant( 758 Log2_32(Src1VT.getScalarSizeInBits()), DL, XLenVT); 759 SDValue VL; 760 selectVLOp(Node->getOperand(3), VL); 761 762 // Expand to 763 // vmslt{u}.vx vd, va, x; vmnand.mm vd, vd, vd 764 SDValue Cmp = SDValue( 765 CurDAG->getMachineNode(VMSLTOpcode, DL, VT, {Src1, Src2, VL, SEW}), 766 0); 767 ReplaceNode(Node, CurDAG->getMachineNode(VMNANDOpcode, DL, VT, 768 {Cmp, Cmp, VL, SEW})); 769 return; 770 } 771 case Intrinsic::riscv_vmsgeu_mask: 772 case Intrinsic::riscv_vmsge_mask: { 773 SDValue Src1 = Node->getOperand(2); 774 SDValue Src2 = Node->getOperand(3); 775 // Only custom select scalar second operand. 776 if (Src2.getValueType() != XLenVT) 777 break; 778 // Small constants are handled with patterns. 779 if (auto *C = dyn_cast<ConstantSDNode>(Src2)) { 780 int64_t CVal = C->getSExtValue(); 781 if (CVal >= -15 && CVal <= 16) 782 break; 783 } 784 bool IsUnsigned = IntNo == Intrinsic::riscv_vmsgeu_mask; 785 MVT Src1VT = Src1.getSimpleValueType(); 786 unsigned VMSLTOpcode, VMSLTMaskOpcode, VMXOROpcode, VMANDNOTOpcode; 787 switch (RISCVTargetLowering::getLMUL(Src1VT)) { 788 default: 789 llvm_unreachable("Unexpected LMUL!"); 790 case RISCVII::VLMUL::LMUL_F8: 791 VMSLTOpcode = 792 IsUnsigned ? RISCV::PseudoVMSLTU_VX_MF8 : RISCV::PseudoVMSLT_VX_MF8; 793 VMSLTMaskOpcode = IsUnsigned ? RISCV::PseudoVMSLTU_VX_MF8_MASK 794 : RISCV::PseudoVMSLT_VX_MF8_MASK; 795 break; 796 case RISCVII::VLMUL::LMUL_F4: 797 VMSLTOpcode = 798 IsUnsigned ? RISCV::PseudoVMSLTU_VX_MF4 : RISCV::PseudoVMSLT_VX_MF4; 799 VMSLTMaskOpcode = IsUnsigned ? RISCV::PseudoVMSLTU_VX_MF4_MASK 800 : RISCV::PseudoVMSLT_VX_MF4_MASK; 801 break; 802 case RISCVII::VLMUL::LMUL_F2: 803 VMSLTOpcode = 804 IsUnsigned ? RISCV::PseudoVMSLTU_VX_MF2 : RISCV::PseudoVMSLT_VX_MF2; 805 VMSLTMaskOpcode = IsUnsigned ? RISCV::PseudoVMSLTU_VX_MF2_MASK 806 : RISCV::PseudoVMSLT_VX_MF2_MASK; 807 break; 808 case RISCVII::VLMUL::LMUL_1: 809 VMSLTOpcode = 810 IsUnsigned ? RISCV::PseudoVMSLTU_VX_M1 : RISCV::PseudoVMSLT_VX_M1; 811 VMSLTMaskOpcode = IsUnsigned ? RISCV::PseudoVMSLTU_VX_M1_MASK 812 : RISCV::PseudoVMSLT_VX_M1_MASK; 813 break; 814 case RISCVII::VLMUL::LMUL_2: 815 VMSLTOpcode = 816 IsUnsigned ? RISCV::PseudoVMSLTU_VX_M2 : RISCV::PseudoVMSLT_VX_M2; 817 VMSLTMaskOpcode = IsUnsigned ? RISCV::PseudoVMSLTU_VX_M2_MASK 818 : RISCV::PseudoVMSLT_VX_M2_MASK; 819 break; 820 case RISCVII::VLMUL::LMUL_4: 821 VMSLTOpcode = 822 IsUnsigned ? RISCV::PseudoVMSLTU_VX_M4 : RISCV::PseudoVMSLT_VX_M4; 823 VMSLTMaskOpcode = IsUnsigned ? RISCV::PseudoVMSLTU_VX_M4_MASK 824 : RISCV::PseudoVMSLT_VX_M4_MASK; 825 break; 826 case RISCVII::VLMUL::LMUL_8: 827 VMSLTOpcode = 828 IsUnsigned ? RISCV::PseudoVMSLTU_VX_M8 : RISCV::PseudoVMSLT_VX_M8; 829 VMSLTMaskOpcode = IsUnsigned ? RISCV::PseudoVMSLTU_VX_M8_MASK 830 : RISCV::PseudoVMSLT_VX_M8_MASK; 831 break; 832 } 833 // Mask operations use the LMUL from the mask type. 834 switch (RISCVTargetLowering::getLMUL(VT)) { 835 default: 836 llvm_unreachable("Unexpected LMUL!"); 837 case RISCVII::VLMUL::LMUL_F8: 838 VMXOROpcode = RISCV::PseudoVMXOR_MM_MF8; 839 VMANDNOTOpcode = RISCV::PseudoVMANDNOT_MM_MF8; 840 break; 841 case RISCVII::VLMUL::LMUL_F4: 842 VMXOROpcode = RISCV::PseudoVMXOR_MM_MF4; 843 VMANDNOTOpcode = RISCV::PseudoVMANDNOT_MM_MF4; 844 break; 845 case RISCVII::VLMUL::LMUL_F2: 846 VMXOROpcode = RISCV::PseudoVMXOR_MM_MF2; 847 VMANDNOTOpcode = RISCV::PseudoVMANDNOT_MM_MF2; 848 break; 849 case RISCVII::VLMUL::LMUL_1: 850 VMXOROpcode = RISCV::PseudoVMXOR_MM_M1; 851 VMANDNOTOpcode = RISCV::PseudoVMANDNOT_MM_M1; 852 break; 853 case RISCVII::VLMUL::LMUL_2: 854 VMXOROpcode = RISCV::PseudoVMXOR_MM_M2; 855 VMANDNOTOpcode = RISCV::PseudoVMANDNOT_MM_M2; 856 break; 857 case RISCVII::VLMUL::LMUL_4: 858 VMXOROpcode = RISCV::PseudoVMXOR_MM_M4; 859 VMANDNOTOpcode = RISCV::PseudoVMANDNOT_MM_M4; 860 break; 861 case RISCVII::VLMUL::LMUL_8: 862 VMXOROpcode = RISCV::PseudoVMXOR_MM_M8; 863 VMANDNOTOpcode = RISCV::PseudoVMANDNOT_MM_M8; 864 break; 865 } 866 SDValue SEW = CurDAG->getTargetConstant( 867 Log2_32(Src1VT.getScalarSizeInBits()), DL, XLenVT); 868 SDValue MaskSEW = CurDAG->getTargetConstant(0, DL, XLenVT); 869 SDValue VL; 870 selectVLOp(Node->getOperand(5), VL); 871 SDValue MaskedOff = Node->getOperand(1); 872 SDValue Mask = Node->getOperand(4); 873 // If the MaskedOff value and the Mask are the same value use 874 // vmslt{u}.vx vt, va, x; vmandnot.mm vd, vd, vt 875 // This avoids needing to copy v0 to vd before starting the next sequence. 876 if (Mask == MaskedOff) { 877 SDValue Cmp = SDValue( 878 CurDAG->getMachineNode(VMSLTOpcode, DL, VT, {Src1, Src2, VL, SEW}), 879 0); 880 ReplaceNode(Node, CurDAG->getMachineNode(VMANDNOTOpcode, DL, VT, 881 {Mask, Cmp, VL, MaskSEW})); 882 return; 883 } 884 885 // Mask needs to be copied to V0. 886 SDValue Chain = CurDAG->getCopyToReg(CurDAG->getEntryNode(), DL, 887 RISCV::V0, Mask, SDValue()); 888 SDValue Glue = Chain.getValue(1); 889 SDValue V0 = CurDAG->getRegister(RISCV::V0, VT); 890 891 // Otherwise use 892 // vmslt{u}.vx vd, va, x, v0.t; vmxor.mm vd, vd, v0 893 SDValue Cmp = SDValue( 894 CurDAG->getMachineNode(VMSLTMaskOpcode, DL, VT, 895 {MaskedOff, Src1, Src2, V0, VL, SEW, Glue}), 896 0); 897 ReplaceNode(Node, CurDAG->getMachineNode(VMXOROpcode, DL, VT, 898 {Cmp, Mask, VL, MaskSEW})); 899 return; 900 } 901 } 902 break; 903 } 904 case ISD::INTRINSIC_W_CHAIN: { 905 unsigned IntNo = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue(); 906 switch (IntNo) { 907 // By default we do not custom select any intrinsic. 908 default: 909 break; 910 911 case Intrinsic::riscv_vsetvli: 912 case Intrinsic::riscv_vsetvlimax: { 913 if (!Subtarget->hasStdExtV()) 914 break; 915 916 bool VLMax = IntNo == Intrinsic::riscv_vsetvlimax; 917 unsigned Offset = VLMax ? 2 : 3; 918 919 assert(Node->getNumOperands() == Offset + 2 && 920 "Unexpected number of operands"); 921 922 unsigned SEW = 923 RISCVVType::decodeVSEW(Node->getConstantOperandVal(Offset) & 0x7); 924 RISCVII::VLMUL VLMul = static_cast<RISCVII::VLMUL>( 925 Node->getConstantOperandVal(Offset + 1) & 0x7); 926 927 unsigned VTypeI = RISCVVType::encodeVTYPE( 928 VLMul, SEW, /*TailAgnostic*/ true, /*MaskAgnostic*/ false); 929 SDValue VTypeIOp = CurDAG->getTargetConstant(VTypeI, DL, XLenVT); 930 931 SDValue VLOperand; 932 unsigned Opcode = RISCV::PseudoVSETVLI; 933 if (VLMax) { 934 VLOperand = CurDAG->getRegister(RISCV::X0, XLenVT); 935 Opcode = RISCV::PseudoVSETVLIX0; 936 } else { 937 VLOperand = Node->getOperand(2); 938 939 if (auto *C = dyn_cast<ConstantSDNode>(VLOperand)) { 940 uint64_t AVL = C->getZExtValue(); 941 if (isUInt<5>(AVL)) { 942 SDValue VLImm = CurDAG->getTargetConstant(AVL, DL, XLenVT); 943 ReplaceNode( 944 Node, CurDAG->getMachineNode(RISCV::PseudoVSETIVLI, DL, XLenVT, 945 MVT::Other, VLImm, VTypeIOp, 946 /* Chain */ Node->getOperand(0))); 947 return; 948 } 949 } 950 } 951 952 ReplaceNode(Node, 953 CurDAG->getMachineNode(Opcode, DL, XLenVT, 954 MVT::Other, VLOperand, VTypeIOp, 955 /* Chain */ Node->getOperand(0))); 956 return; 957 } 958 case Intrinsic::riscv_vlseg2: 959 case Intrinsic::riscv_vlseg3: 960 case Intrinsic::riscv_vlseg4: 961 case Intrinsic::riscv_vlseg5: 962 case Intrinsic::riscv_vlseg6: 963 case Intrinsic::riscv_vlseg7: 964 case Intrinsic::riscv_vlseg8: { 965 selectVLSEG(Node, /*IsMasked*/ false, /*IsStrided*/ false); 966 return; 967 } 968 case Intrinsic::riscv_vlseg2_mask: 969 case Intrinsic::riscv_vlseg3_mask: 970 case Intrinsic::riscv_vlseg4_mask: 971 case Intrinsic::riscv_vlseg5_mask: 972 case Intrinsic::riscv_vlseg6_mask: 973 case Intrinsic::riscv_vlseg7_mask: 974 case Intrinsic::riscv_vlseg8_mask: { 975 selectVLSEG(Node, /*IsMasked*/ true, /*IsStrided*/ false); 976 return; 977 } 978 case Intrinsic::riscv_vlsseg2: 979 case Intrinsic::riscv_vlsseg3: 980 case Intrinsic::riscv_vlsseg4: 981 case Intrinsic::riscv_vlsseg5: 982 case Intrinsic::riscv_vlsseg6: 983 case Intrinsic::riscv_vlsseg7: 984 case Intrinsic::riscv_vlsseg8: { 985 selectVLSEG(Node, /*IsMasked*/ false, /*IsStrided*/ true); 986 return; 987 } 988 case Intrinsic::riscv_vlsseg2_mask: 989 case Intrinsic::riscv_vlsseg3_mask: 990 case Intrinsic::riscv_vlsseg4_mask: 991 case Intrinsic::riscv_vlsseg5_mask: 992 case Intrinsic::riscv_vlsseg6_mask: 993 case Intrinsic::riscv_vlsseg7_mask: 994 case Intrinsic::riscv_vlsseg8_mask: { 995 selectVLSEG(Node, /*IsMasked*/ true, /*IsStrided*/ true); 996 return; 997 } 998 case Intrinsic::riscv_vloxseg2: 999 case Intrinsic::riscv_vloxseg3: 1000 case Intrinsic::riscv_vloxseg4: 1001 case Intrinsic::riscv_vloxseg5: 1002 case Intrinsic::riscv_vloxseg6: 1003 case Intrinsic::riscv_vloxseg7: 1004 case Intrinsic::riscv_vloxseg8: 1005 selectVLXSEG(Node, /*IsMasked*/ false, /*IsOrdered*/ true); 1006 return; 1007 case Intrinsic::riscv_vluxseg2: 1008 case Intrinsic::riscv_vluxseg3: 1009 case Intrinsic::riscv_vluxseg4: 1010 case Intrinsic::riscv_vluxseg5: 1011 case Intrinsic::riscv_vluxseg6: 1012 case Intrinsic::riscv_vluxseg7: 1013 case Intrinsic::riscv_vluxseg8: 1014 selectVLXSEG(Node, /*IsMasked*/ false, /*IsOrdered*/ false); 1015 return; 1016 case Intrinsic::riscv_vloxseg2_mask: 1017 case Intrinsic::riscv_vloxseg3_mask: 1018 case Intrinsic::riscv_vloxseg4_mask: 1019 case Intrinsic::riscv_vloxseg5_mask: 1020 case Intrinsic::riscv_vloxseg6_mask: 1021 case Intrinsic::riscv_vloxseg7_mask: 1022 case Intrinsic::riscv_vloxseg8_mask: 1023 selectVLXSEG(Node, /*IsMasked*/ true, /*IsOrdered*/ true); 1024 return; 1025 case Intrinsic::riscv_vluxseg2_mask: 1026 case Intrinsic::riscv_vluxseg3_mask: 1027 case Intrinsic::riscv_vluxseg4_mask: 1028 case Intrinsic::riscv_vluxseg5_mask: 1029 case Intrinsic::riscv_vluxseg6_mask: 1030 case Intrinsic::riscv_vluxseg7_mask: 1031 case Intrinsic::riscv_vluxseg8_mask: 1032 selectVLXSEG(Node, /*IsMasked*/ true, /*IsOrdered*/ false); 1033 return; 1034 case Intrinsic::riscv_vlseg8ff: 1035 case Intrinsic::riscv_vlseg7ff: 1036 case Intrinsic::riscv_vlseg6ff: 1037 case Intrinsic::riscv_vlseg5ff: 1038 case Intrinsic::riscv_vlseg4ff: 1039 case Intrinsic::riscv_vlseg3ff: 1040 case Intrinsic::riscv_vlseg2ff: { 1041 selectVLSEGFF(Node, /*IsMasked*/ false); 1042 return; 1043 } 1044 case Intrinsic::riscv_vlseg8ff_mask: 1045 case Intrinsic::riscv_vlseg7ff_mask: 1046 case Intrinsic::riscv_vlseg6ff_mask: 1047 case Intrinsic::riscv_vlseg5ff_mask: 1048 case Intrinsic::riscv_vlseg4ff_mask: 1049 case Intrinsic::riscv_vlseg3ff_mask: 1050 case Intrinsic::riscv_vlseg2ff_mask: { 1051 selectVLSEGFF(Node, /*IsMasked*/ true); 1052 return; 1053 } 1054 case Intrinsic::riscv_vloxei: 1055 case Intrinsic::riscv_vloxei_mask: 1056 case Intrinsic::riscv_vluxei: 1057 case Intrinsic::riscv_vluxei_mask: { 1058 bool IsMasked = IntNo == Intrinsic::riscv_vloxei_mask || 1059 IntNo == Intrinsic::riscv_vluxei_mask; 1060 bool IsOrdered = IntNo == Intrinsic::riscv_vloxei || 1061 IntNo == Intrinsic::riscv_vloxei_mask; 1062 1063 MVT VT = Node->getSimpleValueType(0); 1064 unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits()); 1065 1066 unsigned CurOp = 2; 1067 SmallVector<SDValue, 8> Operands; 1068 if (IsMasked) 1069 Operands.push_back(Node->getOperand(CurOp++)); 1070 1071 MVT IndexVT; 1072 addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked, 1073 /*IsStridedOrIndexed*/ true, Operands, 1074 &IndexVT); 1075 1076 assert(VT.getVectorElementCount() == IndexVT.getVectorElementCount() && 1077 "Element count mismatch"); 1078 1079 RISCVII::VLMUL LMUL = RISCVTargetLowering::getLMUL(VT); 1080 RISCVII::VLMUL IndexLMUL = RISCVTargetLowering::getLMUL(IndexVT); 1081 unsigned IndexLog2EEW = Log2_32(IndexVT.getScalarSizeInBits()); 1082 const RISCV::VLX_VSXPseudo *P = RISCV::getVLXPseudo( 1083 IsMasked, IsOrdered, IndexLog2EEW, static_cast<unsigned>(LMUL), 1084 static_cast<unsigned>(IndexLMUL)); 1085 MachineSDNode *Load = 1086 CurDAG->getMachineNode(P->Pseudo, DL, Node->getVTList(), Operands); 1087 1088 if (auto *MemOp = dyn_cast<MemSDNode>(Node)) 1089 CurDAG->setNodeMemRefs(Load, {MemOp->getMemOperand()}); 1090 1091 ReplaceNode(Node, Load); 1092 return; 1093 } 1094 case Intrinsic::riscv_vle1: 1095 case Intrinsic::riscv_vle: 1096 case Intrinsic::riscv_vle_mask: 1097 case Intrinsic::riscv_vlse: 1098 case Intrinsic::riscv_vlse_mask: { 1099 bool IsMasked = IntNo == Intrinsic::riscv_vle_mask || 1100 IntNo == Intrinsic::riscv_vlse_mask; 1101 bool IsStrided = 1102 IntNo == Intrinsic::riscv_vlse || IntNo == Intrinsic::riscv_vlse_mask; 1103 1104 MVT VT = Node->getSimpleValueType(0); 1105 unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits()); 1106 1107 unsigned CurOp = 2; 1108 SmallVector<SDValue, 8> Operands; 1109 if (IsMasked) 1110 Operands.push_back(Node->getOperand(CurOp++)); 1111 1112 addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked, IsStrided, 1113 Operands); 1114 1115 RISCVII::VLMUL LMUL = RISCVTargetLowering::getLMUL(VT); 1116 const RISCV::VLEPseudo *P = 1117 RISCV::getVLEPseudo(IsMasked, IsStrided, /*FF*/ false, Log2SEW, 1118 static_cast<unsigned>(LMUL)); 1119 MachineSDNode *Load = 1120 CurDAG->getMachineNode(P->Pseudo, DL, Node->getVTList(), Operands); 1121 1122 if (auto *MemOp = dyn_cast<MemSDNode>(Node)) 1123 CurDAG->setNodeMemRefs(Load, {MemOp->getMemOperand()}); 1124 1125 ReplaceNode(Node, Load); 1126 return; 1127 } 1128 case Intrinsic::riscv_vleff: 1129 case Intrinsic::riscv_vleff_mask: { 1130 bool IsMasked = IntNo == Intrinsic::riscv_vleff_mask; 1131 1132 MVT VT = Node->getSimpleValueType(0); 1133 unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits()); 1134 1135 unsigned CurOp = 2; 1136 SmallVector<SDValue, 7> Operands; 1137 if (IsMasked) 1138 Operands.push_back(Node->getOperand(CurOp++)); 1139 1140 addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked, 1141 /*IsStridedOrIndexed*/ false, Operands); 1142 1143 RISCVII::VLMUL LMUL = RISCVTargetLowering::getLMUL(VT); 1144 const RISCV::VLEPseudo *P = 1145 RISCV::getVLEPseudo(IsMasked, /*Strided*/ false, /*FF*/ true, Log2SEW, 1146 static_cast<unsigned>(LMUL)); 1147 MachineSDNode *Load = 1148 CurDAG->getMachineNode(P->Pseudo, DL, Node->getValueType(0), 1149 MVT::Other, MVT::Glue, Operands); 1150 SDNode *ReadVL = CurDAG->getMachineNode(RISCV::PseudoReadVL, DL, XLenVT, 1151 /*Glue*/ SDValue(Load, 2)); 1152 1153 if (auto *MemOp = dyn_cast<MemSDNode>(Node)) 1154 CurDAG->setNodeMemRefs(Load, {MemOp->getMemOperand()}); 1155 1156 ReplaceUses(SDValue(Node, 0), SDValue(Load, 0)); 1157 ReplaceUses(SDValue(Node, 1), SDValue(ReadVL, 0)); // VL 1158 ReplaceUses(SDValue(Node, 2), SDValue(Load, 1)); // Chain 1159 CurDAG->RemoveDeadNode(Node); 1160 return; 1161 } 1162 } 1163 break; 1164 } 1165 case ISD::INTRINSIC_VOID: { 1166 unsigned IntNo = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue(); 1167 switch (IntNo) { 1168 case Intrinsic::riscv_vsseg2: 1169 case Intrinsic::riscv_vsseg3: 1170 case Intrinsic::riscv_vsseg4: 1171 case Intrinsic::riscv_vsseg5: 1172 case Intrinsic::riscv_vsseg6: 1173 case Intrinsic::riscv_vsseg7: 1174 case Intrinsic::riscv_vsseg8: { 1175 selectVSSEG(Node, /*IsMasked*/ false, /*IsStrided*/ false); 1176 return; 1177 } 1178 case Intrinsic::riscv_vsseg2_mask: 1179 case Intrinsic::riscv_vsseg3_mask: 1180 case Intrinsic::riscv_vsseg4_mask: 1181 case Intrinsic::riscv_vsseg5_mask: 1182 case Intrinsic::riscv_vsseg6_mask: 1183 case Intrinsic::riscv_vsseg7_mask: 1184 case Intrinsic::riscv_vsseg8_mask: { 1185 selectVSSEG(Node, /*IsMasked*/ true, /*IsStrided*/ false); 1186 return; 1187 } 1188 case Intrinsic::riscv_vssseg2: 1189 case Intrinsic::riscv_vssseg3: 1190 case Intrinsic::riscv_vssseg4: 1191 case Intrinsic::riscv_vssseg5: 1192 case Intrinsic::riscv_vssseg6: 1193 case Intrinsic::riscv_vssseg7: 1194 case Intrinsic::riscv_vssseg8: { 1195 selectVSSEG(Node, /*IsMasked*/ false, /*IsStrided*/ true); 1196 return; 1197 } 1198 case Intrinsic::riscv_vssseg2_mask: 1199 case Intrinsic::riscv_vssseg3_mask: 1200 case Intrinsic::riscv_vssseg4_mask: 1201 case Intrinsic::riscv_vssseg5_mask: 1202 case Intrinsic::riscv_vssseg6_mask: 1203 case Intrinsic::riscv_vssseg7_mask: 1204 case Intrinsic::riscv_vssseg8_mask: { 1205 selectVSSEG(Node, /*IsMasked*/ true, /*IsStrided*/ true); 1206 return; 1207 } 1208 case Intrinsic::riscv_vsoxseg2: 1209 case Intrinsic::riscv_vsoxseg3: 1210 case Intrinsic::riscv_vsoxseg4: 1211 case Intrinsic::riscv_vsoxseg5: 1212 case Intrinsic::riscv_vsoxseg6: 1213 case Intrinsic::riscv_vsoxseg7: 1214 case Intrinsic::riscv_vsoxseg8: 1215 selectVSXSEG(Node, /*IsMasked*/ false, /*IsOrdered*/ true); 1216 return; 1217 case Intrinsic::riscv_vsuxseg2: 1218 case Intrinsic::riscv_vsuxseg3: 1219 case Intrinsic::riscv_vsuxseg4: 1220 case Intrinsic::riscv_vsuxseg5: 1221 case Intrinsic::riscv_vsuxseg6: 1222 case Intrinsic::riscv_vsuxseg7: 1223 case Intrinsic::riscv_vsuxseg8: 1224 selectVSXSEG(Node, /*IsMasked*/ false, /*IsOrdered*/ false); 1225 return; 1226 case Intrinsic::riscv_vsoxseg2_mask: 1227 case Intrinsic::riscv_vsoxseg3_mask: 1228 case Intrinsic::riscv_vsoxseg4_mask: 1229 case Intrinsic::riscv_vsoxseg5_mask: 1230 case Intrinsic::riscv_vsoxseg6_mask: 1231 case Intrinsic::riscv_vsoxseg7_mask: 1232 case Intrinsic::riscv_vsoxseg8_mask: 1233 selectVSXSEG(Node, /*IsMasked*/ true, /*IsOrdered*/ true); 1234 return; 1235 case Intrinsic::riscv_vsuxseg2_mask: 1236 case Intrinsic::riscv_vsuxseg3_mask: 1237 case Intrinsic::riscv_vsuxseg4_mask: 1238 case Intrinsic::riscv_vsuxseg5_mask: 1239 case Intrinsic::riscv_vsuxseg6_mask: 1240 case Intrinsic::riscv_vsuxseg7_mask: 1241 case Intrinsic::riscv_vsuxseg8_mask: 1242 selectVSXSEG(Node, /*IsMasked*/ true, /*IsOrdered*/ false); 1243 return; 1244 case Intrinsic::riscv_vsoxei: 1245 case Intrinsic::riscv_vsoxei_mask: 1246 case Intrinsic::riscv_vsuxei: 1247 case Intrinsic::riscv_vsuxei_mask: { 1248 bool IsMasked = IntNo == Intrinsic::riscv_vsoxei_mask || 1249 IntNo == Intrinsic::riscv_vsuxei_mask; 1250 bool IsOrdered = IntNo == Intrinsic::riscv_vsoxei || 1251 IntNo == Intrinsic::riscv_vsoxei_mask; 1252 1253 MVT VT = Node->getOperand(2)->getSimpleValueType(0); 1254 unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits()); 1255 1256 unsigned CurOp = 2; 1257 SmallVector<SDValue, 8> Operands; 1258 Operands.push_back(Node->getOperand(CurOp++)); // Store value. 1259 1260 MVT IndexVT; 1261 addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked, 1262 /*IsStridedOrIndexed*/ true, Operands, 1263 &IndexVT); 1264 1265 assert(VT.getVectorElementCount() == IndexVT.getVectorElementCount() && 1266 "Element count mismatch"); 1267 1268 RISCVII::VLMUL LMUL = RISCVTargetLowering::getLMUL(VT); 1269 RISCVII::VLMUL IndexLMUL = RISCVTargetLowering::getLMUL(IndexVT); 1270 unsigned IndexLog2EEW = Log2_32(IndexVT.getScalarSizeInBits()); 1271 const RISCV::VLX_VSXPseudo *P = RISCV::getVSXPseudo( 1272 IsMasked, IsOrdered, IndexLog2EEW, static_cast<unsigned>(LMUL), 1273 static_cast<unsigned>(IndexLMUL)); 1274 MachineSDNode *Store = 1275 CurDAG->getMachineNode(P->Pseudo, DL, Node->getVTList(), Operands); 1276 1277 if (auto *MemOp = dyn_cast<MemSDNode>(Node)) 1278 CurDAG->setNodeMemRefs(Store, {MemOp->getMemOperand()}); 1279 1280 ReplaceNode(Node, Store); 1281 return; 1282 } 1283 case Intrinsic::riscv_vse1: 1284 case Intrinsic::riscv_vse: 1285 case Intrinsic::riscv_vse_mask: 1286 case Intrinsic::riscv_vsse: 1287 case Intrinsic::riscv_vsse_mask: { 1288 bool IsMasked = IntNo == Intrinsic::riscv_vse_mask || 1289 IntNo == Intrinsic::riscv_vsse_mask; 1290 bool IsStrided = 1291 IntNo == Intrinsic::riscv_vsse || IntNo == Intrinsic::riscv_vsse_mask; 1292 1293 MVT VT = Node->getOperand(2)->getSimpleValueType(0); 1294 unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits()); 1295 1296 unsigned CurOp = 2; 1297 SmallVector<SDValue, 8> Operands; 1298 Operands.push_back(Node->getOperand(CurOp++)); // Store value. 1299 1300 addVectorLoadStoreOperands(Node, Log2SEW, DL, CurOp, IsMasked, IsStrided, 1301 Operands); 1302 1303 RISCVII::VLMUL LMUL = RISCVTargetLowering::getLMUL(VT); 1304 const RISCV::VSEPseudo *P = RISCV::getVSEPseudo( 1305 IsMasked, IsStrided, Log2SEW, static_cast<unsigned>(LMUL)); 1306 MachineSDNode *Store = 1307 CurDAG->getMachineNode(P->Pseudo, DL, Node->getVTList(), Operands); 1308 if (auto *MemOp = dyn_cast<MemSDNode>(Node)) 1309 CurDAG->setNodeMemRefs(Store, {MemOp->getMemOperand()}); 1310 1311 ReplaceNode(Node, Store); 1312 return; 1313 } 1314 } 1315 break; 1316 } 1317 case ISD::BITCAST: { 1318 MVT SrcVT = Node->getOperand(0).getSimpleValueType(); 1319 // Just drop bitcasts between vectors if both are fixed or both are 1320 // scalable. 1321 if ((VT.isScalableVector() && SrcVT.isScalableVector()) || 1322 (VT.isFixedLengthVector() && SrcVT.isFixedLengthVector())) { 1323 ReplaceUses(SDValue(Node, 0), Node->getOperand(0)); 1324 CurDAG->RemoveDeadNode(Node); 1325 return; 1326 } 1327 break; 1328 } 1329 case ISD::INSERT_SUBVECTOR: { 1330 SDValue V = Node->getOperand(0); 1331 SDValue SubV = Node->getOperand(1); 1332 SDLoc DL(SubV); 1333 auto Idx = Node->getConstantOperandVal(2); 1334 MVT SubVecVT = SubV.getSimpleValueType(); 1335 1336 const RISCVTargetLowering &TLI = *Subtarget->getTargetLowering(); 1337 MVT SubVecContainerVT = SubVecVT; 1338 // Establish the correct scalable-vector types for any fixed-length type. 1339 if (SubVecVT.isFixedLengthVector()) 1340 SubVecContainerVT = TLI.getContainerForFixedLengthVector(SubVecVT); 1341 if (VT.isFixedLengthVector()) 1342 VT = TLI.getContainerForFixedLengthVector(VT); 1343 1344 const auto *TRI = Subtarget->getRegisterInfo(); 1345 unsigned SubRegIdx; 1346 std::tie(SubRegIdx, Idx) = 1347 RISCVTargetLowering::decomposeSubvectorInsertExtractToSubRegs( 1348 VT, SubVecContainerVT, Idx, TRI); 1349 1350 // If the Idx hasn't been completely eliminated then this is a subvector 1351 // insert which doesn't naturally align to a vector register. These must 1352 // be handled using instructions to manipulate the vector registers. 1353 if (Idx != 0) 1354 break; 1355 1356 RISCVII::VLMUL SubVecLMUL = RISCVTargetLowering::getLMUL(SubVecContainerVT); 1357 bool IsSubVecPartReg = SubVecLMUL == RISCVII::VLMUL::LMUL_F2 || 1358 SubVecLMUL == RISCVII::VLMUL::LMUL_F4 || 1359 SubVecLMUL == RISCVII::VLMUL::LMUL_F8; 1360 (void)IsSubVecPartReg; // Silence unused variable warning without asserts. 1361 assert((!IsSubVecPartReg || V.isUndef()) && 1362 "Expecting lowering to have created legal INSERT_SUBVECTORs when " 1363 "the subvector is smaller than a full-sized register"); 1364 1365 // If we haven't set a SubRegIdx, then we must be going between 1366 // equally-sized LMUL groups (e.g. VR -> VR). This can be done as a copy. 1367 if (SubRegIdx == RISCV::NoSubRegister) { 1368 unsigned InRegClassID = RISCVTargetLowering::getRegClassIDForVecVT(VT); 1369 assert(RISCVTargetLowering::getRegClassIDForVecVT(SubVecContainerVT) == 1370 InRegClassID && 1371 "Unexpected subvector extraction"); 1372 SDValue RC = CurDAG->getTargetConstant(InRegClassID, DL, XLenVT); 1373 SDNode *NewNode = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, 1374 DL, VT, SubV, RC); 1375 ReplaceNode(Node, NewNode); 1376 return; 1377 } 1378 1379 SDValue Insert = CurDAG->getTargetInsertSubreg(SubRegIdx, DL, VT, V, SubV); 1380 ReplaceNode(Node, Insert.getNode()); 1381 return; 1382 } 1383 case ISD::EXTRACT_SUBVECTOR: { 1384 SDValue V = Node->getOperand(0); 1385 auto Idx = Node->getConstantOperandVal(1); 1386 MVT InVT = V.getSimpleValueType(); 1387 SDLoc DL(V); 1388 1389 const RISCVTargetLowering &TLI = *Subtarget->getTargetLowering(); 1390 MVT SubVecContainerVT = VT; 1391 // Establish the correct scalable-vector types for any fixed-length type. 1392 if (VT.isFixedLengthVector()) 1393 SubVecContainerVT = TLI.getContainerForFixedLengthVector(VT); 1394 if (InVT.isFixedLengthVector()) 1395 InVT = TLI.getContainerForFixedLengthVector(InVT); 1396 1397 const auto *TRI = Subtarget->getRegisterInfo(); 1398 unsigned SubRegIdx; 1399 std::tie(SubRegIdx, Idx) = 1400 RISCVTargetLowering::decomposeSubvectorInsertExtractToSubRegs( 1401 InVT, SubVecContainerVT, Idx, TRI); 1402 1403 // If the Idx hasn't been completely eliminated then this is a subvector 1404 // extract which doesn't naturally align to a vector register. These must 1405 // be handled using instructions to manipulate the vector registers. 1406 if (Idx != 0) 1407 break; 1408 1409 // If we haven't set a SubRegIdx, then we must be going between 1410 // equally-sized LMUL types (e.g. VR -> VR). This can be done as a copy. 1411 if (SubRegIdx == RISCV::NoSubRegister) { 1412 unsigned InRegClassID = RISCVTargetLowering::getRegClassIDForVecVT(InVT); 1413 assert(RISCVTargetLowering::getRegClassIDForVecVT(SubVecContainerVT) == 1414 InRegClassID && 1415 "Unexpected subvector extraction"); 1416 SDValue RC = CurDAG->getTargetConstant(InRegClassID, DL, XLenVT); 1417 SDNode *NewNode = 1418 CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, DL, VT, V, RC); 1419 ReplaceNode(Node, NewNode); 1420 return; 1421 } 1422 1423 SDValue Extract = CurDAG->getTargetExtractSubreg(SubRegIdx, DL, VT, V); 1424 ReplaceNode(Node, Extract.getNode()); 1425 return; 1426 } 1427 case RISCVISD::VMV_V_X_VL: 1428 case RISCVISD::VFMV_V_F_VL: { 1429 // Try to match splat of a scalar load to a strided load with stride of x0. 1430 SDValue Src = Node->getOperand(0); 1431 auto *Ld = dyn_cast<LoadSDNode>(Src); 1432 if (!Ld) 1433 break; 1434 EVT MemVT = Ld->getMemoryVT(); 1435 // The memory VT should be the same size as the element type. 1436 if (MemVT.getStoreSize() != VT.getVectorElementType().getStoreSize()) 1437 break; 1438 if (!IsProfitableToFold(Src, Node, Node) || 1439 !IsLegalToFold(Src, Node, Node, TM.getOptLevel())) 1440 break; 1441 1442 SDValue VL; 1443 selectVLOp(Node->getOperand(1), VL); 1444 1445 unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits()); 1446 SDValue SEW = CurDAG->getTargetConstant(Log2SEW, DL, XLenVT); 1447 1448 SDValue Operands[] = {Ld->getBasePtr(), 1449 CurDAG->getRegister(RISCV::X0, XLenVT), VL, SEW, 1450 Ld->getChain()}; 1451 1452 RISCVII::VLMUL LMUL = RISCVTargetLowering::getLMUL(VT); 1453 const RISCV::VLEPseudo *P = RISCV::getVLEPseudo( 1454 /*IsMasked*/ false, /*IsStrided*/ true, /*FF*/ false, Log2SEW, 1455 static_cast<unsigned>(LMUL)); 1456 MachineSDNode *Load = 1457 CurDAG->getMachineNode(P->Pseudo, DL, Node->getVTList(), Operands); 1458 1459 if (auto *MemOp = dyn_cast<MemSDNode>(Node)) 1460 CurDAG->setNodeMemRefs(Load, {MemOp->getMemOperand()}); 1461 1462 ReplaceNode(Node, Load); 1463 return; 1464 } 1465 } 1466 1467 // Select the default instruction. 1468 SelectCode(Node); 1469 } 1470 1471 bool RISCVDAGToDAGISel::SelectInlineAsmMemoryOperand( 1472 const SDValue &Op, unsigned ConstraintID, std::vector<SDValue> &OutOps) { 1473 switch (ConstraintID) { 1474 case InlineAsm::Constraint_m: 1475 // We just support simple memory operands that have a single address 1476 // operand and need no special handling. 1477 OutOps.push_back(Op); 1478 return false; 1479 case InlineAsm::Constraint_A: 1480 OutOps.push_back(Op); 1481 return false; 1482 default: 1483 break; 1484 } 1485 1486 return true; 1487 } 1488 1489 bool RISCVDAGToDAGISel::SelectAddrFI(SDValue Addr, SDValue &Base) { 1490 if (auto *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 1491 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), Subtarget->getXLenVT()); 1492 return true; 1493 } 1494 return false; 1495 } 1496 1497 bool RISCVDAGToDAGISel::SelectBaseAddr(SDValue Addr, SDValue &Base) { 1498 // If this is FrameIndex, select it directly. Otherwise just let it get 1499 // selected to a register independently. 1500 if (auto *FIN = dyn_cast<FrameIndexSDNode>(Addr)) 1501 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), Subtarget->getXLenVT()); 1502 else 1503 Base = Addr; 1504 return true; 1505 } 1506 1507 bool RISCVDAGToDAGISel::selectShiftMask(SDValue N, unsigned ShiftWidth, 1508 SDValue &ShAmt) { 1509 // Shift instructions on RISCV only read the lower 5 or 6 bits of the shift 1510 // amount. If there is an AND on the shift amount, we can bypass it if it 1511 // doesn't affect any of those bits. 1512 if (N.getOpcode() == ISD::AND && isa<ConstantSDNode>(N.getOperand(1))) { 1513 const APInt &AndMask = N->getConstantOperandAPInt(1); 1514 1515 // Since the max shift amount is a power of 2 we can subtract 1 to make a 1516 // mask that covers the bits needed to represent all shift amounts. 1517 assert(isPowerOf2_32(ShiftWidth) && "Unexpected max shift amount!"); 1518 APInt ShMask(AndMask.getBitWidth(), ShiftWidth - 1); 1519 1520 if (ShMask.isSubsetOf(AndMask)) { 1521 ShAmt = N.getOperand(0); 1522 return true; 1523 } 1524 1525 // SimplifyDemandedBits may have optimized the mask so try restoring any 1526 // bits that are known zero. 1527 KnownBits Known = CurDAG->computeKnownBits(N->getOperand(0)); 1528 if (ShMask.isSubsetOf(AndMask | Known.Zero)) { 1529 ShAmt = N.getOperand(0); 1530 return true; 1531 } 1532 } 1533 1534 ShAmt = N; 1535 return true; 1536 } 1537 1538 bool RISCVDAGToDAGISel::selectSExti32(SDValue N, SDValue &Val) { 1539 if (N.getOpcode() == ISD::SIGN_EXTEND_INREG && 1540 cast<VTSDNode>(N.getOperand(1))->getVT() == MVT::i32) { 1541 Val = N.getOperand(0); 1542 return true; 1543 } 1544 MVT VT = N.getSimpleValueType(); 1545 if (CurDAG->ComputeNumSignBits(N) > (VT.getSizeInBits() - 32)) { 1546 Val = N; 1547 return true; 1548 } 1549 1550 return false; 1551 } 1552 1553 bool RISCVDAGToDAGISel::selectZExti32(SDValue N, SDValue &Val) { 1554 if (N.getOpcode() == ISD::AND) { 1555 auto *C = dyn_cast<ConstantSDNode>(N.getOperand(1)); 1556 if (C && C->getZExtValue() == UINT64_C(0xFFFFFFFF)) { 1557 Val = N.getOperand(0); 1558 return true; 1559 } 1560 } 1561 MVT VT = N.getSimpleValueType(); 1562 APInt Mask = APInt::getHighBitsSet(VT.getSizeInBits(), 32); 1563 if (CurDAG->MaskedValueIsZero(N, Mask)) { 1564 Val = N; 1565 return true; 1566 } 1567 1568 return false; 1569 } 1570 1571 // Return true if all users of this SDNode* only consume the lower \p Bits. 1572 // This can be used to form W instructions for add/sub/mul/shl even when the 1573 // root isn't a sext_inreg. This can allow the ADDW/SUBW/MULW/SLLIW to CSE if 1574 // SimplifyDemandedBits has made it so some users see a sext_inreg and some 1575 // don't. The sext_inreg+add/sub/mul/shl will get selected, but still leave 1576 // the add/sub/mul/shl to become non-W instructions. By checking the users we 1577 // may be able to use a W instruction and CSE with the other instruction if 1578 // this has happened. We could try to detect that the CSE opportunity exists 1579 // before doing this, but that would be more complicated. 1580 // TODO: Does this need to look through AND/OR/XOR to their users to find more 1581 // opportunities. 1582 bool RISCVDAGToDAGISel::hasAllNBitUsers(SDNode *Node, unsigned Bits) const { 1583 assert((Node->getOpcode() == ISD::ADD || Node->getOpcode() == ISD::SUB || 1584 Node->getOpcode() == ISD::MUL || Node->getOpcode() == ISD::SHL || 1585 Node->getOpcode() == ISD::SRL || 1586 Node->getOpcode() == ISD::SIGN_EXTEND_INREG || 1587 isa<ConstantSDNode>(Node)) && 1588 "Unexpected opcode"); 1589 1590 for (auto UI = Node->use_begin(), UE = Node->use_end(); UI != UE; ++UI) { 1591 SDNode *User = *UI; 1592 // Users of this node should have already been instruction selected 1593 if (!User->isMachineOpcode()) 1594 return false; 1595 1596 // TODO: Add more opcodes? 1597 switch (User->getMachineOpcode()) { 1598 default: 1599 return false; 1600 case RISCV::ADDW: 1601 case RISCV::ADDIW: 1602 case RISCV::SUBW: 1603 case RISCV::MULW: 1604 case RISCV::SLLW: 1605 case RISCV::SLLIW: 1606 case RISCV::SRAW: 1607 case RISCV::SRAIW: 1608 case RISCV::SRLW: 1609 case RISCV::SRLIW: 1610 case RISCV::DIVW: 1611 case RISCV::DIVUW: 1612 case RISCV::REMW: 1613 case RISCV::REMUW: 1614 case RISCV::ROLW: 1615 case RISCV::RORW: 1616 case RISCV::RORIW: 1617 case RISCV::CLZW: 1618 case RISCV::CTZW: 1619 case RISCV::CPOPW: 1620 case RISCV::SLLIUW: 1621 case RISCV::FCVT_H_W: 1622 case RISCV::FCVT_H_WU: 1623 case RISCV::FCVT_S_W: 1624 case RISCV::FCVT_S_WU: 1625 case RISCV::FCVT_D_W: 1626 case RISCV::FCVT_D_WU: 1627 if (Bits < 32) 1628 return false; 1629 break; 1630 case RISCV::SLLI: 1631 // SLLI only uses the lower (XLen - ShAmt) bits. 1632 if (Bits < Subtarget->getXLen() - User->getConstantOperandVal(1)) 1633 return false; 1634 break; 1635 case RISCV::ADDUW: 1636 case RISCV::SH1ADDUW: 1637 case RISCV::SH2ADDUW: 1638 case RISCV::SH3ADDUW: 1639 // The first operand to add.uw/shXadd.uw is implicitly zero extended from 1640 // 32 bits. 1641 if (UI.getOperandNo() != 0 || Bits < 32) 1642 return false; 1643 break; 1644 case RISCV::SB: 1645 if (UI.getOperandNo() != 0 || Bits < 8) 1646 return false; 1647 break; 1648 case RISCV::SH: 1649 if (UI.getOperandNo() != 0 || Bits < 16) 1650 return false; 1651 break; 1652 case RISCV::SW: 1653 if (UI.getOperandNo() != 0 || Bits < 32) 1654 return false; 1655 break; 1656 } 1657 } 1658 1659 return true; 1660 } 1661 1662 // Select VL as a 5 bit immediate or a value that will become a register. This 1663 // allows us to choose betwen VSETIVLI or VSETVLI later. 1664 bool RISCVDAGToDAGISel::selectVLOp(SDValue N, SDValue &VL) { 1665 auto *C = dyn_cast<ConstantSDNode>(N); 1666 if (C && isUInt<5>(C->getZExtValue())) 1667 VL = CurDAG->getTargetConstant(C->getZExtValue(), SDLoc(N), 1668 N->getValueType(0)); 1669 else 1670 VL = N; 1671 1672 return true; 1673 } 1674 1675 bool RISCVDAGToDAGISel::selectVSplat(SDValue N, SDValue &SplatVal) { 1676 if (N.getOpcode() != ISD::SPLAT_VECTOR && 1677 N.getOpcode() != RISCVISD::SPLAT_VECTOR_I64 && 1678 N.getOpcode() != RISCVISD::VMV_V_X_VL) 1679 return false; 1680 SplatVal = N.getOperand(0); 1681 return true; 1682 } 1683 1684 using ValidateFn = bool (*)(int64_t); 1685 1686 static bool selectVSplatSimmHelper(SDValue N, SDValue &SplatVal, 1687 SelectionDAG &DAG, 1688 const RISCVSubtarget &Subtarget, 1689 ValidateFn ValidateImm) { 1690 if ((N.getOpcode() != ISD::SPLAT_VECTOR && 1691 N.getOpcode() != RISCVISD::SPLAT_VECTOR_I64 && 1692 N.getOpcode() != RISCVISD::VMV_V_X_VL) || 1693 !isa<ConstantSDNode>(N.getOperand(0))) 1694 return false; 1695 1696 int64_t SplatImm = cast<ConstantSDNode>(N.getOperand(0))->getSExtValue(); 1697 1698 // ISD::SPLAT_VECTOR, RISCVISD::SPLAT_VECTOR_I64 and RISCVISD::VMV_V_X_VL 1699 // share semantics when the operand type is wider than the resulting vector 1700 // element type: an implicit truncation first takes place. Therefore, perform 1701 // a manual truncation/sign-extension in order to ignore any truncated bits 1702 // and catch any zero-extended immediate. 1703 // For example, we wish to match (i8 -1) -> (XLenVT 255) as a simm5 by first 1704 // sign-extending to (XLenVT -1). 1705 MVT XLenVT = Subtarget.getXLenVT(); 1706 assert(XLenVT == N.getOperand(0).getSimpleValueType() && 1707 "Unexpected splat operand type"); 1708 MVT EltVT = N.getSimpleValueType().getVectorElementType(); 1709 if (EltVT.bitsLT(XLenVT)) 1710 SplatImm = SignExtend64(SplatImm, EltVT.getSizeInBits()); 1711 1712 if (!ValidateImm(SplatImm)) 1713 return false; 1714 1715 SplatVal = DAG.getTargetConstant(SplatImm, SDLoc(N), XLenVT); 1716 return true; 1717 } 1718 1719 bool RISCVDAGToDAGISel::selectVSplatSimm5(SDValue N, SDValue &SplatVal) { 1720 return selectVSplatSimmHelper(N, SplatVal, *CurDAG, *Subtarget, 1721 [](int64_t Imm) { return isInt<5>(Imm); }); 1722 } 1723 1724 bool RISCVDAGToDAGISel::selectVSplatSimm5Plus1(SDValue N, SDValue &SplatVal) { 1725 return selectVSplatSimmHelper( 1726 N, SplatVal, *CurDAG, *Subtarget, 1727 [](int64_t Imm) { return (isInt<5>(Imm) && Imm != -16) || Imm == 16; }); 1728 } 1729 1730 bool RISCVDAGToDAGISel::selectVSplatSimm5Plus1NonZero(SDValue N, 1731 SDValue &SplatVal) { 1732 return selectVSplatSimmHelper( 1733 N, SplatVal, *CurDAG, *Subtarget, [](int64_t Imm) { 1734 return Imm != 0 && ((isInt<5>(Imm) && Imm != -16) || Imm == 16); 1735 }); 1736 } 1737 1738 bool RISCVDAGToDAGISel::selectVSplatUimm5(SDValue N, SDValue &SplatVal) { 1739 if ((N.getOpcode() != ISD::SPLAT_VECTOR && 1740 N.getOpcode() != RISCVISD::SPLAT_VECTOR_I64 && 1741 N.getOpcode() != RISCVISD::VMV_V_X_VL) || 1742 !isa<ConstantSDNode>(N.getOperand(0))) 1743 return false; 1744 1745 int64_t SplatImm = cast<ConstantSDNode>(N.getOperand(0))->getSExtValue(); 1746 1747 if (!isUInt<5>(SplatImm)) 1748 return false; 1749 1750 SplatVal = 1751 CurDAG->getTargetConstant(SplatImm, SDLoc(N), Subtarget->getXLenVT()); 1752 1753 return true; 1754 } 1755 1756 bool RISCVDAGToDAGISel::selectRVVSimm5(SDValue N, unsigned Width, 1757 SDValue &Imm) { 1758 if (auto *C = dyn_cast<ConstantSDNode>(N)) { 1759 int64_t ImmVal = SignExtend64(C->getSExtValue(), Width); 1760 1761 if (!isInt<5>(ImmVal)) 1762 return false; 1763 1764 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(N), Subtarget->getXLenVT()); 1765 return true; 1766 } 1767 1768 return false; 1769 } 1770 1771 // Merge an ADDI into the offset of a load/store instruction where possible. 1772 // (load (addi base, off1), off2) -> (load base, off1+off2) 1773 // (store val, (addi base, off1), off2) -> (store val, base, off1+off2) 1774 // This is possible when off1+off2 fits a 12-bit immediate. 1775 bool RISCVDAGToDAGISel::doPeepholeLoadStoreADDI(SDNode *N) { 1776 int OffsetOpIdx; 1777 int BaseOpIdx; 1778 1779 // Only attempt this optimisation for I-type loads and S-type stores. 1780 switch (N->getMachineOpcode()) { 1781 default: 1782 return false; 1783 case RISCV::LB: 1784 case RISCV::LH: 1785 case RISCV::LW: 1786 case RISCV::LBU: 1787 case RISCV::LHU: 1788 case RISCV::LWU: 1789 case RISCV::LD: 1790 case RISCV::FLH: 1791 case RISCV::FLW: 1792 case RISCV::FLD: 1793 BaseOpIdx = 0; 1794 OffsetOpIdx = 1; 1795 break; 1796 case RISCV::SB: 1797 case RISCV::SH: 1798 case RISCV::SW: 1799 case RISCV::SD: 1800 case RISCV::FSH: 1801 case RISCV::FSW: 1802 case RISCV::FSD: 1803 BaseOpIdx = 1; 1804 OffsetOpIdx = 2; 1805 break; 1806 } 1807 1808 if (!isa<ConstantSDNode>(N->getOperand(OffsetOpIdx))) 1809 return false; 1810 1811 SDValue Base = N->getOperand(BaseOpIdx); 1812 1813 // If the base is an ADDI, we can merge it in to the load/store. 1814 if (!Base.isMachineOpcode() || Base.getMachineOpcode() != RISCV::ADDI) 1815 return false; 1816 1817 SDValue ImmOperand = Base.getOperand(1); 1818 uint64_t Offset2 = N->getConstantOperandVal(OffsetOpIdx); 1819 1820 if (auto *Const = dyn_cast<ConstantSDNode>(ImmOperand)) { 1821 int64_t Offset1 = Const->getSExtValue(); 1822 int64_t CombinedOffset = Offset1 + Offset2; 1823 if (!isInt<12>(CombinedOffset)) 1824 return false; 1825 ImmOperand = CurDAG->getTargetConstant(CombinedOffset, SDLoc(ImmOperand), 1826 ImmOperand.getValueType()); 1827 } else if (auto *GA = dyn_cast<GlobalAddressSDNode>(ImmOperand)) { 1828 // If the off1 in (addi base, off1) is a global variable's address (its 1829 // low part, really), then we can rely on the alignment of that variable 1830 // to provide a margin of safety before off1 can overflow the 12 bits. 1831 // Check if off2 falls within that margin; if so off1+off2 can't overflow. 1832 const DataLayout &DL = CurDAG->getDataLayout(); 1833 Align Alignment = GA->getGlobal()->getPointerAlignment(DL); 1834 if (Offset2 != 0 && Alignment <= Offset2) 1835 return false; 1836 int64_t Offset1 = GA->getOffset(); 1837 int64_t CombinedOffset = Offset1 + Offset2; 1838 ImmOperand = CurDAG->getTargetGlobalAddress( 1839 GA->getGlobal(), SDLoc(ImmOperand), ImmOperand.getValueType(), 1840 CombinedOffset, GA->getTargetFlags()); 1841 } else if (auto *CP = dyn_cast<ConstantPoolSDNode>(ImmOperand)) { 1842 // Ditto. 1843 Align Alignment = CP->getAlign(); 1844 if (Offset2 != 0 && Alignment <= Offset2) 1845 return false; 1846 int64_t Offset1 = CP->getOffset(); 1847 int64_t CombinedOffset = Offset1 + Offset2; 1848 ImmOperand = CurDAG->getTargetConstantPool( 1849 CP->getConstVal(), ImmOperand.getValueType(), CP->getAlign(), 1850 CombinedOffset, CP->getTargetFlags()); 1851 } else { 1852 return false; 1853 } 1854 1855 LLVM_DEBUG(dbgs() << "Folding add-immediate into mem-op:\nBase: "); 1856 LLVM_DEBUG(Base->dump(CurDAG)); 1857 LLVM_DEBUG(dbgs() << "\nN: "); 1858 LLVM_DEBUG(N->dump(CurDAG)); 1859 LLVM_DEBUG(dbgs() << "\n"); 1860 1861 // Modify the offset operand of the load/store. 1862 if (BaseOpIdx == 0) // Load 1863 CurDAG->UpdateNodeOperands(N, Base.getOperand(0), ImmOperand, 1864 N->getOperand(2)); 1865 else // Store 1866 CurDAG->UpdateNodeOperands(N, N->getOperand(0), Base.getOperand(0), 1867 ImmOperand, N->getOperand(3)); 1868 1869 return true; 1870 } 1871 1872 // Try to remove sext.w if the input is a W instruction or can be made into 1873 // a W instruction cheaply. 1874 bool RISCVDAGToDAGISel::doPeepholeSExtW(SDNode *N) { 1875 // Look for the sext.w pattern, addiw rd, rs1, 0. 1876 if (N->getMachineOpcode() != RISCV::ADDIW || 1877 !isNullConstant(N->getOperand(1))) 1878 return false; 1879 1880 SDValue N0 = N->getOperand(0); 1881 if (!N0.isMachineOpcode()) 1882 return false; 1883 1884 switch (N0.getMachineOpcode()) { 1885 default: 1886 break; 1887 case RISCV::ADD: 1888 case RISCV::ADDI: 1889 case RISCV::SUB: 1890 case RISCV::MUL: 1891 case RISCV::SLLI: { 1892 // Convert sext.w+add/sub/mul to their W instructions. This will create 1893 // a new independent instruction. This improves latency. 1894 unsigned Opc; 1895 switch (N0.getMachineOpcode()) { 1896 default: 1897 llvm_unreachable("Unexpected opcode!"); 1898 case RISCV::ADD: Opc = RISCV::ADDW; break; 1899 case RISCV::ADDI: Opc = RISCV::ADDIW; break; 1900 case RISCV::SUB: Opc = RISCV::SUBW; break; 1901 case RISCV::MUL: Opc = RISCV::MULW; break; 1902 case RISCV::SLLI: Opc = RISCV::SLLIW; break; 1903 } 1904 1905 SDValue N00 = N0.getOperand(0); 1906 SDValue N01 = N0.getOperand(1); 1907 1908 // Shift amount needs to be uimm5. 1909 if (N0.getMachineOpcode() == RISCV::SLLI && 1910 !isUInt<5>(cast<ConstantSDNode>(N01)->getSExtValue())) 1911 break; 1912 1913 SDNode *Result = 1914 CurDAG->getMachineNode(Opc, SDLoc(N), N->getValueType(0), 1915 N00, N01); 1916 ReplaceUses(N, Result); 1917 return true; 1918 } 1919 case RISCV::ADDW: 1920 case RISCV::ADDIW: 1921 case RISCV::SUBW: 1922 case RISCV::MULW: 1923 case RISCV::SLLIW: 1924 // Result is already sign extended just remove the sext.w. 1925 // NOTE: We only handle the nodes that are selected with hasAllWUsers. 1926 ReplaceUses(N, N0.getNode()); 1927 return true; 1928 } 1929 1930 return false; 1931 } 1932 1933 // This pass converts a legalized DAG into a RISCV-specific DAG, ready 1934 // for instruction scheduling. 1935 FunctionPass *llvm::createRISCVISelDag(RISCVTargetMachine &TM) { 1936 return new RISCVDAGToDAGISel(TM); 1937 } 1938