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