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