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