1 //===-- RISCVInstructionSelector.cpp -----------------------------*- C++ -*-==// 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 /// \file 9 /// This file implements the targeting of the InstructionSelector class for 10 /// RISC-V. 11 /// \todo This should be generated by TableGen. 12 //===----------------------------------------------------------------------===// 13 14 #include "MCTargetDesc/RISCVMatInt.h" 15 #include "RISCVRegisterBankInfo.h" 16 #include "RISCVSubtarget.h" 17 #include "RISCVTargetMachine.h" 18 #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h" 19 #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h" 20 #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h" 21 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" 22 #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h" 23 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 24 #include "llvm/CodeGen/MachineJumpTableInfo.h" 25 #include "llvm/IR/IntrinsicsRISCV.h" 26 #include "llvm/Support/Debug.h" 27 28 #define DEBUG_TYPE "riscv-isel" 29 30 using namespace llvm; 31 using namespace MIPatternMatch; 32 33 #define GET_GLOBALISEL_PREDICATE_BITSET 34 #include "RISCVGenGlobalISel.inc" 35 #undef GET_GLOBALISEL_PREDICATE_BITSET 36 37 namespace { 38 39 class RISCVInstructionSelector : public InstructionSelector { 40 public: 41 RISCVInstructionSelector(const RISCVTargetMachine &TM, 42 const RISCVSubtarget &STI, 43 const RISCVRegisterBankInfo &RBI); 44 45 bool select(MachineInstr &MI) override; 46 47 void setupMF(MachineFunction &MF, GISelKnownBits *KB, 48 CodeGenCoverage *CoverageInfo, ProfileSummaryInfo *PSI, 49 BlockFrequencyInfo *BFI) override { 50 InstructionSelector::setupMF(MF, KB, CoverageInfo, PSI, BFI); 51 MRI = &MF.getRegInfo(); 52 } 53 54 static const char *getName() { return DEBUG_TYPE; } 55 56 private: 57 const TargetRegisterClass * 58 getRegClassForTypeOnBank(LLT Ty, const RegisterBank &RB) const; 59 60 bool isRegInGprb(Register Reg) const; 61 bool isRegInFprb(Register Reg) const; 62 63 // tblgen-erated 'select' implementation, used as the initial selector for 64 // the patterns that don't require complex C++. 65 bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const; 66 67 // A lowering phase that runs before any selection attempts. 68 // Returns true if the instruction was modified. 69 void preISelLower(MachineInstr &MI, MachineIRBuilder &MIB); 70 71 bool replacePtrWithInt(MachineOperand &Op, MachineIRBuilder &MIB); 72 73 // Custom selection methods 74 bool selectCopy(MachineInstr &MI) const; 75 bool selectImplicitDef(MachineInstr &MI, MachineIRBuilder &MIB) const; 76 bool materializeImm(Register Reg, int64_t Imm, MachineIRBuilder &MIB) const; 77 bool selectAddr(MachineInstr &MI, MachineIRBuilder &MIB, bool IsLocal = true, 78 bool IsExternWeak = false) const; 79 bool selectSExtInreg(MachineInstr &MI, MachineIRBuilder &MIB) const; 80 bool selectSelect(MachineInstr &MI, MachineIRBuilder &MIB) const; 81 bool selectFPCompare(MachineInstr &MI, MachineIRBuilder &MIB) const; 82 void emitFence(AtomicOrdering FenceOrdering, SyncScope::ID FenceSSID, 83 MachineIRBuilder &MIB) const; 84 bool selectMergeValues(MachineInstr &MI, MachineIRBuilder &MIB) const; 85 bool selectUnmergeValues(MachineInstr &MI, MachineIRBuilder &MIB) const; 86 87 ComplexRendererFns selectShiftMask(MachineOperand &Root) const; 88 ComplexRendererFns selectAddrRegImm(MachineOperand &Root) const; 89 90 ComplexRendererFns selectSExtBits(MachineOperand &Root, unsigned Bits) const; 91 template <unsigned Bits> 92 ComplexRendererFns selectSExtBits(MachineOperand &Root) const { 93 return selectSExtBits(Root, Bits); 94 } 95 96 ComplexRendererFns selectZExtBits(MachineOperand &Root, unsigned Bits) const; 97 template <unsigned Bits> 98 ComplexRendererFns selectZExtBits(MachineOperand &Root) const { 99 return selectZExtBits(Root, Bits); 100 } 101 102 ComplexRendererFns selectSHXADDOp(MachineOperand &Root, unsigned ShAmt) const; 103 template <unsigned ShAmt> 104 ComplexRendererFns selectSHXADDOp(MachineOperand &Root) const { 105 return selectSHXADDOp(Root, ShAmt); 106 } 107 108 ComplexRendererFns selectSHXADD_UWOp(MachineOperand &Root, 109 unsigned ShAmt) const; 110 template <unsigned ShAmt> 111 ComplexRendererFns selectSHXADD_UWOp(MachineOperand &Root) const { 112 return selectSHXADD_UWOp(Root, ShAmt); 113 } 114 115 ComplexRendererFns renderVLOp(MachineOperand &Root) const; 116 117 // Custom renderers for tablegen 118 void renderNegImm(MachineInstrBuilder &MIB, const MachineInstr &MI, 119 int OpIdx) const; 120 void renderImmSubFromXLen(MachineInstrBuilder &MIB, const MachineInstr &MI, 121 int OpIdx) const; 122 void renderImmSubFrom32(MachineInstrBuilder &MIB, const MachineInstr &MI, 123 int OpIdx) const; 124 void renderImmPlus1(MachineInstrBuilder &MIB, const MachineInstr &MI, 125 int OpIdx) const; 126 void renderImm(MachineInstrBuilder &MIB, const MachineInstr &MI, 127 int OpIdx) const; 128 129 void renderTrailingZeros(MachineInstrBuilder &MIB, const MachineInstr &MI, 130 int OpIdx) const; 131 132 const RISCVSubtarget &STI; 133 const RISCVInstrInfo &TII; 134 const RISCVRegisterInfo &TRI; 135 const RISCVRegisterBankInfo &RBI; 136 const RISCVTargetMachine &TM; 137 138 MachineRegisterInfo *MRI = nullptr; 139 140 // FIXME: This is necessary because DAGISel uses "Subtarget->" and GlobalISel 141 // uses "STI." in the code generated by TableGen. We need to unify the name of 142 // Subtarget variable. 143 const RISCVSubtarget *Subtarget = &STI; 144 145 #define GET_GLOBALISEL_PREDICATES_DECL 146 #include "RISCVGenGlobalISel.inc" 147 #undef GET_GLOBALISEL_PREDICATES_DECL 148 149 #define GET_GLOBALISEL_TEMPORARIES_DECL 150 #include "RISCVGenGlobalISel.inc" 151 #undef GET_GLOBALISEL_TEMPORARIES_DECL 152 }; 153 154 } // end anonymous namespace 155 156 #define GET_GLOBALISEL_IMPL 157 #include "RISCVGenGlobalISel.inc" 158 #undef GET_GLOBALISEL_IMPL 159 160 RISCVInstructionSelector::RISCVInstructionSelector( 161 const RISCVTargetMachine &TM, const RISCVSubtarget &STI, 162 const RISCVRegisterBankInfo &RBI) 163 : STI(STI), TII(*STI.getInstrInfo()), TRI(*STI.getRegisterInfo()), RBI(RBI), 164 TM(TM), 165 166 #define GET_GLOBALISEL_PREDICATES_INIT 167 #include "RISCVGenGlobalISel.inc" 168 #undef GET_GLOBALISEL_PREDICATES_INIT 169 #define GET_GLOBALISEL_TEMPORARIES_INIT 170 #include "RISCVGenGlobalISel.inc" 171 #undef GET_GLOBALISEL_TEMPORARIES_INIT 172 { 173 } 174 175 InstructionSelector::ComplexRendererFns 176 RISCVInstructionSelector::selectShiftMask(MachineOperand &Root) const { 177 if (!Root.isReg()) 178 return std::nullopt; 179 180 using namespace llvm::MIPatternMatch; 181 182 Register RootReg = Root.getReg(); 183 Register ShAmtReg = RootReg; 184 const LLT ShiftLLT = MRI->getType(RootReg); 185 unsigned ShiftWidth = ShiftLLT.getSizeInBits(); 186 assert(isPowerOf2_32(ShiftWidth) && "Unexpected max shift amount!"); 187 // Peek through zext. 188 Register ZExtSrcReg; 189 if (mi_match(ShAmtReg, *MRI, m_GZExt(m_Reg(ZExtSrcReg)))) { 190 ShAmtReg = ZExtSrcReg; 191 } 192 193 APInt AndMask; 194 Register AndSrcReg; 195 // Try to combine the following pattern (applicable to other shift 196 // instructions as well as 32-bit ones): 197 // 198 // %4:gprb(s64) = G_AND %3, %2 199 // %5:gprb(s64) = G_LSHR %1, %4(s64) 200 // 201 // According to RISC-V's ISA manual, SLL, SRL, and SRA ignore other bits than 202 // the lowest log2(XLEN) bits of register rs2. As for the above pattern, if 203 // the lowest log2(XLEN) bits of register rd and rs2 of G_AND are the same, 204 // then it can be eliminated. Given register rs1 or rs2 holding a constant 205 // (the and mask), there are two cases G_AND can be erased: 206 // 207 // 1. the lowest log2(XLEN) bits of the and mask are all set 208 // 2. the bits of the register being masked are already unset (zero set) 209 if (mi_match(ShAmtReg, *MRI, m_GAnd(m_Reg(AndSrcReg), m_ICst(AndMask)))) { 210 APInt ShMask(AndMask.getBitWidth(), ShiftWidth - 1); 211 if (ShMask.isSubsetOf(AndMask)) { 212 ShAmtReg = AndSrcReg; 213 } else { 214 // SimplifyDemandedBits may have optimized the mask so try restoring any 215 // bits that are known zero. 216 KnownBits Known = KB->getKnownBits(AndSrcReg); 217 if (ShMask.isSubsetOf(AndMask | Known.Zero)) 218 ShAmtReg = AndSrcReg; 219 } 220 } 221 222 APInt Imm; 223 Register Reg; 224 if (mi_match(ShAmtReg, *MRI, m_GAdd(m_Reg(Reg), m_ICst(Imm)))) { 225 if (Imm != 0 && Imm.urem(ShiftWidth) == 0) 226 // If we are shifting by X+N where N == 0 mod Size, then just shift by X 227 // to avoid the ADD. 228 ShAmtReg = Reg; 229 } else if (mi_match(ShAmtReg, *MRI, m_GSub(m_ICst(Imm), m_Reg(Reg)))) { 230 if (Imm != 0 && Imm.urem(ShiftWidth) == 0) { 231 // If we are shifting by N-X where N == 0 mod Size, then just shift by -X 232 // to generate a NEG instead of a SUB of a constant. 233 ShAmtReg = MRI->createVirtualRegister(&RISCV::GPRRegClass); 234 unsigned NegOpc = Subtarget->is64Bit() ? RISCV::SUBW : RISCV::SUB; 235 return {{[=](MachineInstrBuilder &MIB) { 236 MachineIRBuilder(*MIB.getInstr()) 237 .buildInstr(NegOpc, {ShAmtReg}, {Register(RISCV::X0), Reg}); 238 MIB.addReg(ShAmtReg); 239 }}}; 240 } 241 if (Imm.urem(ShiftWidth) == ShiftWidth - 1) { 242 // If we are shifting by N-X where N == -1 mod Size, then just shift by ~X 243 // to generate a NOT instead of a SUB of a constant. 244 ShAmtReg = MRI->createVirtualRegister(&RISCV::GPRRegClass); 245 return {{[=](MachineInstrBuilder &MIB) { 246 MachineIRBuilder(*MIB.getInstr()) 247 .buildInstr(RISCV::XORI, {ShAmtReg}, {Reg}) 248 .addImm(-1); 249 MIB.addReg(ShAmtReg); 250 }}}; 251 } 252 } 253 254 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(ShAmtReg); }}}; 255 } 256 257 InstructionSelector::ComplexRendererFns 258 RISCVInstructionSelector::selectSExtBits(MachineOperand &Root, 259 unsigned Bits) const { 260 if (!Root.isReg()) 261 return std::nullopt; 262 Register RootReg = Root.getReg(); 263 MachineInstr *RootDef = MRI->getVRegDef(RootReg); 264 265 if (RootDef->getOpcode() == TargetOpcode::G_SEXT_INREG && 266 RootDef->getOperand(2).getImm() == Bits) { 267 return { 268 {[=](MachineInstrBuilder &MIB) { MIB.add(RootDef->getOperand(1)); }}}; 269 } 270 271 unsigned Size = MRI->getType(RootReg).getScalarSizeInBits(); 272 if ((Size - KB->computeNumSignBits(RootReg)) < Bits) 273 return {{[=](MachineInstrBuilder &MIB) { MIB.add(Root); }}}; 274 275 return std::nullopt; 276 } 277 278 InstructionSelector::ComplexRendererFns 279 RISCVInstructionSelector::selectZExtBits(MachineOperand &Root, 280 unsigned Bits) const { 281 if (!Root.isReg()) 282 return std::nullopt; 283 Register RootReg = Root.getReg(); 284 285 Register RegX; 286 uint64_t Mask = maskTrailingOnes<uint64_t>(Bits); 287 if (mi_match(RootReg, *MRI, m_GAnd(m_Reg(RegX), m_SpecificICst(Mask)))) { 288 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(RegX); }}}; 289 } 290 291 unsigned Size = MRI->getType(RootReg).getScalarSizeInBits(); 292 if (KB->maskedValueIsZero(RootReg, APInt::getBitsSetFrom(Size, Bits))) 293 return {{[=](MachineInstrBuilder &MIB) { MIB.add(Root); }}}; 294 295 return std::nullopt; 296 } 297 298 InstructionSelector::ComplexRendererFns 299 RISCVInstructionSelector::selectSHXADDOp(MachineOperand &Root, 300 unsigned ShAmt) const { 301 using namespace llvm::MIPatternMatch; 302 303 if (!Root.isReg()) 304 return std::nullopt; 305 Register RootReg = Root.getReg(); 306 307 const unsigned XLen = STI.getXLen(); 308 APInt Mask, C2; 309 Register RegY; 310 std::optional<bool> LeftShift; 311 // (and (shl y, c2), mask) 312 if (mi_match(RootReg, *MRI, 313 m_GAnd(m_GShl(m_Reg(RegY), m_ICst(C2)), m_ICst(Mask)))) 314 LeftShift = true; 315 // (and (lshr y, c2), mask) 316 else if (mi_match(RootReg, *MRI, 317 m_GAnd(m_GLShr(m_Reg(RegY), m_ICst(C2)), m_ICst(Mask)))) 318 LeftShift = false; 319 320 if (LeftShift.has_value()) { 321 if (*LeftShift) 322 Mask &= maskTrailingZeros<uint64_t>(C2.getLimitedValue()); 323 else 324 Mask &= maskTrailingOnes<uint64_t>(XLen - C2.getLimitedValue()); 325 326 if (Mask.isShiftedMask()) { 327 unsigned Leading = XLen - Mask.getActiveBits(); 328 unsigned Trailing = Mask.countr_zero(); 329 // Given (and (shl y, c2), mask) in which mask has no leading zeros and 330 // c3 trailing zeros. We can use an SRLI by c3 - c2 followed by a SHXADD. 331 if (*LeftShift && Leading == 0 && C2.ult(Trailing) && Trailing == ShAmt) { 332 Register DstReg = MRI->createVirtualRegister(&RISCV::GPRRegClass); 333 return {{[=](MachineInstrBuilder &MIB) { 334 MachineIRBuilder(*MIB.getInstr()) 335 .buildInstr(RISCV::SRLI, {DstReg}, {RegY}) 336 .addImm(Trailing - C2.getLimitedValue()); 337 MIB.addReg(DstReg); 338 }}}; 339 } 340 341 // Given (and (lshr y, c2), mask) in which mask has c2 leading zeros and 342 // c3 trailing zeros. We can use an SRLI by c2 + c3 followed by a SHXADD. 343 if (!*LeftShift && Leading == C2 && Trailing == ShAmt) { 344 Register DstReg = MRI->createVirtualRegister(&RISCV::GPRRegClass); 345 return {{[=](MachineInstrBuilder &MIB) { 346 MachineIRBuilder(*MIB.getInstr()) 347 .buildInstr(RISCV::SRLI, {DstReg}, {RegY}) 348 .addImm(Leading + Trailing); 349 MIB.addReg(DstReg); 350 }}}; 351 } 352 } 353 } 354 355 LeftShift.reset(); 356 357 // (shl (and y, mask), c2) 358 if (mi_match(RootReg, *MRI, 359 m_GShl(m_OneNonDBGUse(m_GAnd(m_Reg(RegY), m_ICst(Mask))), 360 m_ICst(C2)))) 361 LeftShift = true; 362 // (lshr (and y, mask), c2) 363 else if (mi_match(RootReg, *MRI, 364 m_GLShr(m_OneNonDBGUse(m_GAnd(m_Reg(RegY), m_ICst(Mask))), 365 m_ICst(C2)))) 366 LeftShift = false; 367 368 if (LeftShift.has_value() && Mask.isShiftedMask()) { 369 unsigned Leading = XLen - Mask.getActiveBits(); 370 unsigned Trailing = Mask.countr_zero(); 371 372 // Given (shl (and y, mask), c2) in which mask has 32 leading zeros and 373 // c3 trailing zeros. If c1 + c3 == ShAmt, we can emit SRLIW + SHXADD. 374 bool Cond = *LeftShift && Leading == 32 && Trailing > 0 && 375 (Trailing + C2.getLimitedValue()) == ShAmt; 376 if (!Cond) 377 // Given (lshr (and y, mask), c2) in which mask has 32 leading zeros and 378 // c3 trailing zeros. If c3 - c1 == ShAmt, we can emit SRLIW + SHXADD. 379 Cond = !*LeftShift && Leading == 32 && C2.ult(Trailing) && 380 (Trailing - C2.getLimitedValue()) == ShAmt; 381 382 if (Cond) { 383 Register DstReg = MRI->createVirtualRegister(&RISCV::GPRRegClass); 384 return {{[=](MachineInstrBuilder &MIB) { 385 MachineIRBuilder(*MIB.getInstr()) 386 .buildInstr(RISCV::SRLIW, {DstReg}, {RegY}) 387 .addImm(Trailing); 388 MIB.addReg(DstReg); 389 }}}; 390 } 391 } 392 393 return std::nullopt; 394 } 395 396 InstructionSelector::ComplexRendererFns 397 RISCVInstructionSelector::selectSHXADD_UWOp(MachineOperand &Root, 398 unsigned ShAmt) const { 399 using namespace llvm::MIPatternMatch; 400 401 if (!Root.isReg()) 402 return std::nullopt; 403 Register RootReg = Root.getReg(); 404 405 // Given (and (shl x, c2), mask) in which mask is a shifted mask with 406 // 32 - ShAmt leading zeros and c2 trailing zeros. We can use SLLI by 407 // c2 - ShAmt followed by SHXADD_UW with ShAmt for x amount. 408 APInt Mask, C2; 409 Register RegX; 410 if (mi_match( 411 RootReg, *MRI, 412 m_OneNonDBGUse(m_GAnd(m_OneNonDBGUse(m_GShl(m_Reg(RegX), m_ICst(C2))), 413 m_ICst(Mask))))) { 414 Mask &= maskTrailingZeros<uint64_t>(C2.getLimitedValue()); 415 416 if (Mask.isShiftedMask()) { 417 unsigned Leading = Mask.countl_zero(); 418 unsigned Trailing = Mask.countr_zero(); 419 if (Leading == 32 - ShAmt && C2 == Trailing && Trailing > ShAmt) { 420 Register DstReg = MRI->createVirtualRegister(&RISCV::GPRRegClass); 421 return {{[=](MachineInstrBuilder &MIB) { 422 MachineIRBuilder(*MIB.getInstr()) 423 .buildInstr(RISCV::SLLI, {DstReg}, {RegX}) 424 .addImm(C2.getLimitedValue() - ShAmt); 425 MIB.addReg(DstReg); 426 }}}; 427 } 428 } 429 } 430 431 return std::nullopt; 432 } 433 434 InstructionSelector::ComplexRendererFns 435 RISCVInstructionSelector::renderVLOp(MachineOperand &Root) const { 436 assert(Root.isReg() && "Expected operand to be a Register"); 437 MachineInstr *RootDef = MRI->getVRegDef(Root.getReg()); 438 439 if (RootDef->getOpcode() == TargetOpcode::G_CONSTANT) { 440 auto C = RootDef->getOperand(1).getCImm(); 441 if (C->getValue().isAllOnes()) 442 // If the operand is a G_CONSTANT with value of all ones it is larger than 443 // VLMAX. We convert it to an immediate with value VLMaxSentinel. This is 444 // recognized specially by the vsetvli insertion pass. 445 return {{[=](MachineInstrBuilder &MIB) { 446 MIB.addImm(RISCV::VLMaxSentinel); 447 }}}; 448 449 if (isUInt<5>(C->getZExtValue())) { 450 uint64_t ZExtC = C->getZExtValue(); 451 return {{[=](MachineInstrBuilder &MIB) { MIB.addImm(ZExtC); }}}; 452 } 453 } 454 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(Root.getReg()); }}}; 455 } 456 457 InstructionSelector::ComplexRendererFns 458 RISCVInstructionSelector::selectAddrRegImm(MachineOperand &Root) const { 459 if (!Root.isReg()) 460 return std::nullopt; 461 462 MachineInstr *RootDef = MRI->getVRegDef(Root.getReg()); 463 if (RootDef->getOpcode() == TargetOpcode::G_FRAME_INDEX) { 464 return {{ 465 [=](MachineInstrBuilder &MIB) { MIB.add(RootDef->getOperand(1)); }, 466 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }, 467 }}; 468 } 469 470 if (isBaseWithConstantOffset(Root, *MRI)) { 471 MachineOperand &LHS = RootDef->getOperand(1); 472 MachineOperand &RHS = RootDef->getOperand(2); 473 MachineInstr *LHSDef = MRI->getVRegDef(LHS.getReg()); 474 MachineInstr *RHSDef = MRI->getVRegDef(RHS.getReg()); 475 476 int64_t RHSC = RHSDef->getOperand(1).getCImm()->getSExtValue(); 477 if (isInt<12>(RHSC)) { 478 if (LHSDef->getOpcode() == TargetOpcode::G_FRAME_INDEX) 479 return {{ 480 [=](MachineInstrBuilder &MIB) { MIB.add(LHSDef->getOperand(1)); }, 481 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); }, 482 }}; 483 484 return {{[=](MachineInstrBuilder &MIB) { MIB.add(LHS); }, 485 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); }}}; 486 } 487 } 488 489 // TODO: Need to get the immediate from a G_PTR_ADD. Should this be done in 490 // the combiner? 491 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(Root.getReg()); }, 492 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }}}; 493 } 494 495 /// Returns the RISCVCC::CondCode that corresponds to the CmpInst::Predicate CC. 496 /// CC Must be an ICMP Predicate. 497 static RISCVCC::CondCode getRISCVCCFromICmp(CmpInst::Predicate CC) { 498 switch (CC) { 499 default: 500 llvm_unreachable("Expected ICMP CmpInst::Predicate."); 501 case CmpInst::Predicate::ICMP_EQ: 502 return RISCVCC::COND_EQ; 503 case CmpInst::Predicate::ICMP_NE: 504 return RISCVCC::COND_NE; 505 case CmpInst::Predicate::ICMP_ULT: 506 return RISCVCC::COND_LTU; 507 case CmpInst::Predicate::ICMP_SLT: 508 return RISCVCC::COND_LT; 509 case CmpInst::Predicate::ICMP_UGE: 510 return RISCVCC::COND_GEU; 511 case CmpInst::Predicate::ICMP_SGE: 512 return RISCVCC::COND_GE; 513 } 514 } 515 516 static void getOperandsForBranch(Register CondReg, RISCVCC::CondCode &CC, 517 Register &LHS, Register &RHS, 518 MachineRegisterInfo &MRI) { 519 // Try to fold an ICmp. If that fails, use a NE compare with X0. 520 CmpInst::Predicate Pred = CmpInst::BAD_ICMP_PREDICATE; 521 if (!mi_match(CondReg, MRI, m_GICmp(m_Pred(Pred), m_Reg(LHS), m_Reg(RHS)))) { 522 LHS = CondReg; 523 RHS = RISCV::X0; 524 CC = RISCVCC::COND_NE; 525 return; 526 } 527 528 // We found an ICmp, do some canonicalizations. 529 530 // Adjust comparisons to use comparison with 0 if possible. 531 if (auto Constant = getIConstantVRegSExtVal(RHS, MRI)) { 532 switch (Pred) { 533 case CmpInst::Predicate::ICMP_SGT: 534 // Convert X > -1 to X >= 0 535 if (*Constant == -1) { 536 CC = RISCVCC::COND_GE; 537 RHS = RISCV::X0; 538 return; 539 } 540 break; 541 case CmpInst::Predicate::ICMP_SLT: 542 // Convert X < 1 to 0 >= X 543 if (*Constant == 1) { 544 CC = RISCVCC::COND_GE; 545 RHS = LHS; 546 LHS = RISCV::X0; 547 return; 548 } 549 break; 550 default: 551 break; 552 } 553 } 554 555 switch (Pred) { 556 default: 557 llvm_unreachable("Expected ICMP CmpInst::Predicate."); 558 case CmpInst::Predicate::ICMP_EQ: 559 case CmpInst::Predicate::ICMP_NE: 560 case CmpInst::Predicate::ICMP_ULT: 561 case CmpInst::Predicate::ICMP_SLT: 562 case CmpInst::Predicate::ICMP_UGE: 563 case CmpInst::Predicate::ICMP_SGE: 564 // These CCs are supported directly by RISC-V branches. 565 break; 566 case CmpInst::Predicate::ICMP_SGT: 567 case CmpInst::Predicate::ICMP_SLE: 568 case CmpInst::Predicate::ICMP_UGT: 569 case CmpInst::Predicate::ICMP_ULE: 570 // These CCs are not supported directly by RISC-V branches, but changing the 571 // direction of the CC and swapping LHS and RHS are. 572 Pred = CmpInst::getSwappedPredicate(Pred); 573 std::swap(LHS, RHS); 574 break; 575 } 576 577 CC = getRISCVCCFromICmp(Pred); 578 return; 579 } 580 581 bool RISCVInstructionSelector::select(MachineInstr &MI) { 582 MachineBasicBlock &MBB = *MI.getParent(); 583 MachineFunction &MF = *MBB.getParent(); 584 MachineIRBuilder MIB(MI); 585 586 preISelLower(MI, MIB); 587 const unsigned Opc = MI.getOpcode(); 588 589 if (!MI.isPreISelOpcode() || Opc == TargetOpcode::G_PHI) { 590 if (Opc == TargetOpcode::PHI || Opc == TargetOpcode::G_PHI) { 591 const Register DefReg = MI.getOperand(0).getReg(); 592 const LLT DefTy = MRI->getType(DefReg); 593 594 const RegClassOrRegBank &RegClassOrBank = 595 MRI->getRegClassOrRegBank(DefReg); 596 597 const TargetRegisterClass *DefRC = 598 RegClassOrBank.dyn_cast<const TargetRegisterClass *>(); 599 if (!DefRC) { 600 if (!DefTy.isValid()) { 601 LLVM_DEBUG(dbgs() << "PHI operand has no type, not a gvreg?\n"); 602 return false; 603 } 604 605 const RegisterBank &RB = *RegClassOrBank.get<const RegisterBank *>(); 606 DefRC = getRegClassForTypeOnBank(DefTy, RB); 607 if (!DefRC) { 608 LLVM_DEBUG(dbgs() << "PHI operand has unexpected size/bank\n"); 609 return false; 610 } 611 } 612 613 MI.setDesc(TII.get(TargetOpcode::PHI)); 614 return RBI.constrainGenericRegister(DefReg, *DefRC, *MRI); 615 } 616 617 // Certain non-generic instructions also need some special handling. 618 if (MI.isCopy()) 619 return selectCopy(MI); 620 621 return true; 622 } 623 624 if (selectImpl(MI, *CoverageInfo)) 625 return true; 626 627 switch (Opc) { 628 case TargetOpcode::G_ANYEXT: 629 case TargetOpcode::G_PTRTOINT: 630 case TargetOpcode::G_INTTOPTR: 631 case TargetOpcode::G_TRUNC: 632 case TargetOpcode::G_FREEZE: 633 return selectCopy(MI); 634 case TargetOpcode::G_CONSTANT: { 635 Register DstReg = MI.getOperand(0).getReg(); 636 int64_t Imm = MI.getOperand(1).getCImm()->getSExtValue(); 637 638 if (!materializeImm(DstReg, Imm, MIB)) 639 return false; 640 641 MI.eraseFromParent(); 642 return true; 643 } 644 case TargetOpcode::G_FCONSTANT: { 645 // TODO: Use constant pool for complext constants. 646 // TODO: Optimize +0.0 to use fcvt.d.w for s64 on rv32. 647 Register DstReg = MI.getOperand(0).getReg(); 648 const APFloat &FPimm = MI.getOperand(1).getFPImm()->getValueAPF(); 649 APInt Imm = FPimm.bitcastToAPInt(); 650 unsigned Size = MRI->getType(DstReg).getSizeInBits(); 651 if (Size == 16 || Size == 32 || (Size == 64 && Subtarget->is64Bit())) { 652 Register GPRReg = MRI->createVirtualRegister(&RISCV::GPRRegClass); 653 if (!materializeImm(GPRReg, Imm.getSExtValue(), MIB)) 654 return false; 655 656 unsigned Opcode = Size == 64 ? RISCV::FMV_D_X 657 : Size == 32 ? RISCV::FMV_W_X 658 : RISCV::FMV_H_X; 659 auto FMV = MIB.buildInstr(Opcode, {DstReg}, {GPRReg}); 660 if (!FMV.constrainAllUses(TII, TRI, RBI)) 661 return false; 662 } else { 663 assert(Size == 64 && !Subtarget->is64Bit() && 664 "Unexpected size or subtarget"); 665 // Split into two pieces and build through the stack. 666 Register GPRRegHigh = MRI->createVirtualRegister(&RISCV::GPRRegClass); 667 Register GPRRegLow = MRI->createVirtualRegister(&RISCV::GPRRegClass); 668 if (!materializeImm(GPRRegHigh, Imm.extractBits(32, 32).getSExtValue(), 669 MIB)) 670 return false; 671 if (!materializeImm(GPRRegLow, Imm.trunc(32).getSExtValue(), MIB)) 672 return false; 673 MachineInstrBuilder PairF64 = MIB.buildInstr( 674 RISCV::BuildPairF64Pseudo, {DstReg}, {GPRRegLow, GPRRegHigh}); 675 if (!PairF64.constrainAllUses(TII, TRI, RBI)) 676 return false; 677 } 678 679 MI.eraseFromParent(); 680 return true; 681 } 682 case TargetOpcode::G_GLOBAL_VALUE: { 683 auto *GV = MI.getOperand(1).getGlobal(); 684 if (GV->isThreadLocal()) { 685 // TODO: implement this case. 686 return false; 687 } 688 689 return selectAddr(MI, MIB, GV->isDSOLocal(), GV->hasExternalWeakLinkage()); 690 } 691 case TargetOpcode::G_JUMP_TABLE: 692 case TargetOpcode::G_CONSTANT_POOL: 693 return selectAddr(MI, MIB, MRI); 694 case TargetOpcode::G_BRCOND: { 695 Register LHS, RHS; 696 RISCVCC::CondCode CC; 697 getOperandsForBranch(MI.getOperand(0).getReg(), CC, LHS, RHS, *MRI); 698 699 auto Bcc = MIB.buildInstr(RISCVCC::getBrCond(CC), {}, {LHS, RHS}) 700 .addMBB(MI.getOperand(1).getMBB()); 701 MI.eraseFromParent(); 702 return constrainSelectedInstRegOperands(*Bcc, TII, TRI, RBI); 703 } 704 case TargetOpcode::G_BRJT: { 705 // FIXME: Move to legalization? 706 const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo(); 707 unsigned EntrySize = MJTI->getEntrySize(MF.getDataLayout()); 708 assert((EntrySize == 4 || (Subtarget->is64Bit() && EntrySize == 8)) && 709 "Unsupported jump-table entry size"); 710 assert( 711 (MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 || 712 MJTI->getEntryKind() == MachineJumpTableInfo::EK_Custom32 || 713 MJTI->getEntryKind() == MachineJumpTableInfo::EK_BlockAddress) && 714 "Unexpected jump-table entry kind"); 715 716 auto SLL = 717 MIB.buildInstr(RISCV::SLLI, {&RISCV::GPRRegClass}, {MI.getOperand(2)}) 718 .addImm(Log2_32(EntrySize)); 719 if (!SLL.constrainAllUses(TII, TRI, RBI)) 720 return false; 721 722 // TODO: Use SHXADD. Moving to legalization would fix this automatically. 723 auto ADD = MIB.buildInstr(RISCV::ADD, {&RISCV::GPRRegClass}, 724 {MI.getOperand(0), SLL.getReg(0)}); 725 if (!ADD.constrainAllUses(TII, TRI, RBI)) 726 return false; 727 728 unsigned LdOpc = EntrySize == 8 ? RISCV::LD : RISCV::LW; 729 auto Dest = 730 MIB.buildInstr(LdOpc, {&RISCV::GPRRegClass}, {ADD.getReg(0)}) 731 .addImm(0) 732 .addMemOperand(MF.getMachineMemOperand( 733 MachinePointerInfo::getJumpTable(MF), MachineMemOperand::MOLoad, 734 EntrySize, Align(MJTI->getEntryAlignment(MF.getDataLayout())))); 735 if (!Dest.constrainAllUses(TII, TRI, RBI)) 736 return false; 737 738 // If the Kind is EK_LabelDifference32, the table stores an offset from 739 // the location of the table. Add the table address to get an absolute 740 // address. 741 if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32) { 742 Dest = MIB.buildInstr(RISCV::ADD, {&RISCV::GPRRegClass}, 743 {Dest.getReg(0), MI.getOperand(0)}); 744 if (!Dest.constrainAllUses(TII, TRI, RBI)) 745 return false; 746 } 747 748 auto Branch = 749 MIB.buildInstr(RISCV::PseudoBRIND, {}, {Dest.getReg(0)}).addImm(0); 750 if (!Branch.constrainAllUses(TII, TRI, RBI)) 751 return false; 752 753 MI.eraseFromParent(); 754 return true; 755 } 756 case TargetOpcode::G_BRINDIRECT: 757 MI.setDesc(TII.get(RISCV::PseudoBRIND)); 758 MI.addOperand(MachineOperand::CreateImm(0)); 759 return constrainSelectedInstRegOperands(MI, TII, TRI, RBI); 760 case TargetOpcode::G_SEXT_INREG: 761 return selectSExtInreg(MI, MIB); 762 case TargetOpcode::G_FRAME_INDEX: { 763 // TODO: We may want to replace this code with the SelectionDAG patterns, 764 // which fail to get imported because it uses FrameAddrRegImm, which is a 765 // ComplexPattern 766 MI.setDesc(TII.get(RISCV::ADDI)); 767 MI.addOperand(MachineOperand::CreateImm(0)); 768 return constrainSelectedInstRegOperands(MI, TII, TRI, RBI); 769 } 770 case TargetOpcode::G_SELECT: 771 return selectSelect(MI, MIB); 772 case TargetOpcode::G_FCMP: 773 return selectFPCompare(MI, MIB); 774 case TargetOpcode::G_FENCE: { 775 AtomicOrdering FenceOrdering = 776 static_cast<AtomicOrdering>(MI.getOperand(0).getImm()); 777 SyncScope::ID FenceSSID = 778 static_cast<SyncScope::ID>(MI.getOperand(1).getImm()); 779 emitFence(FenceOrdering, FenceSSID, MIB); 780 MI.eraseFromParent(); 781 return true; 782 } 783 case TargetOpcode::G_IMPLICIT_DEF: 784 return selectImplicitDef(MI, MIB); 785 case TargetOpcode::G_MERGE_VALUES: 786 return selectMergeValues(MI, MIB); 787 case TargetOpcode::G_UNMERGE_VALUES: 788 return selectUnmergeValues(MI, MIB); 789 default: 790 return false; 791 } 792 } 793 794 bool RISCVInstructionSelector::selectMergeValues(MachineInstr &MI, 795 MachineIRBuilder &MIB) const { 796 assert(MI.getOpcode() == TargetOpcode::G_MERGE_VALUES); 797 798 // Build a F64 Pair from operands 799 if (MI.getNumOperands() != 3) 800 return false; 801 Register Dst = MI.getOperand(0).getReg(); 802 Register Lo = MI.getOperand(1).getReg(); 803 Register Hi = MI.getOperand(2).getReg(); 804 if (!isRegInFprb(Dst) || !isRegInGprb(Lo) || !isRegInGprb(Hi)) 805 return false; 806 MI.setDesc(TII.get(RISCV::BuildPairF64Pseudo)); 807 return constrainSelectedInstRegOperands(MI, TII, TRI, RBI); 808 } 809 810 bool RISCVInstructionSelector::selectUnmergeValues( 811 MachineInstr &MI, MachineIRBuilder &MIB) const { 812 assert(MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES); 813 814 // Split F64 Src into two s32 parts 815 if (MI.getNumOperands() != 3) 816 return false; 817 Register Src = MI.getOperand(2).getReg(); 818 Register Lo = MI.getOperand(0).getReg(); 819 Register Hi = MI.getOperand(1).getReg(); 820 if (!isRegInFprb(Src) || !isRegInGprb(Lo) || !isRegInGprb(Hi)) 821 return false; 822 MI.setDesc(TII.get(RISCV::SplitF64Pseudo)); 823 return constrainSelectedInstRegOperands(MI, TII, TRI, RBI); 824 } 825 826 bool RISCVInstructionSelector::replacePtrWithInt(MachineOperand &Op, 827 MachineIRBuilder &MIB) { 828 Register PtrReg = Op.getReg(); 829 assert(MRI->getType(PtrReg).isPointer() && "Operand is not a pointer!"); 830 831 const LLT sXLen = LLT::scalar(STI.getXLen()); 832 auto PtrToInt = MIB.buildPtrToInt(sXLen, PtrReg); 833 MRI->setRegBank(PtrToInt.getReg(0), RBI.getRegBank(RISCV::GPRBRegBankID)); 834 Op.setReg(PtrToInt.getReg(0)); 835 return select(*PtrToInt); 836 } 837 838 void RISCVInstructionSelector::preISelLower(MachineInstr &MI, 839 MachineIRBuilder &MIB) { 840 switch (MI.getOpcode()) { 841 case TargetOpcode::G_PTR_ADD: { 842 Register DstReg = MI.getOperand(0).getReg(); 843 const LLT sXLen = LLT::scalar(STI.getXLen()); 844 845 replacePtrWithInt(MI.getOperand(1), MIB); 846 MI.setDesc(TII.get(TargetOpcode::G_ADD)); 847 MRI->setType(DstReg, sXLen); 848 break; 849 } 850 case TargetOpcode::G_PTRMASK: { 851 Register DstReg = MI.getOperand(0).getReg(); 852 const LLT sXLen = LLT::scalar(STI.getXLen()); 853 replacePtrWithInt(MI.getOperand(1), MIB); 854 MI.setDesc(TII.get(TargetOpcode::G_AND)); 855 MRI->setType(DstReg, sXLen); 856 break; 857 } 858 } 859 } 860 861 void RISCVInstructionSelector::renderNegImm(MachineInstrBuilder &MIB, 862 const MachineInstr &MI, 863 int OpIdx) const { 864 assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 && 865 "Expected G_CONSTANT"); 866 int64_t CstVal = MI.getOperand(1).getCImm()->getSExtValue(); 867 MIB.addImm(-CstVal); 868 } 869 870 void RISCVInstructionSelector::renderImmSubFromXLen(MachineInstrBuilder &MIB, 871 const MachineInstr &MI, 872 int OpIdx) const { 873 assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 && 874 "Expected G_CONSTANT"); 875 uint64_t CstVal = MI.getOperand(1).getCImm()->getZExtValue(); 876 MIB.addImm(STI.getXLen() - CstVal); 877 } 878 879 void RISCVInstructionSelector::renderImmSubFrom32(MachineInstrBuilder &MIB, 880 const MachineInstr &MI, 881 int OpIdx) const { 882 assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 && 883 "Expected G_CONSTANT"); 884 uint64_t CstVal = MI.getOperand(1).getCImm()->getZExtValue(); 885 MIB.addImm(32 - CstVal); 886 } 887 888 void RISCVInstructionSelector::renderImmPlus1(MachineInstrBuilder &MIB, 889 const MachineInstr &MI, 890 int OpIdx) const { 891 assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 && 892 "Expected G_CONSTANT"); 893 int64_t CstVal = MI.getOperand(1).getCImm()->getSExtValue(); 894 MIB.addImm(CstVal + 1); 895 } 896 897 void RISCVInstructionSelector::renderImm(MachineInstrBuilder &MIB, 898 const MachineInstr &MI, 899 int OpIdx) const { 900 assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 && 901 "Expected G_CONSTANT"); 902 int64_t CstVal = MI.getOperand(1).getCImm()->getSExtValue(); 903 MIB.addImm(CstVal); 904 } 905 906 void RISCVInstructionSelector::renderTrailingZeros(MachineInstrBuilder &MIB, 907 const MachineInstr &MI, 908 int OpIdx) const { 909 assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 && 910 "Expected G_CONSTANT"); 911 uint64_t C = MI.getOperand(1).getCImm()->getZExtValue(); 912 MIB.addImm(llvm::countr_zero(C)); 913 } 914 915 const TargetRegisterClass *RISCVInstructionSelector::getRegClassForTypeOnBank( 916 LLT Ty, const RegisterBank &RB) const { 917 if (RB.getID() == RISCV::GPRBRegBankID) { 918 if (Ty.getSizeInBits() <= 32 || (STI.is64Bit() && Ty.getSizeInBits() == 64)) 919 return &RISCV::GPRRegClass; 920 } 921 922 if (RB.getID() == RISCV::FPRBRegBankID) { 923 if (Ty.getSizeInBits() == 16) 924 return &RISCV::FPR16RegClass; 925 if (Ty.getSizeInBits() == 32) 926 return &RISCV::FPR32RegClass; 927 if (Ty.getSizeInBits() == 64) 928 return &RISCV::FPR64RegClass; 929 } 930 931 if (RB.getID() == RISCV::VRBRegBankID) { 932 if (Ty.getSizeInBits().getKnownMinValue() <= 64) 933 return &RISCV::VRRegClass; 934 935 if (Ty.getSizeInBits().getKnownMinValue() == 128) 936 return &RISCV::VRM2RegClass; 937 938 if (Ty.getSizeInBits().getKnownMinValue() == 256) 939 return &RISCV::VRM4RegClass; 940 941 if (Ty.getSizeInBits().getKnownMinValue() == 512) 942 return &RISCV::VRM8RegClass; 943 } 944 945 return nullptr; 946 } 947 948 bool RISCVInstructionSelector::isRegInGprb(Register Reg) const { 949 return RBI.getRegBank(Reg, *MRI, TRI)->getID() == RISCV::GPRBRegBankID; 950 } 951 952 bool RISCVInstructionSelector::isRegInFprb(Register Reg) const { 953 return RBI.getRegBank(Reg, *MRI, TRI)->getID() == RISCV::FPRBRegBankID; 954 } 955 956 bool RISCVInstructionSelector::selectCopy(MachineInstr &MI) const { 957 Register DstReg = MI.getOperand(0).getReg(); 958 959 if (DstReg.isPhysical()) 960 return true; 961 962 const TargetRegisterClass *DstRC = getRegClassForTypeOnBank( 963 MRI->getType(DstReg), *RBI.getRegBank(DstReg, *MRI, TRI)); 964 assert(DstRC && 965 "Register class not available for LLT, register bank combination"); 966 967 // No need to constrain SrcReg. It will get constrained when 968 // we hit another of its uses or its defs. 969 // Copies do not have constraints. 970 if (!RBI.constrainGenericRegister(DstReg, *DstRC, *MRI)) { 971 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(MI.getOpcode()) 972 << " operand\n"); 973 return false; 974 } 975 976 MI.setDesc(TII.get(RISCV::COPY)); 977 return true; 978 } 979 980 bool RISCVInstructionSelector::selectImplicitDef(MachineInstr &MI, 981 MachineIRBuilder &MIB) const { 982 assert(MI.getOpcode() == TargetOpcode::G_IMPLICIT_DEF); 983 984 const Register DstReg = MI.getOperand(0).getReg(); 985 const TargetRegisterClass *DstRC = getRegClassForTypeOnBank( 986 MRI->getType(DstReg), *RBI.getRegBank(DstReg, *MRI, TRI)); 987 988 assert(DstRC && 989 "Register class not available for LLT, register bank combination"); 990 991 if (!RBI.constrainGenericRegister(DstReg, *DstRC, *MRI)) { 992 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(MI.getOpcode()) 993 << " operand\n"); 994 } 995 MI.setDesc(TII.get(TargetOpcode::IMPLICIT_DEF)); 996 return true; 997 } 998 999 bool RISCVInstructionSelector::materializeImm(Register DstReg, int64_t Imm, 1000 MachineIRBuilder &MIB) const { 1001 if (Imm == 0) { 1002 MIB.buildCopy(DstReg, Register(RISCV::X0)); 1003 RBI.constrainGenericRegister(DstReg, RISCV::GPRRegClass, *MRI); 1004 return true; 1005 } 1006 1007 RISCVMatInt::InstSeq Seq = RISCVMatInt::generateInstSeq(Imm, *Subtarget); 1008 unsigned NumInsts = Seq.size(); 1009 Register SrcReg = RISCV::X0; 1010 1011 for (unsigned i = 0; i < NumInsts; i++) { 1012 Register TmpReg = i < NumInsts - 1 1013 ? MRI->createVirtualRegister(&RISCV::GPRRegClass) 1014 : DstReg; 1015 const RISCVMatInt::Inst &I = Seq[i]; 1016 MachineInstr *Result; 1017 1018 switch (I.getOpndKind()) { 1019 case RISCVMatInt::Imm: 1020 // clang-format off 1021 Result = MIB.buildInstr(I.getOpcode(), {TmpReg}, {}) 1022 .addImm(I.getImm()); 1023 // clang-format on 1024 break; 1025 case RISCVMatInt::RegX0: 1026 Result = MIB.buildInstr(I.getOpcode(), {TmpReg}, 1027 {SrcReg, Register(RISCV::X0)}); 1028 break; 1029 case RISCVMatInt::RegReg: 1030 Result = MIB.buildInstr(I.getOpcode(), {TmpReg}, {SrcReg, SrcReg}); 1031 break; 1032 case RISCVMatInt::RegImm: 1033 Result = 1034 MIB.buildInstr(I.getOpcode(), {TmpReg}, {SrcReg}).addImm(I.getImm()); 1035 break; 1036 } 1037 1038 if (!constrainSelectedInstRegOperands(*Result, TII, TRI, RBI)) 1039 return false; 1040 1041 SrcReg = TmpReg; 1042 } 1043 1044 return true; 1045 } 1046 1047 bool RISCVInstructionSelector::selectAddr(MachineInstr &MI, 1048 MachineIRBuilder &MIB, bool IsLocal, 1049 bool IsExternWeak) const { 1050 assert((MI.getOpcode() == TargetOpcode::G_GLOBAL_VALUE || 1051 MI.getOpcode() == TargetOpcode::G_JUMP_TABLE || 1052 MI.getOpcode() == TargetOpcode::G_CONSTANT_POOL) && 1053 "Unexpected opcode"); 1054 1055 const MachineOperand &DispMO = MI.getOperand(1); 1056 1057 Register DefReg = MI.getOperand(0).getReg(); 1058 const LLT DefTy = MRI->getType(DefReg); 1059 1060 // When HWASAN is used and tagging of global variables is enabled 1061 // they should be accessed via the GOT, since the tagged address of a global 1062 // is incompatible with existing code models. This also applies to non-pic 1063 // mode. 1064 if (TM.isPositionIndependent() || Subtarget->allowTaggedGlobals()) { 1065 if (IsLocal && !Subtarget->allowTaggedGlobals()) { 1066 // Use PC-relative addressing to access the symbol. This generates the 1067 // pattern (PseudoLLA sym), which expands to (addi (auipc %pcrel_hi(sym)) 1068 // %pcrel_lo(auipc)). 1069 MI.setDesc(TII.get(RISCV::PseudoLLA)); 1070 return constrainSelectedInstRegOperands(MI, TII, TRI, RBI); 1071 } 1072 1073 // Use PC-relative addressing to access the GOT for this symbol, then 1074 // load the address from the GOT. This generates the pattern (PseudoLGA 1075 // sym), which expands to (ld (addi (auipc %got_pcrel_hi(sym)) 1076 // %pcrel_lo(auipc))). 1077 MachineFunction &MF = *MI.getParent()->getParent(); 1078 MachineMemOperand *MemOp = MF.getMachineMemOperand( 1079 MachinePointerInfo::getGOT(MF), 1080 MachineMemOperand::MOLoad | MachineMemOperand::MODereferenceable | 1081 MachineMemOperand::MOInvariant, 1082 DefTy, Align(DefTy.getSizeInBits() / 8)); 1083 1084 auto Result = MIB.buildInstr(RISCV::PseudoLGA, {DefReg}, {}) 1085 .addDisp(DispMO, 0) 1086 .addMemOperand(MemOp); 1087 1088 if (!constrainSelectedInstRegOperands(*Result, TII, TRI, RBI)) 1089 return false; 1090 1091 MI.eraseFromParent(); 1092 return true; 1093 } 1094 1095 switch (TM.getCodeModel()) { 1096 default: { 1097 reportGISelFailure(const_cast<MachineFunction &>(*MF), *TPC, *MORE, 1098 getName(), "Unsupported code model for lowering", MI); 1099 return false; 1100 } 1101 case CodeModel::Small: { 1102 // Must lie within a single 2 GiB address range and must lie between 1103 // absolute addresses -2 GiB and +2 GiB. This generates the pattern (addi 1104 // (lui %hi(sym)) %lo(sym)). 1105 Register AddrHiDest = MRI->createVirtualRegister(&RISCV::GPRRegClass); 1106 MachineInstr *AddrHi = MIB.buildInstr(RISCV::LUI, {AddrHiDest}, {}) 1107 .addDisp(DispMO, 0, RISCVII::MO_HI); 1108 1109 if (!constrainSelectedInstRegOperands(*AddrHi, TII, TRI, RBI)) 1110 return false; 1111 1112 auto Result = MIB.buildInstr(RISCV::ADDI, {DefReg}, {AddrHiDest}) 1113 .addDisp(DispMO, 0, RISCVII::MO_LO); 1114 1115 if (!constrainSelectedInstRegOperands(*Result, TII, TRI, RBI)) 1116 return false; 1117 1118 MI.eraseFromParent(); 1119 return true; 1120 } 1121 case CodeModel::Medium: 1122 // Emit LGA/LLA instead of the sequence it expands to because the pcrel_lo 1123 // relocation needs to reference a label that points to the auipc 1124 // instruction itself, not the global. This cannot be done inside the 1125 // instruction selector. 1126 if (IsExternWeak) { 1127 // An extern weak symbol may be undefined, i.e. have value 0, which may 1128 // not be within 2GiB of PC, so use GOT-indirect addressing to access the 1129 // symbol. This generates the pattern (PseudoLGA sym), which expands to 1130 // (ld (addi (auipc %got_pcrel_hi(sym)) %pcrel_lo(auipc))). 1131 MachineFunction &MF = *MI.getParent()->getParent(); 1132 MachineMemOperand *MemOp = MF.getMachineMemOperand( 1133 MachinePointerInfo::getGOT(MF), 1134 MachineMemOperand::MOLoad | MachineMemOperand::MODereferenceable | 1135 MachineMemOperand::MOInvariant, 1136 DefTy, Align(DefTy.getSizeInBits() / 8)); 1137 1138 auto Result = MIB.buildInstr(RISCV::PseudoLGA, {DefReg}, {}) 1139 .addDisp(DispMO, 0) 1140 .addMemOperand(MemOp); 1141 1142 if (!constrainSelectedInstRegOperands(*Result, TII, TRI, RBI)) 1143 return false; 1144 1145 MI.eraseFromParent(); 1146 return true; 1147 } 1148 1149 // Generate a sequence for accessing addresses within any 2GiB range 1150 // within the address space. This generates the pattern (PseudoLLA sym), 1151 // which expands to (addi (auipc %pcrel_hi(sym)) %pcrel_lo(auipc)). 1152 MI.setDesc(TII.get(RISCV::PseudoLLA)); 1153 return constrainSelectedInstRegOperands(MI, TII, TRI, RBI); 1154 } 1155 1156 return false; 1157 } 1158 1159 bool RISCVInstructionSelector::selectSExtInreg(MachineInstr &MI, 1160 MachineIRBuilder &MIB) const { 1161 Register DstReg = MI.getOperand(0).getReg(); 1162 Register SrcReg = MI.getOperand(1).getReg(); 1163 unsigned SrcSize = MI.getOperand(2).getImm(); 1164 1165 MachineInstr *NewMI; 1166 if (SrcSize == 32) { 1167 assert(Subtarget->is64Bit() && "Unexpected extend"); 1168 // addiw rd, rs, 0 (i.e. sext.w rd, rs) 1169 NewMI = MIB.buildInstr(RISCV::ADDIW, {DstReg}, {SrcReg}).addImm(0U); 1170 } else { 1171 assert(Subtarget->hasStdExtZbb() && "Unexpected extension"); 1172 assert((SrcSize == 8 || SrcSize == 16) && "Unexpected size"); 1173 unsigned Opc = SrcSize == 16 ? RISCV::SEXT_H : RISCV::SEXT_B; 1174 NewMI = MIB.buildInstr(Opc, {DstReg}, {SrcReg}); 1175 } 1176 1177 if (!constrainSelectedInstRegOperands(*NewMI, TII, TRI, RBI)) 1178 return false; 1179 1180 MI.eraseFromParent(); 1181 return true; 1182 } 1183 1184 bool RISCVInstructionSelector::selectSelect(MachineInstr &MI, 1185 MachineIRBuilder &MIB) const { 1186 auto &SelectMI = cast<GSelect>(MI); 1187 1188 Register LHS, RHS; 1189 RISCVCC::CondCode CC; 1190 getOperandsForBranch(SelectMI.getCondReg(), CC, LHS, RHS, *MRI); 1191 1192 Register DstReg = SelectMI.getReg(0); 1193 1194 unsigned Opc = RISCV::Select_GPR_Using_CC_GPR; 1195 if (RBI.getRegBank(DstReg, *MRI, TRI)->getID() == RISCV::FPRBRegBankID) { 1196 unsigned Size = MRI->getType(DstReg).getSizeInBits(); 1197 Opc = Size == 32 ? RISCV::Select_FPR32_Using_CC_GPR 1198 : RISCV::Select_FPR64_Using_CC_GPR; 1199 } 1200 1201 MachineInstr *Result = MIB.buildInstr(Opc) 1202 .addDef(DstReg) 1203 .addReg(LHS) 1204 .addReg(RHS) 1205 .addImm(CC) 1206 .addReg(SelectMI.getTrueReg()) 1207 .addReg(SelectMI.getFalseReg()); 1208 MI.eraseFromParent(); 1209 return constrainSelectedInstRegOperands(*Result, TII, TRI, RBI); 1210 } 1211 1212 // Convert an FCMP predicate to one of the supported F or D instructions. 1213 static unsigned getFCmpOpcode(CmpInst::Predicate Pred, unsigned Size) { 1214 assert((Size == 16 || Size == 32 || Size == 64) && "Unsupported size"); 1215 switch (Pred) { 1216 default: 1217 llvm_unreachable("Unsupported predicate"); 1218 case CmpInst::FCMP_OLT: 1219 return Size == 16 ? RISCV::FLT_H : Size == 32 ? RISCV::FLT_S : RISCV::FLT_D; 1220 case CmpInst::FCMP_OLE: 1221 return Size == 16 ? RISCV::FLE_H : Size == 32 ? RISCV::FLE_S : RISCV::FLE_D; 1222 case CmpInst::FCMP_OEQ: 1223 return Size == 16 ? RISCV::FEQ_H : Size == 32 ? RISCV::FEQ_S : RISCV::FEQ_D; 1224 } 1225 } 1226 1227 // Try legalizing an FCMP by swapping or inverting the predicate to one that 1228 // is supported. 1229 static bool legalizeFCmpPredicate(Register &LHS, Register &RHS, 1230 CmpInst::Predicate &Pred, bool &NeedInvert) { 1231 auto isLegalFCmpPredicate = [](CmpInst::Predicate Pred) { 1232 return Pred == CmpInst::FCMP_OLT || Pred == CmpInst::FCMP_OLE || 1233 Pred == CmpInst::FCMP_OEQ; 1234 }; 1235 1236 assert(!isLegalFCmpPredicate(Pred) && "Predicate already legal?"); 1237 1238 CmpInst::Predicate InvPred = CmpInst::getSwappedPredicate(Pred); 1239 if (isLegalFCmpPredicate(InvPred)) { 1240 Pred = InvPred; 1241 std::swap(LHS, RHS); 1242 return true; 1243 } 1244 1245 InvPred = CmpInst::getInversePredicate(Pred); 1246 NeedInvert = true; 1247 if (isLegalFCmpPredicate(InvPred)) { 1248 Pred = InvPred; 1249 return true; 1250 } 1251 InvPred = CmpInst::getSwappedPredicate(InvPred); 1252 if (isLegalFCmpPredicate(InvPred)) { 1253 Pred = InvPred; 1254 std::swap(LHS, RHS); 1255 return true; 1256 } 1257 1258 return false; 1259 } 1260 1261 // Emit a sequence of instructions to compare LHS and RHS using Pred. Return 1262 // the result in DstReg. 1263 // FIXME: Maybe we should expand this earlier. 1264 bool RISCVInstructionSelector::selectFPCompare(MachineInstr &MI, 1265 MachineIRBuilder &MIB) const { 1266 auto &CmpMI = cast<GFCmp>(MI); 1267 CmpInst::Predicate Pred = CmpMI.getCond(); 1268 1269 Register DstReg = CmpMI.getReg(0); 1270 Register LHS = CmpMI.getLHSReg(); 1271 Register RHS = CmpMI.getRHSReg(); 1272 1273 unsigned Size = MRI->getType(LHS).getSizeInBits(); 1274 assert((Size == 16 || Size == 32 || Size == 64) && "Unexpected size"); 1275 1276 Register TmpReg = DstReg; 1277 1278 bool NeedInvert = false; 1279 // First try swapping operands or inverting. 1280 if (legalizeFCmpPredicate(LHS, RHS, Pred, NeedInvert)) { 1281 if (NeedInvert) 1282 TmpReg = MRI->createVirtualRegister(&RISCV::GPRRegClass); 1283 auto Cmp = MIB.buildInstr(getFCmpOpcode(Pred, Size), {TmpReg}, {LHS, RHS}); 1284 if (!Cmp.constrainAllUses(TII, TRI, RBI)) 1285 return false; 1286 } else if (Pred == CmpInst::FCMP_ONE || Pred == CmpInst::FCMP_UEQ) { 1287 // fcmp one LHS, RHS => (OR (FLT LHS, RHS), (FLT RHS, LHS)) 1288 NeedInvert = Pred == CmpInst::FCMP_UEQ; 1289 auto Cmp1 = MIB.buildInstr(getFCmpOpcode(CmpInst::FCMP_OLT, Size), 1290 {&RISCV::GPRRegClass}, {LHS, RHS}); 1291 if (!Cmp1.constrainAllUses(TII, TRI, RBI)) 1292 return false; 1293 auto Cmp2 = MIB.buildInstr(getFCmpOpcode(CmpInst::FCMP_OLT, Size), 1294 {&RISCV::GPRRegClass}, {RHS, LHS}); 1295 if (!Cmp2.constrainAllUses(TII, TRI, RBI)) 1296 return false; 1297 if (NeedInvert) 1298 TmpReg = MRI->createVirtualRegister(&RISCV::GPRRegClass); 1299 auto Or = 1300 MIB.buildInstr(RISCV::OR, {TmpReg}, {Cmp1.getReg(0), Cmp2.getReg(0)}); 1301 if (!Or.constrainAllUses(TII, TRI, RBI)) 1302 return false; 1303 } else if (Pred == CmpInst::FCMP_ORD || Pred == CmpInst::FCMP_UNO) { 1304 // fcmp ord LHS, RHS => (AND (FEQ LHS, LHS), (FEQ RHS, RHS)) 1305 // FIXME: If LHS and RHS are the same we can use a single FEQ. 1306 NeedInvert = Pred == CmpInst::FCMP_UNO; 1307 auto Cmp1 = MIB.buildInstr(getFCmpOpcode(CmpInst::FCMP_OEQ, Size), 1308 {&RISCV::GPRRegClass}, {LHS, LHS}); 1309 if (!Cmp1.constrainAllUses(TII, TRI, RBI)) 1310 return false; 1311 auto Cmp2 = MIB.buildInstr(getFCmpOpcode(CmpInst::FCMP_OEQ, Size), 1312 {&RISCV::GPRRegClass}, {RHS, RHS}); 1313 if (!Cmp2.constrainAllUses(TII, TRI, RBI)) 1314 return false; 1315 if (NeedInvert) 1316 TmpReg = MRI->createVirtualRegister(&RISCV::GPRRegClass); 1317 auto And = 1318 MIB.buildInstr(RISCV::AND, {TmpReg}, {Cmp1.getReg(0), Cmp2.getReg(0)}); 1319 if (!And.constrainAllUses(TII, TRI, RBI)) 1320 return false; 1321 } else 1322 llvm_unreachable("Unhandled predicate"); 1323 1324 // Emit an XORI to invert the result if needed. 1325 if (NeedInvert) { 1326 auto Xor = MIB.buildInstr(RISCV::XORI, {DstReg}, {TmpReg}).addImm(1); 1327 if (!Xor.constrainAllUses(TII, TRI, RBI)) 1328 return false; 1329 } 1330 1331 MI.eraseFromParent(); 1332 return true; 1333 } 1334 1335 void RISCVInstructionSelector::emitFence(AtomicOrdering FenceOrdering, 1336 SyncScope::ID FenceSSID, 1337 MachineIRBuilder &MIB) const { 1338 if (STI.hasStdExtZtso()) { 1339 // The only fence that needs an instruction is a sequentially-consistent 1340 // cross-thread fence. 1341 if (FenceOrdering == AtomicOrdering::SequentiallyConsistent && 1342 FenceSSID == SyncScope::System) { 1343 // fence rw, rw 1344 MIB.buildInstr(RISCV::FENCE, {}, {}) 1345 .addImm(RISCVFenceField::R | RISCVFenceField::W) 1346 .addImm(RISCVFenceField::R | RISCVFenceField::W); 1347 return; 1348 } 1349 1350 // MEMBARRIER is a compiler barrier; it codegens to a no-op. 1351 MIB.buildInstr(TargetOpcode::MEMBARRIER, {}, {}); 1352 return; 1353 } 1354 1355 // singlethread fences only synchronize with signal handlers on the same 1356 // thread and thus only need to preserve instruction order, not actually 1357 // enforce memory ordering. 1358 if (FenceSSID == SyncScope::SingleThread) { 1359 MIB.buildInstr(TargetOpcode::MEMBARRIER, {}, {}); 1360 return; 1361 } 1362 1363 // Refer to Table A.6 in the version 2.3 draft of the RISC-V Instruction Set 1364 // Manual: Volume I. 1365 unsigned Pred, Succ; 1366 switch (FenceOrdering) { 1367 default: 1368 llvm_unreachable("Unexpected ordering"); 1369 case AtomicOrdering::AcquireRelease: 1370 // fence acq_rel -> fence.tso 1371 MIB.buildInstr(RISCV::FENCE_TSO, {}, {}); 1372 return; 1373 case AtomicOrdering::Acquire: 1374 // fence acquire -> fence r, rw 1375 Pred = RISCVFenceField::R; 1376 Succ = RISCVFenceField::R | RISCVFenceField::W; 1377 break; 1378 case AtomicOrdering::Release: 1379 // fence release -> fence rw, w 1380 Pred = RISCVFenceField::R | RISCVFenceField::W; 1381 Succ = RISCVFenceField::W; 1382 break; 1383 case AtomicOrdering::SequentiallyConsistent: 1384 // fence seq_cst -> fence rw, rw 1385 Pred = RISCVFenceField::R | RISCVFenceField::W; 1386 Succ = RISCVFenceField::R | RISCVFenceField::W; 1387 break; 1388 } 1389 MIB.buildInstr(RISCV::FENCE, {}, {}).addImm(Pred).addImm(Succ); 1390 } 1391 1392 namespace llvm { 1393 InstructionSelector * 1394 createRISCVInstructionSelector(const RISCVTargetMachine &TM, 1395 const RISCVSubtarget &Subtarget, 1396 const RISCVRegisterBankInfo &RBI) { 1397 return new RISCVInstructionSelector(TM, Subtarget, RBI); 1398 } 1399 } // end namespace llvm 1400