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