LLVM 22.0.0git
RISCVInstrInfo.cpp
Go to the documentation of this file.
1//===-- RISCVInstrInfo.cpp - RISC-V Instruction Information -----*- 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//
9// This file contains the RISC-V implementation of the TargetInstrInfo class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "RISCVInstrInfo.h"
16#include "RISCV.h"
18#include "RISCVSubtarget.h"
19#include "llvm/ADT/STLExtras.h"
21#include "llvm/ADT/Statistic.h"
33#include "llvm/IR/Module.h"
37
38using namespace llvm;
39
40#define GEN_CHECK_COMPRESS_INSTR
41#include "RISCVGenCompressInstEmitter.inc"
42
43#define GET_INSTRINFO_CTOR_DTOR
44#define GET_INSTRINFO_NAMED_OPS
45#include "RISCVGenInstrInfo.inc"
46
47#define DEBUG_TYPE "riscv-instr-info"
48STATISTIC(NumVRegSpilled,
49 "Number of registers within vector register groups spilled");
50STATISTIC(NumVRegReloaded,
51 "Number of registers within vector register groups reloaded");
52
54 "riscv-prefer-whole-register-move", cl::init(false), cl::Hidden,
55 cl::desc("Prefer whole register move for vector registers."));
56
58 "riscv-force-machine-combiner-strategy", cl::Hidden,
59 cl::desc("Force machine combiner to use a specific strategy for machine "
60 "trace metrics evaluation."),
61 cl::init(MachineTraceStrategy::TS_NumStrategies),
62 cl::values(clEnumValN(MachineTraceStrategy::TS_Local, "local",
63 "Local strategy."),
64 clEnumValN(MachineTraceStrategy::TS_MinInstrCount, "min-instr",
65 "MinInstrCount strategy.")));
66
68
69using namespace RISCV;
70
71#define GET_RISCVVPseudosTable_IMPL
72#include "RISCVGenSearchableTables.inc"
73
74} // namespace llvm::RISCVVPseudosTable
75
76namespace llvm::RISCV {
77
78#define GET_RISCVMaskedPseudosTable_IMPL
79#include "RISCVGenSearchableTables.inc"
80
81} // end namespace llvm::RISCV
82
84 : RISCVGenInstrInfo(RISCV::ADJCALLSTACKDOWN, RISCV::ADJCALLSTACKUP),
85 STI(STI) {}
86
87#define GET_INSTRINFO_HELPERS
88#include "RISCVGenInstrInfo.inc"
89
91 if (STI.hasStdExtZca())
92 return MCInstBuilder(RISCV::C_NOP);
93 return MCInstBuilder(RISCV::ADDI)
94 .addReg(RISCV::X0)
95 .addReg(RISCV::X0)
96 .addImm(0);
97}
98
100 int &FrameIndex) const {
101 TypeSize Dummy = TypeSize::getZero();
102 return isLoadFromStackSlot(MI, FrameIndex, Dummy);
103}
104
105static std::optional<unsigned> getLMULForRVVWholeLoadStore(unsigned Opcode) {
106 switch (Opcode) {
107 default:
108 return std::nullopt;
109 case RISCV::VS1R_V:
110 case RISCV::VL1RE8_V:
111 case RISCV::VL1RE16_V:
112 case RISCV::VL1RE32_V:
113 case RISCV::VL1RE64_V:
114 return 1;
115 case RISCV::VS2R_V:
116 case RISCV::VL2RE8_V:
117 case RISCV::VL2RE16_V:
118 case RISCV::VL2RE32_V:
119 case RISCV::VL2RE64_V:
120 return 2;
121 case RISCV::VS4R_V:
122 case RISCV::VL4RE8_V:
123 case RISCV::VL4RE16_V:
124 case RISCV::VL4RE32_V:
125 case RISCV::VL4RE64_V:
126 return 4;
127 case RISCV::VS8R_V:
128 case RISCV::VL8RE8_V:
129 case RISCV::VL8RE16_V:
130 case RISCV::VL8RE32_V:
131 case RISCV::VL8RE64_V:
132 return 8;
133 }
134}
135
137 int &FrameIndex,
138 TypeSize &MemBytes) const {
139 switch (MI.getOpcode()) {
140 default:
141 return 0;
142 case RISCV::LB:
143 case RISCV::LBU:
144 MemBytes = TypeSize::getFixed(1);
145 break;
146 case RISCV::LH:
147 case RISCV::LH_INX:
148 case RISCV::LHU:
149 case RISCV::FLH:
150 MemBytes = TypeSize::getFixed(2);
151 break;
152 case RISCV::LW:
153 case RISCV::LW_INX:
154 case RISCV::FLW:
155 case RISCV::LWU:
156 MemBytes = TypeSize::getFixed(4);
157 break;
158 case RISCV::LD:
159 case RISCV::LD_RV32:
160 case RISCV::FLD:
161 MemBytes = TypeSize::getFixed(8);
162 break;
163 case RISCV::VL1RE8_V:
164 case RISCV::VL2RE8_V:
165 case RISCV::VL4RE8_V:
166 case RISCV::VL8RE8_V:
167 if (!MI.getOperand(1).isFI())
168 return Register();
169 FrameIndex = MI.getOperand(1).getIndex();
170 unsigned LMUL = *getLMULForRVVWholeLoadStore(MI.getOpcode());
172 return MI.getOperand(0).getReg();
173 }
174
175 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
176 MI.getOperand(2).getImm() == 0) {
177 FrameIndex = MI.getOperand(1).getIndex();
178 return MI.getOperand(0).getReg();
179 }
180
181 return 0;
182}
183
185 int &FrameIndex) const {
186 TypeSize Dummy = TypeSize::getZero();
187 return isStoreToStackSlot(MI, FrameIndex, Dummy);
188}
189
191 int &FrameIndex,
192 TypeSize &MemBytes) const {
193 switch (MI.getOpcode()) {
194 default:
195 return 0;
196 case RISCV::SB:
197 MemBytes = TypeSize::getFixed(1);
198 break;
199 case RISCV::SH:
200 case RISCV::SH_INX:
201 case RISCV::FSH:
202 MemBytes = TypeSize::getFixed(2);
203 break;
204 case RISCV::SW:
205 case RISCV::SW_INX:
206 case RISCV::FSW:
207 MemBytes = TypeSize::getFixed(4);
208 break;
209 case RISCV::SD:
210 case RISCV::SD_RV32:
211 case RISCV::FSD:
212 MemBytes = TypeSize::getFixed(8);
213 break;
214 case RISCV::VS1R_V:
215 case RISCV::VS2R_V:
216 case RISCV::VS4R_V:
217 case RISCV::VS8R_V:
218 if (!MI.getOperand(1).isFI())
219 return Register();
220 FrameIndex = MI.getOperand(1).getIndex();
221 unsigned LMUL = *getLMULForRVVWholeLoadStore(MI.getOpcode());
223 return MI.getOperand(0).getReg();
224 }
225
226 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
227 MI.getOperand(2).getImm() == 0) {
228 FrameIndex = MI.getOperand(1).getIndex();
229 return MI.getOperand(0).getReg();
230 }
231
232 return 0;
233}
234
236 const MachineInstr &MI) const {
237 switch (RISCV::getRVVMCOpcode(MI.getOpcode())) {
238 case RISCV::VMV_V_X:
239 case RISCV::VFMV_V_F:
240 case RISCV::VMV_V_I:
241 case RISCV::VMV_S_X:
242 case RISCV::VFMV_S_F:
243 case RISCV::VID_V:
244 return MI.getOperand(1).isUndef();
245 default:
247 }
248}
249
250static bool forwardCopyWillClobberTuple(unsigned DstReg, unsigned SrcReg,
251 unsigned NumRegs) {
252 return DstReg > SrcReg && (DstReg - SrcReg) < NumRegs;
253}
254
256 const MachineBasicBlock &MBB,
259 RISCVVType::VLMUL LMul) {
261 return false;
262
263 assert(MBBI->getOpcode() == TargetOpcode::COPY &&
264 "Unexpected COPY instruction.");
265 Register SrcReg = MBBI->getOperand(1).getReg();
267
268 bool FoundDef = false;
269 bool FirstVSetVLI = false;
270 unsigned FirstSEW = 0;
271 while (MBBI != MBB.begin()) {
272 --MBBI;
273 if (MBBI->isMetaInstruction())
274 continue;
275
276 if (RISCVInstrInfo::isVectorConfigInstr(*MBBI)) {
277 // There is a vsetvli between COPY and source define instruction.
278 // vy = def_vop ... (producing instruction)
279 // ...
280 // vsetvli
281 // ...
282 // vx = COPY vy
283 if (!FoundDef) {
284 if (!FirstVSetVLI) {
285 FirstVSetVLI = true;
286 unsigned FirstVType = MBBI->getOperand(2).getImm();
287 RISCVVType::VLMUL FirstLMul = RISCVVType::getVLMUL(FirstVType);
288 FirstSEW = RISCVVType::getSEW(FirstVType);
289 // The first encountered vsetvli must have the same lmul as the
290 // register class of COPY.
291 if (FirstLMul != LMul)
292 return false;
293 }
294 // Only permit `vsetvli x0, x0, vtype` between COPY and the source
295 // define instruction.
296 if (!RISCVInstrInfo::isVLPreservingConfig(*MBBI))
297 return false;
298 continue;
299 }
300
301 // MBBI is the first vsetvli before the producing instruction.
302 unsigned VType = MBBI->getOperand(2).getImm();
303 // If there is a vsetvli between COPY and the producing instruction.
304 if (FirstVSetVLI) {
305 // If SEW is different, return false.
306 if (RISCVVType::getSEW(VType) != FirstSEW)
307 return false;
308 }
309
310 // If the vsetvli is tail undisturbed, keep the whole register move.
311 if (!RISCVVType::isTailAgnostic(VType))
312 return false;
313
314 // The checking is conservative. We only have register classes for
315 // LMUL = 1/2/4/8. We should be able to convert vmv1r.v to vmv.v.v
316 // for fractional LMUL operations. However, we could not use the vsetvli
317 // lmul for widening operations. The result of widening operation is
318 // 2 x LMUL.
319 return LMul == RISCVVType::getVLMUL(VType);
320 } else if (MBBI->isInlineAsm() || MBBI->isCall()) {
321 return false;
322 } else if (MBBI->getNumDefs()) {
323 // Check all the instructions which will change VL.
324 // For example, vleff has implicit def VL.
325 if (MBBI->modifiesRegister(RISCV::VL, /*TRI=*/nullptr))
326 return false;
327
328 // Only converting whole register copies to vmv.v.v when the defining
329 // value appears in the explicit operands.
330 for (const MachineOperand &MO : MBBI->explicit_operands()) {
331 if (!MO.isReg() || !MO.isDef())
332 continue;
333 if (!FoundDef && TRI->regsOverlap(MO.getReg(), SrcReg)) {
334 // We only permit the source of COPY has the same LMUL as the defined
335 // operand.
336 // There are cases we need to keep the whole register copy if the LMUL
337 // is different.
338 // For example,
339 // $x0 = PseudoVSETIVLI 4, 73 // vsetivli zero, 4, e16,m2,ta,m
340 // $v28m4 = PseudoVWADD_VV_M2 $v26m2, $v8m2
341 // # The COPY may be created by vlmul_trunc intrinsic.
342 // $v26m2 = COPY renamable $v28m2, implicit killed $v28m4
343 //
344 // After widening, the valid value will be 4 x e32 elements. If we
345 // convert the COPY to vmv.v.v, it will only copy 4 x e16 elements.
346 // FIXME: The COPY of subregister of Zvlsseg register will not be able
347 // to convert to vmv.v.[v|i] under the constraint.
348 if (MO.getReg() != SrcReg)
349 return false;
350
351 // In widening reduction instructions with LMUL_1 input vector case,
352 // only checking the LMUL is insufficient due to reduction result is
353 // always LMUL_1.
354 // For example,
355 // $x11 = PseudoVSETIVLI 1, 64 // vsetivli a1, 1, e8, m1, ta, mu
356 // $v8m1 = PseudoVWREDSUM_VS_M1 $v26, $v27
357 // $v26 = COPY killed renamable $v8
358 // After widening, The valid value will be 1 x e16 elements. If we
359 // convert the COPY to vmv.v.v, it will only copy 1 x e8 elements.
360 uint64_t TSFlags = MBBI->getDesc().TSFlags;
362 return false;
363
364 // If the producing instruction does not depend on vsetvli, do not
365 // convert COPY to vmv.v.v. For example, VL1R_V or PseudoVRELOAD.
366 if (!RISCVII::hasSEWOp(TSFlags) || !RISCVII::hasVLOp(TSFlags))
367 return false;
368
369 // Found the definition.
370 FoundDef = true;
371 DefMBBI = MBBI;
372 break;
373 }
374 }
375 }
376 }
377
378 return false;
379}
380
383 const DebugLoc &DL, MCRegister DstReg, MCRegister SrcReg, bool KillSrc,
384 const TargetRegisterClass *RegClass) const {
387 unsigned NF = RISCVRI::getNF(RegClass->TSFlags);
388
389 uint16_t SrcEncoding = TRI->getEncodingValue(SrcReg);
390 uint16_t DstEncoding = TRI->getEncodingValue(DstReg);
391 auto [LMulVal, Fractional] = RISCVVType::decodeVLMUL(LMul);
392 assert(!Fractional && "It is impossible be fractional lmul here.");
393 unsigned NumRegs = NF * LMulVal;
394 bool ReversedCopy =
395 forwardCopyWillClobberTuple(DstEncoding, SrcEncoding, NumRegs);
396 if (ReversedCopy) {
397 // If the src and dest overlap when copying a tuple, we need to copy the
398 // registers in reverse.
399 SrcEncoding += NumRegs - 1;
400 DstEncoding += NumRegs - 1;
401 }
402
403 unsigned I = 0;
404 auto GetCopyInfo = [&](uint16_t SrcEncoding, uint16_t DstEncoding)
405 -> std::tuple<RISCVVType::VLMUL, const TargetRegisterClass &, unsigned,
406 unsigned, unsigned> {
407 if (ReversedCopy) {
408 // For reversed copying, if there are enough aligned registers(8/4/2), we
409 // can do a larger copy(LMUL8/4/2).
410 // Besides, we have already known that DstEncoding is larger than
411 // SrcEncoding in forwardCopyWillClobberTuple, so the difference between
412 // DstEncoding and SrcEncoding should be >= LMUL value we try to use to
413 // avoid clobbering.
414 uint16_t Diff = DstEncoding - SrcEncoding;
415 if (I + 8 <= NumRegs && Diff >= 8 && SrcEncoding % 8 == 7 &&
416 DstEncoding % 8 == 7)
417 return {RISCVVType::LMUL_8, RISCV::VRM8RegClass, RISCV::VMV8R_V,
418 RISCV::PseudoVMV_V_V_M8, RISCV::PseudoVMV_V_I_M8};
419 if (I + 4 <= NumRegs && Diff >= 4 && SrcEncoding % 4 == 3 &&
420 DstEncoding % 4 == 3)
421 return {RISCVVType::LMUL_4, RISCV::VRM4RegClass, RISCV::VMV4R_V,
422 RISCV::PseudoVMV_V_V_M4, RISCV::PseudoVMV_V_I_M4};
423 if (I + 2 <= NumRegs && Diff >= 2 && SrcEncoding % 2 == 1 &&
424 DstEncoding % 2 == 1)
425 return {RISCVVType::LMUL_2, RISCV::VRM2RegClass, RISCV::VMV2R_V,
426 RISCV::PseudoVMV_V_V_M2, RISCV::PseudoVMV_V_I_M2};
427 // Or we should do LMUL1 copying.
428 return {RISCVVType::LMUL_1, RISCV::VRRegClass, RISCV::VMV1R_V,
429 RISCV::PseudoVMV_V_V_M1, RISCV::PseudoVMV_V_I_M1};
430 }
431
432 // For forward copying, if source register encoding and destination register
433 // encoding are aligned to 8/4/2, we can do a LMUL8/4/2 copying.
434 if (I + 8 <= NumRegs && SrcEncoding % 8 == 0 && DstEncoding % 8 == 0)
435 return {RISCVVType::LMUL_8, RISCV::VRM8RegClass, RISCV::VMV8R_V,
436 RISCV::PseudoVMV_V_V_M8, RISCV::PseudoVMV_V_I_M8};
437 if (I + 4 <= NumRegs && SrcEncoding % 4 == 0 && DstEncoding % 4 == 0)
438 return {RISCVVType::LMUL_4, RISCV::VRM4RegClass, RISCV::VMV4R_V,
439 RISCV::PseudoVMV_V_V_M4, RISCV::PseudoVMV_V_I_M4};
440 if (I + 2 <= NumRegs && SrcEncoding % 2 == 0 && DstEncoding % 2 == 0)
441 return {RISCVVType::LMUL_2, RISCV::VRM2RegClass, RISCV::VMV2R_V,
442 RISCV::PseudoVMV_V_V_M2, RISCV::PseudoVMV_V_I_M2};
443 // Or we should do LMUL1 copying.
444 return {RISCVVType::LMUL_1, RISCV::VRRegClass, RISCV::VMV1R_V,
445 RISCV::PseudoVMV_V_V_M1, RISCV::PseudoVMV_V_I_M1};
446 };
447
448 while (I != NumRegs) {
449 // For non-segment copying, we only do this once as the registers are always
450 // aligned.
451 // For segment copying, we may do this several times. If the registers are
452 // aligned to larger LMUL, we can eliminate some copyings.
453 auto [LMulCopied, RegClass, Opc, VVOpc, VIOpc] =
454 GetCopyInfo(SrcEncoding, DstEncoding);
455 auto [NumCopied, _] = RISCVVType::decodeVLMUL(LMulCopied);
456
458 if (LMul == LMulCopied &&
459 isConvertibleToVMV_V_V(STI, MBB, MBBI, DefMBBI, LMul)) {
460 Opc = VVOpc;
461 if (DefMBBI->getOpcode() == VIOpc)
462 Opc = VIOpc;
463 }
464
465 // Emit actual copying.
466 // For reversed copying, the encoding should be decreased.
467 MCRegister ActualSrcReg = TRI->findVRegWithEncoding(
468 RegClass, ReversedCopy ? (SrcEncoding - NumCopied + 1) : SrcEncoding);
469 MCRegister ActualDstReg = TRI->findVRegWithEncoding(
470 RegClass, ReversedCopy ? (DstEncoding - NumCopied + 1) : DstEncoding);
471
472 auto MIB = BuildMI(MBB, MBBI, DL, get(Opc), ActualDstReg);
473 bool UseVMV_V_I = RISCV::getRVVMCOpcode(Opc) == RISCV::VMV_V_I;
474 bool UseVMV = UseVMV_V_I || RISCV::getRVVMCOpcode(Opc) == RISCV::VMV_V_V;
475 if (UseVMV)
476 MIB.addReg(ActualDstReg, RegState::Undef);
477 if (UseVMV_V_I)
478 MIB = MIB.add(DefMBBI->getOperand(2));
479 else
480 MIB = MIB.addReg(ActualSrcReg, getKillRegState(KillSrc));
481 if (UseVMV) {
482 const MCInstrDesc &Desc = DefMBBI->getDesc();
483 MIB.add(DefMBBI->getOperand(RISCVII::getVLOpNum(Desc))); // AVL
484 unsigned Log2SEW =
485 DefMBBI->getOperand(RISCVII::getSEWOpNum(Desc)).getImm();
486 MIB.addImm(Log2SEW ? Log2SEW : 3); // SEW
487 MIB.addImm(0); // tu, mu
488 MIB.addReg(RISCV::VL, RegState::Implicit);
489 MIB.addReg(RISCV::VTYPE, RegState::Implicit);
490 }
491 // Add an implicit read of the original source to silence the verifier
492 // in the cases where some of the smaller VRs we're copying from might be
493 // undef, caused by the fact that the original, larger source VR might not
494 // be fully initialized at the time this COPY happens.
495 MIB.addReg(SrcReg, RegState::Implicit);
496
497 // If we are copying reversely, we should decrease the encoding.
498 SrcEncoding += (ReversedCopy ? -NumCopied : NumCopied);
499 DstEncoding += (ReversedCopy ? -NumCopied : NumCopied);
500 I += NumCopied;
501 }
502}
503
506 const DebugLoc &DL, Register DstReg,
507 Register SrcReg, bool KillSrc,
508 bool RenamableDest, bool RenamableSrc) const {
510 unsigned KillFlag = getKillRegState(KillSrc);
511
512 if (RISCV::GPRRegClass.contains(DstReg, SrcReg)) {
513 BuildMI(MBB, MBBI, DL, get(RISCV::ADDI), DstReg)
514 .addReg(SrcReg, KillFlag | getRenamableRegState(RenamableSrc))
515 .addImm(0);
516 return;
517 }
518
519 if (RISCV::GPRF16RegClass.contains(DstReg, SrcReg)) {
520 BuildMI(MBB, MBBI, DL, get(RISCV::PseudoMV_FPR16INX), DstReg)
521 .addReg(SrcReg, KillFlag | getRenamableRegState(RenamableSrc));
522 return;
523 }
524
525 if (RISCV::GPRF32RegClass.contains(DstReg, SrcReg)) {
526 BuildMI(MBB, MBBI, DL, get(RISCV::PseudoMV_FPR32INX), DstReg)
527 .addReg(SrcReg, KillFlag | getRenamableRegState(RenamableSrc));
528 return;
529 }
530
531 if (RISCV::GPRPairRegClass.contains(DstReg, SrcReg)) {
532 MCRegister EvenReg = TRI->getSubReg(SrcReg, RISCV::sub_gpr_even);
533 MCRegister OddReg = TRI->getSubReg(SrcReg, RISCV::sub_gpr_odd);
534 // We need to correct the odd register of X0_Pair.
535 if (OddReg == RISCV::DUMMY_REG_PAIR_WITH_X0)
536 OddReg = RISCV::X0;
537 assert(DstReg != RISCV::X0_Pair && "Cannot write to X0_Pair");
538
539 // Emit an ADDI for both parts of GPRPair.
540 BuildMI(MBB, MBBI, DL, get(RISCV::ADDI),
541 TRI->getSubReg(DstReg, RISCV::sub_gpr_even))
542 .addReg(EvenReg, KillFlag)
543 .addImm(0);
544 BuildMI(MBB, MBBI, DL, get(RISCV::ADDI),
545 TRI->getSubReg(DstReg, RISCV::sub_gpr_odd))
546 .addReg(OddReg, KillFlag)
547 .addImm(0);
548 return;
549 }
550
551 // Handle copy from csr
552 if (RISCV::VCSRRegClass.contains(SrcReg) &&
553 RISCV::GPRRegClass.contains(DstReg)) {
554 BuildMI(MBB, MBBI, DL, get(RISCV::CSRRS), DstReg)
555 .addImm(RISCVSysReg::lookupSysRegByName(TRI->getName(SrcReg))->Encoding)
556 .addReg(RISCV::X0);
557 return;
558 }
559
560 if (RISCV::FPR16RegClass.contains(DstReg, SrcReg)) {
561 unsigned Opc;
562 if (STI.hasStdExtZfh()) {
563 Opc = RISCV::FSGNJ_H;
564 } else {
565 assert(STI.hasStdExtF() &&
566 (STI.hasStdExtZfhmin() || STI.hasStdExtZfbfmin()) &&
567 "Unexpected extensions");
568 // Zfhmin/Zfbfmin doesn't have FSGNJ_H, replace FSGNJ_H with FSGNJ_S.
569 DstReg = TRI->getMatchingSuperReg(DstReg, RISCV::sub_16,
570 &RISCV::FPR32RegClass);
571 SrcReg = TRI->getMatchingSuperReg(SrcReg, RISCV::sub_16,
572 &RISCV::FPR32RegClass);
573 Opc = RISCV::FSGNJ_S;
574 }
575 BuildMI(MBB, MBBI, DL, get(Opc), DstReg)
576 .addReg(SrcReg, KillFlag)
577 .addReg(SrcReg, KillFlag);
578 return;
579 }
580
581 if (RISCV::FPR32RegClass.contains(DstReg, SrcReg)) {
582 BuildMI(MBB, MBBI, DL, get(RISCV::FSGNJ_S), DstReg)
583 .addReg(SrcReg, KillFlag)
584 .addReg(SrcReg, KillFlag);
585 return;
586 }
587
588 if (RISCV::FPR64RegClass.contains(DstReg, SrcReg)) {
589 BuildMI(MBB, MBBI, DL, get(RISCV::FSGNJ_D), DstReg)
590 .addReg(SrcReg, KillFlag)
591 .addReg(SrcReg, KillFlag);
592 return;
593 }
594
595 if (RISCV::FPR32RegClass.contains(DstReg) &&
596 RISCV::GPRRegClass.contains(SrcReg)) {
597 BuildMI(MBB, MBBI, DL, get(RISCV::FMV_W_X), DstReg)
598 .addReg(SrcReg, KillFlag);
599 return;
600 }
601
602 if (RISCV::GPRRegClass.contains(DstReg) &&
603 RISCV::FPR32RegClass.contains(SrcReg)) {
604 BuildMI(MBB, MBBI, DL, get(RISCV::FMV_X_W), DstReg)
605 .addReg(SrcReg, KillFlag);
606 return;
607 }
608
609 if (RISCV::FPR64RegClass.contains(DstReg) &&
610 RISCV::GPRRegClass.contains(SrcReg)) {
611 assert(STI.getXLen() == 64 && "Unexpected GPR size");
612 BuildMI(MBB, MBBI, DL, get(RISCV::FMV_D_X), DstReg)
613 .addReg(SrcReg, KillFlag);
614 return;
615 }
616
617 if (RISCV::GPRRegClass.contains(DstReg) &&
618 RISCV::FPR64RegClass.contains(SrcReg)) {
619 assert(STI.getXLen() == 64 && "Unexpected GPR size");
620 BuildMI(MBB, MBBI, DL, get(RISCV::FMV_X_D), DstReg)
621 .addReg(SrcReg, KillFlag);
622 return;
623 }
624
625 // VR->VR copies.
626 const TargetRegisterClass *RegClass =
627 TRI->getCommonMinimalPhysRegClass(SrcReg, DstReg);
628 if (RISCVRegisterInfo::isRVVRegClass(RegClass)) {
629 copyPhysRegVector(MBB, MBBI, DL, DstReg, SrcReg, KillSrc, RegClass);
630 return;
631 }
632
633 llvm_unreachable("Impossible reg-to-reg copy");
634}
635
638 Register SrcReg, bool IsKill, int FI,
639 const TargetRegisterClass *RC,
640 const TargetRegisterInfo *TRI,
641 Register VReg,
642 MachineInstr::MIFlag Flags) const {
644 MachineFrameInfo &MFI = MF->getFrameInfo();
645
646 unsigned Opcode;
647 if (RISCV::GPRRegClass.hasSubClassEq(RC)) {
648 Opcode = TRI->getRegSizeInBits(RISCV::GPRRegClass) == 32 ?
649 RISCV::SW : RISCV::SD;
650 } else if (RISCV::GPRF16RegClass.hasSubClassEq(RC)) {
651 Opcode = RISCV::SH_INX;
652 } else if (RISCV::GPRF32RegClass.hasSubClassEq(RC)) {
653 Opcode = RISCV::SW_INX;
654 } else if (RISCV::GPRPairRegClass.hasSubClassEq(RC)) {
655 Opcode = RISCV::PseudoRV32ZdinxSD;
656 } else if (RISCV::FPR16RegClass.hasSubClassEq(RC)) {
657 Opcode = RISCV::FSH;
658 } else if (RISCV::FPR32RegClass.hasSubClassEq(RC)) {
659 Opcode = RISCV::FSW;
660 } else if (RISCV::FPR64RegClass.hasSubClassEq(RC)) {
661 Opcode = RISCV::FSD;
662 } else if (RISCV::VRRegClass.hasSubClassEq(RC)) {
663 Opcode = RISCV::VS1R_V;
664 } else if (RISCV::VRM2RegClass.hasSubClassEq(RC)) {
665 Opcode = RISCV::VS2R_V;
666 } else if (RISCV::VRM4RegClass.hasSubClassEq(RC)) {
667 Opcode = RISCV::VS4R_V;
668 } else if (RISCV::VRM8RegClass.hasSubClassEq(RC)) {
669 Opcode = RISCV::VS8R_V;
670 } else if (RISCV::VRN2M1RegClass.hasSubClassEq(RC))
671 Opcode = RISCV::PseudoVSPILL2_M1;
672 else if (RISCV::VRN2M2RegClass.hasSubClassEq(RC))
673 Opcode = RISCV::PseudoVSPILL2_M2;
674 else if (RISCV::VRN2M4RegClass.hasSubClassEq(RC))
675 Opcode = RISCV::PseudoVSPILL2_M4;
676 else if (RISCV::VRN3M1RegClass.hasSubClassEq(RC))
677 Opcode = RISCV::PseudoVSPILL3_M1;
678 else if (RISCV::VRN3M2RegClass.hasSubClassEq(RC))
679 Opcode = RISCV::PseudoVSPILL3_M2;
680 else if (RISCV::VRN4M1RegClass.hasSubClassEq(RC))
681 Opcode = RISCV::PseudoVSPILL4_M1;
682 else if (RISCV::VRN4M2RegClass.hasSubClassEq(RC))
683 Opcode = RISCV::PseudoVSPILL4_M2;
684 else if (RISCV::VRN5M1RegClass.hasSubClassEq(RC))
685 Opcode = RISCV::PseudoVSPILL5_M1;
686 else if (RISCV::VRN6M1RegClass.hasSubClassEq(RC))
687 Opcode = RISCV::PseudoVSPILL6_M1;
688 else if (RISCV::VRN7M1RegClass.hasSubClassEq(RC))
689 Opcode = RISCV::PseudoVSPILL7_M1;
690 else if (RISCV::VRN8M1RegClass.hasSubClassEq(RC))
691 Opcode = RISCV::PseudoVSPILL8_M1;
692 else
693 llvm_unreachable("Can't store this register to stack slot");
694
699
701 BuildMI(MBB, I, DebugLoc(), get(Opcode))
702 .addReg(SrcReg, getKillRegState(IsKill))
703 .addFrameIndex(FI)
704 .addMemOperand(MMO)
705 .setMIFlag(Flags);
706 NumVRegSpilled += TRI->getRegSizeInBits(*RC) / RISCV::RVVBitsPerBlock;
707 } else {
710 MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
711
712 BuildMI(MBB, I, DebugLoc(), get(Opcode))
713 .addReg(SrcReg, getKillRegState(IsKill))
714 .addFrameIndex(FI)
715 .addImm(0)
716 .addMemOperand(MMO)
717 .setMIFlag(Flags);
718 }
719}
720
723 int FI, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI,
724 Register VReg, MachineInstr::MIFlag Flags) const {
726 MachineFrameInfo &MFI = MF->getFrameInfo();
727 DebugLoc DL =
729
730 unsigned Opcode;
731 if (RISCV::GPRRegClass.hasSubClassEq(RC)) {
732 Opcode = TRI->getRegSizeInBits(RISCV::GPRRegClass) == 32 ?
733 RISCV::LW : RISCV::LD;
734 } else if (RISCV::GPRF16RegClass.hasSubClassEq(RC)) {
735 Opcode = RISCV::LH_INX;
736 } else if (RISCV::GPRF32RegClass.hasSubClassEq(RC)) {
737 Opcode = RISCV::LW_INX;
738 } else if (RISCV::GPRPairRegClass.hasSubClassEq(RC)) {
739 Opcode = RISCV::PseudoRV32ZdinxLD;
740 } else if (RISCV::FPR16RegClass.hasSubClassEq(RC)) {
741 Opcode = RISCV::FLH;
742 } else if (RISCV::FPR32RegClass.hasSubClassEq(RC)) {
743 Opcode = RISCV::FLW;
744 } else if (RISCV::FPR64RegClass.hasSubClassEq(RC)) {
745 Opcode = RISCV::FLD;
746 } else if (RISCV::VRRegClass.hasSubClassEq(RC)) {
747 Opcode = RISCV::VL1RE8_V;
748 } else if (RISCV::VRM2RegClass.hasSubClassEq(RC)) {
749 Opcode = RISCV::VL2RE8_V;
750 } else if (RISCV::VRM4RegClass.hasSubClassEq(RC)) {
751 Opcode = RISCV::VL4RE8_V;
752 } else if (RISCV::VRM8RegClass.hasSubClassEq(RC)) {
753 Opcode = RISCV::VL8RE8_V;
754 } else if (RISCV::VRN2M1RegClass.hasSubClassEq(RC))
755 Opcode = RISCV::PseudoVRELOAD2_M1;
756 else if (RISCV::VRN2M2RegClass.hasSubClassEq(RC))
757 Opcode = RISCV::PseudoVRELOAD2_M2;
758 else if (RISCV::VRN2M4RegClass.hasSubClassEq(RC))
759 Opcode = RISCV::PseudoVRELOAD2_M4;
760 else if (RISCV::VRN3M1RegClass.hasSubClassEq(RC))
761 Opcode = RISCV::PseudoVRELOAD3_M1;
762 else if (RISCV::VRN3M2RegClass.hasSubClassEq(RC))
763 Opcode = RISCV::PseudoVRELOAD3_M2;
764 else if (RISCV::VRN4M1RegClass.hasSubClassEq(RC))
765 Opcode = RISCV::PseudoVRELOAD4_M1;
766 else if (RISCV::VRN4M2RegClass.hasSubClassEq(RC))
767 Opcode = RISCV::PseudoVRELOAD4_M2;
768 else if (RISCV::VRN5M1RegClass.hasSubClassEq(RC))
769 Opcode = RISCV::PseudoVRELOAD5_M1;
770 else if (RISCV::VRN6M1RegClass.hasSubClassEq(RC))
771 Opcode = RISCV::PseudoVRELOAD6_M1;
772 else if (RISCV::VRN7M1RegClass.hasSubClassEq(RC))
773 Opcode = RISCV::PseudoVRELOAD7_M1;
774 else if (RISCV::VRN8M1RegClass.hasSubClassEq(RC))
775 Opcode = RISCV::PseudoVRELOAD8_M1;
776 else
777 llvm_unreachable("Can't load this register from stack slot");
778
783
785 BuildMI(MBB, I, DL, get(Opcode), DstReg)
786 .addFrameIndex(FI)
787 .addMemOperand(MMO)
788 .setMIFlag(Flags);
789 NumVRegReloaded += TRI->getRegSizeInBits(*RC) / RISCV::RVVBitsPerBlock;
790 } else {
793 MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
794
795 BuildMI(MBB, I, DL, get(Opcode), DstReg)
796 .addFrameIndex(FI)
797 .addImm(0)
798 .addMemOperand(MMO)
799 .setMIFlag(Flags);
800 }
801}
802std::optional<unsigned> getFoldedOpcode(MachineFunction &MF, MachineInstr &MI,
804 const RISCVSubtarget &ST) {
805
806 // The below optimizations narrow the load so they are only valid for little
807 // endian.
808 // TODO: Support big endian by adding an offset into the frame object?
809 if (MF.getDataLayout().isBigEndian())
810 return std::nullopt;
811
812 // Fold load from stack followed by sext.b/sext.h/sext.w/zext.b/zext.h/zext.w.
813 if (Ops.size() != 1 || Ops[0] != 1)
814 return std::nullopt;
815
816 switch (MI.getOpcode()) {
817 default:
818 if (RISCVInstrInfo::isSEXT_W(MI))
819 return RISCV::LW;
820 if (RISCVInstrInfo::isZEXT_W(MI))
821 return RISCV::LWU;
822 if (RISCVInstrInfo::isZEXT_B(MI))
823 return RISCV::LBU;
824 break;
825 case RISCV::SEXT_H:
826 return RISCV::LH;
827 case RISCV::SEXT_B:
828 return RISCV::LB;
829 case RISCV::ZEXT_H_RV32:
830 case RISCV::ZEXT_H_RV64:
831 return RISCV::LHU;
832 }
833
834 switch (RISCV::getRVVMCOpcode(MI.getOpcode())) {
835 default:
836 return std::nullopt;
837 case RISCV::VMV_X_S: {
838 unsigned Log2SEW =
839 MI.getOperand(RISCVII::getSEWOpNum(MI.getDesc())).getImm();
840 if (ST.getXLen() < (1U << Log2SEW))
841 return std::nullopt;
842 switch (Log2SEW) {
843 case 3:
844 return RISCV::LB;
845 case 4:
846 return RISCV::LH;
847 case 5:
848 return RISCV::LW;
849 case 6:
850 return RISCV::LD;
851 default:
852 llvm_unreachable("Unexpected SEW");
853 }
854 }
855 case RISCV::VFMV_F_S: {
856 unsigned Log2SEW =
857 MI.getOperand(RISCVII::getSEWOpNum(MI.getDesc())).getImm();
858 switch (Log2SEW) {
859 case 4:
860 return RISCV::FLH;
861 case 5:
862 return RISCV::FLW;
863 case 6:
864 return RISCV::FLD;
865 default:
866 llvm_unreachable("Unexpected SEW");
867 }
868 }
869 }
870}
871
872// This is the version used during inline spilling
875 MachineBasicBlock::iterator InsertPt, int FrameIndex, LiveIntervals *LIS,
876 VirtRegMap *VRM) const {
877
878 std::optional<unsigned> LoadOpc = getFoldedOpcode(MF, MI, Ops, STI);
879 if (!LoadOpc)
880 return nullptr;
881 Register DstReg = MI.getOperand(0).getReg();
882 return BuildMI(*MI.getParent(), InsertPt, MI.getDebugLoc(), get(*LoadOpc),
883 DstReg)
884 .addFrameIndex(FrameIndex)
885 .addImm(0);
886}
887
890 const DebugLoc &DL, Register DstReg, uint64_t Val,
891 MachineInstr::MIFlag Flag, bool DstRenamable,
892 bool DstIsDead) const {
893 Register SrcReg = RISCV::X0;
894
895 // For RV32, allow a sign or unsigned 32 bit value.
896 if (!STI.is64Bit() && !isInt<32>(Val)) {
897 // If have a uimm32 it will still fit in a register so we can allow it.
898 if (!isUInt<32>(Val))
899 report_fatal_error("Should only materialize 32-bit constants for RV32");
900
901 // Sign extend for generateInstSeq.
902 Val = SignExtend64<32>(Val);
903 }
904
906 assert(!Seq.empty());
907
908 bool SrcRenamable = false;
909 unsigned Num = 0;
910
911 for (const RISCVMatInt::Inst &Inst : Seq) {
912 bool LastItem = ++Num == Seq.size();
913 unsigned DstRegState = getDeadRegState(DstIsDead && LastItem) |
914 getRenamableRegState(DstRenamable);
915 unsigned SrcRegState = getKillRegState(SrcReg != RISCV::X0) |
916 getRenamableRegState(SrcRenamable);
917 switch (Inst.getOpndKind()) {
918 case RISCVMatInt::Imm:
919 BuildMI(MBB, MBBI, DL, get(Inst.getOpcode()))
920 .addReg(DstReg, RegState::Define | DstRegState)
921 .addImm(Inst.getImm())
922 .setMIFlag(Flag);
923 break;
925 BuildMI(MBB, MBBI, DL, get(Inst.getOpcode()))
926 .addReg(DstReg, RegState::Define | DstRegState)
927 .addReg(SrcReg, SrcRegState)
928 .addReg(RISCV::X0)
929 .setMIFlag(Flag);
930 break;
932 BuildMI(MBB, MBBI, DL, get(Inst.getOpcode()))
933 .addReg(DstReg, RegState::Define | DstRegState)
934 .addReg(SrcReg, SrcRegState)
935 .addReg(SrcReg, SrcRegState)
936 .setMIFlag(Flag);
937 break;
939 BuildMI(MBB, MBBI, DL, get(Inst.getOpcode()))
940 .addReg(DstReg, RegState::Define | DstRegState)
941 .addReg(SrcReg, SrcRegState)
942 .addImm(Inst.getImm())
943 .setMIFlag(Flag);
944 break;
945 }
946
947 // Only the first instruction has X0 as its source.
948 SrcReg = DstReg;
949 SrcRenamable = DstRenamable;
950 }
951}
952
954 switch (Opc) {
955 default:
957 case RISCV::BEQ:
958 case RISCV::CV_BEQIMM:
959 case RISCV::QC_BEQI:
960 case RISCV::QC_E_BEQI:
961 case RISCV::NDS_BBC:
962 case RISCV::NDS_BEQC:
963 return RISCVCC::COND_EQ;
964 case RISCV::BNE:
965 case RISCV::QC_BNEI:
966 case RISCV::QC_E_BNEI:
967 case RISCV::CV_BNEIMM:
968 case RISCV::NDS_BBS:
969 case RISCV::NDS_BNEC:
970 return RISCVCC::COND_NE;
971 case RISCV::BLT:
972 case RISCV::QC_BLTI:
973 case RISCV::QC_E_BLTI:
974 return RISCVCC::COND_LT;
975 case RISCV::BGE:
976 case RISCV::QC_BGEI:
977 case RISCV::QC_E_BGEI:
978 return RISCVCC::COND_GE;
979 case RISCV::BLTU:
980 case RISCV::QC_BLTUI:
981 case RISCV::QC_E_BLTUI:
982 return RISCVCC::COND_LTU;
983 case RISCV::BGEU:
984 case RISCV::QC_BGEUI:
985 case RISCV::QC_E_BGEUI:
986 return RISCVCC::COND_GEU;
987 }
988}
989
991 int64_t C1) {
992 switch (CC) {
993 default:
994 llvm_unreachable("Unexpected CC");
995 case RISCVCC::COND_EQ:
996 return C0 == C1;
997 case RISCVCC::COND_NE:
998 return C0 != C1;
999 case RISCVCC::COND_LT:
1000 return C0 < C1;
1001 case RISCVCC::COND_GE:
1002 return C0 >= C1;
1003 case RISCVCC::COND_LTU:
1004 return (uint64_t)C0 < (uint64_t)C1;
1005 case RISCVCC::COND_GEU:
1006 return (uint64_t)C0 >= (uint64_t)C1;
1007 }
1008}
1009
1010// The contents of values added to Cond are not examined outside of
1011// RISCVInstrInfo, giving us flexibility in what to push to it. For RISCV, we
1012// push BranchOpcode, Reg1, Reg2.
1015 // Block ends with fall-through condbranch.
1016 assert(LastInst.getDesc().isConditionalBranch() &&
1017 "Unknown conditional branch");
1018 Target = LastInst.getOperand(2).getMBB();
1019 Cond.push_back(MachineOperand::CreateImm(LastInst.getOpcode()));
1020 Cond.push_back(LastInst.getOperand(0));
1021 Cond.push_back(LastInst.getOperand(1));
1022}
1023
1024unsigned RISCVCC::getBrCond(RISCVCC::CondCode CC, unsigned SelectOpc) {
1025 switch (SelectOpc) {
1026 default:
1027 switch (CC) {
1028 default:
1029 llvm_unreachable("Unexpected condition code!");
1030 case RISCVCC::COND_EQ:
1031 return RISCV::BEQ;
1032 case RISCVCC::COND_NE:
1033 return RISCV::BNE;
1034 case RISCVCC::COND_LT:
1035 return RISCV::BLT;
1036 case RISCVCC::COND_GE:
1037 return RISCV::BGE;
1038 case RISCVCC::COND_LTU:
1039 return RISCV::BLTU;
1040 case RISCVCC::COND_GEU:
1041 return RISCV::BGEU;
1042 }
1043 break;
1044 case RISCV::Select_GPR_Using_CC_SImm5_CV:
1045 switch (CC) {
1046 default:
1047 llvm_unreachable("Unexpected condition code!");
1048 case RISCVCC::COND_EQ:
1049 return RISCV::CV_BEQIMM;
1050 case RISCVCC::COND_NE:
1051 return RISCV::CV_BNEIMM;
1052 }
1053 break;
1054 case RISCV::Select_GPRNoX0_Using_CC_SImm5NonZero_QC:
1055 switch (CC) {
1056 default:
1057 llvm_unreachable("Unexpected condition code!");
1058 case RISCVCC::COND_EQ:
1059 return RISCV::QC_BEQI;
1060 case RISCVCC::COND_NE:
1061 return RISCV::QC_BNEI;
1062 case RISCVCC::COND_LT:
1063 return RISCV::QC_BLTI;
1064 case RISCVCC::COND_GE:
1065 return RISCV::QC_BGEI;
1066 }
1067 break;
1068 case RISCV::Select_GPRNoX0_Using_CC_UImm5NonZero_QC:
1069 switch (CC) {
1070 default:
1071 llvm_unreachable("Unexpected condition code!");
1072 case RISCVCC::COND_LTU:
1073 return RISCV::QC_BLTUI;
1074 case RISCVCC::COND_GEU:
1075 return RISCV::QC_BGEUI;
1076 }
1077 break;
1078 case RISCV::Select_GPRNoX0_Using_CC_SImm16NonZero_QC:
1079 switch (CC) {
1080 default:
1081 llvm_unreachable("Unexpected condition code!");
1082 case RISCVCC::COND_EQ:
1083 return RISCV::QC_E_BEQI;
1084 case RISCVCC::COND_NE:
1085 return RISCV::QC_E_BNEI;
1086 case RISCVCC::COND_LT:
1087 return RISCV::QC_E_BLTI;
1088 case RISCVCC::COND_GE:
1089 return RISCV::QC_E_BGEI;
1090 }
1091 break;
1092 case RISCV::Select_GPRNoX0_Using_CC_UImm16NonZero_QC:
1093 switch (CC) {
1094 default:
1095 llvm_unreachable("Unexpected condition code!");
1096 case RISCVCC::COND_LTU:
1097 return RISCV::QC_E_BLTUI;
1098 case RISCVCC::COND_GEU:
1099 return RISCV::QC_E_BGEUI;
1100 }
1101 break;
1102 case RISCV::Select_GPR_Using_CC_UImmLog2XLen_NDS:
1103 switch (CC) {
1104 default:
1105 llvm_unreachable("Unexpected condition code!");
1106 case RISCVCC::COND_EQ:
1107 return RISCV::NDS_BBC;
1108 case RISCVCC::COND_NE:
1109 return RISCV::NDS_BBS;
1110 }
1111 break;
1112 case RISCV::Select_GPR_Using_CC_UImm7_NDS:
1113 switch (CC) {
1114 default:
1115 llvm_unreachable("Unexpected condition code!");
1116 case RISCVCC::COND_EQ:
1117 return RISCV::NDS_BEQC;
1118 case RISCVCC::COND_NE:
1119 return RISCV::NDS_BNEC;
1120 }
1121 break;
1122 }
1123}
1124
1126 switch (CC) {
1127 default:
1128 llvm_unreachable("Unrecognized conditional branch");
1129 case RISCVCC::COND_EQ:
1130 return RISCVCC::COND_NE;
1131 case RISCVCC::COND_NE:
1132 return RISCVCC::COND_EQ;
1133 case RISCVCC::COND_LT:
1134 return RISCVCC::COND_GE;
1135 case RISCVCC::COND_GE:
1136 return RISCVCC::COND_LT;
1137 case RISCVCC::COND_LTU:
1138 return RISCVCC::COND_GEU;
1139 case RISCVCC::COND_GEU:
1140 return RISCVCC::COND_LTU;
1141 }
1142}
1143
1146 MachineBasicBlock *&FBB,
1148 bool AllowModify) const {
1149 TBB = FBB = nullptr;
1150 Cond.clear();
1151
1152 // If the block has no terminators, it just falls into the block after it.
1154 if (I == MBB.end() || !isUnpredicatedTerminator(*I))
1155 return false;
1156
1157 // Count the number of terminators and find the first unconditional or
1158 // indirect branch.
1159 MachineBasicBlock::iterator FirstUncondOrIndirectBr = MBB.end();
1160 int NumTerminators = 0;
1161 for (auto J = I.getReverse(); J != MBB.rend() && isUnpredicatedTerminator(*J);
1162 J++) {
1163 NumTerminators++;
1164 if (J->getDesc().isUnconditionalBranch() ||
1165 J->getDesc().isIndirectBranch()) {
1166 FirstUncondOrIndirectBr = J.getReverse();
1167 }
1168 }
1169
1170 // If AllowModify is true, we can erase any terminators after
1171 // FirstUncondOrIndirectBR.
1172 if (AllowModify && FirstUncondOrIndirectBr != MBB.end()) {
1173 while (std::next(FirstUncondOrIndirectBr) != MBB.end()) {
1174 std::next(FirstUncondOrIndirectBr)->eraseFromParent();
1175 NumTerminators--;
1176 }
1177 I = FirstUncondOrIndirectBr;
1178 }
1179
1180 // We can't handle blocks that end in an indirect branch.
1181 if (I->getDesc().isIndirectBranch())
1182 return true;
1183
1184 // We can't handle Generic branch opcodes from Global ISel.
1185 if (I->isPreISelOpcode())
1186 return true;
1187
1188 // We can't handle blocks with more than 2 terminators.
1189 if (NumTerminators > 2)
1190 return true;
1191
1192 // Handle a single unconditional branch.
1193 if (NumTerminators == 1 && I->getDesc().isUnconditionalBranch()) {
1195 return false;
1196 }
1197
1198 // Handle a single conditional branch.
1199 if (NumTerminators == 1 && I->getDesc().isConditionalBranch()) {
1201 return false;
1202 }
1203
1204 // Handle a conditional branch followed by an unconditional branch.
1205 if (NumTerminators == 2 && std::prev(I)->getDesc().isConditionalBranch() &&
1206 I->getDesc().isUnconditionalBranch()) {
1207 parseCondBranch(*std::prev(I), TBB, Cond);
1208 FBB = getBranchDestBlock(*I);
1209 return false;
1210 }
1211
1212 // Otherwise, we can't handle this.
1213 return true;
1214}
1215
1217 int *BytesRemoved) const {
1218 if (BytesRemoved)
1219 *BytesRemoved = 0;
1221 if (I == MBB.end())
1222 return 0;
1223
1224 if (!I->getDesc().isUnconditionalBranch() &&
1225 !I->getDesc().isConditionalBranch())
1226 return 0;
1227
1228 // Remove the branch.
1229 if (BytesRemoved)
1230 *BytesRemoved += getInstSizeInBytes(*I);
1231 I->eraseFromParent();
1232
1233 I = MBB.end();
1234
1235 if (I == MBB.begin())
1236 return 1;
1237 --I;
1238 if (!I->getDesc().isConditionalBranch())
1239 return 1;
1240
1241 // Remove the branch.
1242 if (BytesRemoved)
1243 *BytesRemoved += getInstSizeInBytes(*I);
1244 I->eraseFromParent();
1245 return 2;
1246}
1247
1248// Inserts a branch into the end of the specific MachineBasicBlock, returning
1249// the number of instructions inserted.
1252 ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const {
1253 if (BytesAdded)
1254 *BytesAdded = 0;
1255
1256 // Shouldn't be a fall through.
1257 assert(TBB && "insertBranch must not be told to insert a fallthrough");
1258 assert((Cond.size() == 3 || Cond.size() == 0) &&
1259 "RISC-V branch conditions have two components!");
1260
1261 // Unconditional branch.
1262 if (Cond.empty()) {
1263 MachineInstr &MI = *BuildMI(&MBB, DL, get(RISCV::PseudoBR)).addMBB(TBB);
1264 if (BytesAdded)
1265 *BytesAdded += getInstSizeInBytes(MI);
1266 return 1;
1267 }
1268
1269 // Either a one or two-way conditional branch.
1270 MachineInstr &CondMI = *BuildMI(&MBB, DL, get(Cond[0].getImm()))
1271 .add(Cond[1])
1272 .add(Cond[2])
1273 .addMBB(TBB);
1274 if (BytesAdded)
1275 *BytesAdded += getInstSizeInBytes(CondMI);
1276
1277 // One-way conditional branch.
1278 if (!FBB)
1279 return 1;
1280
1281 // Two-way conditional branch.
1282 MachineInstr &MI = *BuildMI(&MBB, DL, get(RISCV::PseudoBR)).addMBB(FBB);
1283 if (BytesAdded)
1284 *BytesAdded += getInstSizeInBytes(MI);
1285 return 2;
1286}
1287
1289 MachineBasicBlock &DestBB,
1290 MachineBasicBlock &RestoreBB,
1291 const DebugLoc &DL, int64_t BrOffset,
1292 RegScavenger *RS) const {
1293 assert(RS && "RegScavenger required for long branching");
1294 assert(MBB.empty() &&
1295 "new block should be inserted for expanding unconditional branch");
1296 assert(MBB.pred_size() == 1);
1297 assert(RestoreBB.empty() &&
1298 "restore block should be inserted for restoring clobbered registers");
1299
1304
1305 if (!isInt<32>(BrOffset))
1307 "Branch offsets outside of the signed 32-bit range not supported");
1308
1309 // FIXME: A virtual register must be used initially, as the register
1310 // scavenger won't work with empty blocks (SIInstrInfo::insertIndirectBranch
1311 // uses the same workaround).
1312 Register ScratchReg = MRI.createVirtualRegister(&RISCV::GPRJALRRegClass);
1313 auto II = MBB.end();
1314 // We may also update the jump target to RestoreBB later.
1315 MachineInstr &MI = *BuildMI(MBB, II, DL, get(RISCV::PseudoJump))
1316 .addReg(ScratchReg, RegState::Define | RegState::Dead)
1317 .addMBB(&DestBB, RISCVII::MO_CALL);
1318
1320 Register TmpGPR =
1321 RS->scavengeRegisterBackwards(RISCV::GPRRegClass, MI.getIterator(),
1322 /*RestoreAfter=*/false, /*SpAdj=*/0,
1323 /*AllowSpill=*/false);
1324 if (TmpGPR != RISCV::NoRegister)
1325 RS->setRegUsed(TmpGPR);
1326 else {
1327 // The case when there is no scavenged register needs special handling.
1328
1329 // Pick s11(or s1 for rve) because it doesn't make a difference.
1330 TmpGPR = STI.hasStdExtE() ? RISCV::X9 : RISCV::X27;
1331
1332 int FrameIndex = RVFI->getBranchRelaxationScratchFrameIndex();
1333 if (FrameIndex == -1)
1334 report_fatal_error("underestimated function size");
1335
1336 storeRegToStackSlot(MBB, MI, TmpGPR, /*IsKill=*/true, FrameIndex,
1337 &RISCV::GPRRegClass, TRI, Register());
1338 TRI->eliminateFrameIndex(std::prev(MI.getIterator()),
1339 /*SpAdj=*/0, /*FIOperandNum=*/1);
1340
1341 MI.getOperand(1).setMBB(&RestoreBB);
1342
1343 loadRegFromStackSlot(RestoreBB, RestoreBB.end(), TmpGPR, FrameIndex,
1344 &RISCV::GPRRegClass, TRI, Register());
1345 TRI->eliminateFrameIndex(RestoreBB.back(),
1346 /*SpAdj=*/0, /*FIOperandNum=*/1);
1347 }
1348
1349 MRI.replaceRegWith(ScratchReg, TmpGPR);
1350 MRI.clearVirtRegs();
1351}
1352
1355 assert((Cond.size() == 3) && "Invalid branch condition!");
1356 switch (Cond[0].getImm()) {
1357 default:
1358 llvm_unreachable("Unknown conditional branch!");
1359 case RISCV::BEQ:
1360 Cond[0].setImm(RISCV::BNE);
1361 break;
1362 case RISCV::BNE:
1363 Cond[0].setImm(RISCV::BEQ);
1364 break;
1365 case RISCV::BLT:
1366 Cond[0].setImm(RISCV::BGE);
1367 break;
1368 case RISCV::BGE:
1369 Cond[0].setImm(RISCV::BLT);
1370 break;
1371 case RISCV::BLTU:
1372 Cond[0].setImm(RISCV::BGEU);
1373 break;
1374 case RISCV::BGEU:
1375 Cond[0].setImm(RISCV::BLTU);
1376 break;
1377 case RISCV::CV_BEQIMM:
1378 Cond[0].setImm(RISCV::CV_BNEIMM);
1379 break;
1380 case RISCV::CV_BNEIMM:
1381 Cond[0].setImm(RISCV::CV_BEQIMM);
1382 break;
1383 case RISCV::QC_BEQI:
1384 Cond[0].setImm(RISCV::QC_BNEI);
1385 break;
1386 case RISCV::QC_BNEI:
1387 Cond[0].setImm(RISCV::QC_BEQI);
1388 break;
1389 case RISCV::QC_BGEI:
1390 Cond[0].setImm(RISCV::QC_BLTI);
1391 break;
1392 case RISCV::QC_BLTI:
1393 Cond[0].setImm(RISCV::QC_BGEI);
1394 break;
1395 case RISCV::QC_BGEUI:
1396 Cond[0].setImm(RISCV::QC_BLTUI);
1397 break;
1398 case RISCV::QC_BLTUI:
1399 Cond[0].setImm(RISCV::QC_BGEUI);
1400 break;
1401 case RISCV::QC_E_BEQI:
1402 Cond[0].setImm(RISCV::QC_E_BNEI);
1403 break;
1404 case RISCV::QC_E_BNEI:
1405 Cond[0].setImm(RISCV::QC_E_BEQI);
1406 break;
1407 case RISCV::QC_E_BGEI:
1408 Cond[0].setImm(RISCV::QC_E_BLTI);
1409 break;
1410 case RISCV::QC_E_BLTI:
1411 Cond[0].setImm(RISCV::QC_E_BGEI);
1412 break;
1413 case RISCV::QC_E_BGEUI:
1414 Cond[0].setImm(RISCV::QC_E_BLTUI);
1415 break;
1416 case RISCV::QC_E_BLTUI:
1417 Cond[0].setImm(RISCV::QC_E_BGEUI);
1418 break;
1419 case RISCV::NDS_BBC:
1420 Cond[0].setImm(RISCV::NDS_BBS);
1421 break;
1422 case RISCV::NDS_BBS:
1423 Cond[0].setImm(RISCV::NDS_BBC);
1424 break;
1425 case RISCV::NDS_BEQC:
1426 Cond[0].setImm(RISCV::NDS_BNEC);
1427 break;
1428 case RISCV::NDS_BNEC:
1429 Cond[0].setImm(RISCV::NDS_BEQC);
1430 break;
1431 }
1432
1433 return false;
1434}
1435
1436// Return true if the instruction is a load immediate instruction (i.e.
1437// ADDI x0, imm).
1438static bool isLoadImm(const MachineInstr *MI, int64_t &Imm) {
1439 if (MI->getOpcode() == RISCV::ADDI && MI->getOperand(1).isReg() &&
1440 MI->getOperand(1).getReg() == RISCV::X0) {
1441 Imm = MI->getOperand(2).getImm();
1442 return true;
1443 }
1444 return false;
1445}
1446
1448 const MachineOperand &Op, int64_t &Imm) {
1449 // Either a load from immediate instruction or X0.
1450 if (!Op.isReg())
1451 return false;
1452
1453 Register Reg = Op.getReg();
1454 if (Reg == RISCV::X0) {
1455 Imm = 0;
1456 return true;
1457 }
1458 return Reg.isVirtual() && isLoadImm(MRI.getVRegDef(Reg), Imm);
1459}
1460
1462 bool IsSigned = false;
1463 bool IsEquality = false;
1464 switch (MI.getOpcode()) {
1465 default:
1466 return false;
1467 case RISCV::BEQ:
1468 case RISCV::BNE:
1469 IsEquality = true;
1470 break;
1471 case RISCV::BGE:
1472 case RISCV::BLT:
1473 IsSigned = true;
1474 break;
1475 case RISCV::BGEU:
1476 case RISCV::BLTU:
1477 break;
1478 }
1479
1480 MachineBasicBlock *MBB = MI.getParent();
1482
1483 const MachineOperand &LHS = MI.getOperand(0);
1484 const MachineOperand &RHS = MI.getOperand(1);
1485 MachineBasicBlock *TBB = MI.getOperand(2).getMBB();
1486
1487 RISCVCC::CondCode CC = getCondFromBranchOpc(MI.getOpcode());
1489
1490 // Canonicalize conditional branches which can be constant folded into
1491 // beqz or bnez. We can't modify the CFG here.
1492 int64_t C0, C1;
1493 if (isFromLoadImm(MRI, LHS, C0) && isFromLoadImm(MRI, RHS, C1)) {
1494 unsigned NewOpc = evaluateCondBranch(CC, C0, C1) ? RISCV::BEQ : RISCV::BNE;
1495 // Build the new branch and remove the old one.
1496 BuildMI(*MBB, MI, MI.getDebugLoc(), get(NewOpc))
1497 .addReg(RISCV::X0)
1498 .addReg(RISCV::X0)
1499 .addMBB(TBB);
1500 MI.eraseFromParent();
1501 return true;
1502 }
1503
1504 if (IsEquality)
1505 return false;
1506
1507 // For two constants C0 and C1 from
1508 // ```
1509 // li Y, C0
1510 // li Z, C1
1511 // ```
1512 // 1. if C1 = C0 + 1
1513 // we can turn:
1514 // (a) blt Y, X -> bge X, Z
1515 // (b) bge Y, X -> blt X, Z
1516 //
1517 // 2. if C1 = C0 - 1
1518 // we can turn:
1519 // (a) blt X, Y -> bge Z, X
1520 // (b) bge X, Y -> blt Z, X
1521 //
1522 // To make sure this optimization is really beneficial, we only
1523 // optimize for cases where Y had only one use (i.e. only used by the branch).
1524 // Try to find the register for constant Z; return
1525 // invalid register otherwise.
1526 auto searchConst = [&](int64_t C1) -> Register {
1528 auto DefC1 = std::find_if(++II, E, [&](const MachineInstr &I) -> bool {
1529 int64_t Imm;
1530 return isLoadImm(&I, Imm) && Imm == C1 &&
1531 I.getOperand(0).getReg().isVirtual();
1532 });
1533 if (DefC1 != E)
1534 return DefC1->getOperand(0).getReg();
1535
1536 return Register();
1537 };
1538
1539 unsigned NewOpc = RISCVCC::getBrCond(getOppositeBranchCondition(CC));
1540
1541 // Might be case 1.
1542 // Don't change 0 to 1 since we can use x0.
1543 // For unsigned cases changing -1U to 0 would be incorrect.
1544 // The incorrect case for signed would be INT_MAX, but isFromLoadImm can't
1545 // return that.
1546 if (isFromLoadImm(MRI, LHS, C0) && C0 != 0 && LHS.getReg().isVirtual() &&
1547 MRI.hasOneUse(LHS.getReg()) && (IsSigned || C0 != -1)) {
1548 assert(isInt<12>(C0) && "Unexpected immediate");
1549 if (Register RegZ = searchConst(C0 + 1)) {
1550 BuildMI(*MBB, MI, MI.getDebugLoc(), get(NewOpc))
1551 .add(RHS)
1552 .addReg(RegZ)
1553 .addMBB(TBB);
1554 // We might extend the live range of Z, clear its kill flag to
1555 // account for this.
1556 MRI.clearKillFlags(RegZ);
1557 MI.eraseFromParent();
1558 return true;
1559 }
1560 }
1561
1562 // Might be case 2.
1563 // For signed cases we don't want to change 0 since we can use x0.
1564 // For unsigned cases changing 0 to -1U would be incorrect.
1565 // The incorrect case for signed would be INT_MIN, but isFromLoadImm can't
1566 // return that.
1567 if (isFromLoadImm(MRI, RHS, C0) && C0 != 0 && RHS.getReg().isVirtual() &&
1568 MRI.hasOneUse(RHS.getReg())) {
1569 assert(isInt<12>(C0) && "Unexpected immediate");
1570 if (Register RegZ = searchConst(C0 - 1)) {
1571 BuildMI(*MBB, MI, MI.getDebugLoc(), get(NewOpc))
1572 .addReg(RegZ)
1573 .add(LHS)
1574 .addMBB(TBB);
1575 // We might extend the live range of Z, clear its kill flag to
1576 // account for this.
1577 MRI.clearKillFlags(RegZ);
1578 MI.eraseFromParent();
1579 return true;
1580 }
1581 }
1582
1583 return false;
1584}
1585
1588 assert(MI.getDesc().isBranch() && "Unexpected opcode!");
1589 // The branch target is always the last operand.
1590 int NumOp = MI.getNumExplicitOperands();
1591 return MI.getOperand(NumOp - 1).getMBB();
1592}
1593
1595 int64_t BrOffset) const {
1596 unsigned XLen = STI.getXLen();
1597 // Ideally we could determine the supported branch offset from the
1598 // RISCVII::FormMask, but this can't be used for Pseudo instructions like
1599 // PseudoBR.
1600 switch (BranchOp) {
1601 default:
1602 llvm_unreachable("Unexpected opcode!");
1603 case RISCV::NDS_BBC:
1604 case RISCV::NDS_BBS:
1605 case RISCV::NDS_BEQC:
1606 case RISCV::NDS_BNEC:
1607 return isInt<11>(BrOffset);
1608 case RISCV::BEQ:
1609 case RISCV::BNE:
1610 case RISCV::BLT:
1611 case RISCV::BGE:
1612 case RISCV::BLTU:
1613 case RISCV::BGEU:
1614 case RISCV::CV_BEQIMM:
1615 case RISCV::CV_BNEIMM:
1616 case RISCV::QC_BEQI:
1617 case RISCV::QC_BNEI:
1618 case RISCV::QC_BGEI:
1619 case RISCV::QC_BLTI:
1620 case RISCV::QC_BLTUI:
1621 case RISCV::QC_BGEUI:
1622 case RISCV::QC_E_BEQI:
1623 case RISCV::QC_E_BNEI:
1624 case RISCV::QC_E_BGEI:
1625 case RISCV::QC_E_BLTI:
1626 case RISCV::QC_E_BLTUI:
1627 case RISCV::QC_E_BGEUI:
1628 return isInt<13>(BrOffset);
1629 case RISCV::JAL:
1630 case RISCV::PseudoBR:
1631 return isInt<21>(BrOffset);
1632 case RISCV::PseudoJump:
1633 return isInt<32>(SignExtend64(BrOffset + 0x800, XLen));
1634 }
1635}
1636
1637// If the operation has a predicated pseudo instruction, return the pseudo
1638// instruction opcode. Otherwise, return RISCV::INSTRUCTION_LIST_END.
1639// TODO: Support more operations.
1640unsigned getPredicatedOpcode(unsigned Opcode) {
1641 switch (Opcode) {
1642 case RISCV::ADD: return RISCV::PseudoCCADD; break;
1643 case RISCV::SUB: return RISCV::PseudoCCSUB; break;
1644 case RISCV::SLL: return RISCV::PseudoCCSLL; break;
1645 case RISCV::SRL: return RISCV::PseudoCCSRL; break;
1646 case RISCV::SRA: return RISCV::PseudoCCSRA; break;
1647 case RISCV::AND: return RISCV::PseudoCCAND; break;
1648 case RISCV::OR: return RISCV::PseudoCCOR; break;
1649 case RISCV::XOR: return RISCV::PseudoCCXOR; break;
1650
1651 case RISCV::ADDI: return RISCV::PseudoCCADDI; break;
1652 case RISCV::SLLI: return RISCV::PseudoCCSLLI; break;
1653 case RISCV::SRLI: return RISCV::PseudoCCSRLI; break;
1654 case RISCV::SRAI: return RISCV::PseudoCCSRAI; break;
1655 case RISCV::ANDI: return RISCV::PseudoCCANDI; break;
1656 case RISCV::ORI: return RISCV::PseudoCCORI; break;
1657 case RISCV::XORI: return RISCV::PseudoCCXORI; break;
1658
1659 case RISCV::ADDW: return RISCV::PseudoCCADDW; break;
1660 case RISCV::SUBW: return RISCV::PseudoCCSUBW; break;
1661 case RISCV::SLLW: return RISCV::PseudoCCSLLW; break;
1662 case RISCV::SRLW: return RISCV::PseudoCCSRLW; break;
1663 case RISCV::SRAW: return RISCV::PseudoCCSRAW; break;
1664
1665 case RISCV::ADDIW: return RISCV::PseudoCCADDIW; break;
1666 case RISCV::SLLIW: return RISCV::PseudoCCSLLIW; break;
1667 case RISCV::SRLIW: return RISCV::PseudoCCSRLIW; break;
1668 case RISCV::SRAIW: return RISCV::PseudoCCSRAIW; break;
1669
1670 case RISCV::ANDN: return RISCV::PseudoCCANDN; break;
1671 case RISCV::ORN: return RISCV::PseudoCCORN; break;
1672 case RISCV::XNOR: return RISCV::PseudoCCXNOR; break;
1673
1674 case RISCV::NDS_BFOS: return RISCV::PseudoCCNDS_BFOS; break;
1675 case RISCV::NDS_BFOZ: return RISCV::PseudoCCNDS_BFOZ; break;
1676 }
1677
1678 return RISCV::INSTRUCTION_LIST_END;
1679}
1680
1681/// Identify instructions that can be folded into a CCMOV instruction, and
1682/// return the defining instruction.
1684 const MachineRegisterInfo &MRI,
1685 const TargetInstrInfo *TII) {
1686 if (!Reg.isVirtual())
1687 return nullptr;
1688 if (!MRI.hasOneNonDBGUse(Reg))
1689 return nullptr;
1690 MachineInstr *MI = MRI.getVRegDef(Reg);
1691 if (!MI)
1692 return nullptr;
1693 // Check if MI can be predicated and folded into the CCMOV.
1694 if (getPredicatedOpcode(MI->getOpcode()) == RISCV::INSTRUCTION_LIST_END)
1695 return nullptr;
1696 // Don't predicate li idiom.
1697 if (MI->getOpcode() == RISCV::ADDI && MI->getOperand(1).isReg() &&
1698 MI->getOperand(1).getReg() == RISCV::X0)
1699 return nullptr;
1700 // Check if MI has any other defs or physreg uses.
1701 for (const MachineOperand &MO : llvm::drop_begin(MI->operands())) {
1702 // Reject frame index operands, PEI can't handle the predicated pseudos.
1703 if (MO.isFI() || MO.isCPI() || MO.isJTI())
1704 return nullptr;
1705 if (!MO.isReg())
1706 continue;
1707 // MI can't have any tied operands, that would conflict with predication.
1708 if (MO.isTied())
1709 return nullptr;
1710 if (MO.isDef())
1711 return nullptr;
1712 // Allow constant physregs.
1713 if (MO.getReg().isPhysical() && !MRI.isConstantPhysReg(MO.getReg()))
1714 return nullptr;
1715 }
1716 bool DontMoveAcrossStores = true;
1717 if (!MI->isSafeToMove(DontMoveAcrossStores))
1718 return nullptr;
1719 return MI;
1720}
1721
1724 unsigned &TrueOp, unsigned &FalseOp,
1725 bool &Optimizable) const {
1726 assert(MI.getOpcode() == RISCV::PseudoCCMOVGPR &&
1727 "Unknown select instruction");
1728 // CCMOV operands:
1729 // 0: Def.
1730 // 1: LHS of compare.
1731 // 2: RHS of compare.
1732 // 3: Condition code.
1733 // 4: False use.
1734 // 5: True use.
1735 TrueOp = 5;
1736 FalseOp = 4;
1737 Cond.push_back(MI.getOperand(1));
1738 Cond.push_back(MI.getOperand(2));
1739 Cond.push_back(MI.getOperand(3));
1740 // We can only fold when we support short forward branch opt.
1741 Optimizable = STI.hasShortForwardBranchOpt();
1742 return false;
1743}
1744
1748 bool PreferFalse) const {
1749 assert(MI.getOpcode() == RISCV::PseudoCCMOVGPR &&
1750 "Unknown select instruction");
1751 if (!STI.hasShortForwardBranchOpt())
1752 return nullptr;
1753
1754 MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
1756 canFoldAsPredicatedOp(MI.getOperand(5).getReg(), MRI, this);
1757 bool Invert = !DefMI;
1758 if (!DefMI)
1759 DefMI = canFoldAsPredicatedOp(MI.getOperand(4).getReg(), MRI, this);
1760 if (!DefMI)
1761 return nullptr;
1762
1763 // Find new register class to use.
1764 MachineOperand FalseReg = MI.getOperand(Invert ? 5 : 4);
1765 Register DestReg = MI.getOperand(0).getReg();
1766 const TargetRegisterClass *PreviousClass = MRI.getRegClass(FalseReg.getReg());
1767 if (!MRI.constrainRegClass(DestReg, PreviousClass))
1768 return nullptr;
1769
1770 unsigned PredOpc = getPredicatedOpcode(DefMI->getOpcode());
1771 assert(PredOpc != RISCV::INSTRUCTION_LIST_END && "Unexpected opcode!");
1772
1773 // Create a new predicated version of DefMI.
1774 MachineInstrBuilder NewMI =
1775 BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), get(PredOpc), DestReg);
1776
1777 // Copy the condition portion.
1778 NewMI.add(MI.getOperand(1));
1779 NewMI.add(MI.getOperand(2));
1780
1781 // Add condition code, inverting if necessary.
1782 auto CC = static_cast<RISCVCC::CondCode>(MI.getOperand(3).getImm());
1783 if (Invert)
1785 NewMI.addImm(CC);
1786
1787 // Copy the false register.
1788 NewMI.add(FalseReg);
1789
1790 // Copy all the DefMI operands.
1791 const MCInstrDesc &DefDesc = DefMI->getDesc();
1792 for (unsigned i = 1, e = DefDesc.getNumOperands(); i != e; ++i)
1793 NewMI.add(DefMI->getOperand(i));
1794
1795 // Update SeenMIs set: register newly created MI and erase removed DefMI.
1796 SeenMIs.insert(NewMI);
1797 SeenMIs.erase(DefMI);
1798
1799 // If MI is inside a loop, and DefMI is outside the loop, then kill flags on
1800 // DefMI would be invalid when transferred inside the loop. Checking for a
1801 // loop is expensive, but at least remove kill flags if they are in different
1802 // BBs.
1803 if (DefMI->getParent() != MI.getParent())
1804 NewMI->clearKillInfo();
1805
1806 // The caller will erase MI, but not DefMI.
1808 return NewMI;
1809}
1810
1812 if (MI.isMetaInstruction())
1813 return 0;
1814
1815 unsigned Opcode = MI.getOpcode();
1816
1817 if (Opcode == TargetOpcode::INLINEASM ||
1818 Opcode == TargetOpcode::INLINEASM_BR) {
1819 const MachineFunction &MF = *MI.getParent()->getParent();
1820 return getInlineAsmLength(MI.getOperand(0).getSymbolName(),
1821 *MF.getTarget().getMCAsmInfo());
1822 }
1823
1824 if (!MI.memoperands_empty()) {
1825 MachineMemOperand *MMO = *(MI.memoperands_begin());
1826 if (STI.hasStdExtZihintntl() && MMO->isNonTemporal()) {
1827 if (STI.hasStdExtZca()) {
1828 if (isCompressibleInst(MI, STI))
1829 return 4; // c.ntl.all + c.load/c.store
1830 return 6; // c.ntl.all + load/store
1831 }
1832 return 8; // ntl.all + load/store
1833 }
1834 }
1835
1836 if (Opcode == TargetOpcode::BUNDLE)
1837 return getInstBundleLength(MI);
1838
1839 if (MI.getParent() && MI.getParent()->getParent()) {
1840 if (isCompressibleInst(MI, STI))
1841 return 2;
1842 }
1843
1844 switch (Opcode) {
1845 case RISCV::PseudoMV_FPR16INX:
1846 case RISCV::PseudoMV_FPR32INX:
1847 // MV is always compressible to either c.mv or c.li rd, 0.
1848 return STI.hasStdExtZca() ? 2 : 4;
1849 case TargetOpcode::STACKMAP:
1850 // The upper bound for a stackmap intrinsic is the full length of its shadow
1852 case TargetOpcode::PATCHPOINT:
1853 // The size of the patchpoint intrinsic is the number of bytes requested
1855 case TargetOpcode::STATEPOINT: {
1856 // The size of the statepoint intrinsic is the number of bytes requested
1857 unsigned NumBytes = StatepointOpers(&MI).getNumPatchBytes();
1858 // No patch bytes means at most a PseudoCall is emitted
1859 return std::max(NumBytes, 8U);
1860 }
1861 case TargetOpcode::PATCHABLE_FUNCTION_ENTER:
1862 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
1863 case TargetOpcode::PATCHABLE_TAIL_CALL: {
1864 const MachineFunction &MF = *MI.getParent()->getParent();
1865 const Function &F = MF.getFunction();
1866 if (Opcode == TargetOpcode::PATCHABLE_FUNCTION_ENTER &&
1867 F.hasFnAttribute("patchable-function-entry")) {
1868 unsigned Num;
1869 if (F.getFnAttribute("patchable-function-entry")
1870 .getValueAsString()
1871 .getAsInteger(10, Num))
1872 return get(Opcode).getSize();
1873
1874 // Number of C.NOP or NOP
1875 return (STI.hasStdExtZca() ? 2 : 4) * Num;
1876 }
1877 // XRay uses C.JAL + 21 or 33 C.NOP for each sled in RV32 and RV64,
1878 // respectively.
1879 return STI.is64Bit() ? 68 : 44;
1880 }
1881 default:
1882 return get(Opcode).getSize();
1883 }
1884}
1885
1886unsigned RISCVInstrInfo::getInstBundleLength(const MachineInstr &MI) const {
1887 unsigned Size = 0;
1889 MachineBasicBlock::const_instr_iterator E = MI.getParent()->instr_end();
1890 while (++I != E && I->isInsideBundle()) {
1891 assert(!I->isBundle() && "No nested bundle!");
1893 }
1894 return Size;
1895}
1896
1898 const unsigned Opcode = MI.getOpcode();
1899 switch (Opcode) {
1900 default:
1901 break;
1902 case RISCV::FSGNJ_D:
1903 case RISCV::FSGNJ_S:
1904 case RISCV::FSGNJ_H:
1905 case RISCV::FSGNJ_D_INX:
1906 case RISCV::FSGNJ_D_IN32X:
1907 case RISCV::FSGNJ_S_INX:
1908 case RISCV::FSGNJ_H_INX:
1909 // The canonical floating-point move is fsgnj rd, rs, rs.
1910 return MI.getOperand(1).isReg() && MI.getOperand(2).isReg() &&
1911 MI.getOperand(1).getReg() == MI.getOperand(2).getReg();
1912 case RISCV::ADDI:
1913 case RISCV::ORI:
1914 case RISCV::XORI:
1915 return (MI.getOperand(1).isReg() &&
1916 MI.getOperand(1).getReg() == RISCV::X0) ||
1917 (MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0);
1918 }
1919 return MI.isAsCheapAsAMove();
1920}
1921
1922std::optional<DestSourcePair>
1924 if (MI.isMoveReg())
1925 return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
1926 switch (MI.getOpcode()) {
1927 default:
1928 break;
1929 case RISCV::ADD:
1930 case RISCV::OR:
1931 case RISCV::XOR:
1932 if (MI.getOperand(1).isReg() && MI.getOperand(1).getReg() == RISCV::X0 &&
1933 MI.getOperand(2).isReg())
1934 return DestSourcePair{MI.getOperand(0), MI.getOperand(2)};
1935 if (MI.getOperand(2).isReg() && MI.getOperand(2).getReg() == RISCV::X0 &&
1936 MI.getOperand(1).isReg())
1937 return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
1938 break;
1939 case RISCV::ADDI:
1940 // Operand 1 can be a frameindex but callers expect registers
1941 if (MI.getOperand(1).isReg() && MI.getOperand(2).isImm() &&
1942 MI.getOperand(2).getImm() == 0)
1943 return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
1944 break;
1945 case RISCV::SUB:
1946 if (MI.getOperand(2).isReg() && MI.getOperand(2).getReg() == RISCV::X0 &&
1947 MI.getOperand(1).isReg())
1948 return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
1949 break;
1950 case RISCV::SH1ADD:
1951 case RISCV::SH1ADD_UW:
1952 case RISCV::SH2ADD:
1953 case RISCV::SH2ADD_UW:
1954 case RISCV::SH3ADD:
1955 case RISCV::SH3ADD_UW:
1956 if (MI.getOperand(1).isReg() && MI.getOperand(1).getReg() == RISCV::X0 &&
1957 MI.getOperand(2).isReg())
1958 return DestSourcePair{MI.getOperand(0), MI.getOperand(2)};
1959 break;
1960 case RISCV::FSGNJ_D:
1961 case RISCV::FSGNJ_S:
1962 case RISCV::FSGNJ_H:
1963 case RISCV::FSGNJ_D_INX:
1964 case RISCV::FSGNJ_D_IN32X:
1965 case RISCV::FSGNJ_S_INX:
1966 case RISCV::FSGNJ_H_INX:
1967 // The canonical floating-point move is fsgnj rd, rs, rs.
1968 if (MI.getOperand(1).isReg() && MI.getOperand(2).isReg() &&
1969 MI.getOperand(1).getReg() == MI.getOperand(2).getReg())
1970 return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
1971 break;
1972 }
1973 return std::nullopt;
1974}
1975
1977 if (ForceMachineCombinerStrategy.getNumOccurrences() == 0) {
1978 // The option is unused. Choose Local strategy only for in-order cores. When
1979 // scheduling model is unspecified, use MinInstrCount strategy as more
1980 // generic one.
1981 const auto &SchedModel = STI.getSchedModel();
1982 return (!SchedModel.hasInstrSchedModel() || SchedModel.isOutOfOrder())
1985 }
1986 // The strategy was forced by the option.
1988}
1989
1991 MachineInstr &Root, unsigned &Pattern,
1992 SmallVectorImpl<MachineInstr *> &InsInstrs) const {
1993 int16_t FrmOpIdx =
1994 RISCV::getNamedOperandIdx(Root.getOpcode(), RISCV::OpName::frm);
1995 if (FrmOpIdx < 0) {
1996 assert(all_of(InsInstrs,
1997 [](MachineInstr *MI) {
1998 return RISCV::getNamedOperandIdx(MI->getOpcode(),
1999 RISCV::OpName::frm) < 0;
2000 }) &&
2001 "New instructions require FRM whereas the old one does not have it");
2002 return;
2003 }
2004
2005 const MachineOperand &FRM = Root.getOperand(FrmOpIdx);
2006 MachineFunction &MF = *Root.getMF();
2007
2008 for (auto *NewMI : InsInstrs) {
2009 // We'd already added the FRM operand.
2010 if (static_cast<unsigned>(RISCV::getNamedOperandIdx(
2011 NewMI->getOpcode(), RISCV::OpName::frm)) != NewMI->getNumOperands())
2012 continue;
2013 MachineInstrBuilder MIB(MF, NewMI);
2014 MIB.add(FRM);
2015 if (FRM.getImm() == RISCVFPRndMode::DYN)
2016 MIB.addUse(RISCV::FRM, RegState::Implicit);
2017 }
2018}
2019
2020static bool isFADD(unsigned Opc) {
2021 switch (Opc) {
2022 default:
2023 return false;
2024 case RISCV::FADD_H:
2025 case RISCV::FADD_S:
2026 case RISCV::FADD_D:
2027 return true;
2028 }
2029}
2030
2031static bool isFSUB(unsigned Opc) {
2032 switch (Opc) {
2033 default:
2034 return false;
2035 case RISCV::FSUB_H:
2036 case RISCV::FSUB_S:
2037 case RISCV::FSUB_D:
2038 return true;
2039 }
2040}
2041
2042static bool isFMUL(unsigned Opc) {
2043 switch (Opc) {
2044 default:
2045 return false;
2046 case RISCV::FMUL_H:
2047 case RISCV::FMUL_S:
2048 case RISCV::FMUL_D:
2049 return true;
2050 }
2051}
2052
2053bool RISCVInstrInfo::isVectorAssociativeAndCommutative(const MachineInstr &Inst,
2054 bool Invert) const {
2055#define OPCODE_LMUL_CASE(OPC) \
2056 case RISCV::OPC##_M1: \
2057 case RISCV::OPC##_M2: \
2058 case RISCV::OPC##_M4: \
2059 case RISCV::OPC##_M8: \
2060 case RISCV::OPC##_MF2: \
2061 case RISCV::OPC##_MF4: \
2062 case RISCV::OPC##_MF8
2063
2064#define OPCODE_LMUL_MASK_CASE(OPC) \
2065 case RISCV::OPC##_M1_MASK: \
2066 case RISCV::OPC##_M2_MASK: \
2067 case RISCV::OPC##_M4_MASK: \
2068 case RISCV::OPC##_M8_MASK: \
2069 case RISCV::OPC##_MF2_MASK: \
2070 case RISCV::OPC##_MF4_MASK: \
2071 case RISCV::OPC##_MF8_MASK
2072
2073 unsigned Opcode = Inst.getOpcode();
2074 if (Invert) {
2075 if (auto InvOpcode = getInverseOpcode(Opcode))
2076 Opcode = *InvOpcode;
2077 else
2078 return false;
2079 }
2080
2081 // clang-format off
2082 switch (Opcode) {
2083 default:
2084 return false;
2085 OPCODE_LMUL_CASE(PseudoVADD_VV):
2086 OPCODE_LMUL_MASK_CASE(PseudoVADD_VV):
2087 OPCODE_LMUL_CASE(PseudoVMUL_VV):
2088 OPCODE_LMUL_MASK_CASE(PseudoVMUL_VV):
2089 return true;
2090 }
2091 // clang-format on
2092
2093#undef OPCODE_LMUL_MASK_CASE
2094#undef OPCODE_LMUL_CASE
2095}
2096
2097bool RISCVInstrInfo::areRVVInstsReassociable(const MachineInstr &Root,
2098 const MachineInstr &Prev) const {
2099 if (!areOpcodesEqualOrInverse(Root.getOpcode(), Prev.getOpcode()))
2100 return false;
2101
2102 assert(Root.getMF() == Prev.getMF());
2103 const MachineRegisterInfo *MRI = &Root.getMF()->getRegInfo();
2104 const TargetRegisterInfo *TRI = MRI->getTargetRegisterInfo();
2105
2106 // Make sure vtype operands are also the same.
2107 const MCInstrDesc &Desc = get(Root.getOpcode());
2108 const uint64_t TSFlags = Desc.TSFlags;
2109
2110 auto checkImmOperand = [&](unsigned OpIdx) {
2111 return Root.getOperand(OpIdx).getImm() == Prev.getOperand(OpIdx).getImm();
2112 };
2113
2114 auto checkRegOperand = [&](unsigned OpIdx) {
2115 return Root.getOperand(OpIdx).getReg() == Prev.getOperand(OpIdx).getReg();
2116 };
2117
2118 // PassThru
2119 // TODO: Potentially we can loosen the condition to consider Root to be
2120 // associable with Prev if Root has NoReg as passthru. In which case we
2121 // also need to loosen the condition on vector policies between these.
2122 if (!checkRegOperand(1))
2123 return false;
2124
2125 // SEW
2126 if (RISCVII::hasSEWOp(TSFlags) &&
2127 !checkImmOperand(RISCVII::getSEWOpNum(Desc)))
2128 return false;
2129
2130 // Mask
2131 if (RISCVII::usesMaskPolicy(TSFlags)) {
2132 const MachineBasicBlock *MBB = Root.getParent();
2135 Register MI1VReg;
2136
2137 bool SeenMI2 = false;
2138 for (auto End = MBB->rend(), It = It1; It != End; ++It) {
2139 if (It == It2) {
2140 SeenMI2 = true;
2141 if (!MI1VReg.isValid())
2142 // There is no V0 def between Root and Prev; they're sharing the
2143 // same V0.
2144 break;
2145 }
2146
2147 if (It->modifiesRegister(RISCV::V0, TRI)) {
2148 Register SrcReg = It->getOperand(1).getReg();
2149 // If it's not VReg it'll be more difficult to track its defs, so
2150 // bailing out here just to be safe.
2151 if (!SrcReg.isVirtual())
2152 return false;
2153
2154 if (!MI1VReg.isValid()) {
2155 // This is the V0 def for Root.
2156 MI1VReg = SrcReg;
2157 continue;
2158 }
2159
2160 // Some random mask updates.
2161 if (!SeenMI2)
2162 continue;
2163
2164 // This is the V0 def for Prev; check if it's the same as that of
2165 // Root.
2166 if (MI1VReg != SrcReg)
2167 return false;
2168 else
2169 break;
2170 }
2171 }
2172
2173 // If we haven't encountered Prev, it's likely that this function was
2174 // called in a wrong way (e.g. Root is before Prev).
2175 assert(SeenMI2 && "Prev is expected to appear before Root");
2176 }
2177
2178 // Tail / Mask policies
2179 if (RISCVII::hasVecPolicyOp(TSFlags) &&
2180 !checkImmOperand(RISCVII::getVecPolicyOpNum(Desc)))
2181 return false;
2182
2183 // VL
2184 if (RISCVII::hasVLOp(TSFlags)) {
2185 unsigned OpIdx = RISCVII::getVLOpNum(Desc);
2186 const MachineOperand &Op1 = Root.getOperand(OpIdx);
2187 const MachineOperand &Op2 = Prev.getOperand(OpIdx);
2188 if (Op1.getType() != Op2.getType())
2189 return false;
2190 switch (Op1.getType()) {
2192 if (Op1.getReg() != Op2.getReg())
2193 return false;
2194 break;
2196 if (Op1.getImm() != Op2.getImm())
2197 return false;
2198 break;
2199 default:
2200 llvm_unreachable("Unrecognized VL operand type");
2201 }
2202 }
2203
2204 // Rounding modes
2205 if (RISCVII::hasRoundModeOp(TSFlags) &&
2206 !checkImmOperand(RISCVII::getVLOpNum(Desc) - 1))
2207 return false;
2208
2209 return true;
2210}
2211
2212// Most of our RVV pseudos have passthru operand, so the real operands
2213// start from index = 2.
2214bool RISCVInstrInfo::hasReassociableVectorSibling(const MachineInstr &Inst,
2215 bool &Commuted) const {
2216 const MachineBasicBlock *MBB = Inst.getParent();
2219 "Expect the present of passthrough operand.");
2220 MachineInstr *MI1 = MRI.getUniqueVRegDef(Inst.getOperand(2).getReg());
2221 MachineInstr *MI2 = MRI.getUniqueVRegDef(Inst.getOperand(3).getReg());
2222
2223 // If only one operand has the same or inverse opcode and it's the second
2224 // source operand, the operands must be commuted.
2225 Commuted = !areRVVInstsReassociable(Inst, *MI1) &&
2226 areRVVInstsReassociable(Inst, *MI2);
2227 if (Commuted)
2228 std::swap(MI1, MI2);
2229
2230 return areRVVInstsReassociable(Inst, *MI1) &&
2231 (isVectorAssociativeAndCommutative(*MI1) ||
2232 isVectorAssociativeAndCommutative(*MI1, /* Invert */ true)) &&
2234 MRI.hasOneNonDBGUse(MI1->getOperand(0).getReg());
2235}
2236
2238 const MachineInstr &Inst, const MachineBasicBlock *MBB) const {
2239 if (!isVectorAssociativeAndCommutative(Inst) &&
2240 !isVectorAssociativeAndCommutative(Inst, /*Invert=*/true))
2242
2243 const MachineOperand &Op1 = Inst.getOperand(2);
2244 const MachineOperand &Op2 = Inst.getOperand(3);
2246
2247 // We need virtual register definitions for the operands that we will
2248 // reassociate.
2249 MachineInstr *MI1 = nullptr;
2250 MachineInstr *MI2 = nullptr;
2251 if (Op1.isReg() && Op1.getReg().isVirtual())
2252 MI1 = MRI.getUniqueVRegDef(Op1.getReg());
2253 if (Op2.isReg() && Op2.getReg().isVirtual())
2254 MI2 = MRI.getUniqueVRegDef(Op2.getReg());
2255
2256 // And at least one operand must be defined in MBB.
2257 return MI1 && MI2 && (MI1->getParent() == MBB || MI2->getParent() == MBB);
2258}
2259
2261 const MachineInstr &Root, unsigned Pattern,
2262 std::array<unsigned, 5> &OperandIndices) const {
2264 if (RISCV::getRVVMCOpcode(Root.getOpcode())) {
2265 // Skip the passthrough operand, so increment all indices by one.
2266 for (unsigned I = 0; I < 5; ++I)
2267 ++OperandIndices[I];
2268 }
2269}
2270
2272 bool &Commuted) const {
2273 if (isVectorAssociativeAndCommutative(Inst) ||
2274 isVectorAssociativeAndCommutative(Inst, /*Invert=*/true))
2275 return hasReassociableVectorSibling(Inst, Commuted);
2276
2277 if (!TargetInstrInfo::hasReassociableSibling(Inst, Commuted))
2278 return false;
2279
2280 const MachineRegisterInfo &MRI = Inst.getMF()->getRegInfo();
2281 unsigned OperandIdx = Commuted ? 2 : 1;
2282 const MachineInstr &Sibling =
2283 *MRI.getVRegDef(Inst.getOperand(OperandIdx).getReg());
2284
2285 int16_t InstFrmOpIdx =
2286 RISCV::getNamedOperandIdx(Inst.getOpcode(), RISCV::OpName::frm);
2287 int16_t SiblingFrmOpIdx =
2288 RISCV::getNamedOperandIdx(Sibling.getOpcode(), RISCV::OpName::frm);
2289
2290 return (InstFrmOpIdx < 0 && SiblingFrmOpIdx < 0) ||
2291 RISCV::hasEqualFRM(Inst, Sibling);
2292}
2293
2295 bool Invert) const {
2296 if (isVectorAssociativeAndCommutative(Inst, Invert))
2297 return true;
2298
2299 unsigned Opc = Inst.getOpcode();
2300 if (Invert) {
2301 auto InverseOpcode = getInverseOpcode(Opc);
2302 if (!InverseOpcode)
2303 return false;
2304 Opc = *InverseOpcode;
2305 }
2306
2307 if (isFADD(Opc) || isFMUL(Opc))
2310
2311 switch (Opc) {
2312 default:
2313 return false;
2314 case RISCV::ADD:
2315 case RISCV::ADDW:
2316 case RISCV::AND:
2317 case RISCV::OR:
2318 case RISCV::XOR:
2319 // From RISC-V ISA spec, if both the high and low bits of the same product
2320 // are required, then the recommended code sequence is:
2321 //
2322 // MULH[[S]U] rdh, rs1, rs2
2323 // MUL rdl, rs1, rs2
2324 // (source register specifiers must be in same order and rdh cannot be the
2325 // same as rs1 or rs2)
2326 //
2327 // Microarchitectures can then fuse these into a single multiply operation
2328 // instead of performing two separate multiplies.
2329 // MachineCombiner may reassociate MUL operands and lose the fusion
2330 // opportunity.
2331 case RISCV::MUL:
2332 case RISCV::MULW:
2333 case RISCV::MIN:
2334 case RISCV::MINU:
2335 case RISCV::MAX:
2336 case RISCV::MAXU:
2337 case RISCV::FMIN_H:
2338 case RISCV::FMIN_S:
2339 case RISCV::FMIN_D:
2340 case RISCV::FMAX_H:
2341 case RISCV::FMAX_S:
2342 case RISCV::FMAX_D:
2343 return true;
2344 }
2345
2346 return false;
2347}
2348
2349std::optional<unsigned>
2350RISCVInstrInfo::getInverseOpcode(unsigned Opcode) const {
2351#define RVV_OPC_LMUL_CASE(OPC, INV) \
2352 case RISCV::OPC##_M1: \
2353 return RISCV::INV##_M1; \
2354 case RISCV::OPC##_M2: \
2355 return RISCV::INV##_M2; \
2356 case RISCV::OPC##_M4: \
2357 return RISCV::INV##_M4; \
2358 case RISCV::OPC##_M8: \
2359 return RISCV::INV##_M8; \
2360 case RISCV::OPC##_MF2: \
2361 return RISCV::INV##_MF2; \
2362 case RISCV::OPC##_MF4: \
2363 return RISCV::INV##_MF4; \
2364 case RISCV::OPC##_MF8: \
2365 return RISCV::INV##_MF8
2366
2367#define RVV_OPC_LMUL_MASK_CASE(OPC, INV) \
2368 case RISCV::OPC##_M1_MASK: \
2369 return RISCV::INV##_M1_MASK; \
2370 case RISCV::OPC##_M2_MASK: \
2371 return RISCV::INV##_M2_MASK; \
2372 case RISCV::OPC##_M4_MASK: \
2373 return RISCV::INV##_M4_MASK; \
2374 case RISCV::OPC##_M8_MASK: \
2375 return RISCV::INV##_M8_MASK; \
2376 case RISCV::OPC##_MF2_MASK: \
2377 return RISCV::INV##_MF2_MASK; \
2378 case RISCV::OPC##_MF4_MASK: \
2379 return RISCV::INV##_MF4_MASK; \
2380 case RISCV::OPC##_MF8_MASK: \
2381 return RISCV::INV##_MF8_MASK
2382
2383 switch (Opcode) {
2384 default:
2385 return std::nullopt;
2386 case RISCV::FADD_H:
2387 return RISCV::FSUB_H;
2388 case RISCV::FADD_S:
2389 return RISCV::FSUB_S;
2390 case RISCV::FADD_D:
2391 return RISCV::FSUB_D;
2392 case RISCV::FSUB_H:
2393 return RISCV::FADD_H;
2394 case RISCV::FSUB_S:
2395 return RISCV::FADD_S;
2396 case RISCV::FSUB_D:
2397 return RISCV::FADD_D;
2398 case RISCV::ADD:
2399 return RISCV::SUB;
2400 case RISCV::SUB:
2401 return RISCV::ADD;
2402 case RISCV::ADDW:
2403 return RISCV::SUBW;
2404 case RISCV::SUBW:
2405 return RISCV::ADDW;
2406 // clang-format off
2407 RVV_OPC_LMUL_CASE(PseudoVADD_VV, PseudoVSUB_VV);
2408 RVV_OPC_LMUL_MASK_CASE(PseudoVADD_VV, PseudoVSUB_VV);
2409 RVV_OPC_LMUL_CASE(PseudoVSUB_VV, PseudoVADD_VV);
2410 RVV_OPC_LMUL_MASK_CASE(PseudoVSUB_VV, PseudoVADD_VV);
2411 // clang-format on
2412 }
2413
2414#undef RVV_OPC_LMUL_MASK_CASE
2415#undef RVV_OPC_LMUL_CASE
2416}
2417
2419 const MachineOperand &MO,
2420 bool DoRegPressureReduce) {
2421 if (!MO.isReg() || !MO.getReg().isVirtual())
2422 return false;
2423 const MachineRegisterInfo &MRI = Root.getMF()->getRegInfo();
2424 MachineInstr *MI = MRI.getVRegDef(MO.getReg());
2425 if (!MI || !isFMUL(MI->getOpcode()))
2426 return false;
2427
2430 return false;
2431
2432 // Try combining even if fmul has more than one use as it eliminates
2433 // dependency between fadd(fsub) and fmul. However, it can extend liveranges
2434 // for fmul operands, so reject the transformation in register pressure
2435 // reduction mode.
2436 if (DoRegPressureReduce && !MRI.hasOneNonDBGUse(MI->getOperand(0).getReg()))
2437 return false;
2438
2439 // Do not combine instructions from different basic blocks.
2440 if (Root.getParent() != MI->getParent())
2441 return false;
2442 return RISCV::hasEqualFRM(Root, *MI);
2443}
2444
2446 SmallVectorImpl<unsigned> &Patterns,
2447 bool DoRegPressureReduce) {
2448 unsigned Opc = Root.getOpcode();
2449 bool IsFAdd = isFADD(Opc);
2450 if (!IsFAdd && !isFSUB(Opc))
2451 return false;
2452 bool Added = false;
2453 if (canCombineFPFusedMultiply(Root, Root.getOperand(1),
2454 DoRegPressureReduce)) {
2457 Added = true;
2458 }
2459 if (canCombineFPFusedMultiply(Root, Root.getOperand(2),
2460 DoRegPressureReduce)) {
2463 Added = true;
2464 }
2465 return Added;
2466}
2467
2468static bool getFPPatterns(MachineInstr &Root,
2469 SmallVectorImpl<unsigned> &Patterns,
2470 bool DoRegPressureReduce) {
2471 return getFPFusedMultiplyPatterns(Root, Patterns, DoRegPressureReduce);
2472}
2473
2474/// Utility routine that checks if \param MO is defined by an
2475/// \param CombineOpc instruction in the basic block \param MBB
2477 const MachineOperand &MO,
2478 unsigned CombineOpc) {
2480 const MachineInstr *MI = nullptr;
2481
2482 if (MO.isReg() && MO.getReg().isVirtual())
2483 MI = MRI.getUniqueVRegDef(MO.getReg());
2484 // And it needs to be in the trace (otherwise, it won't have a depth).
2485 if (!MI || MI->getParent() != &MBB || MI->getOpcode() != CombineOpc)
2486 return nullptr;
2487 // Must only used by the user we combine with.
2488 if (!MRI.hasOneNonDBGUse(MI->getOperand(0).getReg()))
2489 return nullptr;
2490
2491 return MI;
2492}
2493
2494/// Utility routine that checks if \param MO is defined by a SLLI in \param
2495/// MBB that can be combined by splitting across 2 SHXADD instructions. The
2496/// first SHXADD shift amount is given by \param OuterShiftAmt.
2498 const MachineOperand &MO,
2499 unsigned OuterShiftAmt) {
2500 const MachineInstr *ShiftMI = canCombine(MBB, MO, RISCV::SLLI);
2501 if (!ShiftMI)
2502 return false;
2503
2504 unsigned InnerShiftAmt = ShiftMI->getOperand(2).getImm();
2505 if (InnerShiftAmt < OuterShiftAmt || (InnerShiftAmt - OuterShiftAmt) > 3)
2506 return false;
2507
2508 return true;
2509}
2510
2511// Returns the shift amount from a SHXADD instruction. Returns 0 if the
2512// instruction is not a SHXADD.
2513static unsigned getSHXADDShiftAmount(unsigned Opc) {
2514 switch (Opc) {
2515 default:
2516 return 0;
2517 case RISCV::SH1ADD:
2518 return 1;
2519 case RISCV::SH2ADD:
2520 return 2;
2521 case RISCV::SH3ADD:
2522 return 3;
2523 }
2524}
2525
2526// Returns the shift amount from a SHXADD.UW instruction. Returns 0 if the
2527// instruction is not a SHXADD.UW.
2528static unsigned getSHXADDUWShiftAmount(unsigned Opc) {
2529 switch (Opc) {
2530 default:
2531 return 0;
2532 case RISCV::SH1ADD_UW:
2533 return 1;
2534 case RISCV::SH2ADD_UW:
2535 return 2;
2536 case RISCV::SH3ADD_UW:
2537 return 3;
2538 }
2539}
2540
2541// Look for opportunities to combine (sh3add Z, (add X, (slli Y, 5))) into
2542// (sh3add (sh2add Y, Z), X).
2543static bool getSHXADDPatterns(const MachineInstr &Root,
2544 SmallVectorImpl<unsigned> &Patterns) {
2545 unsigned ShiftAmt = getSHXADDShiftAmount(Root.getOpcode());
2546 if (!ShiftAmt)
2547 return false;
2548
2549 const MachineBasicBlock &MBB = *Root.getParent();
2550
2551 const MachineInstr *AddMI = canCombine(MBB, Root.getOperand(2), RISCV::ADD);
2552 if (!AddMI)
2553 return false;
2554
2555 bool Found = false;
2556 if (canCombineShiftIntoShXAdd(MBB, AddMI->getOperand(1), ShiftAmt)) {
2558 Found = true;
2559 }
2560 if (canCombineShiftIntoShXAdd(MBB, AddMI->getOperand(2), ShiftAmt)) {
2562 Found = true;
2563 }
2564
2565 return Found;
2566}
2567
2569 switch (Pattern) {
2575 default:
2577 }
2578}
2579
2581 MachineInstr &Root, SmallVectorImpl<unsigned> &Patterns,
2582 bool DoRegPressureReduce) const {
2583
2584 if (getFPPatterns(Root, Patterns, DoRegPressureReduce))
2585 return true;
2586
2587 if (getSHXADDPatterns(Root, Patterns))
2588 return true;
2589
2590 return TargetInstrInfo::getMachineCombinerPatterns(Root, Patterns,
2591 DoRegPressureReduce);
2592}
2593
2594static unsigned getFPFusedMultiplyOpcode(unsigned RootOpc, unsigned Pattern) {
2595 switch (RootOpc) {
2596 default:
2597 llvm_unreachable("Unexpected opcode");
2598 case RISCV::FADD_H:
2599 return RISCV::FMADD_H;
2600 case RISCV::FADD_S:
2601 return RISCV::FMADD_S;
2602 case RISCV::FADD_D:
2603 return RISCV::FMADD_D;
2604 case RISCV::FSUB_H:
2605 return Pattern == RISCVMachineCombinerPattern::FMSUB ? RISCV::FMSUB_H
2606 : RISCV::FNMSUB_H;
2607 case RISCV::FSUB_S:
2608 return Pattern == RISCVMachineCombinerPattern::FMSUB ? RISCV::FMSUB_S
2609 : RISCV::FNMSUB_S;
2610 case RISCV::FSUB_D:
2611 return Pattern == RISCVMachineCombinerPattern::FMSUB ? RISCV::FMSUB_D
2612 : RISCV::FNMSUB_D;
2613 }
2614}
2615
2616static unsigned getAddendOperandIdx(unsigned Pattern) {
2617 switch (Pattern) {
2618 default:
2619 llvm_unreachable("Unexpected pattern");
2622 return 2;
2625 return 1;
2626 }
2627}
2628
2630 unsigned Pattern,
2633 MachineFunction *MF = Root.getMF();
2636
2637 MachineOperand &Mul1 = Prev.getOperand(1);
2638 MachineOperand &Mul2 = Prev.getOperand(2);
2639 MachineOperand &Dst = Root.getOperand(0);
2641
2642 Register DstReg = Dst.getReg();
2643 unsigned FusedOpc = getFPFusedMultiplyOpcode(Root.getOpcode(), Pattern);
2644 uint32_t IntersectedFlags = Root.getFlags() & Prev.getFlags();
2645 DebugLoc MergedLoc =
2647
2648 bool Mul1IsKill = Mul1.isKill();
2649 bool Mul2IsKill = Mul2.isKill();
2650 bool AddendIsKill = Addend.isKill();
2651
2652 // We need to clear kill flags since we may be extending the live range past
2653 // a kill. If the mul had kill flags, we can preserve those since we know
2654 // where the previous range stopped.
2655 MRI.clearKillFlags(Mul1.getReg());
2656 MRI.clearKillFlags(Mul2.getReg());
2657
2659 BuildMI(*MF, MergedLoc, TII->get(FusedOpc), DstReg)
2660 .addReg(Mul1.getReg(), getKillRegState(Mul1IsKill))
2661 .addReg(Mul2.getReg(), getKillRegState(Mul2IsKill))
2662 .addReg(Addend.getReg(), getKillRegState(AddendIsKill))
2663 .setMIFlags(IntersectedFlags);
2664
2665 InsInstrs.push_back(MIB);
2666 if (MRI.hasOneNonDBGUse(Prev.getOperand(0).getReg()))
2667 DelInstrs.push_back(&Prev);
2668 DelInstrs.push_back(&Root);
2669}
2670
2671// Combine patterns like (sh3add Z, (add X, (slli Y, 5))) to
2672// (sh3add (sh2add Y, Z), X) if the shift amount can be split across two
2673// shXadd instructions. The outer shXadd keeps its original opcode.
2674static void
2675genShXAddAddShift(MachineInstr &Root, unsigned AddOpIdx,
2678 DenseMap<Register, unsigned> &InstrIdxForVirtReg) {
2679 MachineFunction *MF = Root.getMF();
2682
2683 unsigned OuterShiftAmt = getSHXADDShiftAmount(Root.getOpcode());
2684 assert(OuterShiftAmt != 0 && "Unexpected opcode");
2685
2686 MachineInstr *AddMI = MRI.getUniqueVRegDef(Root.getOperand(2).getReg());
2687 MachineInstr *ShiftMI =
2688 MRI.getUniqueVRegDef(AddMI->getOperand(AddOpIdx).getReg());
2689
2690 unsigned InnerShiftAmt = ShiftMI->getOperand(2).getImm();
2691 assert(InnerShiftAmt >= OuterShiftAmt && "Unexpected shift amount");
2692
2693 unsigned InnerOpc;
2694 switch (InnerShiftAmt - OuterShiftAmt) {
2695 default:
2696 llvm_unreachable("Unexpected shift amount");
2697 case 0:
2698 InnerOpc = RISCV::ADD;
2699 break;
2700 case 1:
2701 InnerOpc = RISCV::SH1ADD;
2702 break;
2703 case 2:
2704 InnerOpc = RISCV::SH2ADD;
2705 break;
2706 case 3:
2707 InnerOpc = RISCV::SH3ADD;
2708 break;
2709 }
2710
2711 const MachineOperand &X = AddMI->getOperand(3 - AddOpIdx);
2712 const MachineOperand &Y = ShiftMI->getOperand(1);
2713 const MachineOperand &Z = Root.getOperand(1);
2714
2715 Register NewVR = MRI.createVirtualRegister(&RISCV::GPRRegClass);
2716
2717 auto MIB1 = BuildMI(*MF, MIMetadata(Root), TII->get(InnerOpc), NewVR)
2718 .addReg(Y.getReg(), getKillRegState(Y.isKill()))
2719 .addReg(Z.getReg(), getKillRegState(Z.isKill()));
2720 auto MIB2 = BuildMI(*MF, MIMetadata(Root), TII->get(Root.getOpcode()),
2721 Root.getOperand(0).getReg())
2722 .addReg(NewVR, RegState::Kill)
2723 .addReg(X.getReg(), getKillRegState(X.isKill()));
2724
2725 InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0));
2726 InsInstrs.push_back(MIB1);
2727 InsInstrs.push_back(MIB2);
2728 DelInstrs.push_back(ShiftMI);
2729 DelInstrs.push_back(AddMI);
2730 DelInstrs.push_back(&Root);
2731}
2732
2734 MachineInstr &Root, unsigned Pattern,
2737 DenseMap<Register, unsigned> &InstrIdxForVirtReg) const {
2739 switch (Pattern) {
2740 default:
2742 DelInstrs, InstrIdxForVirtReg);
2743 return;
2746 MachineInstr &Prev = *MRI.getVRegDef(Root.getOperand(1).getReg());
2747 combineFPFusedMultiply(Root, Prev, Pattern, InsInstrs, DelInstrs);
2748 return;
2749 }
2752 MachineInstr &Prev = *MRI.getVRegDef(Root.getOperand(2).getReg());
2753 combineFPFusedMultiply(Root, Prev, Pattern, InsInstrs, DelInstrs);
2754 return;
2755 }
2757 genShXAddAddShift(Root, 1, InsInstrs, DelInstrs, InstrIdxForVirtReg);
2758 return;
2760 genShXAddAddShift(Root, 2, InsInstrs, DelInstrs, InstrIdxForVirtReg);
2761 return;
2762 }
2763}
2764
2766 StringRef &ErrInfo) const {
2767 MCInstrDesc const &Desc = MI.getDesc();
2768
2769 for (const auto &[Index, Operand] : enumerate(Desc.operands())) {
2770 unsigned OpType = Operand.OperandType;
2771 if (OpType >= RISCVOp::OPERAND_FIRST_RISCV_IMM &&
2773 const MachineOperand &MO = MI.getOperand(Index);
2774 if (MO.isReg()) {
2775 ErrInfo = "Expected a non-register operand.";
2776 return false;
2777 }
2778 if (MO.isImm()) {
2779 int64_t Imm = MO.getImm();
2780 bool Ok;
2781 switch (OpType) {
2782 default:
2783 llvm_unreachable("Unexpected operand type");
2784
2785 // clang-format off
2786#define CASE_OPERAND_UIMM(NUM) \
2787 case RISCVOp::OPERAND_UIMM##NUM: \
2788 Ok = isUInt<NUM>(Imm); \
2789 break;
2790#define CASE_OPERAND_SIMM(NUM) \
2791 case RISCVOp::OPERAND_SIMM##NUM: \
2792 Ok = isInt<NUM>(Imm); \
2793 break;
2810 // clang-format on
2812 Ok = isShiftedUInt<1, 1>(Imm);
2813 break;
2815 Ok = isShiftedUInt<4, 1>(Imm);
2816 break;
2818 Ok = isUInt<5>(Imm) && (Imm != 0);
2819 break;
2821 Ok = isUInt<5>(Imm) && (Imm > 3);
2822 break;
2824 Ok = (isUInt<5>(Imm) && (Imm != 0)) || (Imm == 32);
2825 break;
2827 Ok = isShiftedUInt<5, 1>(Imm);
2828 break;
2830 Ok = isShiftedUInt<5, 2>(Imm);
2831 break;
2833 Ok = isShiftedUInt<4, 3>(Imm);
2834 break;
2836 Ok = isShiftedUInt<6, 2>(Imm);
2837 break;
2839 Ok = isShiftedUInt<5, 3>(Imm);
2840 break;
2842 Ok = isUInt<8>(Imm) && Imm >= 32;
2843 break;
2845 Ok = isShiftedUInt<6, 3>(Imm);
2846 break;
2848 Ok = isShiftedInt<6, 4>(Imm) && (Imm != 0);
2849 break;
2851 Ok = isShiftedUInt<8, 2>(Imm) && (Imm != 0);
2852 break;
2854 Ok = isUInt<16>(Imm) && (Imm != 0);
2855 break;
2857 Ok = Imm == 3;
2858 break;
2860 Ok = Imm == 4;
2861 break;
2862 // clang-format off
2868 // clang-format on
2870 Ok = (isInt<5>(Imm) && Imm != -16) || Imm == 16;
2871 break;
2873 Ok = isInt<5>(Imm) && (Imm != 0);
2874 break;
2876 Ok = Imm != 0 && isInt<6>(Imm);
2877 break;
2879 Ok = isUInt<10>(Imm);
2880 break;
2882 Ok = isUInt<11>(Imm);
2883 break;
2885 Ok = isShiftedInt<7, 5>(Imm);
2886 break;
2888 Ok = isInt<16>(Imm) && (Imm != 0);
2889 break;
2891 Ok = isInt<20>(Imm);
2892 break;
2894 Ok = isInt<32>(Imm);
2895 break;
2897 Ok = STI.is64Bit() ? isUInt<6>(Imm) : isUInt<5>(Imm);
2898 break;
2900 Ok = STI.is64Bit() ? isUInt<6>(Imm) : isUInt<5>(Imm);
2901 Ok = Ok && Imm != 0;
2902 break;
2904 Ok = (isUInt<5>(Imm) && Imm != 0) ||
2905 (Imm >= 0xfffe0 && Imm <= 0xfffff);
2906 break;
2908 Ok = Imm >= 0 && Imm <= 10;
2909 break;
2911 Ok = Imm >= 0 && Imm <= 7;
2912 break;
2914 Ok = Imm >= 1 && Imm <= 10;
2915 break;
2917 Ok = Imm >= 2 && Imm <= 14;
2918 break;
2920 Ok = Imm >= RISCVZC::RA && Imm <= RISCVZC::RA_S0_S11;
2921 break;
2923 Ok = Imm >= RISCVZC::RA_S0 && Imm <= RISCVZC::RA_S0_S11;
2924 break;
2926 Ok = Imm >= 0 && Imm <= 48 && Imm % 16 == 0;
2927 break;
2930 break;
2932 Ok = Imm == RISCVFPRndMode::RTZ;
2933 break;
2935 Ok = Imm >= 0 && Imm < RISCVCC::COND_INVALID;
2936 break;
2938 Ok = (Imm &
2940 break;
2942 Ok = (isUInt<5>(Imm) && RISCVVType::isValidSEW(1 << Imm));
2943 break;
2945 Ok = Imm == 0;
2946 break;
2949 if (RISCVII::usesVXRM(Desc.TSFlags))
2950 Ok = isUInt<2>(Imm);
2951 else
2953 break;
2954 }
2955 if (!Ok) {
2956 ErrInfo = "Invalid immediate";
2957 return false;
2958 }
2959 }
2960 }
2961 }
2962
2963 const uint64_t TSFlags = Desc.TSFlags;
2964 if (RISCVII::hasVLOp(TSFlags)) {
2965 const MachineOperand &Op = MI.getOperand(RISCVII::getVLOpNum(Desc));
2966 if (!Op.isImm() && !Op.isReg()) {
2967 ErrInfo = "Invalid operand type for VL operand";
2968 return false;
2969 }
2970 if (Op.isReg() && Op.getReg() != RISCV::NoRegister) {
2971 const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
2972 auto *RC = MRI.getRegClass(Op.getReg());
2973 if (!RISCV::GPRRegClass.hasSubClassEq(RC)) {
2974 ErrInfo = "Invalid register class for VL operand";
2975 return false;
2976 }
2977 }
2978 if (!RISCVII::hasSEWOp(TSFlags)) {
2979 ErrInfo = "VL operand w/o SEW operand?";
2980 return false;
2981 }
2982 }
2983 if (RISCVII::hasSEWOp(TSFlags)) {
2984 unsigned OpIdx = RISCVII::getSEWOpNum(Desc);
2985 if (!MI.getOperand(OpIdx).isImm()) {
2986 ErrInfo = "SEW value expected to be an immediate";
2987 return false;
2988 }
2989 uint64_t Log2SEW = MI.getOperand(OpIdx).getImm();
2990 if (Log2SEW > 31) {
2991 ErrInfo = "Unexpected SEW value";
2992 return false;
2993 }
2994 unsigned SEW = Log2SEW ? 1 << Log2SEW : 8;
2995 if (!RISCVVType::isValidSEW(SEW)) {
2996 ErrInfo = "Unexpected SEW value";
2997 return false;
2998 }
2999 }
3000 if (RISCVII::hasVecPolicyOp(TSFlags)) {
3002 if (!MI.getOperand(OpIdx).isImm()) {
3003 ErrInfo = "Policy operand expected to be an immediate";
3004 return false;
3005 }
3006 uint64_t Policy = MI.getOperand(OpIdx).getImm();
3008 ErrInfo = "Invalid Policy Value";
3009 return false;
3010 }
3011 if (!RISCVII::hasVLOp(TSFlags)) {
3012 ErrInfo = "policy operand w/o VL operand?";
3013 return false;
3014 }
3015
3016 // VecPolicy operands can only exist on instructions with passthru/merge
3017 // arguments. Note that not all arguments with passthru have vec policy
3018 // operands- some instructions have implicit policies.
3019 unsigned UseOpIdx;
3020 if (!MI.isRegTiedToUseOperand(0, &UseOpIdx)) {
3021 ErrInfo = "policy operand w/o tied operand?";
3022 return false;
3023 }
3024 }
3025
3026 if (int Idx = RISCVII::getFRMOpNum(Desc);
3027 Idx >= 0 && MI.getOperand(Idx).getImm() == RISCVFPRndMode::DYN &&
3028 !MI.readsRegister(RISCV::FRM, /*TRI=*/nullptr)) {
3029 ErrInfo = "dynamic rounding mode should read FRM";
3030 return false;
3031 }
3032
3033 return true;
3034}
3035
3037 const MachineInstr &AddrI,
3038 ExtAddrMode &AM) const {
3039 switch (MemI.getOpcode()) {
3040 default:
3041 return false;
3042 case RISCV::LB:
3043 case RISCV::LBU:
3044 case RISCV::LH:
3045 case RISCV::LH_INX:
3046 case RISCV::LHU:
3047 case RISCV::LW:
3048 case RISCV::LW_INX:
3049 case RISCV::LWU:
3050 case RISCV::LD:
3051 case RISCV::LD_RV32:
3052 case RISCV::FLH:
3053 case RISCV::FLW:
3054 case RISCV::FLD:
3055 case RISCV::SB:
3056 case RISCV::SH:
3057 case RISCV::SH_INX:
3058 case RISCV::SW:
3059 case RISCV::SW_INX:
3060 case RISCV::SD:
3061 case RISCV::SD_RV32:
3062 case RISCV::FSH:
3063 case RISCV::FSW:
3064 case RISCV::FSD:
3065 break;
3066 }
3067
3068 if (MemI.getOperand(0).getReg() == Reg)
3069 return false;
3070
3071 if (AddrI.getOpcode() != RISCV::ADDI || !AddrI.getOperand(1).isReg() ||
3072 !AddrI.getOperand(2).isImm())
3073 return false;
3074
3075 int64_t OldOffset = MemI.getOperand(2).getImm();
3076 int64_t Disp = AddrI.getOperand(2).getImm();
3077 int64_t NewOffset = OldOffset + Disp;
3078 if (!STI.is64Bit())
3079 NewOffset = SignExtend64<32>(NewOffset);
3080
3081 if (!isInt<12>(NewOffset))
3082 return false;
3083
3084 AM.BaseReg = AddrI.getOperand(1).getReg();
3085 AM.ScaledReg = 0;
3086 AM.Scale = 0;
3087 AM.Displacement = NewOffset;
3089 return true;
3090}
3091
3093 const ExtAddrMode &AM) const {
3094
3095 const DebugLoc &DL = MemI.getDebugLoc();
3096 MachineBasicBlock &MBB = *MemI.getParent();
3097
3098 assert(AM.ScaledReg == 0 && AM.Scale == 0 &&
3099 "Addressing mode not supported for folding");
3100
3101 return BuildMI(MBB, MemI, DL, get(MemI.getOpcode()))
3102 .addReg(MemI.getOperand(0).getReg(),
3103 MemI.mayLoad() ? RegState::Define : 0)
3104 .addReg(AM.BaseReg)
3105 .addImm(AM.Displacement)
3106 .setMemRefs(MemI.memoperands())
3107 .setMIFlags(MemI.getFlags());
3108}
3109
3110// TODO: At the moment, MIPS introduced paring of instructions operating with
3111// word or double word. This should be extended with more instructions when more
3112// vendors support load/store pairing.
3114 switch (Opc) {
3115 default:
3116 return false;
3117 case RISCV::SW:
3118 case RISCV::SD:
3119 case RISCV::LD:
3120 case RISCV::LW:
3121 return true;
3122 }
3123}
3124
3126 const TargetRegisterInfo *TRI) {
3127 // If this is a volatile load/store, don't mess with it.
3128 if (LdSt.hasOrderedMemoryRef() || LdSt.getNumExplicitOperands() != 3)
3129 return false;
3130
3131 if (LdSt.getOperand(1).isFI())
3132 return true;
3133
3134 assert(LdSt.getOperand(1).isReg() && "Expected a reg operand.");
3135 // Can't cluster if the instruction modifies the base register
3136 // or it is update form. e.g. ld x5,8(x5)
3137 if (LdSt.modifiesRegister(LdSt.getOperand(1).getReg(), TRI))
3138 return false;
3139
3140 if (!LdSt.getOperand(2).isImm())
3141 return false;
3142
3143 return true;
3144}
3145
3148 int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width,
3149 const TargetRegisterInfo *TRI) const {
3150 if (!LdSt.mayLoadOrStore())
3151 return false;
3152
3153 // Conservatively, only handle scalar loads/stores for now.
3154 switch (LdSt.getOpcode()) {
3155 case RISCV::LB:
3156 case RISCV::LBU:
3157 case RISCV::SB:
3158 case RISCV::LH:
3159 case RISCV::LH_INX:
3160 case RISCV::LHU:
3161 case RISCV::FLH:
3162 case RISCV::SH:
3163 case RISCV::SH_INX:
3164 case RISCV::FSH:
3165 case RISCV::LW:
3166 case RISCV::LW_INX:
3167 case RISCV::LWU:
3168 case RISCV::FLW:
3169 case RISCV::SW:
3170 case RISCV::SW_INX:
3171 case RISCV::FSW:
3172 case RISCV::LD:
3173 case RISCV::LD_RV32:
3174 case RISCV::FLD:
3175 case RISCV::SD:
3176 case RISCV::SD_RV32:
3177 case RISCV::FSD:
3178 break;
3179 default:
3180 return false;
3181 }
3182 const MachineOperand *BaseOp;
3183 OffsetIsScalable = false;
3184 if (!getMemOperandWithOffsetWidth(LdSt, BaseOp, Offset, Width, TRI))
3185 return false;
3186 BaseOps.push_back(BaseOp);
3187 return true;
3188}
3189
3190// TODO: This was copied from SIInstrInfo. Could it be lifted to a common
3191// helper?
3194 const MachineInstr &MI2,
3196 // Only examine the first "base" operand of each instruction, on the
3197 // assumption that it represents the real base address of the memory access.
3198 // Other operands are typically offsets or indices from this base address.
3199 if (BaseOps1.front()->isIdenticalTo(*BaseOps2.front()))
3200 return true;
3201
3202 if (!MI1.hasOneMemOperand() || !MI2.hasOneMemOperand())
3203 return false;
3204
3205 auto MO1 = *MI1.memoperands_begin();
3206 auto MO2 = *MI2.memoperands_begin();
3207 if (MO1->getAddrSpace() != MO2->getAddrSpace())
3208 return false;
3209
3210 auto Base1 = MO1->getValue();
3211 auto Base2 = MO2->getValue();
3212 if (!Base1 || !Base2)
3213 return false;
3214 Base1 = getUnderlyingObject(Base1);
3215 Base2 = getUnderlyingObject(Base2);
3216
3217 if (isa<UndefValue>(Base1) || isa<UndefValue>(Base2))
3218 return false;
3219
3220 return Base1 == Base2;
3221}
3222
3224 ArrayRef<const MachineOperand *> BaseOps1, int64_t Offset1,
3225 bool OffsetIsScalable1, ArrayRef<const MachineOperand *> BaseOps2,
3226 int64_t Offset2, bool OffsetIsScalable2, unsigned ClusterSize,
3227 unsigned NumBytes) const {
3228 // If the mem ops (to be clustered) do not have the same base ptr, then they
3229 // should not be clustered
3230 if (!BaseOps1.empty() && !BaseOps2.empty()) {
3231 const MachineInstr &FirstLdSt = *BaseOps1.front()->getParent();
3232 const MachineInstr &SecondLdSt = *BaseOps2.front()->getParent();
3233 if (!memOpsHaveSameBasePtr(FirstLdSt, BaseOps1, SecondLdSt, BaseOps2))
3234 return false;
3235 } else if (!BaseOps1.empty() || !BaseOps2.empty()) {
3236 // If only one base op is empty, they do not have the same base ptr
3237 return false;
3238 }
3239
3240 unsigned CacheLineSize =
3241 BaseOps1.front()->getParent()->getMF()->getSubtarget().getCacheLineSize();
3242 // Assume a cache line size of 64 bytes if no size is set in RISCVSubtarget.
3244 // Cluster if the memory operations are on the same or a neighbouring cache
3245 // line, but limit the maximum ClusterSize to avoid creating too much
3246 // additional register pressure.
3247 return ClusterSize <= 4 && std::abs(Offset1 - Offset2) < CacheLineSize;
3248}
3249
3250// Set BaseReg (the base register operand), Offset (the byte offset being
3251// accessed) and the access Width of the passed instruction that reads/writes
3252// memory. Returns false if the instruction does not read/write memory or the
3253// BaseReg/Offset/Width can't be determined. Is not guaranteed to always
3254// recognise base operands and offsets in all cases.
3255// TODO: Add an IsScalable bool ref argument (like the equivalent AArch64
3256// function) and set it as appropriate.
3258 const MachineInstr &LdSt, const MachineOperand *&BaseReg, int64_t &Offset,
3259 LocationSize &Width, const TargetRegisterInfo *TRI) const {
3260 if (!LdSt.mayLoadOrStore())
3261 return false;
3262
3263 // Here we assume the standard RISC-V ISA, which uses a base+offset
3264 // addressing mode. You'll need to relax these conditions to support custom
3265 // load/store instructions.
3266 if (LdSt.getNumExplicitOperands() != 3)
3267 return false;
3268 if ((!LdSt.getOperand(1).isReg() && !LdSt.getOperand(1).isFI()) ||
3269 !LdSt.getOperand(2).isImm())
3270 return false;
3271
3272 if (!LdSt.hasOneMemOperand())
3273 return false;
3274
3275 Width = (*LdSt.memoperands_begin())->getSize();
3276 BaseReg = &LdSt.getOperand(1);
3277 Offset = LdSt.getOperand(2).getImm();
3278 return true;
3279}
3280
3282 const MachineInstr &MIa, const MachineInstr &MIb) const {
3283 assert(MIa.mayLoadOrStore() && "MIa must be a load or store.");
3284 assert(MIb.mayLoadOrStore() && "MIb must be a load or store.");
3285
3288 return false;
3289
3290 // Retrieve the base register, offset from the base register and width. Width
3291 // is the size of memory that is being loaded/stored (e.g. 1, 2, 4). If
3292 // base registers are identical, and the offset of a lower memory access +
3293 // the width doesn't overlap the offset of a higher memory access,
3294 // then the memory accesses are different.
3296 const MachineOperand *BaseOpA = nullptr, *BaseOpB = nullptr;
3297 int64_t OffsetA = 0, OffsetB = 0;
3299 WidthB = LocationSize::precise(0);
3300 if (getMemOperandWithOffsetWidth(MIa, BaseOpA, OffsetA, WidthA, TRI) &&
3301 getMemOperandWithOffsetWidth(MIb, BaseOpB, OffsetB, WidthB, TRI)) {
3302 if (BaseOpA->isIdenticalTo(*BaseOpB)) {
3303 int LowOffset = std::min(OffsetA, OffsetB);
3304 int HighOffset = std::max(OffsetA, OffsetB);
3305 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
3306 if (LowWidth.hasValue() &&
3307 LowOffset + (int)LowWidth.getValue() <= HighOffset)
3308 return true;
3309 }
3310 }
3311 return false;
3312}
3313
3314std::pair<unsigned, unsigned>
3316 const unsigned Mask = RISCVII::MO_DIRECT_FLAG_MASK;
3317 return std::make_pair(TF & Mask, TF & ~Mask);
3318}
3319
3322 using namespace RISCVII;
3323 static const std::pair<unsigned, const char *> TargetFlags[] = {
3324 {MO_CALL, "riscv-call"},
3325 {MO_LO, "riscv-lo"},
3326 {MO_HI, "riscv-hi"},
3327 {MO_PCREL_LO, "riscv-pcrel-lo"},
3328 {MO_PCREL_HI, "riscv-pcrel-hi"},
3329 {MO_GOT_HI, "riscv-got-hi"},
3330 {MO_TPREL_LO, "riscv-tprel-lo"},
3331 {MO_TPREL_HI, "riscv-tprel-hi"},
3332 {MO_TPREL_ADD, "riscv-tprel-add"},
3333 {MO_TLS_GOT_HI, "riscv-tls-got-hi"},
3334 {MO_TLS_GD_HI, "riscv-tls-gd-hi"},
3335 {MO_TLSDESC_HI, "riscv-tlsdesc-hi"},
3336 {MO_TLSDESC_LOAD_LO, "riscv-tlsdesc-load-lo"},
3337 {MO_TLSDESC_ADD_LO, "riscv-tlsdesc-add-lo"},
3338 {MO_TLSDESC_CALL, "riscv-tlsdesc-call"}};
3339 return ArrayRef(TargetFlags);
3340}
3342 MachineFunction &MF, bool OutlineFromLinkOnceODRs) const {
3343 const Function &F = MF.getFunction();
3344
3345 // Can F be deduplicated by the linker? If it can, don't outline from it.
3346 if (!OutlineFromLinkOnceODRs && F.hasLinkOnceODRLinkage())
3347 return false;
3348
3349 // Don't outline from functions with section markings; the program could
3350 // expect that all the code is in the named section.
3351 if (F.hasSection())
3352 return false;
3353
3354 // It's safe to outline from MF.
3355 return true;
3356}
3357
3359 unsigned &Flags) const {
3360 // More accurate safety checking is done in getOutliningCandidateInfo.
3362}
3363
3364// Enum values indicating how an outlined call should be constructed.
3369
3371 MachineFunction &MF) const {
3372 return MF.getFunction().hasMinSize();
3373}
3374
3376 const MachineFunction *MF = MBB.getParent();
3377 const Function &F = MF->getFunction();
3378 return F.getFnAttribute("fentry-call").getValueAsBool() ||
3379 F.hasFnAttribute("patchable-function-entry");
3380}
3381
3383 MCRegister RegNo) {
3384 return MI.readsRegister(RegNo, TRI) ||
3385 MI.getDesc().hasImplicitUseOfPhysReg(RegNo);
3386}
3387
3389 const TargetRegisterInfo *TRI, MCRegister RegNo) {
3390 return MI.modifiesRegister(RegNo, TRI) ||
3391 MI.getDesc().hasImplicitDefOfPhysReg(RegNo);
3392}
3393
3395 if (!MBB.back().isReturn())
3396 return true;
3398 return true;
3399
3400 // If the candidate reads the pre-set register
3401 // that can be used for expanding PseudoTAIL instruction,
3402 // then we cannot insert tail call.
3404 MCRegister TailExpandUseRegNo =
3406 for (const MachineInstr &MI : MBB) {
3407 if (isMIReadsReg(MI, STI.getRegisterInfo(), TailExpandUseRegNo))
3408 return true;
3409 if (isMIModifiesReg(MI, STI.getRegisterInfo(), TailExpandUseRegNo))
3410 break;
3411 }
3412 return false;
3413}
3414
3416 // If last instruction is return then we can rely on
3417 // the verification already performed in the getOutliningTypeImpl.
3418 if (C.back().isReturn()) {
3419 assert(!cannotInsertTailCall(*C.getMBB()) &&
3420 "The candidate who uses return instruction must be outlined "
3421 "using tail call");
3422 return false;
3423 }
3424
3425 // Filter out candidates where the X5 register (t0) can't be used to setup
3426 // the function call.
3427 const TargetRegisterInfo *TRI = C.getMF()->getSubtarget().getRegisterInfo();
3428 if (llvm::any_of(C, [TRI](const MachineInstr &MI) {
3429 return isMIModifiesReg(MI, TRI, RISCV::X5);
3430 }))
3431 return true;
3432
3433 return !C.isAvailableAcrossAndOutOfSeq(RISCV::X5, *TRI);
3434}
3435
3436std::optional<std::unique_ptr<outliner::OutlinedFunction>>
3438 const MachineModuleInfo &MMI,
3439 std::vector<outliner::Candidate> &RepeatedSequenceLocs,
3440 unsigned MinRepeats) const {
3441
3442 // Analyze each candidate and erase the ones that are not viable.
3443 llvm::erase_if(RepeatedSequenceLocs, analyzeCandidate);
3444
3445 // If the sequence doesn't have enough candidates left, then we're done.
3446 if (RepeatedSequenceLocs.size() < MinRepeats)
3447 return std::nullopt;
3448
3449 // Each RepeatedSequenceLoc is identical.
3450 outliner::Candidate &Candidate = RepeatedSequenceLocs[0];
3451 unsigned InstrSizeCExt =
3452 Candidate.getMF()->getSubtarget<RISCVSubtarget>().hasStdExtZca() ? 2 : 4;
3453 unsigned CallOverhead = 0, FrameOverhead = 0;
3454
3456 if (Candidate.back().isReturn()) {
3458 // tail call = auipc + jalr in the worst case without linker relaxation.
3459 // FIXME: This code suggests the JALR can be compressed - how?
3460 CallOverhead = 4 + InstrSizeCExt;
3461 // Using tail call we move ret instruction from caller to callee.
3462 FrameOverhead = 0;
3463 } else {
3464 // call t0, function = 8 bytes.
3465 CallOverhead = 8;
3466 // jr t0 = 4 bytes, 2 bytes if compressed instructions are enabled.
3467 FrameOverhead = InstrSizeCExt;
3468 }
3469
3470 for (auto &C : RepeatedSequenceLocs)
3471 C.setCallInfo(MOCI, CallOverhead);
3472
3473 unsigned SequenceSize = 0;
3474 for (auto &MI : Candidate)
3475 SequenceSize += getInstSizeInBytes(MI);
3476
3477 return std::make_unique<outliner::OutlinedFunction>(
3478 RepeatedSequenceLocs, SequenceSize, FrameOverhead, MOCI);
3479}
3480
3484 unsigned Flags) const {
3485 MachineInstr &MI = *MBBI;
3486 MachineBasicBlock *MBB = MI.getParent();
3487 const TargetRegisterInfo *TRI =
3489 const auto &F = MI.getMF()->getFunction();
3490
3491 // We can manually strip out CFI instructions later.
3492 if (MI.isCFIInstruction())
3493 // If current function has exception handling code, we can't outline &
3494 // strip these CFI instructions since it may break .eh_frame section
3495 // needed in unwinding.
3496 return F.needsUnwindTableEntry() ? outliner::InstrType::Illegal
3498
3499 if (cannotInsertTailCall(*MBB) &&
3500 (MI.isReturn() || isMIModifiesReg(MI, TRI, RISCV::X5)))
3502
3503 // Make sure the operands don't reference something unsafe.
3504 for (const auto &MO : MI.operands()) {
3505
3506 // pcrel-hi and pcrel-lo can't put in separate sections, filter that out
3507 // if any possible.
3508 if (MO.getTargetFlags() == RISCVII::MO_PCREL_LO &&
3509 (MI.getMF()->getTarget().getFunctionSections() || F.hasComdat() ||
3510 F.hasSection() || F.getSectionPrefix()))
3512 }
3513
3515}
3516
3519 const outliner::OutlinedFunction &OF) const {
3520
3521 // Strip out any CFI instructions
3522 bool Changed = true;
3523 while (Changed) {
3524 Changed = false;
3525 auto I = MBB.begin();
3526 auto E = MBB.end();
3527 for (; I != E; ++I) {
3528 if (I->isCFIInstruction()) {
3529 I->removeFromParent();
3530 Changed = true;
3531 break;
3532 }
3533 }
3534 }
3535
3536 if (OF.FrameConstructionID == MachineOutlinerTailCall)
3537 return;
3538
3539 MBB.addLiveIn(RISCV::X5);
3540
3541 // Add in a return instruction to the end of the outlined frame.
3542 MBB.insert(MBB.end(), BuildMI(MF, DebugLoc(), get(RISCV::JALR))
3543 .addReg(RISCV::X0, RegState::Define)
3544 .addReg(RISCV::X5)
3545 .addImm(0));
3546}
3547
3551
3552 if (C.CallConstructionID == MachineOutlinerTailCall) {
3553 It = MBB.insert(It, BuildMI(MF, DebugLoc(), get(RISCV::PseudoTAIL))
3554 .addGlobalAddress(M.getNamedValue(MF.getName()),
3555 /*Offset=*/0, RISCVII::MO_CALL));
3556 return It;
3557 }
3558
3559 // Add in a call instruction to the outlined function at the given location.
3560 It = MBB.insert(It,
3561 BuildMI(MF, DebugLoc(), get(RISCV::PseudoCALLReg), RISCV::X5)
3562 .addGlobalAddress(M.getNamedValue(MF.getName()), 0,
3564 return It;
3565}
3566
3567std::optional<RegImmPair> RISCVInstrInfo::isAddImmediate(const MachineInstr &MI,
3568 Register Reg) const {
3569 // TODO: Handle cases where Reg is a super- or sub-register of the
3570 // destination register.
3571 const MachineOperand &Op0 = MI.getOperand(0);
3572 if (!Op0.isReg() || Reg != Op0.getReg())
3573 return std::nullopt;
3574
3575 // Don't consider ADDIW as a candidate because the caller may not be aware
3576 // of its sign extension behaviour.
3577 if (MI.getOpcode() == RISCV::ADDI && MI.getOperand(1).isReg() &&
3578 MI.getOperand(2).isImm())
3579 return RegImmPair{MI.getOperand(1).getReg(), MI.getOperand(2).getImm()};
3580
3581 return std::nullopt;
3582}
3583
3584// MIR printer helper function to annotate Operands with a comment.
3586 const MachineInstr &MI, const MachineOperand &Op, unsigned OpIdx,
3587 const TargetRegisterInfo *TRI) const {
3588 // Print a generic comment for this operand if there is one.
3589 std::string GenericComment =
3591 if (!GenericComment.empty())
3592 return GenericComment;
3593
3594 // If not, we must have an immediate operand.
3595 if (!Op.isImm())
3596 return std::string();
3597
3598 const MCInstrDesc &Desc = MI.getDesc();
3599 if (OpIdx >= Desc.getNumOperands())
3600 return std::string();
3601
3602 std::string Comment;
3603 raw_string_ostream OS(Comment);
3604
3605 const MCOperandInfo &OpInfo = Desc.operands()[OpIdx];
3606
3607 // Print the full VType operand of vsetvli/vsetivli instructions, and the SEW
3608 // operand of vector codegen pseudos.
3609 switch (OpInfo.OperandType) {
3612 unsigned Imm = Op.getImm();
3614 break;
3615 }
3618 unsigned Log2SEW = Op.getImm();
3619 unsigned SEW = Log2SEW ? 1 << Log2SEW : 8;
3620 assert(RISCVVType::isValidSEW(SEW) && "Unexpected SEW");
3621 OS << "e" << SEW;
3622 break;
3623 }
3625 unsigned Policy = Op.getImm();
3627 "Invalid Policy Value");
3628 OS << (Policy & RISCVVType::TAIL_AGNOSTIC ? "ta" : "tu") << ", "
3629 << (Policy & RISCVVType::MASK_AGNOSTIC ? "ma" : "mu");
3630 break;
3631 }
3632
3633 return Comment;
3634}
3635
3636// clang-format off
3637#define CASE_RVV_OPCODE_UNMASK_LMUL(OP, LMUL) \
3638 RISCV::Pseudo##OP##_##LMUL
3639
3640#define CASE_RVV_OPCODE_MASK_LMUL(OP, LMUL) \
3641 RISCV::Pseudo##OP##_##LMUL##_MASK
3642
3643#define CASE_RVV_OPCODE_LMUL(OP, LMUL) \
3644 CASE_RVV_OPCODE_UNMASK_LMUL(OP, LMUL): \
3645 case CASE_RVV_OPCODE_MASK_LMUL(OP, LMUL)
3646
3647#define CASE_RVV_OPCODE_UNMASK_WIDEN(OP) \
3648 CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF8): \
3649 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF4): \
3650 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF2): \
3651 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M1): \
3652 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M2): \
3653 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M4)
3654
3655#define CASE_RVV_OPCODE_UNMASK(OP) \
3656 CASE_RVV_OPCODE_UNMASK_WIDEN(OP): \
3657 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M8)
3658
3659#define CASE_RVV_OPCODE_MASK_WIDEN(OP) \
3660 CASE_RVV_OPCODE_MASK_LMUL(OP, MF8): \
3661 case CASE_RVV_OPCODE_MASK_LMUL(OP, MF4): \
3662 case CASE_RVV_OPCODE_MASK_LMUL(OP, MF2): \
3663 case CASE_RVV_OPCODE_MASK_LMUL(OP, M1): \
3664 case CASE_RVV_OPCODE_MASK_LMUL(OP, M2): \
3665 case CASE_RVV_OPCODE_MASK_LMUL(OP, M4)
3666
3667#define CASE_RVV_OPCODE_MASK(OP) \
3668 CASE_RVV_OPCODE_MASK_WIDEN(OP): \
3669 case CASE_RVV_OPCODE_MASK_LMUL(OP, M8)
3670
3671#define CASE_RVV_OPCODE_WIDEN(OP) \
3672 CASE_RVV_OPCODE_UNMASK_WIDEN(OP): \
3673 case CASE_RVV_OPCODE_MASK_WIDEN(OP)
3674
3675#define CASE_RVV_OPCODE(OP) \
3676 CASE_RVV_OPCODE_UNMASK(OP): \
3677 case CASE_RVV_OPCODE_MASK(OP)
3678// clang-format on
3679
3680// clang-format off
3681#define CASE_VMA_OPCODE_COMMON(OP, TYPE, LMUL) \
3682 RISCV::PseudoV##OP##_##TYPE##_##LMUL
3683
3684#define CASE_VMA_OPCODE_LMULS(OP, TYPE) \
3685 CASE_VMA_OPCODE_COMMON(OP, TYPE, MF8): \
3686 case CASE_VMA_OPCODE_COMMON(OP, TYPE, MF4): \
3687 case CASE_VMA_OPCODE_COMMON(OP, TYPE, MF2): \
3688 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M1): \
3689 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M2): \
3690 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M4): \
3691 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M8)
3692
3693// VFMA instructions are SEW specific.
3694#define CASE_VFMA_OPCODE_COMMON(OP, TYPE, LMUL, SEW) \
3695 RISCV::PseudoV##OP##_##TYPE##_##LMUL##_##SEW
3696
3697#define CASE_VFMA_OPCODE_LMULS_M1(OP, TYPE, SEW) \
3698 CASE_VFMA_OPCODE_COMMON(OP, TYPE, M1, SEW): \
3699 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M2, SEW): \
3700 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M4, SEW): \
3701 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M8, SEW)
3702
3703#define CASE_VFMA_OPCODE_LMULS_MF2(OP, TYPE, SEW) \
3704 CASE_VFMA_OPCODE_COMMON(OP, TYPE, MF2, SEW): \
3705 case CASE_VFMA_OPCODE_LMULS_M1(OP, TYPE, SEW)
3706
3707#define CASE_VFMA_OPCODE_LMULS_MF4(OP, TYPE, SEW) \
3708 CASE_VFMA_OPCODE_COMMON(OP, TYPE, MF4, SEW): \
3709 case CASE_VFMA_OPCODE_LMULS_MF2(OP, TYPE, SEW)
3710
3711#define CASE_VFMA_OPCODE_VV(OP) \
3712 CASE_VFMA_OPCODE_LMULS_MF4(OP, VV, E16): \
3713 case CASE_VFMA_OPCODE_LMULS_MF2(OP, VV, E32): \
3714 case CASE_VFMA_OPCODE_LMULS_M1(OP, VV, E64)
3715
3716#define CASE_VFMA_SPLATS(OP) \
3717 CASE_VFMA_OPCODE_LMULS_MF4(OP, VFPR16, E16): \
3718 case CASE_VFMA_OPCODE_LMULS_MF2(OP, VFPR32, E32): \
3719 case CASE_VFMA_OPCODE_LMULS_M1(OP, VFPR64, E64)
3720// clang-format on
3721
3723 unsigned &SrcOpIdx1,
3724 unsigned &SrcOpIdx2) const {
3725 const MCInstrDesc &Desc = MI.getDesc();
3726 if (!Desc.isCommutable())
3727 return false;
3728
3729 switch (MI.getOpcode()) {
3730 case RISCV::TH_MVEQZ:
3731 case RISCV::TH_MVNEZ:
3732 // We can't commute operands if operand 2 (i.e., rs1 in
3733 // mveqz/mvnez rd,rs1,rs2) is the zero-register (as it is
3734 // not valid as the in/out-operand 1).
3735 if (MI.getOperand(2).getReg() == RISCV::X0)
3736 return false;
3737 // Operands 1 and 2 are commutable, if we switch the opcode.
3738 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 2);
3739 case RISCV::TH_MULA:
3740 case RISCV::TH_MULAW:
3741 case RISCV::TH_MULAH:
3742 case RISCV::TH_MULS:
3743 case RISCV::TH_MULSW:
3744 case RISCV::TH_MULSH:
3745 // Operands 2 and 3 are commutable.
3746 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
3747 case RISCV::PseudoCCMOVGPRNoX0:
3748 case RISCV::PseudoCCMOVGPR:
3749 // Operands 4 and 5 are commutable.
3750 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 4, 5);
3751 case CASE_RVV_OPCODE(VADD_VV):
3752 case CASE_RVV_OPCODE(VAND_VV):
3753 case CASE_RVV_OPCODE(VOR_VV):
3754 case CASE_RVV_OPCODE(VXOR_VV):
3755 case CASE_RVV_OPCODE_MASK(VMSEQ_VV):
3756 case CASE_RVV_OPCODE_MASK(VMSNE_VV):
3757 case CASE_RVV_OPCODE(VMIN_VV):
3758 case CASE_RVV_OPCODE(VMINU_VV):
3759 case CASE_RVV_OPCODE(VMAX_VV):
3760 case CASE_RVV_OPCODE(VMAXU_VV):
3761 case CASE_RVV_OPCODE(VMUL_VV):
3762 case CASE_RVV_OPCODE(VMULH_VV):
3763 case CASE_RVV_OPCODE(VMULHU_VV):
3764 case CASE_RVV_OPCODE_WIDEN(VWADD_VV):
3765 case CASE_RVV_OPCODE_WIDEN(VWADDU_VV):
3766 case CASE_RVV_OPCODE_WIDEN(VWMUL_VV):
3767 case CASE_RVV_OPCODE_WIDEN(VWMULU_VV):
3768 case CASE_RVV_OPCODE_WIDEN(VWMACC_VV):
3769 case CASE_RVV_OPCODE_WIDEN(VWMACCU_VV):
3770 case CASE_RVV_OPCODE_UNMASK(VADC_VVM):
3771 case CASE_RVV_OPCODE(VSADD_VV):
3772 case CASE_RVV_OPCODE(VSADDU_VV):
3773 case CASE_RVV_OPCODE(VAADD_VV):
3774 case CASE_RVV_OPCODE(VAADDU_VV):
3775 case CASE_RVV_OPCODE(VSMUL_VV):
3776 // Operands 2 and 3 are commutable.
3777 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
3778 case CASE_VFMA_SPLATS(FMADD):
3779 case CASE_VFMA_SPLATS(FMSUB):
3780 case CASE_VFMA_SPLATS(FMACC):
3781 case CASE_VFMA_SPLATS(FMSAC):
3784 case CASE_VFMA_SPLATS(FNMACC):
3785 case CASE_VFMA_SPLATS(FNMSAC):
3786 case CASE_VFMA_OPCODE_VV(FMACC):
3787 case CASE_VFMA_OPCODE_VV(FMSAC):
3788 case CASE_VFMA_OPCODE_VV(FNMACC):
3789 case CASE_VFMA_OPCODE_VV(FNMSAC):
3790 case CASE_VMA_OPCODE_LMULS(MADD, VX):
3791 case CASE_VMA_OPCODE_LMULS(NMSUB, VX):
3792 case CASE_VMA_OPCODE_LMULS(MACC, VX):
3793 case CASE_VMA_OPCODE_LMULS(NMSAC, VX):
3794 case CASE_VMA_OPCODE_LMULS(MACC, VV):
3795 case CASE_VMA_OPCODE_LMULS(NMSAC, VV): {
3796 // If the tail policy is undisturbed we can't commute.
3797 assert(RISCVII::hasVecPolicyOp(MI.getDesc().TSFlags));
3798 if ((MI.getOperand(RISCVII::getVecPolicyOpNum(MI.getDesc())).getImm() &
3799 1) == 0)
3800 return false;
3801
3802 // For these instructions we can only swap operand 1 and operand 3 by
3803 // changing the opcode.
3804 unsigned CommutableOpIdx1 = 1;
3805 unsigned CommutableOpIdx2 = 3;
3806 if (!fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, CommutableOpIdx1,
3807 CommutableOpIdx2))
3808 return false;
3809 return true;
3810 }
3811 case CASE_VFMA_OPCODE_VV(FMADD):
3815 case CASE_VMA_OPCODE_LMULS(MADD, VV):
3816 case CASE_VMA_OPCODE_LMULS(NMSUB, VV): {
3817 // If the tail policy is undisturbed we can't commute.
3818 assert(RISCVII::hasVecPolicyOp(MI.getDesc().TSFlags));
3819 if ((MI.getOperand(RISCVII::getVecPolicyOpNum(MI.getDesc())).getImm() &
3820 1) == 0)
3821 return false;
3822
3823 // For these instructions we have more freedom. We can commute with the
3824 // other multiplicand or with the addend/subtrahend/minuend.
3825
3826 // Any fixed operand must be from source 1, 2 or 3.
3827 if (SrcOpIdx1 != CommuteAnyOperandIndex && SrcOpIdx1 > 3)
3828 return false;
3829 if (SrcOpIdx2 != CommuteAnyOperandIndex && SrcOpIdx2 > 3)
3830 return false;
3831
3832 // It both ops are fixed one must be the tied source.
3833 if (SrcOpIdx1 != CommuteAnyOperandIndex &&
3834 SrcOpIdx2 != CommuteAnyOperandIndex && SrcOpIdx1 != 1 && SrcOpIdx2 != 1)
3835 return false;
3836
3837 // Look for two different register operands assumed to be commutable
3838 // regardless of the FMA opcode. The FMA opcode is adjusted later if
3839 // needed.
3840 if (SrcOpIdx1 == CommuteAnyOperandIndex ||
3841 SrcOpIdx2 == CommuteAnyOperandIndex) {
3842 // At least one of operands to be commuted is not specified and
3843 // this method is free to choose appropriate commutable operands.
3844 unsigned CommutableOpIdx1 = SrcOpIdx1;
3845 if (SrcOpIdx1 == SrcOpIdx2) {
3846 // Both of operands are not fixed. Set one of commutable
3847 // operands to the tied source.
3848 CommutableOpIdx1 = 1;
3849 } else if (SrcOpIdx1 == CommuteAnyOperandIndex) {
3850 // Only one of the operands is not fixed.
3851 CommutableOpIdx1 = SrcOpIdx2;
3852 }
3853
3854 // CommutableOpIdx1 is well defined now. Let's choose another commutable
3855 // operand and assign its index to CommutableOpIdx2.
3856 unsigned CommutableOpIdx2;
3857 if (CommutableOpIdx1 != 1) {
3858 // If we haven't already used the tied source, we must use it now.
3859 CommutableOpIdx2 = 1;
3860 } else {
3861 Register Op1Reg = MI.getOperand(CommutableOpIdx1).getReg();
3862
3863 // The commuted operands should have different registers.
3864 // Otherwise, the commute transformation does not change anything and
3865 // is useless. We use this as a hint to make our decision.
3866 if (Op1Reg != MI.getOperand(2).getReg())
3867 CommutableOpIdx2 = 2;
3868 else
3869 CommutableOpIdx2 = 3;
3870 }
3871
3872 // Assign the found pair of commutable indices to SrcOpIdx1 and
3873 // SrcOpIdx2 to return those values.
3874 if (!fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, CommutableOpIdx1,
3875 CommutableOpIdx2))
3876 return false;
3877 }
3878
3879 return true;
3880 }
3881 }
3882
3883 return TargetInstrInfo::findCommutedOpIndices(MI, SrcOpIdx1, SrcOpIdx2);
3884}
3885
3886// clang-format off
3887#define CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, LMUL) \
3888 case RISCV::PseudoV##OLDOP##_##TYPE##_##LMUL: \
3889 Opc = RISCV::PseudoV##NEWOP##_##TYPE##_##LMUL; \
3890 break;
3891
3892#define CASE_VMA_CHANGE_OPCODE_LMULS(OLDOP, NEWOP, TYPE) \
3893 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF8) \
3894 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF4) \
3895 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF2) \
3896 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M1) \
3897 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M2) \
3898 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M4) \
3899 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M8)
3900
3901// VFMA depends on SEW.
3902#define CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, LMUL, SEW) \
3903 case RISCV::PseudoV##OLDOP##_##TYPE##_##LMUL##_##SEW: \
3904 Opc = RISCV::PseudoV##NEWOP##_##TYPE##_##LMUL##_##SEW; \
3905 break;
3906
3907#define CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, TYPE, SEW) \
3908 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M1, SEW) \
3909 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M2, SEW) \
3910 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M4, SEW) \
3911 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M8, SEW)
3912
3913#define CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, TYPE, SEW) \
3914 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF2, SEW) \
3915 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, TYPE, SEW)
3916
3917#define CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, TYPE, SEW) \
3918 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF4, SEW) \
3919 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, TYPE, SEW)
3920
3921#define CASE_VFMA_CHANGE_OPCODE_VV(OLDOP, NEWOP) \
3922 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, VV, E16) \
3923 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, VV, E32) \
3924 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, VV, E64)
3925
3926#define CASE_VFMA_CHANGE_OPCODE_SPLATS(OLDOP, NEWOP) \
3927 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, VFPR16, E16) \
3928 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, VFPR32, E32) \
3929 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, VFPR64, E64)
3930// clang-format on
3931
3933 bool NewMI,
3934 unsigned OpIdx1,
3935 unsigned OpIdx2) const {
3936 auto cloneIfNew = [NewMI](MachineInstr &MI) -> MachineInstr & {
3937 if (NewMI)
3938 return *MI.getParent()->getParent()->CloneMachineInstr(&MI);
3939 return MI;
3940 };
3941
3942 switch (MI.getOpcode()) {
3943 case RISCV::TH_MVEQZ:
3944 case RISCV::TH_MVNEZ: {
3945 auto &WorkingMI = cloneIfNew(MI);
3946 WorkingMI.setDesc(get(MI.getOpcode() == RISCV::TH_MVEQZ ? RISCV::TH_MVNEZ
3947 : RISCV::TH_MVEQZ));
3948 return TargetInstrInfo::commuteInstructionImpl(WorkingMI, false, OpIdx1,
3949 OpIdx2);
3950 }
3951 case RISCV::PseudoCCMOVGPRNoX0:
3952 case RISCV::PseudoCCMOVGPR: {
3953 // CCMOV can be commuted by inverting the condition.
3954 auto CC = static_cast<RISCVCC::CondCode>(MI.getOperand(3).getImm());
3956 auto &WorkingMI = cloneIfNew(MI);
3957 WorkingMI.getOperand(3).setImm(CC);
3958 return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI*/ false,
3959 OpIdx1, OpIdx2);
3960 }
3961 case CASE_VFMA_SPLATS(FMACC):
3962 case CASE_VFMA_SPLATS(FMADD):
3963 case CASE_VFMA_SPLATS(FMSAC):
3964 case CASE_VFMA_SPLATS(FMSUB):
3965 case CASE_VFMA_SPLATS(FNMACC):
3967 case CASE_VFMA_SPLATS(FNMSAC):
3969 case CASE_VFMA_OPCODE_VV(FMACC):
3970 case CASE_VFMA_OPCODE_VV(FMSAC):
3971 case CASE_VFMA_OPCODE_VV(FNMACC):
3972 case CASE_VFMA_OPCODE_VV(FNMSAC):
3973 case CASE_VMA_OPCODE_LMULS(MADD, VX):
3974 case CASE_VMA_OPCODE_LMULS(NMSUB, VX):
3975 case CASE_VMA_OPCODE_LMULS(MACC, VX):
3976 case CASE_VMA_OPCODE_LMULS(NMSAC, VX):
3977 case CASE_VMA_OPCODE_LMULS(MACC, VV):
3978 case CASE_VMA_OPCODE_LMULS(NMSAC, VV): {
3979 // It only make sense to toggle these between clobbering the
3980 // addend/subtrahend/minuend one of the multiplicands.
3981 assert((OpIdx1 == 1 || OpIdx2 == 1) && "Unexpected opcode index");
3982 assert((OpIdx1 == 3 || OpIdx2 == 3) && "Unexpected opcode index");
3983 unsigned Opc;
3984 switch (MI.getOpcode()) {
3985 default:
3986 llvm_unreachable("Unexpected opcode");
3987 CASE_VFMA_CHANGE_OPCODE_SPLATS(FMACC, FMADD)
3988 CASE_VFMA_CHANGE_OPCODE_SPLATS(FMADD, FMACC)
3995 CASE_VFMA_CHANGE_OPCODE_VV(FMACC, FMADD)
3999 CASE_VMA_CHANGE_OPCODE_LMULS(MACC, MADD, VX)
4000 CASE_VMA_CHANGE_OPCODE_LMULS(MADD, MACC, VX)
4001 CASE_VMA_CHANGE_OPCODE_LMULS(NMSAC, NMSUB, VX)
4002 CASE_VMA_CHANGE_OPCODE_LMULS(NMSUB, NMSAC, VX)
4003 CASE_VMA_CHANGE_OPCODE_LMULS(MACC, MADD, VV)
4004 CASE_VMA_CHANGE_OPCODE_LMULS(NMSAC, NMSUB, VV)
4005 }
4006
4007 auto &WorkingMI = cloneIfNew(MI);
4008 WorkingMI.setDesc(get(Opc));
4009 return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI=*/false,
4010 OpIdx1, OpIdx2);
4011 }
4012 case CASE_VFMA_OPCODE_VV(FMADD):
4016 case CASE_VMA_OPCODE_LMULS(MADD, VV):
4017 case CASE_VMA_OPCODE_LMULS(NMSUB, VV): {
4018 assert((OpIdx1 == 1 || OpIdx2 == 1) && "Unexpected opcode index");
4019 // If one of the operands, is the addend we need to change opcode.
4020 // Otherwise we're just swapping 2 of the multiplicands.
4021 if (OpIdx1 == 3 || OpIdx2 == 3) {
4022 unsigned Opc;
4023 switch (MI.getOpcode()) {
4024 default:
4025 llvm_unreachable("Unexpected opcode");
4026 CASE_VFMA_CHANGE_OPCODE_VV(FMADD, FMACC)
4030 CASE_VMA_CHANGE_OPCODE_LMULS(MADD, MACC, VV)
4031 CASE_VMA_CHANGE_OPCODE_LMULS(NMSUB, NMSAC, VV)
4032 }
4033
4034 auto &WorkingMI = cloneIfNew(MI);
4035 WorkingMI.setDesc(get(Opc));
4036 return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI=*/false,
4037 OpIdx1, OpIdx2);
4038 }
4039 // Let the default code handle it.
4040 break;
4041 }
4042 }
4043
4044 return TargetInstrInfo::commuteInstructionImpl(MI, NewMI, OpIdx1, OpIdx2);
4045}
4046
4047#undef CASE_VMA_CHANGE_OPCODE_COMMON
4048#undef CASE_VMA_CHANGE_OPCODE_LMULS
4049#undef CASE_VFMA_CHANGE_OPCODE_COMMON
4050#undef CASE_VFMA_CHANGE_OPCODE_LMULS_M1
4051#undef CASE_VFMA_CHANGE_OPCODE_LMULS_MF2
4052#undef CASE_VFMA_CHANGE_OPCODE_LMULS_MF4
4053#undef CASE_VFMA_CHANGE_OPCODE_VV
4054#undef CASE_VFMA_CHANGE_OPCODE_SPLATS
4055
4056#undef CASE_RVV_OPCODE_UNMASK_LMUL
4057#undef CASE_RVV_OPCODE_MASK_LMUL
4058#undef CASE_RVV_OPCODE_LMUL
4059#undef CASE_RVV_OPCODE_UNMASK_WIDEN
4060#undef CASE_RVV_OPCODE_UNMASK
4061#undef CASE_RVV_OPCODE_MASK_WIDEN
4062#undef CASE_RVV_OPCODE_MASK
4063#undef CASE_RVV_OPCODE_WIDEN
4064#undef CASE_RVV_OPCODE
4065
4066#undef CASE_VMA_OPCODE_COMMON
4067#undef CASE_VMA_OPCODE_LMULS
4068#undef CASE_VFMA_OPCODE_COMMON
4069#undef CASE_VFMA_OPCODE_LMULS_M1
4070#undef CASE_VFMA_OPCODE_LMULS_MF2
4071#undef CASE_VFMA_OPCODE_LMULS_MF4
4072#undef CASE_VFMA_OPCODE_VV
4073#undef CASE_VFMA_SPLATS
4074
4076 switch (MI.getOpcode()) {
4077 default:
4078 break;
4079 case RISCV::ADD:
4080 case RISCV::OR:
4081 case RISCV::XOR:
4082 // Normalize (so we hit the next if clause).
4083 // add/[x]or rd, zero, rs => add/[x]or rd, rs, zero
4084 if (MI.getOperand(1).getReg() == RISCV::X0)
4085 commuteInstruction(MI);
4086 // add/[x]or rd, rs, zero => addi rd, rs, 0
4087 if (MI.getOperand(2).getReg() == RISCV::X0) {
4088 MI.getOperand(2).ChangeToImmediate(0);
4089 MI.setDesc(get(RISCV::ADDI));
4090 return true;
4091 }
4092 // xor rd, rs, rs => addi rd, zero, 0
4093 if (MI.getOpcode() == RISCV::XOR &&
4094 MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) {
4095 MI.getOperand(1).setReg(RISCV::X0);
4096 MI.getOperand(2).ChangeToImmediate(0);
4097 MI.setDesc(get(RISCV::ADDI));
4098 return true;
4099 }
4100 break;
4101 case RISCV::ORI:
4102 case RISCV::XORI:
4103 // [x]ori rd, zero, N => addi rd, zero, N
4104 if (MI.getOperand(1).getReg() == RISCV::X0) {
4105 MI.setDesc(get(RISCV::ADDI));
4106 return true;
4107 }
4108 break;
4109 case RISCV::SUB:
4110 // sub rd, rs, zero => addi rd, rs, 0
4111 if (MI.getOperand(2).getReg() == RISCV::X0) {
4112 MI.getOperand(2).ChangeToImmediate(0);
4113 MI.setDesc(get(RISCV::ADDI));
4114 return true;
4115 }
4116 break;
4117 case RISCV::SUBW:
4118 // subw rd, rs, zero => addiw rd, rs, 0
4119 if (MI.getOperand(2).getReg() == RISCV::X0) {
4120 MI.getOperand(2).ChangeToImmediate(0);
4121 MI.setDesc(get(RISCV::ADDIW));
4122 return true;
4123 }
4124 break;
4125 case RISCV::ADDW:
4126 // Normalize (so we hit the next if clause).
4127 // addw rd, zero, rs => addw rd, rs, zero
4128 if (MI.getOperand(1).getReg() == RISCV::X0)
4129 commuteInstruction(MI);
4130 // addw rd, rs, zero => addiw rd, rs, 0
4131 if (MI.getOperand(2).getReg() == RISCV::X0) {
4132 MI.getOperand(2).ChangeToImmediate(0);
4133 MI.setDesc(get(RISCV::ADDIW));
4134 return true;
4135 }
4136 break;
4137 case RISCV::SH1ADD:
4138 case RISCV::SH1ADD_UW:
4139 case RISCV::SH2ADD:
4140 case RISCV::SH2ADD_UW:
4141 case RISCV::SH3ADD:
4142 case RISCV::SH3ADD_UW:
4143 // shNadd[.uw] rd, zero, rs => addi rd, rs, 0
4144 if (MI.getOperand(1).getReg() == RISCV::X0) {
4145 MI.removeOperand(1);
4146 MI.addOperand(MachineOperand::CreateImm(0));
4147 MI.setDesc(get(RISCV::ADDI));
4148 return true;
4149 }
4150 // shNadd[.uw] rd, rs, zero => slli[.uw] rd, rs, N
4151 if (MI.getOperand(2).getReg() == RISCV::X0) {
4152 MI.removeOperand(2);
4153 unsigned Opc = MI.getOpcode();
4154 if (Opc == RISCV::SH1ADD_UW || Opc == RISCV::SH2ADD_UW ||
4155 Opc == RISCV::SH3ADD_UW) {
4157 MI.setDesc(get(RISCV::SLLI_UW));
4158 return true;
4159 }
4161 MI.setDesc(get(RISCV::SLLI));
4162 return true;
4163 }
4164 break;
4165 case RISCV::AND:
4166 case RISCV::MUL:
4167 case RISCV::MULH:
4168 case RISCV::MULHSU:
4169 case RISCV::MULHU:
4170 case RISCV::MULW:
4171 // and rd, zero, rs => addi rd, zero, 0
4172 // mul* rd, zero, rs => addi rd, zero, 0
4173 // and rd, rs, zero => addi rd, zero, 0
4174 // mul* rd, rs, zero => addi rd, zero, 0
4175 if (MI.getOperand(1).getReg() == RISCV::X0 ||
4176 MI.getOperand(2).getReg() == RISCV::X0) {
4177 MI.getOperand(1).setReg(RISCV::X0);
4178 MI.getOperand(2).ChangeToImmediate(0);
4179 MI.setDesc(get(RISCV::ADDI));
4180 return true;
4181 }
4182 break;
4183 case RISCV::ANDI:
4184 // andi rd, zero, C => addi rd, zero, 0
4185 if (MI.getOperand(1).getReg() == RISCV::X0) {
4186 MI.getOperand(2).setImm(0);
4187 MI.setDesc(get(RISCV::ADDI));
4188 return true;
4189 }
4190 break;
4191 case RISCV::SLL:
4192 case RISCV::SRL:
4193 case RISCV::SRA:
4194 // shift rd, zero, rs => addi rd, zero, 0
4195 if (MI.getOperand(1).getReg() == RISCV::X0) {
4196 MI.getOperand(2).ChangeToImmediate(0);
4197 MI.setDesc(get(RISCV::ADDI));
4198 return true;
4199 }
4200 // shift rd, rs, zero => addi rd, rs, 0
4201 if (MI.getOperand(2).getReg() == RISCV::X0) {
4202 MI.getOperand(2).ChangeToImmediate(0);
4203 MI.setDesc(get(RISCV::ADDI));
4204 return true;
4205 }
4206 break;
4207 case RISCV::SLLW:
4208 case RISCV::SRLW:
4209 case RISCV::SRAW:
4210 // shiftw rd, zero, rs => addi rd, zero, 0
4211 if (MI.getOperand(1).getReg() == RISCV::X0) {
4212 MI.getOperand(2).ChangeToImmediate(0);
4213 MI.setDesc(get(RISCV::ADDI));
4214 return true;
4215 }
4216 break;
4217 case RISCV::SLLI:
4218 case RISCV::SRLI:
4219 case RISCV::SRAI:
4220 case RISCV::SLLIW:
4221 case RISCV::SRLIW:
4222 case RISCV::SRAIW:
4223 case RISCV::SLLI_UW:
4224 // shiftimm rd, zero, N => addi rd, zero, 0
4225 if (MI.getOperand(1).getReg() == RISCV::X0) {
4226 MI.getOperand(2).setImm(0);
4227 MI.setDesc(get(RISCV::ADDI));
4228 return true;
4229 }
4230 break;
4231 case RISCV::SLTU:
4232 case RISCV::ADD_UW:
4233 // sltu rd, zero, zero => addi rd, zero, 0
4234 // add.uw rd, zero, zero => addi rd, zero, 0
4235 if (MI.getOperand(1).getReg() == RISCV::X0 &&
4236 MI.getOperand(2).getReg() == RISCV::X0) {
4237 MI.getOperand(2).ChangeToImmediate(0);
4238 MI.setDesc(get(RISCV::ADDI));
4239 return true;
4240 }
4241 // add.uw rd, zero, rs => addi rd, rs, 0
4242 if (MI.getOpcode() == RISCV::ADD_UW &&
4243 MI.getOperand(1).getReg() == RISCV::X0) {
4244 MI.removeOperand(1);
4245 MI.addOperand(MachineOperand::CreateImm(0));
4246 MI.setDesc(get(RISCV::ADDI));
4247 }
4248 break;
4249 case RISCV::SLTIU:
4250 // sltiu rd, zero, NZC => addi rd, zero, 1
4251 // sltiu rd, zero, 0 => addi rd, zero, 0
4252 if (MI.getOperand(1).getReg() == RISCV::X0) {
4253 MI.getOperand(2).setImm(MI.getOperand(2).getImm() != 0);
4254 MI.setDesc(get(RISCV::ADDI));
4255 return true;
4256 }
4257 break;
4258 case RISCV::SEXT_H:
4259 case RISCV::SEXT_B:
4260 case RISCV::ZEXT_H_RV32:
4261 case RISCV::ZEXT_H_RV64:
4262 // sext.[hb] rd, zero => addi rd, zero, 0
4263 // zext.h rd, zero => addi rd, zero, 0
4264 if (MI.getOperand(1).getReg() == RISCV::X0) {
4265 MI.addOperand(MachineOperand::CreateImm(0));
4266 MI.setDesc(get(RISCV::ADDI));
4267 return true;
4268 }
4269 break;
4270 case RISCV::MIN:
4271 case RISCV::MINU:
4272 case RISCV::MAX:
4273 case RISCV::MAXU:
4274 // min|max rd, rs, rs => addi rd, rs, 0
4275 if (MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) {
4276 MI.getOperand(2).ChangeToImmediate(0);
4277 MI.setDesc(get(RISCV::ADDI));
4278 return true;
4279 }
4280 break;
4281 case RISCV::BEQ:
4282 case RISCV::BNE:
4283 // b{eq,ne} zero, rs, imm => b{eq,ne} rs, zero, imm
4284 if (MI.getOperand(0).getReg() == RISCV::X0) {
4285 MachineOperand MO0 = MI.getOperand(0);
4286 MI.removeOperand(0);
4287 MI.insert(MI.operands_begin() + 1, {MO0});
4288 }
4289 break;
4290 case RISCV::BLTU:
4291 // bltu zero, rs, imm => bne rs, zero, imm
4292 if (MI.getOperand(0).getReg() == RISCV::X0) {
4293 MachineOperand MO0 = MI.getOperand(0);
4294 MI.removeOperand(0);
4295 MI.insert(MI.operands_begin() + 1, {MO0});
4296 MI.setDesc(get(RISCV::BNE));
4297 }
4298 break;
4299 case RISCV::BGEU:
4300 // bgeu zero, rs, imm => beq rs, zero, imm
4301 if (MI.getOperand(0).getReg() == RISCV::X0) {
4302 MachineOperand MO0 = MI.getOperand(0);
4303 MI.removeOperand(0);
4304 MI.insert(MI.operands_begin() + 1, {MO0});
4305 MI.setDesc(get(RISCV::BEQ));
4306 }
4307 break;
4308 }
4309 return false;
4310}
4311
4312// clang-format off
4313#define CASE_WIDEOP_OPCODE_COMMON(OP, LMUL) \
4314 RISCV::PseudoV##OP##_##LMUL##_TIED
4315
4316#define CASE_WIDEOP_OPCODE_LMULS(OP) \
4317 CASE_WIDEOP_OPCODE_COMMON(OP, MF8): \
4318 case CASE_WIDEOP_OPCODE_COMMON(OP, MF4): \
4319 case CASE_WIDEOP_OPCODE_COMMON(OP, MF2): \
4320 case CASE_WIDEOP_OPCODE_COMMON(OP, M1): \
4321 case CASE_WIDEOP_OPCODE_COMMON(OP, M2): \
4322 case CASE_WIDEOP_OPCODE_COMMON(OP, M4)
4323
4324#define CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, LMUL) \
4325 case RISCV::PseudoV##OP##_##LMUL##_TIED: \
4326 NewOpc = RISCV::PseudoV##OP##_##LMUL; \
4327 break;
4328
4329#define CASE_WIDEOP_CHANGE_OPCODE_LMULS(OP) \
4330 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF8) \
4331 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF4) \
4332 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2) \
4333 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1) \
4334 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2) \
4335 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4)
4336
4337// FP Widening Ops may by SEW aware. Create SEW aware cases for these cases.
4338#define CASE_FP_WIDEOP_OPCODE_COMMON(OP, LMUL, SEW) \
4339 RISCV::PseudoV##OP##_##LMUL##_##SEW##_TIED
4340
4341#define CASE_FP_WIDEOP_OPCODE_LMULS(OP) \
4342 CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF4, E16): \
4343 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF2, E16): \
4344 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF2, E32): \
4345 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M1, E16): \
4346 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M1, E32): \
4347 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M2, E16): \
4348 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M2, E32): \
4349 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M4, E16): \
4350 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M4, E32) \
4351
4352#define CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, LMUL, SEW) \
4353 case RISCV::PseudoV##OP##_##LMUL##_##SEW##_TIED: \
4354 NewOpc = RISCV::PseudoV##OP##_##LMUL##_##SEW; \
4355 break;
4356
4357#define CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS(OP) \
4358 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF4, E16) \
4359 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2, E16) \
4360 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2, E32) \
4361 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1, E16) \
4362 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1, E32) \
4363 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2, E16) \
4364 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2, E32) \
4365 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4, E16) \
4366 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4, E32) \
4367// clang-format on
4368
4370 LiveVariables *LV,
4371 LiveIntervals *LIS) const {
4373 switch (MI.getOpcode()) {
4374 default:
4375 return nullptr;
4376 case CASE_FP_WIDEOP_OPCODE_LMULS(FWADD_WV):
4377 case CASE_FP_WIDEOP_OPCODE_LMULS(FWSUB_WV): {
4378 assert(RISCVII::hasVecPolicyOp(MI.getDesc().TSFlags) &&
4379 MI.getNumExplicitOperands() == 7 &&
4380 "Expect 7 explicit operands rd, rs2, rs1, rm, vl, sew, policy");
4381 // If the tail policy is undisturbed we can't convert.
4382 if ((MI.getOperand(RISCVII::getVecPolicyOpNum(MI.getDesc())).getImm() &
4383 1) == 0)
4384 return nullptr;
4385 // clang-format off
4386 unsigned NewOpc;
4387 switch (MI.getOpcode()) {
4388 default:
4389 llvm_unreachable("Unexpected opcode");
4392 }
4393 // clang-format on
4394
4395 MachineBasicBlock &MBB = *MI.getParent();
4396 MIB = BuildMI(MBB, MI, MI.getDebugLoc(), get(NewOpc))
4397 .add(MI.getOperand(0))
4398 .addReg(MI.getOperand(0).getReg(), RegState::Undef)
4399 .add(MI.getOperand(1))
4400 .add(MI.getOperand(2))
4401 .add(MI.getOperand(3))
4402 .add(MI.getOperand(4))
4403 .add(MI.getOperand(5))
4404 .add(MI.getOperand(6));
4405 break;
4406 }
4407 case CASE_WIDEOP_OPCODE_LMULS(WADD_WV):
4408 case CASE_WIDEOP_OPCODE_LMULS(WADDU_WV):
4409 case CASE_WIDEOP_OPCODE_LMULS(WSUB_WV):
4410 case CASE_WIDEOP_OPCODE_LMULS(WSUBU_WV): {
4411 // If the tail policy is undisturbed we can't convert.
4412 assert(RISCVII::hasVecPolicyOp(MI.getDesc().TSFlags) &&
4413 MI.getNumExplicitOperands() == 6);
4414 if ((MI.getOperand(RISCVII::getVecPolicyOpNum(MI.getDesc())).getImm() &
4415 1) == 0)
4416 return nullptr;
4417
4418 // clang-format off
4419 unsigned NewOpc;
4420 switch (MI.getOpcode()) {
4421 default:
4422 llvm_unreachable("Unexpected opcode");
4427 }
4428 // clang-format on
4429
4430 MachineBasicBlock &MBB = *MI.getParent();
4431 MIB = BuildMI(MBB, MI, MI.getDebugLoc(), get(NewOpc))
4432 .add(MI.getOperand(0))
4433 .addReg(MI.getOperand(0).getReg(), RegState::Undef)
4434 .add(MI.getOperand(1))
4435 .add(MI.getOperand(2))
4436 .add(MI.getOperand(3))
4437 .add(MI.getOperand(4))
4438 .add(MI.getOperand(5));
4439 break;
4440 }
4441 }
4442 MIB.copyImplicitOps(MI);
4443
4444 if (LV) {
4445 unsigned NumOps = MI.getNumOperands();
4446 for (unsigned I = 1; I < NumOps; ++I) {
4447 MachineOperand &Op = MI.getOperand(I);
4448 if (Op.isReg() && Op.isKill())
4449 LV->replaceKillInstruction(Op.getReg(), MI, *MIB);
4450 }
4451 }
4452
4453 if (LIS) {
4455
4456 if (MI.getOperand(0).isEarlyClobber()) {
4457 // Use operand 1 was tied to early-clobber def operand 0, so its live
4458 // interval could have ended at an early-clobber slot. Now they are not
4459 // tied we need to update it to the normal register slot.
4460 LiveInterval &LI = LIS->getInterval(MI.getOperand(1).getReg());
4462 if (S->end == Idx.getRegSlot(true))
4463 S->end = Idx.getRegSlot();
4464 }
4465 }
4466
4467 return MIB;
4468}
4469
4470#undef CASE_WIDEOP_OPCODE_COMMON
4471#undef CASE_WIDEOP_OPCODE_LMULS
4472#undef CASE_WIDEOP_CHANGE_OPCODE_COMMON
4473#undef CASE_WIDEOP_CHANGE_OPCODE_LMULS
4474#undef CASE_FP_WIDEOP_OPCODE_COMMON
4475#undef CASE_FP_WIDEOP_OPCODE_LMULS
4476#undef CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON
4477#undef CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS
4478
4481 Register DestReg, uint32_t Amount,
4482 MachineInstr::MIFlag Flag) const {
4484 if (llvm::has_single_bit<uint32_t>(Amount)) {
4485 uint32_t ShiftAmount = Log2_32(Amount);
4486 if (ShiftAmount == 0)
4487 return;
4488 BuildMI(MBB, II, DL, get(RISCV::SLLI), DestReg)
4489 .addReg(DestReg, RegState::Kill)
4490 .addImm(ShiftAmount)
4491 .setMIFlag(Flag);
4492 } else if (STI.hasStdExtZba() &&
4493 ((Amount % 3 == 0 && isPowerOf2_64(Amount / 3)) ||
4494 (Amount % 5 == 0 && isPowerOf2_64(Amount / 5)) ||
4495 (Amount % 9 == 0 && isPowerOf2_64(Amount / 9)))) {
4496 // We can use Zba SHXADD+SLLI instructions for multiply in some cases.
4497 unsigned Opc;
4498 uint32_t ShiftAmount;
4499 if (Amount % 9 == 0) {
4500 Opc = RISCV::SH3ADD;
4501 ShiftAmount = Log2_64(Amount / 9);
4502 } else if (Amount % 5 == 0) {
4503 Opc = RISCV::SH2ADD;
4504 ShiftAmount = Log2_64(Amount / 5);
4505 } else if (Amount % 3 == 0) {
4506 Opc = RISCV::SH1ADD;
4507 ShiftAmount = Log2_64(Amount / 3);
4508 } else {
4509 llvm_unreachable("implied by if-clause");
4510 }
4511 if (ShiftAmount)
4512 BuildMI(MBB, II, DL, get(RISCV::SLLI), DestReg)
4513 .addReg(DestReg, RegState::Kill)
4514 .addImm(ShiftAmount)
4515 .setMIFlag(Flag);
4516 BuildMI(MBB, II, DL, get(Opc), DestReg)
4517 .addReg(DestReg, RegState::Kill)
4518 .addReg(DestReg)
4519 .setMIFlag(Flag);
4520 } else if (llvm::has_single_bit<uint32_t>(Amount - 1)) {
4521 Register ScaledRegister = MRI.createVirtualRegister(&RISCV::GPRRegClass);
4522 uint32_t ShiftAmount = Log2_32(Amount - 1);
4523 BuildMI(MBB, II, DL, get(RISCV::SLLI), ScaledRegister)
4524 .addReg(DestReg)
4525 .addImm(ShiftAmount)
4526 .setMIFlag(Flag);
4527 BuildMI(MBB, II, DL, get(RISCV::ADD), DestReg)
4528 .addReg(ScaledRegister, RegState::Kill)
4529 .addReg(DestReg, RegState::Kill)
4530 .setMIFlag(Flag);
4531 } else if (llvm::has_single_bit<uint32_t>(Amount + 1)) {
4532 Register ScaledRegister = MRI.createVirtualRegister(&RISCV::GPRRegClass);
4533 uint32_t ShiftAmount = Log2_32(Amount + 1);
4534 BuildMI(MBB, II, DL, get(RISCV::SLLI), ScaledRegister)
4535 .addReg(DestReg)
4536 .addImm(ShiftAmount)
4537 .setMIFlag(Flag);
4538 BuildMI(MBB, II, DL, get(RISCV::SUB), DestReg)
4539 .addReg(ScaledRegister, RegState::Kill)
4540 .addReg(DestReg, RegState::Kill)
4541 .setMIFlag(Flag);
4542 } else if (STI.hasStdExtZmmul()) {
4543 Register N = MRI.createVirtualRegister(&RISCV::GPRRegClass);
4544 movImm(MBB, II, DL, N, Amount, Flag);
4545 BuildMI(MBB, II, DL, get(RISCV::MUL), DestReg)
4546 .addReg(DestReg, RegState::Kill)
4548 .setMIFlag(Flag);
4549 } else {
4550 Register Acc;
4551 uint32_t PrevShiftAmount = 0;
4552 for (uint32_t ShiftAmount = 0; Amount >> ShiftAmount; ShiftAmount++) {
4553 if (Amount & (1U << ShiftAmount)) {
4554 if (ShiftAmount)
4555 BuildMI(MBB, II, DL, get(RISCV::SLLI), DestReg)
4556 .addReg(DestReg, RegState::Kill)
4557 .addImm(ShiftAmount - PrevShiftAmount)
4558 .setMIFlag(Flag);
4559 if (Amount >> (ShiftAmount + 1)) {
4560 // If we don't have an accmulator yet, create it and copy DestReg.
4561 if (!Acc) {
4562 Acc = MRI.createVirtualRegister(&RISCV::GPRRegClass);
4563 BuildMI(MBB, II, DL, get(TargetOpcode::COPY), Acc)
4564 .addReg(DestReg)
4565 .setMIFlag(Flag);
4566 } else {
4567 BuildMI(MBB, II, DL, get(RISCV::ADD), Acc)
4568 .addReg(Acc, RegState::Kill)
4569 .addReg(DestReg)
4570 .setMIFlag(Flag);
4571 }
4572 }
4573 PrevShiftAmount = ShiftAmount;
4574 }
4575 }
4576 assert(Acc && "Expected valid accumulator");
4577 BuildMI(MBB, II, DL, get(RISCV::ADD), DestReg)
4578 .addReg(DestReg, RegState::Kill)
4579 .addReg(Acc, RegState::Kill)
4580 .setMIFlag(Flag);
4581 }
4582}
4583
4586 static const std::pair<MachineMemOperand::Flags, const char *> TargetFlags[] =
4587 {{MONontemporalBit0, "riscv-nontemporal-domain-bit-0"},
4588 {MONontemporalBit1, "riscv-nontemporal-domain-bit-1"}};
4589 return ArrayRef(TargetFlags);
4590}
4591
4593 return OptLevel >= CodeGenOptLevel::Aggressive
4595 : 2;
4596}
4597
4599 // RVV lacks any support for immediate addressing for stack addresses, so be
4600 // conservative.
4601 unsigned Opcode = MI.getOpcode();
4602 if (!RISCVVPseudosTable::getPseudoInfo(Opcode) &&
4604 return false;
4605 return true;
4606}
4607
4608std::optional<std::pair<unsigned, unsigned>>
4610 switch (Opcode) {
4611 default:
4612 return std::nullopt;
4613 case RISCV::PseudoVSPILL2_M1:
4614 case RISCV::PseudoVRELOAD2_M1:
4615 return std::make_pair(2u, 1u);
4616 case RISCV::PseudoVSPILL2_M2:
4617 case RISCV::PseudoVRELOAD2_M2:
4618 return std::make_pair(2u, 2u);
4619 case RISCV::PseudoVSPILL2_M4:
4620 case RISCV::PseudoVRELOAD2_M4:
4621 return std::make_pair(2u, 4u);
4622 case RISCV::PseudoVSPILL3_M1:
4623 case RISCV::PseudoVRELOAD3_M1:
4624 return std::make_pair(3u, 1u);
4625 case RISCV::PseudoVSPILL3_M2:
4626 case RISCV::PseudoVRELOAD3_M2:
4627 return std::make_pair(3u, 2u);
4628 case RISCV::PseudoVSPILL4_M1:
4629 case RISCV::PseudoVRELOAD4_M1:
4630 return std::make_pair(4u, 1u);
4631 case RISCV::PseudoVSPILL4_M2:
4632 case RISCV::PseudoVRELOAD4_M2:
4633 return std::make_pair(4u, 2u);
4634 case RISCV::PseudoVSPILL5_M1:
4635 case RISCV::PseudoVRELOAD5_M1:
4636 return std::make_pair(5u, 1u);
4637 case RISCV::PseudoVSPILL6_M1:
4638 case RISCV::PseudoVRELOAD6_M1:
4639 return std::make_pair(6u, 1u);
4640 case RISCV::PseudoVSPILL7_M1:
4641 case RISCV::PseudoVRELOAD7_M1:
4642 return std::make_pair(7u, 1u);
4643 case RISCV::PseudoVSPILL8_M1:
4644 case RISCV::PseudoVRELOAD8_M1:
4645 return std::make_pair(8u, 1u);
4646 }
4647}
4648
4649bool RISCV::hasEqualFRM(const MachineInstr &MI1, const MachineInstr &MI2) {
4650 int16_t MI1FrmOpIdx =
4651 RISCV::getNamedOperandIdx(MI1.getOpcode(), RISCV::OpName::frm);
4652 int16_t MI2FrmOpIdx =
4653 RISCV::getNamedOperandIdx(MI2.getOpcode(), RISCV::OpName::frm);
4654 if (MI1FrmOpIdx < 0 || MI2FrmOpIdx < 0)
4655 return false;
4656 MachineOperand FrmOp1 = MI1.getOperand(MI1FrmOpIdx);
4657 MachineOperand FrmOp2 = MI2.getOperand(MI2FrmOpIdx);
4658 return FrmOp1.getImm() == FrmOp2.getImm();
4659}
4660
4661std::optional<unsigned>
4662RISCV::getVectorLowDemandedScalarBits(unsigned Opcode, unsigned Log2SEW) {
4663 switch (Opcode) {
4664 default:
4665 return std::nullopt;
4666
4667 // 11.6. Vector Single-Width Shift Instructions
4668 case RISCV::VSLL_VX:
4669 case RISCV::VSRL_VX:
4670 case RISCV::VSRA_VX:
4671 // 12.4. Vector Single-Width Scaling Shift Instructions
4672 case RISCV::VSSRL_VX:
4673 case RISCV::VSSRA_VX:
4674 // Zvbb
4675 case RISCV::VROL_VX:
4676 case RISCV::VROR_VX:
4677 // Only the low lg2(SEW) bits of the shift-amount value are used.
4678 return Log2SEW;
4679
4680 // 11.7 Vector Narrowing Integer Right Shift Instructions
4681 case RISCV::VNSRL_WX:
4682 case RISCV::VNSRA_WX:
4683 // 12.5. Vector Narrowing Fixed-Point Clip Instructions
4684 case RISCV::VNCLIPU_WX:
4685 case RISCV::VNCLIP_WX:
4686 // Zvbb
4687 case RISCV::VWSLL_VX:
4688 // Only the low lg2(2*SEW) bits of the shift-amount value are used.
4689 return Log2SEW + 1;
4690
4691 // 11.1. Vector Single-Width Integer Add and Subtract
4692 case RISCV::VADD_VX:
4693 case RISCV::VSUB_VX:
4694 case RISCV::VRSUB_VX:
4695 // 11.2. Vector Widening Integer Add/Subtract
4696 case RISCV::VWADDU_VX:
4697 case RISCV::VWSUBU_VX:
4698 case RISCV::VWADD_VX:
4699 case RISCV::VWSUB_VX:
4700 case RISCV::VWADDU_WX:
4701 case RISCV::VWSUBU_WX:
4702 case RISCV::VWADD_WX:
4703 case RISCV::VWSUB_WX:
4704 // 11.4. Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions
4705 case RISCV::VADC_VXM:
4706 case RISCV::VADC_VIM:
4707 case RISCV::VMADC_VXM:
4708 case RISCV::VMADC_VIM:
4709 case RISCV::VMADC_VX:
4710 case RISCV::VSBC_VXM:
4711 case RISCV::VMSBC_VXM:
4712 case RISCV::VMSBC_VX:
4713 // 11.5 Vector Bitwise Logical Instructions
4714 case RISCV::VAND_VX:
4715 case RISCV::VOR_VX:
4716 case RISCV::VXOR_VX:
4717 // 11.8. Vector Integer Compare Instructions
4718 case RISCV::VMSEQ_VX:
4719 case RISCV::VMSNE_VX:
4720 case RISCV::VMSLTU_VX:
4721 case RISCV::VMSLT_VX:
4722 case RISCV::VMSLEU_VX:
4723 case RISCV::VMSLE_VX:
4724 case RISCV::VMSGTU_VX:
4725 case RISCV::VMSGT_VX:
4726 // 11.9. Vector Integer Min/Max Instructions
4727 case RISCV::VMINU_VX:
4728 case RISCV::VMIN_VX:
4729 case RISCV::VMAXU_VX:
4730 case RISCV::VMAX_VX:
4731 // 11.10. Vector Single-Width Integer Multiply Instructions
4732 case RISCV::VMUL_VX:
4733 case RISCV::VMULH_VX:
4734 case RISCV::VMULHU_VX:
4735 case RISCV::VMULHSU_VX:
4736 // 11.11. Vector Integer Divide Instructions
4737 case RISCV::VDIVU_VX:
4738 case RISCV::VDIV_VX:
4739 case RISCV::VREMU_VX:
4740 case RISCV::VREM_VX:
4741 // 11.12. Vector Widening Integer Multiply Instructions
4742 case RISCV::VWMUL_VX:
4743 case RISCV::VWMULU_VX:
4744 case RISCV::VWMULSU_VX:
4745 // 11.13. Vector Single-Width Integer Multiply-Add Instructions
4746 case RISCV::VMACC_VX:
4747 case RISCV::VNMSAC_VX:
4748 case RISCV::VMADD_VX:
4749 case RISCV::VNMSUB_VX:
4750 // 11.14. Vector Widening Integer Multiply-Add Instructions
4751 case RISCV::VWMACCU_VX:
4752 case RISCV::VWMACC_VX:
4753 case RISCV::VWMACCSU_VX:
4754 case RISCV::VWMACCUS_VX:
4755 // 11.15. Vector Integer Merge Instructions
4756 case RISCV::VMERGE_VXM:
4757 // 11.16. Vector Integer Move Instructions
4758 case RISCV::VMV_V_X:
4759 // 12.1. Vector Single-Width Saturating Add and Subtract
4760 case RISCV::VSADDU_VX:
4761 case RISCV::VSADD_VX:
4762 case RISCV::VSSUBU_VX:
4763 case RISCV::VSSUB_VX:
4764 // 12.2. Vector Single-Width Averaging Add and Subtract
4765 case RISCV::VAADDU_VX:
4766 case RISCV::VAADD_VX:
4767 case RISCV::VASUBU_VX:
4768 case RISCV::VASUB_VX:
4769 // 12.3. Vector Single-Width Fractional Multiply with Rounding and Saturation
4770 case RISCV::VSMUL_VX:
4771 // 16.1. Integer Scalar Move Instructions
4772 case RISCV::VMV_S_X:
4773 // Zvbb
4774 case RISCV::VANDN_VX:
4775 return 1U << Log2SEW;
4776 }
4777}
4778
4779unsigned RISCV::getRVVMCOpcode(unsigned RVVPseudoOpcode) {
4781 RISCVVPseudosTable::getPseudoInfo(RVVPseudoOpcode);
4782 if (!RVV)
4783 return 0;
4784 return RVV->BaseInstr;
4785}
4786
4787unsigned RISCV::getDestLog2EEW(const MCInstrDesc &Desc, unsigned Log2SEW) {
4788 unsigned DestEEW =
4790 // EEW = 1
4791 if (DestEEW == 0)
4792 return 0;
4793 // EEW = SEW * n
4794 unsigned Scaled = Log2SEW + (DestEEW - 1);
4795 assert(Scaled >= 3 && Scaled <= 6);
4796 return Scaled;
4797}
4798
4799/// Given two VL operands, do we know that LHS <= RHS?
4801 if (LHS.isReg() && RHS.isReg() && LHS.getReg().isVirtual() &&
4802 LHS.getReg() == RHS.getReg())
4803 return true;
4804 if (RHS.isImm() && RHS.getImm() == RISCV::VLMaxSentinel)
4805 return true;
4806 if (LHS.isImm() && LHS.getImm() == 0)
4807 return true;
4808 if (LHS.isImm() && LHS.getImm() == RISCV::VLMaxSentinel)
4809 return false;
4810 if (!LHS.isImm() || !RHS.isImm())
4811 return false;
4812 return LHS.getImm() <= RHS.getImm();
4813}
4814
4815namespace {
4816class RISCVPipelinerLoopInfo : public TargetInstrInfo::PipelinerLoopInfo {
4817 const MachineInstr *LHS;
4818 const MachineInstr *RHS;
4820
4821public:
4822 RISCVPipelinerLoopInfo(const MachineInstr *LHS, const MachineInstr *RHS,
4824 : LHS(LHS), RHS(RHS), Cond(Cond.begin(), Cond.end()) {}
4825
4826 bool shouldIgnoreForPipelining(const MachineInstr *MI) const override {
4827 // Make the instructions for loop control be placed in stage 0.
4828 // The predecessors of LHS/RHS are considered by the caller.
4829 if (LHS && MI == LHS)
4830 return true;
4831 if (RHS && MI == RHS)
4832 return true;
4833 return false;
4834 }
4835
4836 std::optional<bool> createTripCountGreaterCondition(
4837 int TC, MachineBasicBlock &MBB,
4838 SmallVectorImpl<MachineOperand> &CondParam) override {
4839 // A branch instruction will be inserted as "if (Cond) goto epilogue".
4840 // Cond is normalized for such use.
4841 // The predecessors of the branch are assumed to have already been inserted.
4842 CondParam = Cond;
4843 return {};
4844 }
4845
4846 void setPreheader(MachineBasicBlock *NewPreheader) override {}
4847
4848 void adjustTripCount(int TripCountAdjust) override {}
4849};
4850} // namespace
4851
4852std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
4854 MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
4856 if (analyzeBranch(*LoopBB, TBB, FBB, Cond, /*AllowModify=*/false))
4857 return nullptr;
4858
4859 // Infinite loops are not supported
4860 if (TBB == LoopBB && FBB == LoopBB)
4861 return nullptr;
4862
4863 // Must be conditional branch
4864 if (FBB == nullptr)
4865 return nullptr;
4866
4867 assert((TBB == LoopBB || FBB == LoopBB) &&
4868 "The Loop must be a single-basic-block loop");
4869
4870 // Normalization for createTripCountGreaterCondition()
4871 if (TBB == LoopBB)
4873
4874 const MachineRegisterInfo &MRI = LoopBB->getParent()->getRegInfo();
4875 auto FindRegDef = [&MRI](MachineOperand &Op) -> const MachineInstr * {
4876 if (!Op.isReg())
4877 return nullptr;
4878 Register Reg = Op.getReg();
4879 if (!Reg.isVirtual())
4880 return nullptr;
4881 return MRI.getVRegDef(Reg);
4882 };
4883
4884 const MachineInstr *LHS = FindRegDef(Cond[1]);
4885 const MachineInstr *RHS = FindRegDef(Cond[2]);
4886 if (LHS && LHS->isPHI())
4887 return nullptr;
4888 if (RHS && RHS->isPHI())
4889 return nullptr;
4890
4891 return std::make_unique<RISCVPipelinerLoopInfo>(LHS, RHS, Cond);
4892}
4893
4894// FIXME: We should remove this if we have a default generic scheduling model.
4896 unsigned RVVMCOpcode = RISCV::getRVVMCOpcode(Opc);
4897 Opc = RVVMCOpcode ? RVVMCOpcode : Opc;
4898 switch (Opc) {
4899 default:
4900 return false;
4901 // Integer div/rem.
4902 case RISCV::DIV:
4903 case RISCV::DIVW:
4904 case RISCV::DIVU:
4905 case RISCV::DIVUW:
4906 case RISCV::REM:
4907 case RISCV::REMW:
4908 case RISCV::REMU:
4909 case RISCV::REMUW:
4910 // Floating-point div/sqrt.
4911 case RISCV::FDIV_H:
4912 case RISCV::FDIV_S:
4913 case RISCV::FDIV_D:
4914 case RISCV::FDIV_H_INX:
4915 case RISCV::FDIV_S_INX:
4916 case RISCV::FDIV_D_INX:
4917 case RISCV::FDIV_D_IN32X:
4918 case RISCV::FSQRT_H:
4919 case RISCV::FSQRT_S:
4920 case RISCV::FSQRT_D:
4921 case RISCV::FSQRT_H_INX:
4922 case RISCV::FSQRT_S_INX:
4923 case RISCV::FSQRT_D_INX:
4924 case RISCV::FSQRT_D_IN32X:
4925 // Vector integer div/rem
4926 case RISCV::VDIV_VV:
4927 case RISCV::VDIV_VX:
4928 case RISCV::VDIVU_VV:
4929 case RISCV::VDIVU_VX:
4930 case RISCV::VREM_VV:
4931 case RISCV::VREM_VX:
4932 case RISCV::VREMU_VV:
4933 case RISCV::VREMU_VX:
4934 // Vector floating-point div/sqrt.
4935 case RISCV::VFDIV_VV:
4936 case RISCV::VFDIV_VF:
4937 case RISCV::VFRDIV_VF:
4938 case RISCV::VFSQRT_V:
4939 case RISCV::VFRSQRT7_V:
4940 return true;
4941 }
4942}
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder MachineInstrBuilder & DefMI
static bool forwardCopyWillClobberTuple(unsigned DestReg, unsigned SrcReg, unsigned NumRegs)
static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target, SmallVectorImpl< MachineOperand > &Cond)
@ MachineOutlinerTailCall
Emit a save, restore, call, and return.
@ MachineOutlinerDefault
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
@ Scaled
static ARCCC::CondCode getOppositeBranchCondition(ARCCC::CondCode CC)
Return the inverse of passed condition, i.e. turning COND_E to COND_NE.
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
Definition: CommandLine.h:687
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
uint64_t Size
bool End
Definition: ELF_riscv.cpp:480
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
const HexagonInstrInfo * TII
#define _
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
Register const TargetRegisterInfo * TRI
This file provides utility analysis objects describing memory locations.
MachineInstr unsigned OpIdx
uint64_t IntrinsicInst * II
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
static bool cannotInsertTailCall(const MachineBasicBlock &MBB)
#define CASE_VFMA_CHANGE_OPCODE_SPLATS(OLDOP, NEWOP)
#define CASE_FP_WIDEOP_OPCODE_LMULS(OP)
#define CASE_OPERAND_SIMM(NUM)
static std::optional< unsigned > getLMULForRVVWholeLoadStore(unsigned Opcode)
#define CASE_VFMA_CHANGE_OPCODE_VV(OLDOP, NEWOP)
static bool analyzeCandidate(outliner::Candidate &C)
static unsigned getFPFusedMultiplyOpcode(unsigned RootOpc, unsigned Pattern)
std::optional< unsigned > getFoldedOpcode(MachineFunction &MF, MachineInstr &MI, ArrayRef< unsigned > Ops, const RISCVSubtarget &ST)
#define RVV_OPC_LMUL_CASE(OPC, INV)
#define CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS(OP)
static void combineFPFusedMultiply(MachineInstr &Root, MachineInstr &Prev, unsigned Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs)
static unsigned getAddendOperandIdx(unsigned Pattern)
#define CASE_RVV_OPCODE_UNMASK(OP)
#define CASE_WIDEOP_CHANGE_OPCODE_LMULS(OP)
static cl::opt< bool > PreferWholeRegisterMove("riscv-prefer-whole-register-move", cl::init(false), cl::Hidden, cl::desc("Prefer whole register move for vector registers."))
#define CASE_VFMA_SPLATS(OP)
unsigned getPredicatedOpcode(unsigned Opcode)
#define CASE_WIDEOP_OPCODE_LMULS(OP)
static bool isMIReadsReg(const MachineInstr &MI, const TargetRegisterInfo *TRI, MCRegister RegNo)
#define OPCODE_LMUL_MASK_CASE(OPC)
static bool isFSUB(unsigned Opc)
#define CASE_VMA_CHANGE_OPCODE_LMULS(OLDOP, NEWOP, TYPE)
#define CASE_RVV_OPCODE(OP)
#define CASE_VFMA_OPCODE_VV(OP)
MachineOutlinerConstructionID
#define CASE_RVV_OPCODE_WIDEN(OP)
static unsigned getSHXADDUWShiftAmount(unsigned Opc)
#define CASE_VMA_OPCODE_LMULS(OP, TYPE)
static bool isConvertibleToVMV_V_V(const RISCVSubtarget &STI, const MachineBasicBlock &MBB, MachineBasicBlock::const_iterator MBBI, MachineBasicBlock::const_iterator &DefMBBI, RISCVVType::VLMUL LMul)
static bool isFMUL(unsigned Opc)
static bool getFPPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce)
#define OPCODE_LMUL_CASE(OPC)
#define CASE_OPERAND_UIMM(NUM)
static bool canCombineShiftIntoShXAdd(const MachineBasicBlock &MBB, const MachineOperand &MO, unsigned OuterShiftAmt)
Utility routine that checks if.
static bool isCandidatePatchable(const MachineBasicBlock &MBB)
static bool isFADD(unsigned Opc)
static void genShXAddAddShift(MachineInstr &Root, unsigned AddOpIdx, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs, DenseMap< Register, unsigned > &InstrIdxForVirtReg)
static bool isLoadImm(const MachineInstr *MI, int64_t &Imm)
static bool isMIModifiesReg(const MachineInstr &MI, const TargetRegisterInfo *TRI, MCRegister RegNo)
static MachineInstr * canFoldAsPredicatedOp(Register Reg, const MachineRegisterInfo &MRI, const TargetInstrInfo *TII)
Identify instructions that can be folded into a CCMOV instruction, and return the defining instructio...
static bool canCombineFPFusedMultiply(const MachineInstr &Root, const MachineOperand &MO, bool DoRegPressureReduce)
static bool getSHXADDPatterns(const MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns)
static bool getFPFusedMultiplyPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce)
static cl::opt< MachineTraceStrategy > ForceMachineCombinerStrategy("riscv-force-machine-combiner-strategy", cl::Hidden, cl::desc("Force machine combiner to use a specific strategy for machine " "trace metrics evaluation."), cl::init(MachineTraceStrategy::TS_NumStrategies), cl::values(clEnumValN(MachineTraceStrategy::TS_Local, "local", "Local strategy."), clEnumValN(MachineTraceStrategy::TS_MinInstrCount, "min-instr", "MinInstrCount strategy.")))
static unsigned getSHXADDShiftAmount(unsigned Opc)
#define CASE_RVV_OPCODE_MASK(OP)
#define RVV_OPC_LMUL_MASK_CASE(OPC, INV)
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file declares the machine register scavenger class.
static bool memOpsHaveSameBasePtr(const MachineInstr &MI1, ArrayRef< const MachineOperand * > BaseOps1, const MachineInstr &MI2, ArrayRef< const MachineOperand * > BaseOps2)
This file contains some templates that are useful if you are working with the STL at all.
raw_pwrite_stream & OS
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition: Value.cpp:480
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition: Statistic.h:167
static bool canCombine(MachineBasicBlock &MBB, MachineOperand &MO, unsigned CombineOpc=0)
static cl::opt< unsigned > CacheLineSize("cache-line-size", cl::init(0), cl::Hidden, cl::desc("Use this to override the target cache line size when " "specified by the user."))
Value * RHS
Value * LHS
static unsigned getSize(unsigned Kind)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
const T & front() const
front - Get the first element.
Definition: ArrayRef.h:150
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:147
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:142
static LLVM_ABI DILocation * getMergedLocation(DILocation *LocA, DILocation *LocB)
Attempts to merge LocA and LocB into a single location; see DebugLoc::getMergedLocation for more deta...
This class represents an Operation in the Expression.
bool isBigEndian() const
Definition: DataLayout.h:199
A debug info location.
Definition: DebugLoc.h:124
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:230
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
Definition: Function.h:703
LiveInterval - This class represents the liveness of a register, or stack slot.
Definition: LiveInterval.h:690
LiveInterval & getInterval(Register Reg)
SlotIndex ReplaceMachineInstrInMaps(MachineInstr &MI, MachineInstr &NewMI)
const Segment * getSegmentContaining(SlotIndex Idx) const
Return the segment that contains the specified index, or null if there is none.
Definition: LiveInterval.h:410
LLVM_ABI void replaceKillInstruction(Register Reg, MachineInstr &OldMI, MachineInstr &NewMI)
replaceKillInstruction - Update register kill info by replacing a kill instruction with a new one.
bool hasValue() const
static LocationSize precise(uint64_t Value)
TypeSize getValue() const
MCInstBuilder & addReg(MCRegister Reg)
Add a new register operand.
Definition: MCInstBuilder.h:37
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
Definition: MCInstBuilder.h:43
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:188
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:199
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
Definition: MCInstrDesc.h:238
bool isConditionalBranch() const
Return true if this is a branch which may fall through to the next instruction or may transfer contro...
Definition: MCInstrDesc.h:318
This holds information about one operand of a machine instruction, indicating the register class for ...
Definition: MCInstrDesc.h:86
uint8_t OperandType
Information about the type of the operand.
Definition: MCInstrDesc.h:98
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
const FeatureBitset & getFeatureBits() const
Set of metadata that should be preserved when using BuildMI().
unsigned pred_size() const
reverse_iterator rend()
LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
LLVM_ABI DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.
LLVM_ABI iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
Instructions::const_iterator const_instr_iterator
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
void setStackID(int ObjectIdx, uint8_t ID)
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & setMemRefs(ArrayRef< MachineMemOperand * > MMOs) const
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & copyImplicitOps(const MachineInstr &OtherMI) const
Copy all the implicit operands from OtherMI onto this one.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
reverse_iterator getReverse() const
Get a reverse iterator to the same node.
Representation of each machine instruction.
Definition: MachineInstr.h:72
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:587
bool isReturn(QueryType Type=AnyInBundle) const
Definition: MachineInstr.h:938
bool mayLoadOrStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read or modify memory.
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:359
bool getFlag(MIFlag Flag) const
Return whether an MI flag is set.
Definition: MachineInstr.h:409
LLVM_ABI unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
bool modifiesRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr modifies (fully define or partially define) the specified register.
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
Definition: MachineInstr.h:584
LLVM_ABI bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore,...
bool hasOneMemOperand() const
Return true if this instruction has exactly one MachineMemOperand.
Definition: MachineInstr.h:813
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
Definition: MachineInstr.h:798
LLVM_ABI bool hasOrderedMemoryRef() const
Return true if this instruction may have an ordered or volatile memory reference, or if the informati...
LLVM_ABI const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
ArrayRef< MachineMemOperand * > memoperands() const
Access to memory operands of the instruction.
Definition: MachineInstr.h:780
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:511
LLVM_ABI void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:595
uint32_t getFlags() const
Return the MI flags bitvector.
Definition: MachineInstr.h:404
LLVM_ABI void clearKillInfo()
Clears kill flags on all operands.
A description of a memory reference used in the backend.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
This class contains meta information specific to a module.
MachineOperand class - Representation of each machine instruction operand.
int64_t getImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
static MachineOperand CreateImm(int64_t Val)
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
Register getReg() const
getReg - Returns the register number.
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
LLVM_ABI bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
@ MO_Immediate
Immediate operand.
@ MO_Register
Register operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
MI-level patchpoint operands.
Definition: StackMaps.h:77
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given patchpoint should emit.
Definition: StackMaps.h:105
MachineInstr * convertToThreeAddress(MachineInstr &MI, LiveVariables *LV, LiveIntervals *LIS) const override
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
std::optional< std::unique_ptr< outliner::OutlinedFunction > > getOutliningCandidateInfo(const MachineModuleInfo &MMI, std::vector< outliner::Candidate > &RepeatedSequenceLocs, unsigned MinRepeats) const override
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
void genAlternativeCodeSequence(MachineInstr &Root, unsigned Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs, DenseMap< Register, unsigned > &InstrIdxForVirtReg) const override
void movImm(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, Register DstReg, uint64_t Val, MachineInstr::MIFlag Flag=MachineInstr::NoFlags, bool DstRenamable=false, bool DstIsDead=false) const
MachineInstr * emitLdStWithAddr(MachineInstr &MemI, const ExtAddrMode &AM) const override
void mulImm(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator II, const DebugLoc &DL, Register DestReg, uint32_t Amt, MachineInstr::MIFlag Flag) const
Generate code to multiply the value in DestReg by Amt - handles all the common optimizations for this...
static bool isPairableLdStInstOpc(unsigned Opc)
Return true if pairing the given load or store may be paired with another.
bool isReallyTriviallyReMaterializable(const MachineInstr &MI) const override
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool IsKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
bool isFunctionSafeToOutlineFrom(MachineFunction &MF, bool OutlineFromLinkOnceODRs) const override
std::unique_ptr< TargetInstrInfo::PipelinerLoopInfo > analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const override
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &dl, int *BytesAdded=nullptr) const override
bool hasReassociableSibling(const MachineInstr &Inst, bool &Commuted) const override
RISCVInstrInfo(RISCVSubtarget &STI)
static bool isLdStSafeToPair(const MachineInstr &LdSt, const TargetRegisterInfo *TRI)
void copyPhysRegVector(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, MCRegister DstReg, MCRegister SrcReg, bool KillSrc, const TargetRegisterClass *RegClass) const
MachineInstr * optimizeSelect(MachineInstr &MI, SmallPtrSetImpl< MachineInstr * > &SeenMIs, bool) const override
bool canFoldIntoAddrMode(const MachineInstr &MemI, Register Reg, const MachineInstr &AddrI, ExtAddrMode &AM) const override
void insertIndirectBranch(MachineBasicBlock &MBB, MachineBasicBlock &NewDestBB, MachineBasicBlock &RestoreBB, const DebugLoc &DL, int64_t BrOffset, RegScavenger *RS) const override
bool isAsCheapAsAMove(const MachineInstr &MI) const override
bool verifyInstruction(const MachineInstr &MI, StringRef &ErrInfo) const override
bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt, const MachineOperand *&BaseOp, int64_t &Offset, LocationSize &Width, const TargetRegisterInfo *TRI) const
unsigned getTailDuplicateSize(CodeGenOptLevel OptLevel) const override
void getReassociateOperandIndices(const MachineInstr &Root, unsigned Pattern, std::array< unsigned, 5 > &OperandIndices) const override
const RISCVSubtarget & STI
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
std::optional< unsigned > getInverseOpcode(unsigned Opcode) const override
bool simplifyInstruction(MachineInstr &MI) const override
ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override
outliner::InstrType getOutliningTypeImpl(const MachineModuleInfo &MMI, MachineBasicBlock::iterator &MBBI, unsigned Flags) const override
MachineTraceStrategy getMachineCombinerTraceStrategy() const override
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
std::optional< RegImmPair > isAddImmediate(const MachineInstr &MI, Register Reg) const override
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
ArrayRef< std::pair< MachineMemOperand::Flags, const char * > > getSerializableMachineMemOperandTargetFlags() const override
MCInst getNop() const override
MachineInstr * foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, ArrayRef< unsigned > Ops, MachineBasicBlock::iterator InsertPt, int FrameIndex, LiveIntervals *LIS=nullptr, VirtRegMap *VRM=nullptr) const override
bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB, unsigned &Flags) const override
bool getMemOperandsWithOffsetWidth(const MachineInstr &MI, SmallVectorImpl< const MachineOperand * > &BaseOps, int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width, const TargetRegisterInfo *TRI) const override
void buildOutlinedFrame(MachineBasicBlock &MBB, MachineFunction &MF, const outliner::OutlinedFunction &OF) const override
void finalizeInsInstrs(MachineInstr &Root, unsigned &Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs) const override
std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override
MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DstReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
bool hasReassociableOperands(const MachineInstr &Inst, const MachineBasicBlock *MBB) const override
MachineBasicBlock * getBranchDestBlock(const MachineInstr &MI) const override
std::string createMIROperandComment(const MachineInstr &MI, const MachineOperand &Op, unsigned OpIdx, const TargetRegisterInfo *TRI) const override
bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, Register DstReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const override
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
MachineBasicBlock::iterator insertOutlinedCall(Module &M, MachineBasicBlock &MBB, MachineBasicBlock::iterator &It, MachineFunction &MF, outliner::Candidate &C) const override
bool isBranchOffsetInRange(unsigned BranchOpc, int64_t BrOffset) const override
static RISCVCC::CondCode getCondFromBranchOpc(unsigned Opc)
bool isAssociativeAndCommutative(const MachineInstr &Inst, bool Invert) const override
CombinerObjective getCombinerObjective(unsigned Pattern) const override
bool isHighLatencyDef(int Opc) const override
static bool evaluateCondBranch(RISCVCC::CondCode CC, int64_t C0, int64_t C1)
Return the result of the evaluation of C0 CC C1, where CC is a RISCVCC::CondCode.
bool getMachineCombinerPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce) const override
bool optimizeCondBranch(MachineInstr &MI) const override
std::optional< DestSourcePair > isCopyInstrImpl(const MachineInstr &MI) const override
bool analyzeSelect(const MachineInstr &MI, SmallVectorImpl< MachineOperand > &Cond, unsigned &TrueOp, unsigned &FalseOp, bool &Optimizable) const override
static bool isFromLoadImm(const MachineRegisterInfo &MRI, const MachineOperand &Op, int64_t &Imm)
Return true if the operand is a load immediate instruction and sets Imm to the immediate value.
bool shouldClusterMemOps(ArrayRef< const MachineOperand * > BaseOps1, int64_t Offset1, bool OffsetIsScalable1, ArrayRef< const MachineOperand * > BaseOps2, int64_t Offset2, bool OffsetIsScalable2, unsigned ClusterSize, unsigned NumBytes) const override
bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, const MachineInstr &MIb) const override
RISCVMachineFunctionInfo - This class is derived from MachineFunctionInfo and contains private RISCV-...
unsigned getTailDupAggressiveThreshold() const
unsigned getXLen() const
const RISCVRegisterInfo * getRegisterInfo() const override
void enterBasicBlockEnd(MachineBasicBlock &MBB)
Start tracking liveness from the end of basic block MBB.
void setRegUsed(Register Reg, LaneBitmask LaneMask=LaneBitmask::getAll())
Tell the scavenger a register is used.
Register scavengeRegisterBackwards(const TargetRegisterClass &RC, MachineBasicBlock::iterator To, bool RestoreAfter, int SPAdj, bool AllowSpill=true)
Make a register of the specific register class available from the current position backwards to the p...
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
constexpr bool isValid() const
Definition: Register.h:107
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:74
SlotIndex - An opaque wrapper around machine indexes.
Definition: SlotIndexes.h:66
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
Definition: SmallPtrSet.h:380
bool erase(PtrType Ptr)
Remove pointer from the set.
Definition: SmallPtrSet.h:418
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:401
bool empty() const
Definition: SmallVector.h:82
size_t size() const
Definition: SmallVector.h:79
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:574
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
MI-level stackmap operands.
Definition: StackMaps.h:36
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given stackmap should emit.
Definition: StackMaps.h:51
MI-level Statepoint operands.
Definition: StackMaps.h:159
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given statepoint should emit.
Definition: StackMaps.h:208
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
Object returned by analyzeLoopForPipelining.
TargetInstrInfo - Interface to description of machine instruction set.
virtual bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const
Returns true iff the routine could find two commutable operands in the given machine instruction.
virtual bool hasReassociableOperands(const MachineInstr &Inst, const MachineBasicBlock *MBB) const
Return true when \P Inst has reassociable operands in the same \P MBB.
virtual void genAlternativeCodeSequence(MachineInstr &Root, unsigned Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs, DenseMap< Register, unsigned > &InstIdxForVirtReg) const
When getMachineCombinerPatterns() finds patterns, this function generates the instructions that could...
virtual bool getMachineCombinerPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce) const
Return true when there is potentially a faster code sequence for an instruction chain ending in Root.
virtual bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB, unsigned &Flags) const
Optional target hook that returns true if MBB is safe to outline from, and returns any target-specifi...
virtual void getReassociateOperandIndices(const MachineInstr &Root, unsigned Pattern, std::array< unsigned, 5 > &OperandIndices) const
The returned array encodes the operand index for each parameter because the operands may be commuted;...
virtual bool isReallyTriviallyReMaterializable(const MachineInstr &MI) const
For instructions with opcodes for which the M_REMATERIALIZABLE flag is set, this hook lets the target...
virtual CombinerObjective getCombinerObjective(unsigned Pattern) const
Return the objective of a combiner pattern.
virtual MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const
This method commutes the operands of the given machine instruction MI.
virtual bool hasReassociableSibling(const MachineInstr &Inst, bool &Commuted) const
Return true when \P Inst has reassociable sibling.
virtual std::string createMIROperandComment(const MachineInstr &MI, const MachineOperand &Op, unsigned OpIdx, const TargetRegisterInfo *TRI) const
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
const uint8_t TSFlags
Configurable target specific flags.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
Target - Wrapper for Target specific information.
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition: TypeSize.h:346
static constexpr TypeSize getZero()
Definition: TypeSize.h:352
static constexpr TypeSize getScalable(ScalarTy MinimumSize)
Definition: TypeSize.h:349
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:662
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
CondCode getOppositeBranchCondition(CondCode)
unsigned getBrCond(CondCode CC, unsigned SelectOpc=0)
static bool isValidRoundingMode(unsigned Mode)
static unsigned getVecPolicyOpNum(const MCInstrDesc &Desc)
static bool usesMaskPolicy(uint64_t TSFlags)
static bool hasRoundModeOp(uint64_t TSFlags)
static unsigned getVLOpNum(const MCInstrDesc &Desc)
static bool hasVLOp(uint64_t TSFlags)
static MCRegister getTailExpandUseRegNo(const FeatureBitset &FeatureBits)
static int getFRMOpNum(const MCInstrDesc &Desc)
static bool hasVecPolicyOp(uint64_t TSFlags)
static bool usesVXRM(uint64_t TSFlags)
static bool isRVVWideningReduction(uint64_t TSFlags)
static unsigned getSEWOpNum(const MCInstrDesc &Desc)
static bool hasSEWOp(uint64_t TSFlags)
static bool isFirstDefTiedToFirstUse(const MCInstrDesc &Desc)
InstSeq generateInstSeq(int64_t Val, const MCSubtargetInfo &STI)
@ OPERAND_UIMMLOG2XLEN_NONZERO
@ OPERAND_UIMM10_LSB00_NONZERO
@ OPERAND_SIMM10_LSB0000_NONZERO
static unsigned getNF(uint8_t TSFlags)
static RISCVVType::VLMUL getLMul(uint8_t TSFlags)
static bool isTailAgnostic(unsigned VType)
LLVM_ABI std::pair< unsigned, bool > decodeVLMUL(VLMUL VLMul)
static bool isValidSEW(unsigned SEW)
LLVM_ABI void printVType(unsigned VType, raw_ostream &OS)
static unsigned getSEW(unsigned VType)
static VLMUL getVLMUL(unsigned VType)
bool hasEqualFRM(const MachineInstr &MI1, const MachineInstr &MI2)
bool isVLKnownLE(const MachineOperand &LHS, const MachineOperand &RHS)
Given two VL operands, do we know that LHS <= RHS?
unsigned getRVVMCOpcode(unsigned RVVPseudoOpcode)
unsigned getDestLog2EEW(const MCInstrDesc &Desc, unsigned Log2SEW)
std::optional< unsigned > getVectorLowDemandedScalarBits(unsigned Opcode, unsigned Log2SEW)
std::optional< std::pair< unsigned, unsigned > > isRVVSpillForZvlsseg(unsigned Opcode)
static constexpr unsigned RVVBitsPerBlock
bool isRVVSpill(const MachineInstr &MI)
static constexpr unsigned RVVBytesPerBlock
static constexpr int64_t VLMaxSentinel
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Dead
Unused definition.
@ Define
Register definition.
@ Kill
The last use of a register.
@ Undef
Value of the register doesn't matter.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
Definition: CommandLine.h:712
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:444
InstrType
Represents how an instruction should be mapped by the outliner.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:338
@ Offset
Definition: DWP.cpp:477
@ SHXADD_ADD_SLLI_OP2
@ FMADD_AX
@ FMADD_XA
@ SHXADD_ADD_SLLI_OP1
MachineTraceStrategy
Strategies for selecting traces.
@ TS_MinInstrCount
Select the trace through a block that has the fewest instructions.
@ TS_Local
Select the trace that contains only the current basic block.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1744
static const MachineMemOperand::Flags MONontemporalBit1
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition: STLExtras.h:2491
static const MachineMemOperand::Flags MONontemporalBit0
unsigned getDeadRegState(bool B)
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition: MathExtras.h:293
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition: MathExtras.h:342
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1751
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:336
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
Definition: SPIRVUtils.cpp:976
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition: Error.cpp:167
CombinerObjective
The combiner's goal may differ based on which pattern it is attempting to optimize.
CodeGenOptLevel
Code generation optimization level.
Definition: CodeGen.h:82
unsigned getKillRegState(bool B)
unsigned getRenamableRegState(bool B)
DWARFExpression::Operation Op
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Definition: STLExtras.h:2139
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:577
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:858
#define N
Description of the encoding of one expression Op.
Used to describe addressing mode similar to ExtAddrMode in CodeGenPrepare.
This represents a simple continuous liveness interval for a value.
Definition: LiveInterval.h:163
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
static bool isRVVRegClass(const TargetRegisterClass *RC)
Used to describe a register and immediate addition.
An individual sequence of instructions to be replaced with a call to an outlined function.
MachineFunction * getMF() const
The information necessary to create an outlined function for some class of candidate.