LLVM 24.0.0git
RISCVInstructionSelector.cpp
Go to the documentation of this file.
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
16#include "RISCVSubtarget.h"
17#include "RISCVTargetMachine.h"
25#include "llvm/IR/IntrinsicsRISCV.h"
26#include "llvm/Support/Debug.h"
27
28#define DEBUG_TYPE "riscv-isel"
29
30using namespace llvm;
31using namespace MIPatternMatch;
32
33#define GET_GLOBALISEL_PREDICATE_BITSET
34#include "RISCVGenGlobalISel.inc"
35#undef GET_GLOBALISEL_PREDICATE_BITSET
36
37namespace {
38
39class RISCVInstructionSelector : public InstructionSelector {
40public:
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, GISelValueTracking *VT,
48 CodeGenCoverage *CoverageInfo, ProfileSummaryInfo *PSI,
49 BlockFrequencyInfo *BFI) override {
50 InstructionSelector::setupMF(MF, VT, CoverageInfo, PSI, BFI);
51 MRI = &MF.getRegInfo();
52 }
53
54 static const char *getName() { return DEBUG_TYPE; }
55
56private:
57 static constexpr unsigned MaxRecursionDepth = 6;
58
59 bool hasAllNBitUsers(const MachineInstr &MI, unsigned Bits,
60 const unsigned Depth = 0) const;
61 bool hasAllHUsers(const MachineInstr &MI) const {
62 return hasAllNBitUsers(MI, 16);
63 }
64 bool hasAllWUsers(const MachineInstr &MI) const {
65 return hasAllNBitUsers(MI, 32);
66 }
67
68 bool isRegInGprb(Register Reg) const;
69 bool isRegInFprb(Register Reg) const;
70 bool isWorthFoldingAdd(Register AddResult) const;
71
72 // tblgen-erated 'select' implementation, used as the initial selector for
73 // the patterns that don't require complex C++.
74 bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
75
76 // A lowering phase that runs before any selection attempts.
77 // Returns true if the instruction was modified.
78 void preISelLower(MachineInstr &MI);
79
80 bool replacePtrWithInt(MachineInstr &MI, unsigned OpIdx);
81
82 // Custom selection methods
83 bool selectCopy(MachineInstr &MI) const;
84 bool selectImplicitDef(MachineInstr &MI) const;
85 bool materializeImm(Register Reg, int64_t Imm, MachineInstr &MI) const;
86 // Emit a constant-materialization instruction sequence.
87 bool materializeInstSeq(Register DstReg, const RISCVMatInt::InstSeq &Seq,
88 MachineInstr &MI) const;
89 bool selectAddr(MachineInstr &MI, bool IsLocal = true,
90 bool IsExternWeak = false) const;
91 bool selectSelect(MachineInstr &MI) const;
92 bool selectFPCompare(MachineInstr &MI) const;
93 void emitFence(AtomicOrdering FenceOrdering, SyncScope::ID FenceSSID,
94 MachineInstr &MI) const;
97 void addVectorLoadStoreOperands(MachineInstr &I,
99 unsigned &CurOp, bool IsMasked,
100 bool IsStridedOrIndexed,
101 LLT *IndexVT = nullptr) const;
102 bool selectIntrinsicWithSideEffects(MachineInstr &I) const;
103 bool selectIntrinsic(MachineInstr &I) const;
104 bool selectExtractSubvector(MachineInstr &MI) const;
105 bool selectInsertSubVector(MachineInstr &I) const;
106 ComplexRendererFns selectShiftMask(MachineOperand &Root,
107 unsigned ShiftWidth) const;
108 ComplexRendererFns selectShiftMaskXLen(MachineOperand &Root) const {
109 return selectShiftMask(Root, STI.getXLen());
110 }
111 ComplexRendererFns selectShiftMask32(MachineOperand &Root) const {
112 return selectShiftMask(Root, 32);
113 }
114 ComplexRendererFns selectAddrRegImm(MachineOperand &Root) const;
115 ComplexRendererFns selectBrindRegImm(MachineOperand &Root) const;
116 ComplexRendererFns selectAddrRegImmLsb00000(MachineOperand &Root) const;
117
118 // Plan for materializing a constant address as (Hi materialization, Lo12
119 // offset). Lo12 is a simm12 that, for prefetch (IsPrefetch), must be
120 // a multiple of 32.
121 struct ConstAddrPlan {
122 enum { X0, LUI, InstSeq } Kind = X0;
123 int64_t Hi20 = 0;
125 int64_t Lo12 = 0;
126 };
127 ComplexRendererFns computeConstAddr(int64_t CVal, bool IsPrefetch,
128 Register OrigBase) const;
129 // Materialize the high part of Plan into a register. If OrigBase is valid,
130 // ADD it to the materialized high part (for G_PTR_ADD + large constant).
131 Register materializeConstBase(MachineInstrBuilder &MIB,
132 const ConstAddrPlan &Plan,
133 Register OrigBase) const;
134
135 ComplexRendererFns selectSExtBits(MachineOperand &Root, unsigned Bits) const;
136 template <unsigned Bits>
137 ComplexRendererFns selectSExtBits(MachineOperand &Root) const {
138 return selectSExtBits(Root, Bits);
139 }
140
141 ComplexRendererFns selectZExtBits(MachineOperand &Root, unsigned Bits) const;
142 template <unsigned Bits>
143 ComplexRendererFns selectZExtBits(MachineOperand &Root) const {
144 return selectZExtBits(Root, Bits);
145 }
146
147 ComplexRendererFns selectSHXADDOp(MachineOperand &Root, unsigned ShAmt) const;
148 template <unsigned ShAmt>
149 ComplexRendererFns selectSHXADDOp(MachineOperand &Root) const {
150 return selectSHXADDOp(Root, ShAmt);
151 }
152
153 ComplexRendererFns selectSHXADD_UWOp(MachineOperand &Root,
154 unsigned ShAmt) const;
155 template <unsigned ShAmt>
156 ComplexRendererFns selectSHXADD_UWOp(MachineOperand &Root) const {
157 return selectSHXADD_UWOp(Root, ShAmt);
158 }
159
160 ComplexRendererFns renderVLOp(MachineOperand &Root) const;
161 ComplexRendererFns renderAddiPair(Register BaseReg, int64_t AddiImm,
162 int64_t OffsetImm) const;
163 // Custom renderers for tablegen
164 void renderNegImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
165 int OpIdx) const;
166 void renderImmSubFromXLen(MachineInstrBuilder &MIB, const MachineInstr &MI,
167 int OpIdx) const;
168 void renderImmSubFrom32(MachineInstrBuilder &MIB, const MachineInstr &MI,
169 int OpIdx) const;
170 void renderImmPlus1(MachineInstrBuilder &MIB, const MachineInstr &MI,
171 int OpIdx) const;
172
173 void renderTrailingZeros(MachineInstrBuilder &MIB, const MachineInstr &MI,
174 int OpIdx) const;
175 void renderXLenSubTrailingOnes(MachineInstrBuilder &MIB,
176 const MachineInstr &MI, int OpIdx) const;
177
178 void renderAddiPairImmLarge(MachineInstrBuilder &MIB, const MachineInstr &MI,
179 int OpIdx) const;
180 void renderAddiPairImmSmall(MachineInstrBuilder &MIB, const MachineInstr &MI,
181 int OpIdx) const;
182
183 const RISCVSubtarget &STI;
184 const RISCVInstrInfo &TII;
185 const RISCVRegisterInfo &TRI;
186 const RISCVRegisterBankInfo &RBI;
187 const RISCVTargetMachine &TM;
188
189 MachineRegisterInfo *MRI = nullptr;
190
191 // FIXME: This is necessary because DAGISel uses "Subtarget->" and GlobalISel
192 // uses "STI." in the code generated by TableGen. We need to unify the name of
193 // Subtarget variable.
194 const RISCVSubtarget *Subtarget = &STI;
195
196#define GET_GLOBALISEL_PREDICATES_DECL
197#include "RISCVGenGlobalISel.inc"
198#undef GET_GLOBALISEL_PREDICATES_DECL
199
200#define GET_GLOBALISEL_TEMPORARIES_DECL
201#include "RISCVGenGlobalISel.inc"
202#undef GET_GLOBALISEL_TEMPORARIES_DECL
203};
204
205} // end anonymous namespace
206
207#define GET_GLOBALISEL_IMPL
208#include "RISCVGenGlobalISel.inc"
209#undef GET_GLOBALISEL_IMPL
210
211RISCVInstructionSelector::RISCVInstructionSelector(
212 const RISCVTargetMachine &TM, const RISCVSubtarget &STI,
213 const RISCVRegisterBankInfo &RBI)
214 : STI(STI), TII(*STI.getInstrInfo()), TRI(*STI.getRegisterInfo()), RBI(RBI),
215 TM(TM),
216
218#include "RISCVGenGlobalISel.inc"
221#include "RISCVGenGlobalISel.inc"
223{
224}
225
226// Mimics optimizations in ISel and RISCVOptWInst Pass
227bool RISCVInstructionSelector::hasAllNBitUsers(const MachineInstr &MI,
228 unsigned Bits,
229 const unsigned Depth) const {
230
231 assert((MI.getOpcode() == TargetOpcode::G_ADD ||
232 MI.getOpcode() == TargetOpcode::G_SUB ||
233 MI.getOpcode() == TargetOpcode::G_MUL ||
234 MI.getOpcode() == TargetOpcode::G_SHL ||
235 MI.getOpcode() == TargetOpcode::G_LSHR ||
236 MI.getOpcode() == TargetOpcode::G_AND ||
237 MI.getOpcode() == TargetOpcode::G_OR ||
238 MI.getOpcode() == TargetOpcode::G_XOR ||
239 MI.getOpcode() == TargetOpcode::G_SEXT_INREG || Depth != 0) &&
240 "Unexpected opcode");
241
242 if (Depth >= RISCVInstructionSelector::MaxRecursionDepth)
243 return false;
244
245 auto DestReg = MI.getOperand(0).getReg();
246 for (auto &UserOp : MRI->use_nodbg_operands(DestReg)) {
247 assert(UserOp.getParent() && "UserOp must have a parent");
248 const MachineInstr &UserMI = *UserOp.getParent();
249 unsigned OpIdx = UserOp.getOperandNo();
250
251 switch (UserMI.getOpcode()) {
252 default:
253 return false;
254 case RISCV::ADDW:
255 case RISCV::ADDIW:
256 case RISCV::SUBW:
257 case RISCV::FCVT_D_W:
258 case RISCV::FCVT_S_W:
259 if (Bits >= 32)
260 break;
261 return false;
262 case RISCV::SLL:
263 case RISCV::SRA:
264 case RISCV::SRL:
265 // Shift amount operands only use log2(Xlen) bits.
266 if (OpIdx == 2 && Bits >= Log2_32(Subtarget->getXLen()))
267 break;
268 return false;
269 case RISCV::SLLI:
270 // SLLI only uses the lower (XLen - ShAmt) bits.
271 if (Bits >= Subtarget->getXLen() - UserMI.getOperand(2).getImm())
272 break;
273 return false;
274 case RISCV::ANDI:
275 if (Bits >= (unsigned)llvm::bit_width<uint64_t>(
276 (uint64_t)UserMI.getOperand(2).getImm()))
277 break;
278 goto RecCheck;
279 case RISCV::AND:
280 case RISCV::OR:
281 case RISCV::XOR:
282 RecCheck:
283 if (hasAllNBitUsers(UserMI, Bits, Depth + 1))
284 break;
285 return false;
286 case RISCV::SRLI: {
287 unsigned ShAmt = UserMI.getOperand(2).getImm();
288 // If we are shifting right by less than Bits, and users don't demand any
289 // bits that were shifted into [Bits-1:0], then we can consider this as an
290 // N-Bit user.
291 if (Bits > ShAmt && hasAllNBitUsers(UserMI, Bits - ShAmt, Depth + 1))
292 break;
293 return false;
294 }
295 }
296 }
297
298 return true;
299}
300
301InstructionSelector::ComplexRendererFns
302RISCVInstructionSelector::selectShiftMask(MachineOperand &Root,
303 unsigned ShiftWidth) const {
304 if (!Root.isReg())
305 return std::nullopt;
306
307 using namespace llvm::MIPatternMatch;
308
309 Register ShAmtReg = Root.getReg();
310 // Peek through zext.
311 Register ZExtSrcReg;
312 if (mi_match(ShAmtReg, *MRI, m_GZExt(m_Reg(ZExtSrcReg))))
313 ShAmtReg = ZExtSrcReg;
314
315 APInt AndMask;
316 Register AndSrcReg;
317 // Try to combine the following pattern (applicable to other shift
318 // instructions as well as 32-bit ones):
319 //
320 // %4:gprb(s64) = G_AND %3, %2
321 // %5:gprb(s64) = G_LSHR %1, %4(s64)
322 //
323 // According to RISC-V's ISA manual, SLL, SRL, and SRA ignore other bits than
324 // the lowest log2(XLEN) bits of register rs2. As for the above pattern, if
325 // the lowest log2(XLEN) bits of register rd and rs2 of G_AND are the same,
326 // then it can be eliminated. Given register rs1 or rs2 holding a constant
327 // (the and mask), there are two cases G_AND can be erased:
328 //
329 // 1. the lowest log2(XLEN) bits of the and mask are all set
330 // 2. the bits of the register being masked are already unset (zero set)
331 if (mi_match(ShAmtReg, *MRI, m_GAnd(m_Reg(AndSrcReg), m_ICst(AndMask)))) {
332 APInt ShMask(AndMask.getBitWidth(), ShiftWidth - 1);
333 if (ShMask.isSubsetOf(AndMask)) {
334 ShAmtReg = AndSrcReg;
335 } else {
336 // SimplifyDemandedBits may have optimized the mask so try restoring any
337 // bits that are known zero.
338 KnownBits Known = VT->getKnownBits(AndSrcReg);
339 if (ShMask.isSubsetOf(AndMask | Known.Zero))
340 ShAmtReg = AndSrcReg;
341 }
342 }
343
344 APInt Imm;
346 if (mi_match(ShAmtReg, *MRI, m_GAdd(m_Reg(Reg), m_ICst(Imm)))) {
347 if (Imm != 0 && Imm.urem(ShiftWidth) == 0)
348 // If we are shifting by X+N where N == 0 mod Size, then just shift by X
349 // to avoid the ADD.
350 ShAmtReg = Reg;
351 } else if (mi_match(ShAmtReg, *MRI, m_GSub(m_ICst(Imm), m_Reg(Reg)))) {
352 if (Imm != 0 && Imm.urem(ShiftWidth) == 0) {
353 // If we are shifting by N-X where N == 0 mod Size, then just shift by -X
354 // to generate a NEG instead of a SUB of a constant.
355 ShAmtReg = MRI->createVirtualRegister(&RISCV::GPRRegClass);
356 unsigned NegOpc = Subtarget->is64Bit() ? RISCV::SUBW : RISCV::SUB;
357 return {{[=](MachineInstrBuilder &MIB) {
358 MachineIRBuilder(*MIB.getInstr())
359 .buildInstr(NegOpc, {ShAmtReg}, {Register(RISCV::X0), Reg});
360 MIB.addReg(ShAmtReg);
361 }}};
362 }
363 if (Imm.urem(ShiftWidth) == ShiftWidth - 1) {
364 // If we are shifting by N-X where N == -1 mod Size, then just shift by ~X
365 // to generate a NOT instead of a SUB of a constant.
366 ShAmtReg = MRI->createVirtualRegister(&RISCV::GPRRegClass);
367 return {{[=](MachineInstrBuilder &MIB) {
368 MachineIRBuilder(*MIB.getInstr())
369 .buildInstr(RISCV::XORI, {ShAmtReg}, {Reg})
370 .addImm(-1);
371 MIB.addReg(ShAmtReg);
372 }}};
373 }
374 }
375
376 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(ShAmtReg); }}};
377}
378
379InstructionSelector::ComplexRendererFns
380RISCVInstructionSelector::selectSExtBits(MachineOperand &Root,
381 unsigned Bits) const {
382 if (!Root.isReg())
383 return std::nullopt;
384 Register RootReg = Root.getReg();
385
386 Register SrcReg;
387 if (mi_match(RootReg, *MRI,
388 m_GSExtInReg(m_Reg(SrcReg), m_SpecificImm(Bits)))) {
389 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(SrcReg); }}};
390 }
391
392 unsigned Size = MRI->getType(RootReg).getScalarSizeInBits();
393 if ((Size - VT->computeNumSignBits(RootReg)) < Bits)
394 return {{[=](MachineInstrBuilder &MIB) { MIB.add(Root); }}};
395
396 return std::nullopt;
397}
398
399InstructionSelector::ComplexRendererFns
400RISCVInstructionSelector::selectZExtBits(MachineOperand &Root,
401 unsigned Bits) const {
402 if (!Root.isReg())
403 return std::nullopt;
404 Register RootReg = Root.getReg();
405
406 Register RegX;
408 if (mi_match(RootReg, *MRI, m_GAnd(m_Reg(RegX), m_SpecificICst(Mask)))) {
409 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(RegX); }}};
410 }
411
412 if (mi_match(RootReg, *MRI, m_GZExt(m_Reg(RegX))) &&
413 MRI->getType(RegX).getScalarSizeInBits() == Bits)
414 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(RegX); }}};
415
416 unsigned Size = MRI->getType(RootReg).getScalarSizeInBits();
417 if (VT->maskedValueIsZero(RootReg, APInt::getBitsSetFrom(Size, Bits)))
418 return {{[=](MachineInstrBuilder &MIB) { MIB.add(Root); }}};
419
420 return std::nullopt;
421}
422
423InstructionSelector::ComplexRendererFns
424RISCVInstructionSelector::selectSHXADDOp(MachineOperand &Root,
425 unsigned ShAmt) const {
426 using namespace llvm::MIPatternMatch;
427
428 if (!Root.isReg())
429 return std::nullopt;
430 Register RootReg = Root.getReg();
431
432 const unsigned XLen = STI.getXLen();
433 APInt Mask;
434 int64_t C2;
435 Register RegY;
436 std::optional<bool> LeftShift;
437 // (and (shl y, c2), mask)
438 if (mi_match(RootReg, *MRI,
439 m_GAnd(m_GShl(m_Reg(RegY), m_ICst(C2)), m_ICst(Mask))))
440 LeftShift = true;
441 // (and (lshr y, c2), mask)
442 else if (mi_match(RootReg, *MRI,
443 m_GAnd(m_GLShr(m_Reg(RegY), m_ICst(C2)), m_ICst(Mask))))
444 LeftShift = false;
445
446 if (LeftShift.has_value()) {
447 assert(Mask.getBitWidth() == XLen && "Unexpected mask size!");
448 assert(C2 > 0 && C2 < XLen && "Unexpected shift amount!");
449 if (*LeftShift)
451 else
452 Mask &= maskTrailingOnes<uint64_t>(XLen - C2);
453
454 if (Mask.isShiftedMask()) {
455 unsigned Leading = XLen - Mask.getActiveBits();
456 unsigned Trailing = Mask.countr_zero();
457 // Given (and (shl y, c2), mask) in which mask has no leading zeros and
458 // c3 trailing zeros. We can use an SRLI by c3 - c2 followed by a SHXADD.
459 if (*LeftShift && Leading == 0 && C2 < Trailing && Trailing == ShAmt) {
460 Register DstReg = MRI->createVirtualRegister(&RISCV::GPRRegClass);
461 return {{[=](MachineInstrBuilder &MIB) {
462 MachineIRBuilder(*MIB.getInstr())
463 .buildInstr(RISCV::SRLI, {DstReg}, {RegY})
464 .addImm(Trailing - C2);
465 MIB.addReg(DstReg);
466 }}};
467 }
468
469 // Given (and (lshr y, c2), mask) in which mask has c2 leading zeros and
470 // c3 trailing zeros. We can use an SRLI by c2 + c3 followed by a SHXADD.
471 if (!*LeftShift && Leading == C2 && Trailing == ShAmt) {
472 Register DstReg = MRI->createVirtualRegister(&RISCV::GPRRegClass);
473 return {{[=](MachineInstrBuilder &MIB) {
474 MachineIRBuilder(*MIB.getInstr())
475 .buildInstr(RISCV::SRLI, {DstReg}, {RegY})
476 .addImm(Leading + Trailing);
477 MIB.addReg(DstReg);
478 }}};
479 }
480 }
481 }
482
483 LeftShift.reset();
484
485 // (shl (and y, mask), c2)
486 if (mi_match(RootReg, *MRI,
487 m_GShl(m_OneNonDBGUse(m_GAnd(m_Reg(RegY), m_ICst(Mask))),
488 m_ICst(C2))))
489 LeftShift = true;
490 // (lshr (and y, mask), c2)
491 else if (mi_match(RootReg, *MRI,
493 m_ICst(C2))))
494 LeftShift = false;
495
496 if (LeftShift.has_value() && Mask.isShiftedMask()) {
497 unsigned Leading = XLen - Mask.getActiveBits();
498 unsigned Trailing = Mask.countr_zero();
499
500 // Given (shl (and y, mask), c2) in which mask has 32 leading zeros and
501 // c3 trailing zeros. If c1 + c3 == ShAmt, we can emit SRLIW + SHXADD.
502 bool Cond =
503 *LeftShift && Leading == 32 && Trailing > 0 && (Trailing + C2) == ShAmt;
504 if (!Cond)
505 // Given (lshr (and y, mask), c2) in which mask has 32 leading zeros and
506 // c3 trailing zeros. If c3 - c1 == ShAmt, we can emit SRLIW + SHXADD.
507 Cond = !*LeftShift && Leading == 32 && C2 < Trailing &&
508 (Trailing - C2) == ShAmt;
509
510 if (Cond) {
511 Register DstReg = MRI->createVirtualRegister(&RISCV::GPRRegClass);
512 return {{[=](MachineInstrBuilder &MIB) {
513 MachineIRBuilder(*MIB.getInstr())
514 .buildInstr(RISCV::SRLIW, {DstReg}, {RegY})
515 .addImm(Trailing);
516 MIB.addReg(DstReg);
517 }}};
518 }
519 }
520
521 return std::nullopt;
522}
523
524InstructionSelector::ComplexRendererFns
525RISCVInstructionSelector::selectSHXADD_UWOp(MachineOperand &Root,
526 unsigned ShAmt) const {
527 using namespace llvm::MIPatternMatch;
528
529 if (!Root.isReg())
530 return std::nullopt;
531 Register RootReg = Root.getReg();
532
533 // Given (and (shl x, c2), mask) in which mask is a shifted mask with
534 // 32 - ShAmt leading zeros and c2 trailing zeros. We can use SLLI by
535 // c2 - ShAmt followed by SHXADD_UW with ShAmt for x amount.
536 APInt Mask;
537 int64_t C2;
538 Register RegX;
539 if (mi_match(
540 RootReg, *MRI,
542 m_ICst(Mask))))) {
543 assert(C2 > 0 && C2 < Mask.getBitWidth() && "Unexpected shift amount!");
545
546 if (Mask.isShiftedMask()) {
547 unsigned Leading = Mask.countl_zero();
548 unsigned Trailing = Mask.countr_zero();
549 if (Leading == 32 - ShAmt && C2 == Trailing && Trailing > ShAmt) {
550 Register DstReg = MRI->createVirtualRegister(&RISCV::GPRRegClass);
551 return {{[=](MachineInstrBuilder &MIB) {
552 MachineIRBuilder(*MIB.getInstr())
553 .buildInstr(RISCV::SLLI, {DstReg}, {RegX})
554 .addImm(C2 - ShAmt);
555 MIB.addReg(DstReg);
556 }}};
557 }
558 }
559 }
560
561 return std::nullopt;
562}
563
564InstructionSelector::ComplexRendererFns
565RISCVInstructionSelector::renderVLOp(MachineOperand &Root) const {
566 assert(Root.isReg() && "Expected operand to be a Register");
567 std::optional<ValueAndVReg> C;
568 if (mi_match(Root.getReg(), *MRI, m_GCst(C))) {
569 if (C->Value.isAllOnes())
570 // If the operand is a G_CONSTANT with value of all ones it is larger than
571 // VLMAX. We convert it to an immediate with value VLMaxSentinel. This is
572 // recognized specially by the vsetvli insertion pass.
573 return {{[=](MachineInstrBuilder &MIB) {
574 MIB.addImm(RISCV::VLMaxSentinel);
575 }}};
576
577 if (isUInt<5>(C->Value.getZExtValue())) {
578 uint64_t ZExtC = C->Value.getZExtValue();
579 return {{[=](MachineInstrBuilder &MIB) { MIB.addImm(ZExtC); }}};
580 }
581 }
582 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(Root.getReg()); }}};
583}
584
585InstructionSelector::ComplexRendererFns
586RISCVInstructionSelector::renderAddiPair(Register BaseReg, int64_t AddiImm,
587 int64_t OffsetImm) const {
588 return {{[=](MachineInstrBuilder &MIB) {
589 Register Tmp = MRI->createVirtualRegister(&RISCV::GPRRegClass);
590 MachineInstr *Addi =
591 BuildMI(*MIB->getParent(), *MIB.getInstr(), MIB->getDebugLoc(),
592 TII.get(RISCV::ADDI), Tmp)
593 .addReg(BaseReg)
594 .addImm(AddiImm);
596 MIB.addReg(Tmp);
597 },
598 [=](MachineInstrBuilder &MIB) { MIB.addImm(OffsetImm); }}};
599}
600
601InstructionSelector::ComplexRendererFns
602RISCVInstructionSelector::selectAddrRegImm(MachineOperand &Root) const {
603 if (!Root.isReg())
604 return std::nullopt;
605
606 Register RootReg = Root.getReg();
607
608 // Frame index.
609 int FI;
610 if (mi_match(RootReg, *MRI, m_GFrameIndex(FI))) {
611 return {{
612 [=](MachineInstrBuilder &MIB) { MIB.addFrameIndex(FI); },
613 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
614 }};
615 }
616
617 // base + constant offset (G_PTR_ADD).
619 int64_t RHSC;
620 if (mi_match(RootReg, *MRI, m_GPtrAdd(m_Reg(BaseReg), m_ICst(RHSC)))) {
621 if (isInt<12>(RHSC)) {
622 int BaseFI;
623 if (mi_match(BaseReg, *MRI, m_GFrameIndex(BaseFI)))
624 return {{
625 [=](MachineInstrBuilder &MIB) { MIB.addFrameIndex(BaseFI); },
626 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); },
627 }};
628
629 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(BaseReg); },
630 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); }}};
631 }
632
633 // Large constant offset. Fold a -2048/2047 adjustment so the whole
634 // constant can be split across an ADDI and the load/store offset.
635 if (RHSC >= -4096 && RHSC <= 4094) {
636 int64_t Adj = RHSC < 0 ? -2048 : 2047;
637 return renderAddiPair(BaseReg, Adj, RHSC - Adj);
638 }
639
640 if (isWorthFoldingAdd(RootReg))
641 if (auto Fns = computeConstAddr(RHSC, /*IsPrefetch=*/false, BaseReg))
642 return Fns;
643 }
644
645 // Bare constant address. IRTranslator lowers inttoptr(C) to
646 // G_INTTOPTR(G_CONSTANT); look through it to reach the constant.
647 int64_t CVal;
648 if (mi_match(RootReg, *MRI, m_GIntToPtr(m_ICst(CVal))) ||
649 mi_match(RootReg, *MRI, m_ICst(CVal))) {
650 if (auto Fns = computeConstAddr(CVal, /*IsPrefetch=*/false, Register()))
651 return Fns;
652 }
653
654 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(RootReg); },
655 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }}};
656}
657
658InstructionSelector::ComplexRendererFns
659RISCVInstructionSelector::selectBrindRegImm(MachineOperand &Root) const {
660 if (!Root.isReg())
661 return std::nullopt;
662
663 Register RootReg = Root.getReg();
664
665 // base + constant offset (G_PTR_ADD). Doesn't match a FrameIndex, unlike
666 // selectAddrRegImm, since the callers of this (e.g. indirect branches)
667 // can't take a FrameIndex or global address operand.
669 int64_t RHSC;
670 if (mi_match(RootReg, *MRI, m_GPtrAdd(m_Reg(BaseReg), m_ICst(RHSC))) &&
671 isInt<12>(RHSC)) {
672 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(BaseReg); },
673 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); }}};
674 }
675
676 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(RootReg); },
677 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }}};
678}
679
680InstructionSelector::ComplexRendererFns
681RISCVInstructionSelector::selectAddrRegImmLsb00000(MachineOperand &Root) const {
682 if (!Root.isReg())
683 return std::nullopt;
684
685 Register RootReg = Root.getReg();
686
687 // Frame index.
688 int FI;
689 if (mi_match(RootReg, *MRI, m_GFrameIndex(FI))) {
690 return {{
691 [=](MachineInstrBuilder &MIB) { MIB.addFrameIndex(FI); },
692 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
693 }};
694 }
695
696 // base + constant offset (G_PTR_ADD).
698 int64_t RHSC;
699 if (mi_match(RootReg, *MRI, m_GPtrAdd(m_Reg(BaseReg), m_ICst(RHSC)))) {
700 if (isInt<12>(RHSC)) {
701 // Not a multiple of 32: can't encode, use the address as-is.
702 if ((RHSC & 0b11111) != 0) {
703 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(RootReg); },
704 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }}};
705 }
706 // Fold the offset.
707 int BaseFI;
708 if (mi_match(BaseReg, *MRI, m_GFrameIndex(BaseFI)))
709 return {{
710 [=](MachineInstrBuilder &MIB) { MIB.addFrameIndex(BaseFI); },
711 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); },
712 }};
713 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(BaseReg); },
714 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); }}};
715 }
716
717 // Large constant: fold a -2048/2016 adjustment to save an instruction.
718 if ((-2049 >= RHSC && RHSC >= -4096) || (4063 >= RHSC && RHSC >= 2017)) {
719 int64_t Adj = RHSC < 0 ? -2048 : 2016;
720 return renderAddiPair(BaseReg, RHSC - Adj, Adj);
721 }
722
723 // Otherwise split the constant into Hi (materialized + added to the base)
724 // and Lo12 (folded offset).
725 if (auto Fns = computeConstAddr(RHSC, /*IsPrefetch=*/true, BaseReg))
726 return Fns;
727 }
728
729 // Bare constant address. IRTranslator emits inttoptr(C) as
730 // G_INTTOPTR(G_CONSTANT); look through the G_INTTOPTR to reach the constant.
731 int64_t CVal;
732 if (mi_match(RootReg, *MRI, m_GIntToPtr(m_ICst(CVal))) ||
733 mi_match(RootReg, *MRI, m_ICst(CVal))) {
734 if (auto Fns = computeConstAddr(CVal, /*IsPrefetch=*/true, Register()))
735 return Fns;
736 }
737
738 return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(RootReg); },
739 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }}};
740}
741
742/// Returns the RISCVCC::CondCode that corresponds to the CmpInst::Predicate CC.
743/// CC Must be an ICMP Predicate.
744static RISCVCC::CondCode getRISCVCCFromICmp(CmpInst::Predicate CC) {
745 switch (CC) {
746 default:
747 llvm_unreachable("Expected ICMP CmpInst::Predicate.");
748 case CmpInst::Predicate::ICMP_EQ:
749 return RISCVCC::COND_EQ;
750 case CmpInst::Predicate::ICMP_NE:
751 return RISCVCC::COND_NE;
752 case CmpInst::Predicate::ICMP_ULT:
753 return RISCVCC::COND_LTU;
754 case CmpInst::Predicate::ICMP_SLT:
755 return RISCVCC::COND_LT;
756 case CmpInst::Predicate::ICMP_UGE:
757 return RISCVCC::COND_GEU;
758 case CmpInst::Predicate::ICMP_SGE:
759 return RISCVCC::COND_GE;
760 }
761}
762
765 MachineRegisterInfo &MRI) {
766 // Try to fold an ICmp. If that fails, use a NE compare with X0.
768 if (!mi_match(CondReg, MRI, m_GICmp(m_Pred(Pred), m_Reg(LHS), m_Reg(RHS)))) {
769 LHS = CondReg;
770 RHS = RISCV::X0;
771 CC = RISCVCC::COND_NE;
772 return;
773 }
774
775 // We found an ICmp, do some canonicalization.
776
777 // Adjust comparisons to use comparison with 0 if possible.
778 if (auto Constant = getIConstantVRegSExtVal(RHS, MRI)) {
779 switch (Pred) {
781 // Convert X > -1 to X >= 0
782 if (*Constant == -1) {
783 CC = RISCVCC::COND_GE;
784 RHS = RISCV::X0;
785 return;
786 }
787 break;
789 // Convert X < 1 to 0 >= X
790 if (*Constant == 1) {
791 CC = RISCVCC::COND_GE;
792 RHS = LHS;
793 LHS = RISCV::X0;
794 return;
795 }
796 break;
797 default:
798 break;
799 }
800 }
801
802 switch (Pred) {
803 default:
804 llvm_unreachable("Expected ICMP CmpInst::Predicate.");
811 // These CCs are supported directly by RISC-V branches.
812 break;
817 // These CCs are not supported directly by RISC-V branches, but changing the
818 // direction of the CC and swapping LHS and RHS are.
819 Pred = CmpInst::getSwappedPredicate(Pred);
820 std::swap(LHS, RHS);
821 break;
822 }
823
824 CC = getRISCVCCFromICmp(Pred);
825}
826
827/// Select the RISC-V Zalasr opcode for the G_LOAD or G_STORE operation
828/// \p GenericOpc, appropriate for the GPR register bank and of memory access
829/// size \p OpSize.
830static unsigned selectZalasrLoadStoreOp(unsigned GenericOpc, unsigned OpSize) {
831 const bool IsStore = GenericOpc == TargetOpcode::G_STORE;
832 switch (OpSize) {
833 default:
834 llvm_unreachable("Unexpected memory size");
835 case 8:
836 return IsStore ? RISCV::SB_RL : RISCV::LB_AQ;
837 case 16:
838 return IsStore ? RISCV::SH_RL : RISCV::LH_AQ;
839 case 32:
840 return IsStore ? RISCV::SW_RL : RISCV::LW_AQ;
841 case 64:
842 return IsStore ? RISCV::SD_RL : RISCV::LD_AQ;
843 }
844}
845
846/// Select the RISC-V regimm opcode for the G_LOAD or G_STORE operation
847/// \p GenericOpc on \p STI, appropriate for the GPR register bank and of
848/// memory access size \p OpSize. \returns \p GenericOpc if the combination
849/// is unsupported.
850static unsigned selectRegImmLoadStoreOp(const RISCVSubtarget &STI,
851 unsigned GenericOpc, unsigned OpSize) {
852 const bool IsStore = GenericOpc == TargetOpcode::G_STORE;
853 switch (OpSize) {
854 case 8:
855 // Prefer unsigned due to no c.lb in Zcb.
856 return IsStore ? RISCV::SB : RISCV::LBU;
857 case 16:
858 return IsStore ? RISCV::SH : RISCV::LH;
859 case 32:
860 return IsStore ? RISCV::SW : RISCV::LW;
861 case 64:
862 // LD/SD are RV64-only. On RV32 a 64-bit access goes through an even/odd
863 // GPR pair, which Zilsd provides via the LD_RV32/SD_RV32 pseudos.
864 if (!STI.is64Bit() && STI.hasStdExtZilsd())
865 return IsStore ? RISCV::SD_RV32 : RISCV::LD_RV32;
866 return IsStore ? RISCV::SD : RISCV::LD;
867 }
868
869 return GenericOpc;
870}
871
872void RISCVInstructionSelector::addVectorLoadStoreOperands(
873 MachineInstr &I, SmallVectorImpl<Register> &SrcOps, unsigned &CurOp,
874 bool IsMasked, bool IsStridedOrIndexed, LLT *IndexVT) const {
875 // Base Pointer
876 auto PtrReg = I.getOperand(CurOp++).getReg();
877 SrcOps.push_back(PtrReg);
878
879 // Stride or Index
880 if (IsStridedOrIndexed) {
881 auto StrideReg = I.getOperand(CurOp++).getReg();
882 SrcOps.push_back(StrideReg);
883 if (IndexVT)
884 *IndexVT = MRI->getType(StrideReg);
885 }
886
887 // Mask
888 if (IsMasked) {
889 auto MaskReg = I.getOperand(CurOp++).getReg();
890 SrcOps.push_back(MaskReg);
891 }
892}
893
894bool RISCVInstructionSelector::selectIntrinsicWithSideEffects(
895 MachineInstr &I) const {
896 // Find the intrinsic ID.
897 unsigned IntrinID = cast<GIntrinsic>(I).getIntrinsicID();
898 // Select the instruction.
899 switch (IntrinID) {
900 default:
901 return false;
902 case Intrinsic::riscv_vlm:
903 case Intrinsic::riscv_vle:
904 case Intrinsic::riscv_vle_mask:
905 case Intrinsic::riscv_vlse:
906 case Intrinsic::riscv_vlse_mask: {
907 bool IsMasked = IntrinID == Intrinsic::riscv_vle_mask ||
908 IntrinID == Intrinsic::riscv_vlse_mask;
909 bool IsStrided = IntrinID == Intrinsic::riscv_vlse ||
910 IntrinID == Intrinsic::riscv_vlse_mask;
911 LLT VT = MRI->getType(I.getOperand(0).getReg());
912 unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits());
913
914 // Result vector
915 const Register DstReg = I.getOperand(0).getReg();
916
917 // Sources
918 bool HasPassthruOperand = IntrinID != Intrinsic::riscv_vlm;
919 unsigned CurOp = 2;
920 SmallVector<Register, 4> SrcOps; // Source registers.
921
922 // Passthru
923 if (HasPassthruOperand) {
924 auto PassthruReg = I.getOperand(CurOp++).getReg();
925 SrcOps.push_back(PassthruReg);
926 } else {
927 SrcOps.push_back(Register(RISCV::NoRegister));
928 }
929
930 addVectorLoadStoreOperands(I, SrcOps, CurOp, IsMasked, IsStrided);
931
933 const RISCV::VLEPseudo *P =
934 RISCV::getVLEPseudo(IsMasked, IsStrided, /*FF*/ false, Log2SEW,
935 static_cast<unsigned>(LMUL));
936
937 MachineInstrBuilder PseudoMI =
938 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(P->Pseudo), DstReg);
939 for (Register Reg : SrcOps)
940 PseudoMI.addReg(Reg);
941
942 // Select VL
943 auto VLOpFn = renderVLOp(I.getOperand(CurOp++));
944 for (auto &RenderFn : *VLOpFn)
945 RenderFn(PseudoMI);
946
947 // SEW
948 PseudoMI.addImm(Log2SEW);
949
950 // Policy
952 if (IsMasked)
953 Policy = I.getOperand(CurOp++).getImm();
954 PseudoMI.addImm(Policy);
955
956 // Memref
957 PseudoMI.cloneMemRefs(I);
958
959 I.eraseFromParent();
960 constrainSelectedInstRegOperands(*PseudoMI, TII, TRI, RBI);
961 return true;
962 }
963 case Intrinsic::riscv_vloxei:
964 case Intrinsic::riscv_vloxei_mask:
965 case Intrinsic::riscv_vluxei:
966 case Intrinsic::riscv_vluxei_mask: {
967 bool IsMasked = IntrinID == Intrinsic::riscv_vloxei_mask ||
968 IntrinID == Intrinsic::riscv_vluxei_mask;
969 bool IsOrdered = IntrinID == Intrinsic::riscv_vloxei ||
970 IntrinID == Intrinsic::riscv_vloxei_mask;
971 LLT VT = MRI->getType(I.getOperand(0).getReg());
972 unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits());
973
974 // Result vector
975 const Register DstReg = I.getOperand(0).getReg();
976
977 // Sources
978 bool HasPassthruOperand = IntrinID != Intrinsic::riscv_vlm;
979 unsigned CurOp = 2;
980 SmallVector<Register, 4> SrcOps; // Source registers.
981
982 // Passthru
983 if (HasPassthruOperand) {
984 auto PassthruReg = I.getOperand(CurOp++).getReg();
985 SrcOps.push_back(PassthruReg);
986 } else {
987 // Use NoRegister if there is no specified passthru.
988 SrcOps.push_back(Register());
989 }
990 LLT IndexVT;
991 addVectorLoadStoreOperands(I, SrcOps, CurOp, IsMasked, true, &IndexVT);
992
994 RISCVVType::VLMUL IndexLMUL =
996 unsigned IndexLog2EEW = Log2_32(IndexVT.getScalarSizeInBits());
997 if (IndexLog2EEW == 6 && !Subtarget->is64Bit()) {
998 reportFatalUsageError("The V extension does not support EEW=64 for index "
999 "values when XLEN=32");
1000 }
1001 const RISCV::VLX_VSXPseudo *P = RISCV::getVLXPseudo(
1002 IsMasked, IsOrdered, IndexLog2EEW, static_cast<unsigned>(LMUL),
1003 static_cast<unsigned>(IndexLMUL));
1004
1005 MachineInstrBuilder PseudoMI =
1006 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(P->Pseudo), DstReg);
1007 for (Register Reg : SrcOps)
1008 PseudoMI.addReg(Reg);
1009
1010 // Select VL
1011 auto VLOpFn = renderVLOp(I.getOperand(CurOp++));
1012 for (auto &RenderFn : *VLOpFn)
1013 RenderFn(PseudoMI);
1014
1015 // SEW
1016 PseudoMI.addImm(Log2SEW);
1017
1018 // Policy
1020 if (IsMasked)
1021 Policy = I.getOperand(CurOp++).getImm();
1022 PseudoMI.addImm(Policy);
1023
1024 // Memref
1025 PseudoMI.cloneMemRefs(I);
1026
1027 I.eraseFromParent();
1028 constrainSelectedInstRegOperands(*PseudoMI, TII, TRI, RBI);
1029 return true;
1030 }
1031 case Intrinsic::riscv_vsm:
1032 case Intrinsic::riscv_vse:
1033 case Intrinsic::riscv_vse_mask:
1034 case Intrinsic::riscv_vsse:
1035 case Intrinsic::riscv_vsse_mask: {
1036 bool IsMasked = IntrinID == Intrinsic::riscv_vse_mask ||
1037 IntrinID == Intrinsic::riscv_vsse_mask;
1038 bool IsStrided = IntrinID == Intrinsic::riscv_vsse ||
1039 IntrinID == Intrinsic::riscv_vsse_mask;
1040 LLT VT = MRI->getType(I.getOperand(1).getReg());
1041 unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits());
1042
1043 // Sources
1044 unsigned CurOp = 1;
1045 SmallVector<Register, 4> SrcOps; // Source registers.
1046
1047 // Store value
1048 auto PassthruReg = I.getOperand(CurOp++).getReg();
1049 SrcOps.push_back(PassthruReg);
1050
1051 addVectorLoadStoreOperands(I, SrcOps, CurOp, IsMasked, IsStrided);
1052
1054 const RISCV::VSEPseudo *P = RISCV::getVSEPseudo(
1055 IsMasked, IsStrided, Log2SEW, static_cast<unsigned>(LMUL));
1056
1057 MachineInstrBuilder PseudoMI =
1058 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(P->Pseudo));
1059 for (Register Reg : SrcOps)
1060 PseudoMI.addReg(Reg);
1061
1062 // Select VL
1063 auto VLOpFn = renderVLOp(I.getOperand(CurOp++));
1064 for (auto &RenderFn : *VLOpFn)
1065 RenderFn(PseudoMI);
1066
1067 // SEW
1068 PseudoMI.addImm(Log2SEW);
1069
1070 // Memref
1071 PseudoMI.cloneMemRefs(I);
1072
1073 I.eraseFromParent();
1074 constrainSelectedInstRegOperands(*PseudoMI, TII, TRI, RBI);
1075 return true;
1076 }
1077 case Intrinsic::riscv_vsoxei:
1078 case Intrinsic::riscv_vsoxei_mask:
1079 case Intrinsic::riscv_vsuxei:
1080 case Intrinsic::riscv_vsuxei_mask: {
1081 bool IsMasked = IntrinID == Intrinsic::riscv_vsoxei_mask ||
1082 IntrinID == Intrinsic::riscv_vsuxei_mask;
1083 bool IsOrdered = IntrinID == Intrinsic::riscv_vsoxei ||
1084 IntrinID == Intrinsic::riscv_vsoxei_mask;
1085 LLT VT = MRI->getType(I.getOperand(1).getReg());
1086 unsigned Log2SEW = Log2_32(VT.getScalarSizeInBits());
1087
1088 // Sources
1089 unsigned CurOp = 1;
1090 SmallVector<Register, 4> SrcOps; // Source registers.
1091
1092 // Store value
1093 auto PassthruReg = I.getOperand(CurOp++).getReg();
1094 SrcOps.push_back(PassthruReg);
1095
1096 LLT IndexVT;
1097 addVectorLoadStoreOperands(I, SrcOps, CurOp, IsMasked, true, &IndexVT);
1098
1100 RISCVVType::VLMUL IndexLMUL =
1102 unsigned IndexLog2EEW = Log2_32(IndexVT.getScalarSizeInBits());
1103 if (IndexLog2EEW == 6 && !Subtarget->is64Bit()) {
1104 reportFatalUsageError("The V extension does not support EEW=64 for index "
1105 "values when XLEN=32");
1106 }
1107 const RISCV::VLX_VSXPseudo *P = RISCV::getVSXPseudo(
1108 IsMasked, IsOrdered, IndexLog2EEW, static_cast<unsigned>(LMUL),
1109 static_cast<unsigned>(IndexLMUL));
1110
1111 MachineInstrBuilder PseudoMI =
1112 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(P->Pseudo));
1113 for (Register Reg : SrcOps)
1114 PseudoMI.addReg(Reg);
1115
1116 // Select VL
1117 auto VLOpFn = renderVLOp(I.getOperand(CurOp++));
1118 for (auto &RenderFn : *VLOpFn)
1119 RenderFn(PseudoMI);
1120
1121 // SEW
1122 PseudoMI.addImm(Log2SEW);
1123
1124 // Memref
1125 PseudoMI.cloneMemRefs(I);
1126
1127 I.eraseFromParent();
1128 constrainSelectedInstRegOperands(*PseudoMI, TII, TRI, RBI);
1129 return true;
1130 }
1131 }
1132}
1133
1134bool RISCVInstructionSelector::selectIntrinsic(MachineInstr &I) const {
1135 // Find the intrinsic ID.
1136 unsigned IntrinID = cast<GIntrinsic>(I).getIntrinsicID();
1137 // Select the instruction.
1138 switch (IntrinID) {
1139 default:
1140 return false;
1141 case Intrinsic::riscv_vsetvli:
1142 case Intrinsic::riscv_vsetvlimax: {
1143
1144 bool VLMax = IntrinID == Intrinsic::riscv_vsetvlimax;
1145
1146 unsigned Offset = VLMax ? 2 : 3;
1147 unsigned SEW = RISCVVType::decodeVSEW(I.getOperand(Offset).getImm() & 0x7);
1148 RISCVVType::VLMUL VLMul =
1149 static_cast<RISCVVType::VLMUL>(I.getOperand(Offset + 1).getImm() & 0x7);
1150
1151 unsigned VTypeI = RISCVVType::encodeVTYPE(VLMul, SEW, /*TailAgnostic*/ true,
1152 /*MaskAgnostic*/ true);
1153
1154 Register DstReg = I.getOperand(0).getReg();
1155
1156 Register VLOperand;
1157 unsigned Opcode = RISCV::PseudoVSETVLI;
1158
1159 // Check if AVL is a constant that equals VLMAX.
1160 if (!VLMax) {
1161 Register AVLReg = I.getOperand(2).getReg();
1162 if (auto AVLConst = getIConstantVRegValWithLookThrough(AVLReg, *MRI)) {
1163 uint64_t AVL = AVLConst->Value.getZExtValue();
1164 if (auto VLEN = Subtarget->getRealVLen()) {
1165 if (*VLEN / RISCVVType::getSEWLMULRatio(SEW, VLMul) == AVL)
1166 VLMax = true;
1167 }
1168 }
1169
1170 if (mi_match(AVLReg, *MRI, m_AllOnes()))
1171 VLMax = true;
1172 }
1173
1174 if (VLMax) {
1175 VLOperand = Register(RISCV::X0);
1176 Opcode = RISCV::PseudoVSETVLIX0;
1177 } else {
1178 Register AVLReg = I.getOperand(2).getReg();
1179 VLOperand = AVLReg;
1180
1181 // Check if AVL is a small constant that can use PseudoVSETIVLI.
1182 if (auto AVLConst = getIConstantVRegValWithLookThrough(AVLReg, *MRI)) {
1183 uint64_t AVL = AVLConst->Value.getZExtValue();
1184 if (isUInt<5>(AVL)) {
1185 MachineInstr *PseudoMI =
1186 BuildMI(*I.getParent(), I, I.getDebugLoc(),
1187 TII.get(RISCV::PseudoVSETIVLI), DstReg)
1188 .addImm(AVL)
1189 .addImm(VTypeI);
1190 I.eraseFromParent();
1191 constrainSelectedInstRegOperands(*PseudoMI, TII, TRI, RBI);
1192 return true;
1193 }
1194 }
1195 }
1196
1197 MachineInstr *PseudoMI =
1198 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opcode), DstReg)
1199 .addReg(VLOperand)
1200 .addImm(VTypeI);
1201 I.eraseFromParent();
1202 constrainSelectedInstRegOperands(*PseudoMI, TII, TRI, RBI);
1203 return true;
1204 }
1205 }
1206}
1207
1208bool RISCVInstructionSelector::selectExtractSubvector(MachineInstr &MI) const {
1209 assert(MI.getOpcode() == TargetOpcode::G_EXTRACT_SUBVECTOR);
1210
1211 Register DstReg = MI.getOperand(0).getReg();
1212 Register SrcReg = MI.getOperand(1).getReg();
1213
1214 LLT DstTy = MRI->getType(DstReg);
1215 LLT SrcTy = MRI->getType(SrcReg);
1216
1217 unsigned Idx = static_cast<unsigned>(MI.getOperand(2).getImm());
1218
1219 MVT DstMVT = getMVTForLLT(DstTy);
1220 MVT SrcMVT = getMVTForLLT(SrcTy);
1221
1222 unsigned SubRegIdx;
1223 std::tie(SubRegIdx, Idx) =
1225 SrcMVT, DstMVT, Idx, &TRI);
1226
1227 if (Idx != 0)
1228 return false;
1229
1230 unsigned DstRegClassID = RISCVTargetLowering::getRegClassIDForVecVT(DstMVT);
1231 const TargetRegisterClass *DstRC = TRI.getRegClass(DstRegClassID);
1232 if (!RBI.constrainGenericRegister(DstReg, *DstRC, *MRI))
1233 return false;
1234
1235 unsigned SrcRegClassID = RISCVTargetLowering::getRegClassIDForVecVT(SrcMVT);
1236 const TargetRegisterClass *SrcRC = TRI.getRegClass(SrcRegClassID);
1237 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, *MRI))
1238 return false;
1239
1240 BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), TII.get(TargetOpcode::COPY),
1241 DstReg)
1242 .addReg(SrcReg, {}, SubRegIdx);
1243
1244 MI.eraseFromParent();
1245 return true;
1246}
1247
1248bool RISCVInstructionSelector::selectInsertSubVector(MachineInstr &MI) const {
1249 assert(MI.getOpcode() == TargetOpcode::G_INSERT_SUBVECTOR);
1250
1251 Register DstReg = MI.getOperand(0).getReg();
1252 Register VecReg = MI.getOperand(1).getReg();
1253 Register SubVecReg = MI.getOperand(2).getReg();
1254
1255 LLT VecTy = MRI->getType(VecReg);
1256 LLT SubVecTy = MRI->getType(SubVecReg);
1257
1258 MVT VecMVT = getMVTForLLT(VecTy);
1259 MVT SubVecMVT = getMVTForLLT(SubVecTy);
1260
1261 unsigned Idx = static_cast<unsigned>(MI.getOperand(3).getImm());
1262
1263 unsigned SubRegIdx;
1264 std::tie(SubRegIdx, Idx) =
1266 VecMVT, SubVecMVT, Idx, &TRI);
1267
1268 // If the Idx hasn't been completely eliminated then this is a subvector
1269 // insert which doesn't naturally align to a vector register. These must
1270 // be handled using instructions to manipulate the vector registers.
1271 if (Idx != 0)
1272 return false;
1273
1274 // Constrain dst
1275 unsigned DstRegClassID = RISCVTargetLowering::getRegClassIDForVecVT(VecMVT);
1276 const TargetRegisterClass *DstRC = TRI.getRegClass(DstRegClassID);
1277 if (!RBI.constrainGenericRegister(DstReg, *DstRC, *MRI))
1278 return false;
1279
1280 // If we haven't set a SubRegIdx, then we must be going between
1281 // equally-sized LMUL groups (e.g. VR -> VR). This can be done as a copy.
1282 if (SubRegIdx == RISCV::NoSubRegister) {
1284 DstRegClassID &&
1285 "Unexpected subvector insert");
1286 BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), TII.get(TargetOpcode::COPY),
1287 DstReg)
1288 .addReg(SubVecReg);
1289 MI.eraseFromParent();
1290 return true;
1291 }
1292
1293 // Use INSERT_SUBREG to insert the subvector into the vector at the
1294 // appropriate subregister index.
1295 MachineInstr *Ins = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),
1296 TII.get(TargetOpcode::INSERT_SUBREG), DstReg)
1297 .addReg(VecReg)
1298 .addReg(SubVecReg)
1299 .addImm(SubRegIdx);
1300
1301 MI.eraseFromParent();
1303 return true;
1304}
1305
1306bool RISCVInstructionSelector::select(MachineInstr &MI) {
1307 preISelLower(MI);
1308 const unsigned Opc = MI.getOpcode();
1309
1310 if (!MI.isPreISelOpcode() || Opc == TargetOpcode::G_PHI) {
1311 if (Opc == TargetOpcode::PHI || Opc == TargetOpcode::G_PHI) {
1312 const Register DefReg = MI.getOperand(0).getReg();
1313 const LLT DefTy = MRI->getType(DefReg);
1314
1315 const RegClassOrRegBank &RegClassOrBank =
1316 MRI->getRegClassOrRegBank(DefReg);
1317
1318 const TargetRegisterClass *DefRC =
1320 if (!DefRC) {
1321 if (!DefTy.isValid()) {
1322 LLVM_DEBUG(dbgs() << "PHI operand has no type, not a gvreg?\n");
1323 return false;
1324 }
1325
1326 const RegisterBank &RB = *cast<const RegisterBank *>(RegClassOrBank);
1327 DefRC = TRI.getRegClassForTypeOnBank(DefTy, RB, STI.is64Bit());
1328 if (!DefRC) {
1329 LLVM_DEBUG(dbgs() << "PHI operand has unexpected size/bank\n");
1330 return false;
1331 }
1332 }
1333
1334 MI.setDesc(TII.get(TargetOpcode::PHI));
1335 return RBI.constrainGenericRegister(DefReg, *DefRC, *MRI);
1336 }
1337
1338 // Certain non-generic instructions also need some special handling.
1339 if (MI.isCopy())
1340 return selectCopy(MI);
1341
1342 return true;
1343 }
1344
1345 if (selectImpl(MI, *CoverageInfo))
1346 return true;
1347
1348 switch (Opc) {
1349 case TargetOpcode::G_ANYEXT:
1350 case TargetOpcode::G_PTRTOINT:
1351 case TargetOpcode::G_INTTOPTR:
1352 case TargetOpcode::G_TRUNC:
1353 case TargetOpcode::G_FREEZE:
1354 return selectCopy(MI);
1355 case TargetOpcode::G_CONSTANT: {
1356 Register DstReg = MI.getOperand(0).getReg();
1357 int64_t Imm = MI.getOperand(1).getCImm()->getSExtValue();
1358
1359 if (!materializeImm(DstReg, Imm, MI))
1360 return false;
1361
1362 MI.eraseFromParent();
1363 return true;
1364 }
1365 case TargetOpcode::G_ZEXT:
1366 case TargetOpcode::G_SEXT: {
1367 bool IsSigned = Opc != TargetOpcode::G_ZEXT;
1368 Register DstReg = MI.getOperand(0).getReg();
1369 Register SrcReg = MI.getOperand(1).getReg();
1370 LLT SrcTy = MRI->getType(SrcReg);
1371 unsigned SrcSize = SrcTy.getSizeInBits();
1372
1373 if (SrcTy.isVector())
1374 return false; // Should be handled by imported patterns.
1375
1376 assert((*RBI.getRegBank(DstReg, *MRI, TRI)).getID() ==
1377 RISCV::GPRBRegBankID &&
1378 "Unexpected ext regbank");
1379
1380 // Use addiw SrcReg, 0 (sext.w) for i32.
1381 if (IsSigned && SrcSize == 32) {
1382 MI.setDesc(TII.get(RISCV::ADDIW));
1383 MI.addOperand(MachineOperand::CreateImm(0));
1385 return true;
1386 }
1387
1388 // Use add.uw SrcReg, X0 (zext.w) for i32 with Zba.
1389 if (!IsSigned && SrcSize == 32 && STI.hasStdExtZba()) {
1390 MI.setDesc(TII.get(RISCV::ADD_UW));
1391 MI.addOperand(MachineOperand::CreateReg(RISCV::X0, /*isDef=*/false));
1393 return true;
1394 }
1395
1396 // Use sext.h/zext.h for i16 with Zbb.
1397 if (SrcSize == 16 &&
1398 (STI.hasStdExtZbb() || (!IsSigned && STI.hasStdExtZbkb()))) {
1399 MI.setDesc(TII.get(IsSigned ? RISCV::SEXT_H
1400 : STI.is64Bit() ? RISCV::ZEXT_H_RV64
1401 : RISCV::ZEXT_H_RV32));
1403 return true;
1404 }
1405
1406 // Fall back to shift pair.
1407 Register ShiftLeftReg = MRI->createVirtualRegister(&RISCV::GPRRegClass);
1408 MachineInstr *ShiftLeft = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),
1409 TII.get(RISCV::SLLI), ShiftLeftReg)
1410 .addReg(SrcReg)
1411 .addImm(STI.getXLen() - SrcSize);
1412 constrainSelectedInstRegOperands(*ShiftLeft, TII, TRI, RBI);
1413 MachineInstr *ShiftRight =
1414 BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),
1415 TII.get(IsSigned ? RISCV::SRAI : RISCV::SRLI), DstReg)
1416 .addReg(ShiftLeftReg)
1417 .addImm(STI.getXLen() - SrcSize);
1418 constrainSelectedInstRegOperands(*ShiftRight, TII, TRI, RBI);
1419 MI.eraseFromParent();
1420 return true;
1421 }
1422 case TargetOpcode::G_FCONSTANT: {
1423 // TODO: Use constant pool for complex constants.
1424 Register DstReg = MI.getOperand(0).getReg();
1425 const APFloat &FPimm = MI.getOperand(1).getFPImm()->getValueAPF();
1426 unsigned Size = MRI->getType(DstReg).getSizeInBits();
1427 if (Size == 16 || Size == 32 || (Size == 64 && Subtarget->is64Bit())) {
1428 Register GPRReg;
1429 if (FPimm.isPosZero()) {
1430 GPRReg = RISCV::X0;
1431 } else {
1432 GPRReg = MRI->createVirtualRegister(&RISCV::GPRRegClass);
1433 APInt Imm = FPimm.bitcastToAPInt();
1434 if (!materializeImm(GPRReg, Imm.getSExtValue(), MI))
1435 return false;
1436 }
1437
1438 unsigned Opcode = Size == 64 ? RISCV::FMV_D_X
1439 : Size == 32 ? RISCV::FMV_W_X
1440 : RISCV::FMV_H_X;
1441 MachineInstr *FMV = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),
1442 TII.get(Opcode), DstReg)
1443 .addReg(GPRReg);
1445 } else {
1446 // s64 on rv32
1447 assert(Size == 64 && !Subtarget->is64Bit() &&
1448 "Unexpected size or subtarget");
1449
1450 if (FPimm.isPosZero()) {
1451 // Optimize +0.0 to use fcvt.d.w
1452 MachineInstr *FCVT = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),
1453 TII.get(RISCV::FCVT_D_W), DstReg)
1454 .addReg(RISCV::X0)
1457
1458 MI.eraseFromParent();
1459 return true;
1460 }
1461
1462 // Split into two pieces and build through the stack.
1463 Register GPRRegHigh = MRI->createVirtualRegister(&RISCV::GPRRegClass);
1464 Register GPRRegLow = MRI->createVirtualRegister(&RISCV::GPRRegClass);
1465 APInt Imm = FPimm.bitcastToAPInt();
1466 if (!materializeImm(GPRRegHigh, Imm.extractBits(32, 32).getSExtValue(),
1467 MI))
1468 return false;
1469 if (!materializeImm(GPRRegLow, Imm.trunc(32).getSExtValue(), MI))
1470 return false;
1471 MachineInstr *PairF64 =
1472 BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),
1473 TII.get(RISCV::BuildPairF64Pseudo), DstReg)
1474 .addReg(GPRRegLow)
1475 .addReg(GPRRegHigh);
1476 constrainSelectedInstRegOperands(*PairF64, TII, TRI, RBI);
1477 }
1478
1479 MI.eraseFromParent();
1480 return true;
1481 }
1482 case TargetOpcode::G_GLOBAL_VALUE: {
1483 auto *GV = MI.getOperand(1).getGlobal();
1484 if (GV->isThreadLocal()) {
1485 // TODO: implement this case.
1486 return false;
1487 }
1488
1489 return selectAddr(MI, GV->isDSOLocal(), GV->hasExternalWeakLinkage());
1490 }
1491 case TargetOpcode::G_JUMP_TABLE:
1492 case TargetOpcode::G_CONSTANT_POOL:
1493 return selectAddr(MI);
1494 case TargetOpcode::G_BRCOND: {
1495 Register LHS, RHS;
1497 getOperandsForBranch(MI.getOperand(0).getReg(), CC, LHS, RHS, *MRI);
1498
1499 MachineInstr *Bcc = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),
1500 TII.get(RISCVCC::getBrCond(CC)))
1501 .addReg(LHS)
1502 .addReg(RHS)
1503 .addMBB(MI.getOperand(1).getMBB());
1504 MI.eraseFromParent();
1506 return true;
1507 }
1508 case TargetOpcode::G_SELECT:
1509 return selectSelect(MI);
1510 case TargetOpcode::G_FCMP:
1511 return selectFPCompare(MI);
1512 case TargetOpcode::G_FENCE: {
1513 AtomicOrdering FenceOrdering =
1514 static_cast<AtomicOrdering>(MI.getOperand(0).getImm());
1515 SyncScope::ID FenceSSID =
1516 static_cast<SyncScope::ID>(MI.getOperand(1).getImm());
1517 emitFence(FenceOrdering, FenceSSID, MI);
1518 MI.eraseFromParent();
1519 return true;
1520 }
1521 case TargetOpcode::G_IMPLICIT_DEF:
1522 return selectImplicitDef(MI);
1523 case TargetOpcode::G_UNMERGE_VALUES:
1524 return selectUnmergeValues(MI);
1525 case TargetOpcode::G_MERGE_VALUES:
1526 return selectMergeValues(MI);
1527 case TargetOpcode::G_LOAD:
1528 case TargetOpcode::G_STORE: {
1529 GLoadStore &LdSt = cast<GLoadStore>(MI);
1530 const Register ValReg = LdSt.getReg(0);
1531 const Register PtrReg = LdSt.getPointerReg();
1532 LLT PtrTy = MRI->getType(PtrReg);
1533
1534 const RegisterBank &RB = *RBI.getRegBank(ValReg, *MRI, TRI);
1535 if (RB.getID() != RISCV::GPRBRegBankID)
1536 return false;
1537
1538#ifndef NDEBUG
1539 const RegisterBank &PtrRB = *RBI.getRegBank(PtrReg, *MRI, TRI);
1540 // Check that the pointer register is valid.
1541 assert(PtrRB.getID() == RISCV::GPRBRegBankID &&
1542 "Load/Store pointer operand isn't a GPR");
1543 assert(PtrTy.isPointer() && "Load/Store pointer operand isn't a pointer");
1544#endif
1545
1546 // Can only handle AddressSpace 0.
1547 if (PtrTy.getAddressSpace() != 0)
1548 return false;
1549
1550 unsigned MemSize = LdSt.getMemSizeInBits().getValue();
1551 AtomicOrdering Order = LdSt.getMMO().getSuccessOrdering();
1552
1553 if (isStrongerThanMonotonic(Order)) {
1554 MI.setDesc(TII.get(selectZalasrLoadStoreOp(Opc, MemSize)));
1556 return true;
1557 }
1558
1559 const unsigned NewOpc =
1560 selectRegImmLoadStoreOp(STI, MI.getOpcode(), MemSize);
1561 if (NewOpc == MI.getOpcode())
1562 return false;
1563
1564 // Check if we can fold anything into the addressing mode.
1565 auto AddrModeFns = selectAddrRegImm(MI.getOperand(1));
1566 if (!AddrModeFns)
1567 return false;
1568
1569 // Folded something. Create a new instruction and return it.
1570 MachineInstrBuilder NewInst =
1571 BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), TII.get(NewOpc));
1572 NewInst.setMIFlags(MI.getFlags());
1573 if (isa<GStore>(MI))
1574 NewInst.addUse(ValReg);
1575 else
1576 NewInst.addDef(ValReg);
1577 NewInst.cloneMemRefs(MI);
1578 for (auto &Fn : *AddrModeFns)
1579 Fn(NewInst);
1580 MI.eraseFromParent();
1581
1582 constrainSelectedInstRegOperands(*NewInst, TII, TRI, RBI);
1583 return true;
1584 }
1585 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
1586 return selectIntrinsicWithSideEffects(MI);
1587 case TargetOpcode::G_INTRINSIC:
1588 return selectIntrinsic(MI);
1589 case TargetOpcode::G_EXTRACT_SUBVECTOR:
1590 return selectExtractSubvector(MI);
1591 case TargetOpcode::G_INSERT_SUBVECTOR:
1592 return selectInsertSubVector(MI);
1593 default:
1594 return false;
1595 }
1596}
1597
1598bool RISCVInstructionSelector::selectUnmergeValues(MachineInstr &MI) const {
1599 assert(MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES);
1600
1601 // Split Src into two s32 parts.
1602 if (MI.getNumOperands() != 3)
1603 return false;
1604 Register Src = MI.getOperand(2).getReg();
1605 Register Lo = MI.getOperand(0).getReg();
1606 Register Hi = MI.getOperand(1).getReg();
1607
1608 // RV32+Zilsd: split a GPRPair (i64) into its two s32 GPR halves.
1609 if (!Subtarget->is64Bit() && Subtarget->hasStdExtZilsd() &&
1610 MRI->getType(Src) == LLT::scalar(64) && isRegInGprb(Src) &&
1611 isRegInGprb(Lo) && isRegInGprb(Hi)) {
1612 // GPRPairNoX0 rather than GPRPair: a sub-register index is only valid for
1613 // a class when every register in it supports the index, and X0_Pair has no
1614 // sub_gpr_odd. SelectionDAG gets the same effect through
1615 // InstrEmitter::ConstrainForSubReg.
1616 if (!RBI.constrainGenericRegister(Src, RISCV::GPRPairNoX0RegClass, *MRI))
1617 return false;
1618 // COPY with a sub-register index rather than EXTRACT_SUBREG, which is what
1619 // SelectionDAG emits too: InstrEmitter lowers an EXTRACT_SUBREG SDNode to
1620 // %dst = COPY %src:sub and never builds the pseudo itself. A literal
1621 // EXTRACT_SUBREG would also survive to ExpandPostRAPseudos, which treats
1622 // one as unreachable.
1623 auto ExtractHalf = [&](Register Dst, unsigned SubIdx) {
1624 RBI.constrainGenericRegister(Dst, RISCV::GPRRegClass, *MRI);
1625 MachineInstr &C = *BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),
1626 TII.get(TargetOpcode::COPY), Dst)
1627 .addReg(Src, {}, SubIdx);
1629 };
1630 ExtractHalf(Lo, RISCV::sub_gpr_even);
1631 ExtractHalf(Hi, RISCV::sub_gpr_odd);
1632 MI.eraseFromParent();
1633 return true;
1634 }
1635
1636 if (!Subtarget->hasStdExtZfa())
1637 return false;
1638
1639 if (!isRegInFprb(Src) || !isRegInGprb(Lo) || !isRegInGprb(Hi))
1640 return false;
1641
1642 MachineInstr *ExtractLo = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),
1643 TII.get(RISCV::FMV_X_W_FPR64), Lo)
1644 .addReg(Src);
1645 constrainSelectedInstRegOperands(*ExtractLo, TII, TRI, RBI);
1646
1647 MachineInstr *ExtractHi = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),
1648 TII.get(RISCV::FMVH_X_D), Hi)
1649 .addReg(Src);
1650 constrainSelectedInstRegOperands(*ExtractHi, TII, TRI, RBI);
1651
1652 MI.eraseFromParent();
1653 return true;
1654}
1655
1656bool RISCVInstructionSelector::selectMergeValues(MachineInstr &MI) const {
1657 assert(MI.getOpcode() == TargetOpcode::G_MERGE_VALUES);
1658
1659 if (MI.getNumOperands() != 3)
1660 return false;
1661 Register Dst = MI.getOperand(0).getReg();
1662 Register Lo = MI.getOperand(1).getReg();
1663 Register Hi = MI.getOperand(2).getReg();
1664
1665 // RV32+Zilsd: build a GPRPair (i64) from two s32 GPR halves.
1666 if (!Subtarget->is64Bit() && Subtarget->hasStdExtZilsd() &&
1667 MRI->getType(Dst) == LLT::scalar(64) && isRegInGprb(Dst) &&
1668 isRegInGprb(Lo) && isRegInGprb(Hi)) {
1669 // GPRPairNoX0 rather than GPRPair, because sub_gpr_odd is not valid for
1670 // X0_Pair. Constrain Dst up front: constrainSelectedInstRegOperands below
1671 // would otherwise infer GPRPair from the s64 type.
1672 if (!RBI.constrainGenericRegister(Dst, RISCV::GPRPairNoX0RegClass, *MRI))
1673 return false;
1674 MachineInstr &Seq = *BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),
1675 TII.get(TargetOpcode::REG_SEQUENCE), Dst)
1676 .addReg(Lo)
1677 .addImm(RISCV::sub_gpr_even)
1678 .addReg(Hi)
1679 .addImm(RISCV::sub_gpr_odd);
1680 MI.eraseFromParent();
1682 return true;
1683 }
1684 return false;
1685}
1686
1687bool RISCVInstructionSelector::replacePtrWithInt(MachineInstr &MI,
1688 unsigned OpIdx) {
1689 MachineOperand &Op = MI.getOperand(OpIdx);
1690 Register PtrReg = Op.getReg();
1691 assert(MRI->getType(PtrReg).isPointer() && "Operand is not a pointer!");
1692
1693 const LLT sXLen = LLT::scalar(STI.getXLen());
1694 Register IntReg = MRI->createGenericVirtualRegister(sXLen);
1695 MRI->setRegBank(IntReg, RBI.getRegBank(RISCV::GPRBRegBankID));
1696 MachineInstr *PtrToInt = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),
1697 TII.get(TargetOpcode::G_PTRTOINT), IntReg)
1698 .addReg(PtrReg);
1699 Op.setReg(IntReg);
1700 return select(*PtrToInt);
1701}
1702
1703void RISCVInstructionSelector::preISelLower(MachineInstr &MI) {
1704 switch (MI.getOpcode()) {
1705 case TargetOpcode::G_PTR_ADD: {
1706 Register DstReg = MI.getOperand(0).getReg();
1707 const LLT sXLen = LLT::scalar(STI.getXLen());
1708
1709 replacePtrWithInt(MI, 1);
1710 MI.setDesc(TII.get(TargetOpcode::G_ADD));
1711 MRI->setType(DstReg, sXLen);
1712 break;
1713 }
1714 case TargetOpcode::G_PTRMASK: {
1715 Register DstReg = MI.getOperand(0).getReg();
1716 const LLT sXLen = LLT::scalar(STI.getXLen());
1717 replacePtrWithInt(MI, 1);
1718 MI.setDesc(TII.get(TargetOpcode::G_AND));
1719 MRI->setType(DstReg, sXLen);
1720 break;
1721 }
1722 }
1723}
1724
1725void RISCVInstructionSelector::renderNegImm(MachineInstrBuilder &MIB,
1726 const MachineInstr &MI,
1727 int OpIdx) const {
1728 assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1729 "Expected G_CONSTANT");
1730 int64_t CstVal = MI.getOperand(1).getCImm()->getSExtValue();
1731 MIB.addImm(-CstVal);
1732}
1733
1734void RISCVInstructionSelector::renderImmSubFromXLen(MachineInstrBuilder &MIB,
1735 const MachineInstr &MI,
1736 int OpIdx) const {
1737 assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1738 "Expected G_CONSTANT");
1739 uint64_t CstVal = MI.getOperand(1).getCImm()->getZExtValue();
1740 MIB.addImm(STI.getXLen() - CstVal);
1741}
1742
1743void RISCVInstructionSelector::renderImmSubFrom32(MachineInstrBuilder &MIB,
1744 const MachineInstr &MI,
1745 int OpIdx) const {
1746 assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1747 "Expected G_CONSTANT");
1748 uint64_t CstVal = MI.getOperand(1).getCImm()->getZExtValue();
1749 MIB.addImm(32 - CstVal);
1750}
1751
1752void RISCVInstructionSelector::renderImmPlus1(MachineInstrBuilder &MIB,
1753 const MachineInstr &MI,
1754 int OpIdx) const {
1755 assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1756 "Expected G_CONSTANT");
1757 int64_t CstVal = MI.getOperand(1).getCImm()->getSExtValue();
1758 MIB.addImm(CstVal + 1);
1759}
1760
1761void RISCVInstructionSelector::renderTrailingZeros(MachineInstrBuilder &MIB,
1762 const MachineInstr &MI,
1763 int OpIdx) const {
1764 assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1765 "Expected G_CONSTANT");
1766 uint64_t C = MI.getOperand(1).getCImm()->getZExtValue();
1768}
1769
1770void RISCVInstructionSelector::renderXLenSubTrailingOnes(
1771 MachineInstrBuilder &MIB, const MachineInstr &MI, int OpIdx) const {
1772 assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1773 "Expected G_CONSTANT");
1774 uint64_t C = MI.getOperand(1).getCImm()->getZExtValue();
1775 MIB.addImm(Subtarget->getXLen() - llvm::countr_one(C));
1776}
1777
1778void RISCVInstructionSelector::renderAddiPairImmSmall(MachineInstrBuilder &MIB,
1779 const MachineInstr &MI,
1780 int OpIdx) const {
1781 assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1782 "Expected G_CONSTANT");
1783 int64_t Imm = MI.getOperand(1).getCImm()->getSExtValue();
1784 int64_t Adj = Imm < 0 ? -2048 : 2047;
1785 MIB.addImm(Imm - Adj);
1786}
1787
1788void RISCVInstructionSelector::renderAddiPairImmLarge(MachineInstrBuilder &MIB,
1789 const MachineInstr &MI,
1790 int OpIdx) const {
1791 assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
1792 "Expected G_CONSTANT");
1793 int64_t Imm = MI.getOperand(1).getCImm()->getSExtValue() < 0 ? -2048 : 2047;
1794 MIB.addImm(Imm);
1795}
1796
1797bool RISCVInstructionSelector::isRegInGprb(Register Reg) const {
1798 return RBI.getRegBank(Reg, *MRI, TRI)->getID() == RISCV::GPRBRegBankID;
1799}
1800
1801bool RISCVInstructionSelector::isRegInFprb(Register Reg) const {
1802 return RBI.getRegBank(Reg, *MRI, TRI)->getID() == RISCV::FPRBRegBankID;
1803}
1804
1805// A G_PTR_ADD result is worth splitting into Hi (materialized) +
1806// Lo12 (folded offset) only if every user is a plain scalar load/store
1807// using it as the address. Otherwise the ADD is selected on its own with
1808// the full materialized constant, making the Hi materialization here redundant.
1809bool RISCVInstructionSelector::isWorthFoldingAdd(Register AddResult) const {
1810 for (const MachineInstr &User : MRI->use_nodbg_instructions(AddResult)) {
1811 auto *LdSt = dyn_cast<GLoadStore>(&User);
1812 if (!LdSt)
1813 return false;
1814 // Must be used as the pointer, not the stored value.
1815 if (LdSt->getPointerReg() != AddResult)
1816 return false;
1818 return false;
1819 // Only scalar integer/f16/f32/f64 memory (exclude vectors, f128, ...).
1820 LLT Ty = MRI->getType(User.getOperand(0).getReg());
1821 if (!Ty.isScalar() || Ty.getSizeInBits() > 64)
1822 return false;
1823 }
1824 return true;
1825}
1826
1827bool RISCVInstructionSelector::selectCopy(MachineInstr &MI) const {
1828 Register DstReg = MI.getOperand(0).getReg();
1829
1830 if (DstReg.isPhysical())
1831 return true;
1832
1833 const TargetRegisterClass *DstRC =
1834 TRI.getConstrainedRegClassForReg(DstReg, *MRI);
1835
1836 assert(DstRC &&
1837 "Register class not available for LLT, register bank combination");
1838
1839 // No need to constrain SrcReg. It will get constrained when
1840 // we hit another of its uses or its defs.
1841 // Copies do not have constraints.
1842 if (!RBI.constrainGenericRegister(DstReg, *DstRC, *MRI)) {
1843 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(MI.getOpcode())
1844 << " operand\n");
1845 return false;
1846 }
1847
1848 MI.setDesc(TII.get(RISCV::COPY));
1849 return true;
1850}
1851
1852bool RISCVInstructionSelector::selectImplicitDef(MachineInstr &MI) const {
1853 assert(MI.getOpcode() == TargetOpcode::G_IMPLICIT_DEF);
1854
1855 const Register DstReg = MI.getOperand(0).getReg();
1856 const TargetRegisterClass *DstRC = TRI.getRegClassForTypeOnBank(
1857 MRI->getType(DstReg), *RBI.getRegBank(DstReg, *MRI, TRI), STI.is64Bit());
1858
1859 assert(DstRC &&
1860 "Register class not available for LLT, register bank combination");
1861
1862 if (!RBI.constrainGenericRegister(DstReg, *DstRC, *MRI)) {
1863 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(MI.getOpcode())
1864 << " operand\n");
1865 }
1866 MI.setDesc(TII.get(TargetOpcode::IMPLICIT_DEF));
1867 return true;
1868}
1869
1870bool RISCVInstructionSelector::materializeImm(Register DstReg, int64_t Imm,
1871 MachineInstr &MI) const {
1872 if (Imm == 0) {
1873 MachineBasicBlock &MBB = *MI.getParent();
1874 DebugLoc DL = MI.getDebugLoc();
1875 BuildMI(MBB, MI, DL, TII.get(TargetOpcode::COPY), DstReg).addReg(RISCV::X0);
1876 RBI.constrainGenericRegister(DstReg, RISCV::GPRRegClass, *MRI);
1877 return true;
1878 }
1879
1881 return materializeInstSeq(DstReg, Seq, MI);
1882}
1883
1884bool RISCVInstructionSelector::materializeInstSeq(
1885 Register DstReg, const RISCVMatInt::InstSeq &Seq, MachineInstr &MI) const {
1886 assert(!Seq.empty() && "materializeInstSeq requires a non-empty sequence");
1887
1888 MachineBasicBlock &MBB = *MI.getParent();
1889 DebugLoc DL = MI.getDebugLoc();
1890 unsigned NumInsts = Seq.size();
1891 Register SrcReg = RISCV::X0;
1892
1893 for (unsigned i = 0; i < NumInsts; i++) {
1894 Register TmpReg = i < NumInsts - 1
1895 ? MRI->createVirtualRegister(&RISCV::GPRRegClass)
1896 : DstReg;
1897 const RISCVMatInt::Inst &I = Seq[i];
1898 MachineInstr *Result;
1899
1900 switch (I.getOpndKind()) {
1901 case RISCVMatInt::Imm:
1902 Result = BuildMI(MBB, MI, DL, TII.get(I.getOpcode()), TmpReg)
1903 .addImm(I.getImm());
1904 break;
1905 case RISCVMatInt::RegX0:
1906 Result = BuildMI(MBB, MI, DL, TII.get(I.getOpcode()), TmpReg)
1907 .addReg(SrcReg)
1908 .addReg(RISCV::X0);
1909 break;
1911 Result = BuildMI(MBB, MI, DL, TII.get(I.getOpcode()), TmpReg)
1912 .addReg(SrcReg)
1913 .addReg(SrcReg);
1914 break;
1916 Result = BuildMI(MBB, MI, DL, TII.get(I.getOpcode()), TmpReg)
1917 .addReg(SrcReg)
1918 .addImm(I.getImm());
1919 break;
1920 }
1921
1923
1924 SrcReg = TmpReg;
1925 }
1926
1927 return true;
1928}
1929
1930InstructionSelector::ComplexRendererFns
1931RISCVInstructionSelector::computeConstAddr(int64_t CVal, bool IsPrefetch,
1932 Register OrigBase) const {
1933 // Split the constant into a materialized high part (the base) and
1934 // a simm12 low part (the offset). For prefetch the low part
1935 // must additionally be a multiple of 32 (simm12_lsb00000).
1936 int64_t Lo12 = SignExtend64<12>(CVal);
1937 int64_t Hi = (uint64_t)CVal - (uint64_t)Lo12;
1938 auto emit = [&](ConstAddrPlan Plan) -> ComplexRendererFns {
1939 return {{[=](MachineInstrBuilder &MIB) {
1940 MIB.addReg(materializeConstBase(MIB, Plan, OrigBase));
1941 },
1942 [=](MachineInstrBuilder &MIB) { MIB.addImm(Plan.Lo12); }}};
1943 };
1944 if (!Subtarget->is64Bit() || isInt<32>(Hi)) {
1945 if (IsPrefetch && (Lo12 & 0b11111) != 0)
1946 return std::nullopt;
1947 ConstAddrPlan Plan;
1948 Plan.Lo12 = Lo12;
1949 if (Hi) {
1950 Plan.Kind = ConstAddrPlan::LUI;
1951 Plan.Hi20 = (Hi >> 12) & 0xfffff;
1952 }
1953 return emit(std::move(Plan));
1954 }
1955
1956 // Otherwise ask constant materialization how it would handle the constant
1957 // and fold the trailing ADDI into the offset.
1958 RISCVMatInt::InstSeq Seq = RISCVMatInt::generateInstSeq(CVal, *Subtarget);
1959 if (Seq.back().getOpcode() != RISCV::ADDI)
1960 return std::nullopt;
1961 Lo12 = Seq.back().getImm();
1962 if (IsPrefetch && (Lo12 & 0b11111) != 0)
1963 return std::nullopt;
1964 Seq.pop_back();
1965 if (Seq.empty())
1966 return std::nullopt;
1967 ConstAddrPlan Plan;
1968 Plan.Kind = ConstAddrPlan::InstSeq;
1969 Plan.Seq = std::move(Seq);
1970 Plan.Lo12 = Lo12;
1971 return emit(std::move(Plan));
1972}
1973
1975RISCVInstructionSelector::materializeConstBase(MachineInstrBuilder &MIB,
1976 const ConstAddrPlan &Plan,
1977 Register OrigBase) const {
1978 MachineBasicBlock &MBB = *MIB->getParent();
1979 DebugLoc DL = MIB->getDebugLoc();
1980 MachineInstr &InsertPt = *MIB.getInstr();
1981
1982 Register HiReg = RISCV::X0;
1983 switch (Plan.Kind) {
1984 case ConstAddrPlan::X0:
1985 break;
1986 case ConstAddrPlan::LUI: {
1987 HiReg = MRI->createVirtualRegister(&RISCV::GPRRegClass);
1988 MachineInstr *LUI = BuildMI(MBB, InsertPt, DL, TII.get(RISCV::LUI), HiReg)
1989 .addImm(Plan.Hi20);
1991 break;
1992 }
1993 case ConstAddrPlan::InstSeq: {
1994 HiReg = MRI->createVirtualRegister(&RISCV::GPRRegClass);
1995 materializeInstSeq(HiReg, Plan.Seq, InsertPt);
1996 break;
1997 }
1998 }
1999
2000 // For G_PTR_ADD + large constant, add the original base to the materialized
2001 // high part.
2002 if (OrigBase.isValid() && HiReg != RISCV::X0) {
2003 Register BaseReg = MRI->createVirtualRegister(&RISCV::GPRRegClass);
2004 MachineInstr *Add = BuildMI(MBB, InsertPt, DL, TII.get(RISCV::ADD), BaseReg)
2005 .addReg(OrigBase)
2006 .addReg(HiReg);
2008 return BaseReg;
2009 }
2010 return OrigBase.isValid() ? OrigBase : HiReg;
2011}
2012
2013bool RISCVInstructionSelector::selectAddr(MachineInstr &MI, bool IsLocal,
2014 bool IsExternWeak) const {
2015 assert((MI.getOpcode() == TargetOpcode::G_GLOBAL_VALUE ||
2016 MI.getOpcode() == TargetOpcode::G_JUMP_TABLE ||
2017 MI.getOpcode() == TargetOpcode::G_CONSTANT_POOL) &&
2018 "Unexpected opcode");
2019
2020 const MachineOperand &DispMO = MI.getOperand(1);
2021
2022 Register DefReg = MI.getOperand(0).getReg();
2023 const LLT DefTy = MRI->getType(DefReg);
2024
2025 // When HWASAN is used and tagging of global variables is enabled
2026 // they should be accessed via the GOT, since the tagged address of a global
2027 // is incompatible with existing code models. This also applies to non-pic
2028 // mode.
2029 if (TM.isPositionIndependent() || Subtarget->allowTaggedGlobals()) {
2030 if (IsLocal && !Subtarget->allowTaggedGlobals()) {
2031 // Use PC-relative addressing to access the symbol. This generates the
2032 // pattern (PseudoLLA sym), which expands to (addi (auipc %pcrel_hi(sym))
2033 // %pcrel_lo(auipc)).
2034 MI.setDesc(TII.get(RISCV::PseudoLLA));
2036 return true;
2037 }
2038
2039 // Use PC-relative addressing to access the GOT for this symbol, then
2040 // load the address from the GOT. This generates the pattern (PseudoLGA
2041 // sym), which expands to (ld (addi (auipc %got_pcrel_hi(sym))
2042 // %pcrel_lo(auipc))).
2043 MachineFunction &MF = *MI.getParent()->getParent();
2044 MachineMemOperand *MemOp = MF.getMachineMemOperand(
2048 DefTy, Align(DefTy.getSizeInBits() / 8));
2049
2050 MachineInstr *Result = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),
2051 TII.get(RISCV::PseudoLGA), DefReg)
2052 .addDisp(DispMO, 0)
2053 .addMemOperand(MemOp);
2054
2056
2057 MI.eraseFromParent();
2058 return true;
2059 }
2060
2061 switch (TM.getCodeModel()) {
2062 default: {
2064 "Unsupported code model for lowering", MI);
2065 return false;
2066 }
2067 case CodeModel::Small: {
2068 // Must lie within a single 2 GiB address range and must lie between
2069 // absolute addresses -2 GiB and +2 GiB. This generates the pattern (addi
2070 // (lui %hi(sym)) %lo(sym)).
2071 Register AddrHiDest = MRI->createVirtualRegister(&RISCV::GPRRegClass);
2072 MachineInstr *AddrHi = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),
2073 TII.get(RISCV::LUI), AddrHiDest)
2074 .addDisp(DispMO, 0, RISCVII::MO_HI);
2075
2077
2078 MachineInstr *Result = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),
2079 TII.get(RISCV::ADDI), DefReg)
2080 .addReg(AddrHiDest)
2081 .addDisp(DispMO, 0, RISCVII::MO_LO);
2082
2084
2085 MI.eraseFromParent();
2086 return true;
2087 }
2088 case CodeModel::Medium:
2089 // Emit LGA/LLA instead of the sequence it expands to because the pcrel_lo
2090 // relocation needs to reference a label that points to the auipc
2091 // instruction itself, not the global. This cannot be done inside the
2092 // instruction selector.
2093 if (IsExternWeak) {
2094 // An extern weak symbol may be undefined, i.e. have value 0, which may
2095 // not be within 2GiB of PC, so use GOT-indirect addressing to access the
2096 // symbol. This generates the pattern (PseudoLGA sym), which expands to
2097 // (ld (addi (auipc %got_pcrel_hi(sym)) %pcrel_lo(auipc))).
2098 MachineFunction &MF = *MI.getParent()->getParent();
2099 MachineMemOperand *MemOp = MF.getMachineMemOperand(
2103 DefTy, Align(DefTy.getSizeInBits() / 8));
2104
2105 MachineInstr *Result = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),
2106 TII.get(RISCV::PseudoLGA), DefReg)
2107 .addDisp(DispMO, 0)
2108 .addMemOperand(MemOp);
2109
2111
2112 MI.eraseFromParent();
2113 return true;
2114 }
2115
2116 // Generate a sequence for accessing addresses within any 2GiB range
2117 // within the address space. This generates the pattern (PseudoLLA sym),
2118 // which expands to (addi (auipc %pcrel_hi(sym)) %pcrel_lo(auipc)).
2119 MI.setDesc(TII.get(RISCV::PseudoLLA));
2121 return true;
2122 }
2123
2124 return false;
2125}
2126
2127bool RISCVInstructionSelector::selectSelect(MachineInstr &MI) const {
2128 auto &SelectMI = cast<GSelect>(MI);
2129
2130 Register LHS, RHS;
2132 getOperandsForBranch(SelectMI.getCondReg(), CC, LHS, RHS, *MRI);
2133
2134 Register DstReg = SelectMI.getReg(0);
2135
2136 unsigned Opc = RISCV::Select_GPR_Using_CC_GPR;
2137 if (RBI.getRegBank(DstReg, *MRI, TRI)->getID() == RISCV::FPRBRegBankID) {
2138 unsigned Size = MRI->getType(DstReg).getSizeInBits();
2139 Opc = Size == 32 ? RISCV::Select_FPR32_Using_CC_GPR
2140 : RISCV::Select_FPR64_Using_CC_GPR;
2141 }
2142
2143 MachineInstr *Result =
2144 BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), TII.get(Opc))
2145 .addDef(DstReg)
2146 .addReg(LHS)
2147 .addReg(RHS)
2148 .addImm(CC)
2149 .addReg(SelectMI.getTrueReg())
2150 .addReg(SelectMI.getFalseReg());
2151 MI.eraseFromParent();
2153 return true;
2154}
2155
2156// Convert an FCMP predicate to one of the supported F or D instructions.
2157static unsigned getFCmpOpcode(CmpInst::Predicate Pred, unsigned Size) {
2158 assert((Size == 16 || Size == 32 || Size == 64) && "Unsupported size");
2159 switch (Pred) {
2160 default:
2161 llvm_unreachable("Unsupported predicate");
2162 case CmpInst::FCMP_OLT:
2163 return Size == 16 ? RISCV::FLT_H : Size == 32 ? RISCV::FLT_S : RISCV::FLT_D;
2164 case CmpInst::FCMP_OLE:
2165 return Size == 16 ? RISCV::FLE_H : Size == 32 ? RISCV::FLE_S : RISCV::FLE_D;
2166 case CmpInst::FCMP_OEQ:
2167 return Size == 16 ? RISCV::FEQ_H : Size == 32 ? RISCV::FEQ_S : RISCV::FEQ_D;
2168 }
2169}
2170
2171// Try legalizing an FCMP by swapping or inverting the predicate to one that
2172// is supported.
2174 CmpInst::Predicate &Pred, bool &NeedInvert) {
2175 auto isLegalFCmpPredicate = [](CmpInst::Predicate Pred) {
2176 return Pred == CmpInst::FCMP_OLT || Pred == CmpInst::FCMP_OLE ||
2177 Pred == CmpInst::FCMP_OEQ;
2178 };
2179
2180 assert(!isLegalFCmpPredicate(Pred) && "Predicate already legal?");
2181
2183 if (isLegalFCmpPredicate(InvPred)) {
2184 Pred = InvPred;
2185 std::swap(LHS, RHS);
2186 return true;
2187 }
2188
2189 InvPred = CmpInst::getInversePredicate(Pred);
2190 NeedInvert = true;
2191 if (isLegalFCmpPredicate(InvPred)) {
2192 Pred = InvPred;
2193 return true;
2194 }
2195 InvPred = CmpInst::getSwappedPredicate(InvPred);
2196 if (isLegalFCmpPredicate(InvPred)) {
2197 Pred = InvPred;
2198 std::swap(LHS, RHS);
2199 return true;
2200 }
2201
2202 return false;
2203}
2204
2205// Emit a sequence of instructions to compare LHS and RHS using Pred. Return
2206// the result in DstReg.
2207// FIXME: Maybe we should expand this earlier.
2208bool RISCVInstructionSelector::selectFPCompare(MachineInstr &MI) const {
2209 auto &CmpMI = cast<GFCmp>(MI);
2210 CmpInst::Predicate Pred = CmpMI.getCond();
2211
2212 Register DstReg = CmpMI.getReg(0);
2213 Register LHS = CmpMI.getLHSReg();
2214 Register RHS = CmpMI.getRHSReg();
2215
2216 unsigned Size = MRI->getType(LHS).getSizeInBits();
2217 assert((Size == 16 || Size == 32 || Size == 64) && "Unexpected size");
2218
2219 Register TmpReg = DstReg;
2220
2221 bool NeedInvert = false;
2222 // First try swapping operands or inverting.
2223 if (legalizeFCmpPredicate(LHS, RHS, Pred, NeedInvert)) {
2224 if (NeedInvert)
2225 TmpReg = MRI->createVirtualRegister(&RISCV::GPRRegClass);
2226 MachineInstr *Cmp = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),
2227 TII.get(getFCmpOpcode(Pred, Size)), TmpReg)
2229 .addReg(LHS)
2230 .addReg(RHS);
2232 } else if (Pred == CmpInst::FCMP_ONE || Pred == CmpInst::FCMP_UEQ) {
2233 // fcmp one LHS, RHS => (OR (FLT LHS, RHS), (FLT RHS, LHS))
2234 NeedInvert = Pred == CmpInst::FCMP_UEQ;
2235 Register Cmp1Reg = MRI->createVirtualRegister(&RISCV::GPRRegClass);
2236 MachineInstr *Cmp1 =
2237 BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),
2238 TII.get(getFCmpOpcode(CmpInst::FCMP_OLT, Size)), Cmp1Reg)
2240 .addReg(LHS)
2241 .addReg(RHS);
2243 Register Cmp2Reg = MRI->createVirtualRegister(&RISCV::GPRRegClass);
2244 MachineInstr *Cmp2 =
2245 BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),
2246 TII.get(getFCmpOpcode(CmpInst::FCMP_OLT, Size)), Cmp2Reg)
2248 .addReg(RHS)
2249 .addReg(LHS);
2251 if (NeedInvert)
2252 TmpReg = MRI->createVirtualRegister(&RISCV::GPRRegClass);
2253 MachineInstr *Or = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),
2254 TII.get(RISCV::OR), TmpReg)
2255 .addReg(Cmp1Reg)
2256 .addReg(Cmp2Reg);
2258 } else if (Pred == CmpInst::FCMP_ORD || Pred == CmpInst::FCMP_UNO) {
2259 // fcmp ord LHS, RHS => (AND (FEQ LHS, LHS), (FEQ RHS, RHS))
2260 // If LHS and RHS are the same, a single FEQ suffices.
2261 NeedInvert = Pred == CmpInst::FCMP_UNO;
2262 if (NeedInvert)
2263 TmpReg = MRI->createVirtualRegister(&RISCV::GPRRegClass);
2264 if (LHS == RHS) {
2265 MachineInstr *Cmp =
2266 BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),
2267 TII.get(getFCmpOpcode(CmpInst::FCMP_OEQ, Size)), TmpReg)
2269 .addReg(LHS)
2270 .addReg(LHS);
2272 } else {
2273 Register Cmp1Reg = MRI->createVirtualRegister(&RISCV::GPRRegClass);
2274 MachineInstr *Cmp1 =
2275 BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),
2276 TII.get(getFCmpOpcode(CmpInst::FCMP_OEQ, Size)), Cmp1Reg)
2278 .addReg(LHS)
2279 .addReg(LHS);
2281 Register Cmp2Reg = MRI->createVirtualRegister(&RISCV::GPRRegClass);
2282 MachineInstr *Cmp2 =
2283 BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),
2284 TII.get(getFCmpOpcode(CmpInst::FCMP_OEQ, Size)), Cmp2Reg)
2286 .addReg(RHS)
2287 .addReg(RHS);
2289 MachineInstr *And = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),
2290 TII.get(RISCV::AND), TmpReg)
2291 .addReg(Cmp1Reg)
2292 .addReg(Cmp2Reg);
2294 }
2295 } else
2296 llvm_unreachable("Unhandled predicate");
2297
2298 // Emit an XORI to invert the result if needed.
2299 if (NeedInvert) {
2300 MachineInstr *Xor = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),
2301 TII.get(RISCV::XORI), DstReg)
2302 .addReg(TmpReg)
2303 .addImm(1);
2305 }
2306
2307 MI.eraseFromParent();
2308 return true;
2309}
2310
2311void RISCVInstructionSelector::emitFence(AtomicOrdering FenceOrdering,
2312 SyncScope::ID FenceSSID,
2313 MachineInstr &MI) const {
2314 MachineBasicBlock &MBB = *MI.getParent();
2315 DebugLoc DL = MI.getDebugLoc();
2316
2317 if (STI.hasStdExtZtso()) {
2318 // The only fence that needs an instruction is a sequentially-consistent
2319 // cross-thread fence.
2320 if (FenceOrdering == AtomicOrdering::SequentiallyConsistent &&
2321 FenceSSID == SyncScope::System) {
2322 // fence rw, rw
2323 BuildMI(MBB, MI, DL, TII.get(RISCV::FENCE))
2326 return;
2327 }
2328
2329 // MEMBARRIER is a compiler barrier; it codegens to a no-op.
2330 BuildMI(MBB, MI, DL, TII.get(TargetOpcode::MEMBARRIER));
2331 return;
2332 }
2333
2334 // singlethread fences only synchronize with signal handlers on the same
2335 // thread and thus only need to preserve instruction order, not actually
2336 // enforce memory ordering.
2337 if (FenceSSID == SyncScope::SingleThread) {
2338 BuildMI(MBB, MI, DL, TII.get(TargetOpcode::MEMBARRIER));
2339 return;
2340 }
2341
2342 // Refer to Table A.6 in the version 2.3 draft of the RISC-V Instruction Set
2343 // Manual: Volume I.
2344 unsigned Pred, Succ;
2345 switch (FenceOrdering) {
2346 default:
2347 llvm_unreachable("Unexpected ordering");
2348 case AtomicOrdering::AcquireRelease:
2349 // fence acq_rel -> fence.tso
2350 BuildMI(MBB, MI, DL, TII.get(RISCV::FENCE_TSO));
2351 return;
2352 case AtomicOrdering::Acquire:
2353 // fence acquire -> fence r, rw
2354 Pred = RISCVFenceField::R;
2356 break;
2357 case AtomicOrdering::Release:
2358 // fence release -> fence rw, w
2360 Succ = RISCVFenceField::W;
2361 break;
2362 case AtomicOrdering::SequentiallyConsistent:
2363 // fence seq_cst -> fence rw, rw
2366 break;
2367 }
2368 BuildMI(MBB, MI, DL, TII.get(RISCV::FENCE)).addImm(Pred).addImm(Succ);
2369}
2370
2371namespace llvm {
2372InstructionSelector *
2374 const RISCVSubtarget &Subtarget,
2375 const RISCVRegisterBankInfo &RBI) {
2376 return new RISCVInstructionSelector(TM, Subtarget, RBI);
2377}
2378} // end namespace llvm
#define GET_GLOBALISEL_PREDICATES_INIT
#define GET_GLOBALISEL_TEMPORARIES_INIT
static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
uint64_t Imm
static bool selectMergeValues(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
static bool selectUnmergeValues(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
Provides analysis for querying information about KnownBits during GISel passes.
#define DEBUG_TYPE
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
static bool hasAllWUsers(const MachineInstr &OrigMI, const LoongArchSubtarget &ST, const MachineRegisterInfo &MRI)
static bool hasAllNBitUsers(const MachineInstr &OrigMI, const LoongArchSubtarget &ST, const MachineRegisterInfo &MRI, unsigned OrigBits)
#define I(x, y, z)
Definition MD5.cpp:57
Contains matchers for matching SSA Machine Instructions.
This file declares the MachineIRBuilder class.
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
#define P(N)
static StringRef getName(Value *V)
static bool isWorthFoldingAdd(SDValue Add)
static unsigned selectRegImmLoadStoreOp(const RISCVSubtarget &STI, unsigned GenericOpc, unsigned OpSize)
Select the RISC-V regimm opcode for the G_LOAD or G_STORE operation GenericOpc on STI,...
static unsigned selectZalasrLoadStoreOp(unsigned GenericOpc, unsigned OpSize)
Select the RISC-V Zalasr opcode for the G_LOAD or G_STORE operation GenericOpc, appropriate for the G...
static unsigned getFCmpOpcode(CmpInst::Predicate Pred, unsigned Size)
static bool legalizeFCmpPredicate(Register &LHS, Register &RHS, CmpInst::Predicate &Pred, bool &NeedInvert)
static void getOperandsForBranch(Register CondReg, RISCVCC::CondCode &CC, Register &LHS, Register &RHS, MachineRegisterInfo &MRI)
const SmallVectorImpl< MachineOperand > & Cond
This file declares the targeting of the RegisterBankInfo class for RISC-V.
#define LLVM_DEBUG(...)
Definition Debug.h:119
Value * RHS
Value * LHS
APInt bitcastToAPInt() const
Definition APFloat.h:1475
bool isPosZero() const
Definition APFloat.h:1594
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1508
static APInt getBitsSetFrom(unsigned numBits, unsigned loBit)
Constructs an APInt value that has a contiguous range of bits set.
Definition APInt.h:282
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
Definition InstrTypes.h:743
@ ICMP_SLT
signed less than
Definition InstrTypes.h:769
@ ICMP_SLE
signed less or equal
Definition InstrTypes.h:770
@ FCMP_OLT
0 1 0 0 True if ordered and less than
Definition InstrTypes.h:746
@ ICMP_UGE
unsigned greater or equal
Definition InstrTypes.h:764
@ ICMP_UGT
unsigned greater than
Definition InstrTypes.h:763
@ ICMP_SGT
signed greater than
Definition InstrTypes.h:767
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
Definition InstrTypes.h:748
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
Definition InstrTypes.h:751
@ ICMP_ULT
unsigned less than
Definition InstrTypes.h:765
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
Definition InstrTypes.h:747
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
Definition InstrTypes.h:749
@ ICMP_NE
not equal
Definition InstrTypes.h:762
@ ICMP_SGE
signed greater or equal
Definition InstrTypes.h:768
@ ICMP_ULE
unsigned less or equal
Definition InstrTypes.h:766
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Definition InstrTypes.h:750
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Definition InstrTypes.h:890
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Definition InstrTypes.h:852
This is an important base class in LLVM.
Definition Constant.h:43
virtual void setupMF(MachineFunction &mf, GISelValueTracking *vt, CodeGenCoverage *covinfo=nullptr, ProfileSummaryInfo *psi=nullptr, BlockFrequencyInfo *bfi=nullptr)
Setup per-MF executor state.
Register getPointerReg() const
Get the source register of the pointer value.
MachineMemOperand & getMMO() const
Get the MachineMemOperand on this instruction.
LocationSize getMemSizeInBits() const
Returns the size in bits of the memory access.
Register getReg(unsigned Idx) const
Access the Idx'th operand as a register and return it.
constexpr unsigned getScalarSizeInBits() const
constexpr bool isScalar() const
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
constexpr bool isValid() const
constexpr bool isVector() const
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
constexpr bool isPointer() const
constexpr unsigned getAddressSpace() const
TypeSize getValue() const
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addDisp(const MachineOperand &Disp, int64_t off, unsigned char TargetFlags=0) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
AtomicOrdering getSuccessOrdering() const
Return the atomic ordering requirements for this memory operation.
MachineOperand class - Representation of each machine instruction operand.
int64_t getImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
static MachineOperand CreateImm(int64_t Val)
Register getReg() const
getReg - Returns the register number.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
iterator_range< use_nodbg_iterator > use_nodbg_operands(Register Reg) const
const RegClassOrRegBank & getRegClassOrRegBank(Register Reg) const
Return the register bank or register class of Reg.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
LLVM_ABI void setRegBank(Register Reg, const RegisterBank &RegBank)
Set the register bank to RegBank for Reg.
iterator_range< use_instr_nodbg_iterator > use_nodbg_instructions(Register Reg) const
LLVM_ABI void setType(Register VReg, LLT Ty)
Set the low-level type of VReg to Ty.
LLVM_ABI Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
Analysis providing profile information.
This class provides the information for the target register banks.
unsigned getXLen() const
std::optional< unsigned > getRealVLen() const
static std::pair< unsigned, unsigned > decomposeSubvectorInsertExtractToSubRegs(MVT VecVT, MVT SubVecVT, unsigned InsertExtractIdx, const RISCVRegisterInfo *TRI)
static unsigned getRegClassIDForVecVT(MVT VT)
static RISCVVType::VLMUL getLMUL(MVT VT)
static const TargetRegisterClass * constrainGenericRegister(Register Reg, const TargetRegisterClass &RC, MachineRegisterInfo &MRI)
Constrain the (possibly generic) virtual register Reg to RC.
const RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
unsigned getID() const
Get the identifier of this register bank.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
constexpr bool isValid() const
Definition Register.h:112
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition Register.h:83
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
bool isPositionIndependent() const
CodeModel::Model getCodeModel() const
Returns the code model.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
operand_type_match m_Reg()
SpecificConstantMatch m_SpecificICst(const APInt &RequestedValue)
Matches a constant equal to RequestedValue.
GCstAndRegMatch m_GCst(std::optional< ValueAndVReg > &ValReg)
operand_type_match m_Pred()
UnaryOp_match< SrcTy, TargetOpcode::G_ZEXT > m_GZExt(const SrcTy &Src)
ConstantMatch< APInt > m_ICst(APInt &Cst)
UnaryOp_match< SrcTy, TargetOpcode::G_INTTOPTR > m_GIntToPtr(const SrcTy &Src)
BinaryOp_match< LHS, RHS, TargetOpcode::G_ADD, true > m_GAdd(const LHS &L, const RHS &R)
OneNonDBGUse_match< SubPat > m_OneNonDBGUse(const SubPat &SP)
SpecificImmMatch m_SpecificImm(int64_t RequestedValue)
Matches an immediate operand equal to RequestedValue.
AllOnesConstantMatch m_AllOnes()
CompareOp_match< Pred, LHS, RHS, TargetOpcode::G_ICMP > m_GICmp(const Pred &P, const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, TargetOpcode::G_SUB > m_GSub(const LHS &L, const RHS &R)
bool mi_match(Reg R, const MachineRegisterInfo &MRI, Pattern &&P)
BinaryOp_match< LHS, RHS, TargetOpcode::G_PTR_ADD, false > m_GPtrAdd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, TargetOpcode::G_SHL, false > m_GShl(const LHS &L, const RHS &R)
GFrameIndexMatch m_GFrameIndex(int &FI)
BinaryOp_match< LHS, RHS, TargetOpcode::G_AND, true > m_GAnd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, TargetOpcode::G_LSHR, false > m_GLShr(const LHS &L, const RHS &R)
SrcImmOp_match< SrcTy, AnyImmMatch, TargetOpcode::G_SEXT_INREG > m_GSExtInReg(const SrcTy &Src)
Matches a G_SEXT_INREG, binding its source and immediate width.
unsigned getBrCond(CondCode CC, unsigned SelectOpc=0)
InstSeq generateInstSeq(int64_t Val, const MCSubtargetInfo &STI)
SmallVector< Inst, 8 > InstSeq
Definition RISCVMatInt.h:43
static unsigned decodeVSEW(unsigned VSEW)
LLVM_ABI unsigned getSEWLMULRatio(unsigned SEW, VLMUL VLMul)
LLVM_ABI unsigned encodeVTYPE(VLMUL VLMUL, unsigned SEW, bool TailAgnostic, bool MaskAgnostic, bool AltFmt=false)
static constexpr int64_t VLMaxSentinel
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
Definition LLVMContext.h:63
@ System
Synchronized with respect to all concurrently executing threads.
Definition LLVMContext.h:66
@ User
could "use" a pointer
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
Definition SFrame.h:77
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
PointerUnion< const TargetRegisterClass *, const RegisterBank * > RegClassOrRegBank
Convenient type to represent either a register class or a register bank.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:166
@ Known
Known to have no common set bits.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
bool isStrongerThanMonotonic(AtomicOrdering AO)
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
Definition bit.h:315
LLVM_ABI void constrainSelectedInstRegOperands(MachineInstr &I, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
Mutate the newly-selected instruction I to constrain its (possibly generic) virtual register operands...
Definition Utils.cpp:159
int bit_width(T Value)
Returns the number of bits needed to represent Value if Value is nonzero.
Definition bit.h:325
LLVM_ABI MVT getMVTForLLT(LLT Ty)
Get a rough equivalent of an MVT for a given LLT.
InstructionSelector * createRISCVInstructionSelector(const RISCVTargetMachine &TM, const RISCVSubtarget &Subtarget, const RISCVRegisterBankInfo &RBI)
LLVM_ABI std::optional< int64_t > getIConstantVRegSExtVal(Register VReg, const MachineRegisterInfo &MRI)
If VReg is defined by a G_CONSTANT fits in int64_t returns it.
Definition Utils.cpp:317
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition bit.h:204
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:326
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
LLVM_ABI void reportGISelFailure(MachineFunction &MF, MachineOptimizationRemarkEmitter &MORE, MachineOptimizationRemarkMissed &R)
Report an ISel error as a missed optimization remark to the LLVMContext's diagnostic stream.
Definition Utils.cpp:261
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
AtomicOrdering
Atomic ordering for LLVM's memory model.
constexpr T maskTrailingZeros(unsigned N)
Create a bitmask with the N right-most bits set to 0, and all other bits set to 1.
Definition MathExtras.h:95
@ Or
Bitwise or logical OR of integers.
@ Xor
Bitwise or logical XOR of integers.
@ And
Bitwise or logical AND of integers.
@ Add
Sum of integers.
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
LLVM_ABI std::optional< ValueAndVReg > getIConstantVRegValWithLookThrough(Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs=true)
If VReg is defined by a statically evaluable chain of instructions rooted on a G_CONSTANT returns its...
Definition Utils.cpp:436
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
Definition MathExtras.h:567
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
Definition MathExtras.h:78
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:177
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
#define MORE()
Definition regcomp.c:247
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.