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