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