LLVM 23.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"
34#include "llvm/MC/MCDwarf.h"
38
39using namespace llvm;
40
41#define GEN_CHECK_COMPRESS_INSTR
42#include "RISCVGenCompressInstEmitter.inc"
43
44#define GET_INSTRINFO_CTOR_DTOR
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."),
63 "Local strategy."),
65 "MinInstrCount strategy.")));
66
68 "riscv-outliner-regsave", cl::init(true), cl::Hidden,
69 cl::desc("Enable RegSave strategy in machine outliner (save X5 to a "
70 "temporary register when X5 is live across outlined calls)."));
71
73
74using namespace RISCV;
75
76#define GET_RISCVVPseudosTable_IMPL
77#include "RISCVGenSearchableTables.inc"
78
79} // namespace llvm::RISCVVPseudosTable
80
81namespace llvm::RISCV {
82
83#define GET_RISCVMaskedPseudosTable_IMPL
84#include "RISCVGenSearchableTables.inc"
85
86} // end namespace llvm::RISCV
87
89 : RISCVGenInstrInfo(STI, RegInfo, RISCV::ADJCALLSTACKDOWN,
90 RISCV::ADJCALLSTACKUP),
91 RegInfo(STI.getHwMode()), STI(STI) {}
92
93#define GET_INSTRINFO_HELPERS
94#include "RISCVGenInstrInfo.inc"
95
97 if (STI.hasStdExtZca())
98 return MCInstBuilder(RISCV::C_NOP);
99 return MCInstBuilder(RISCV::ADDI)
100 .addReg(RISCV::X0)
101 .addReg(RISCV::X0)
102 .addImm(0);
103}
104
106 int &FrameIndex) const {
107 TypeSize Dummy = TypeSize::getZero();
108 return isLoadFromStackSlot(MI, FrameIndex, Dummy);
109}
110
111static std::optional<unsigned> getLMULForRVVWholeLoadStore(unsigned Opcode) {
112 switch (Opcode) {
113 default:
114 return std::nullopt;
115 case RISCV::VS1R_V:
116 case RISCV::VL1RE8_V:
117 case RISCV::VL1RE16_V:
118 case RISCV::VL1RE32_V:
119 case RISCV::VL1RE64_V:
120 return 1;
121 case RISCV::VS2R_V:
122 case RISCV::VL2RE8_V:
123 case RISCV::VL2RE16_V:
124 case RISCV::VL2RE32_V:
125 case RISCV::VL2RE64_V:
126 return 2;
127 case RISCV::VS4R_V:
128 case RISCV::VL4RE8_V:
129 case RISCV::VL4RE16_V:
130 case RISCV::VL4RE32_V:
131 case RISCV::VL4RE64_V:
132 return 4;
133 case RISCV::VS8R_V:
134 case RISCV::VL8RE8_V:
135 case RISCV::VL8RE16_V:
136 case RISCV::VL8RE32_V:
137 case RISCV::VL8RE64_V:
138 return 8;
139 }
140}
141
143 int &FrameIndex,
144 TypeSize &MemBytes) const {
145 switch (MI.getOpcode()) {
146 default:
147 return 0;
148 case RISCV::LB:
149 case RISCV::LBU:
150 MemBytes = TypeSize::getFixed(1);
151 break;
152 case RISCV::LH:
153 case RISCV::LH_INX:
154 case RISCV::LHU:
155 case RISCV::FLH:
156 MemBytes = TypeSize::getFixed(2);
157 break;
158 case RISCV::LW:
159 case RISCV::LW_INX:
160 case RISCV::FLW:
161 case RISCV::LWU:
162 MemBytes = TypeSize::getFixed(4);
163 break;
164 case RISCV::LD:
165 case RISCV::LD_RV32:
166 case RISCV::FLD:
167 MemBytes = TypeSize::getFixed(8);
168 break;
169 case RISCV::VL1RE8_V:
170 case RISCV::VL2RE8_V:
171 case RISCV::VL4RE8_V:
172 case RISCV::VL8RE8_V:
173 if (!MI.getOperand(1).isFI())
174 return Register();
175 FrameIndex = MI.getOperand(1).getIndex();
176 unsigned LMUL = *getLMULForRVVWholeLoadStore(MI.getOpcode());
178 return MI.getOperand(0).getReg();
179 }
180
181 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
182 MI.getOperand(2).getImm() == 0) {
183 FrameIndex = MI.getOperand(1).getIndex();
184 return MI.getOperand(0).getReg();
185 }
186
187 return 0;
188}
189
191 int &FrameIndex) const {
192 TypeSize Dummy = TypeSize::getZero();
193 return isStoreToStackSlot(MI, FrameIndex, Dummy);
194}
195
197 int &FrameIndex,
198 TypeSize &MemBytes) const {
199 switch (MI.getOpcode()) {
200 default:
201 return 0;
202 case RISCV::SB:
203 MemBytes = TypeSize::getFixed(1);
204 break;
205 case RISCV::SH:
206 case RISCV::SH_INX:
207 case RISCV::FSH:
208 MemBytes = TypeSize::getFixed(2);
209 break;
210 case RISCV::SW:
211 case RISCV::SW_INX:
212 case RISCV::FSW:
213 MemBytes = TypeSize::getFixed(4);
214 break;
215 case RISCV::SD:
216 case RISCV::SD_RV32:
217 case RISCV::FSD:
218 MemBytes = TypeSize::getFixed(8);
219 break;
220 case RISCV::VS1R_V:
221 case RISCV::VS2R_V:
222 case RISCV::VS4R_V:
223 case RISCV::VS8R_V:
224 if (!MI.getOperand(1).isFI())
225 return Register();
226 FrameIndex = MI.getOperand(1).getIndex();
227 unsigned LMUL = *getLMULForRVVWholeLoadStore(MI.getOpcode());
229 return MI.getOperand(0).getReg();
230 }
231
232 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
233 MI.getOperand(2).getImm() == 0) {
234 FrameIndex = MI.getOperand(1).getIndex();
235 return MI.getOperand(0).getReg();
236 }
237
238 return 0;
239}
240
242 const MachineInstr &MI) const {
243 switch (RISCV::getRVVMCOpcode(MI.getOpcode())) {
244 case RISCV::VMV_V_X:
245 case RISCV::VFMV_V_F:
246 case RISCV::VMV_V_I:
247 case RISCV::VMV_S_X:
248 case RISCV::VFMV_S_F:
249 case RISCV::VID_V:
250 return MI.getOperand(1).isUndef();
251 default:
253 }
254}
255
256static bool forwardCopyWillClobberTuple(unsigned DstReg, unsigned SrcReg,
257 unsigned NumRegs) {
258 return DstReg > SrcReg && (DstReg - SrcReg) < NumRegs;
259}
260
262 const MachineBasicBlock &MBB,
265 RISCVVType::VLMUL LMul) {
267 return false;
268
269 assert(MBBI->getOpcode() == TargetOpcode::COPY &&
270 "Unexpected COPY instruction.");
271 Register SrcReg = MBBI->getOperand(1).getReg();
273
274 bool FoundDef = false;
275 bool FirstVSetVLI = false;
276 unsigned FirstSEW = 0;
277 while (MBBI != MBB.begin()) {
278 --MBBI;
279 if (MBBI->isMetaInstruction())
280 continue;
281
282 if (RISCVInstrInfo::isVectorConfigInstr(*MBBI)) {
283 // There is a vsetvli between COPY and source define instruction.
284 // vy = def_vop ... (producing instruction)
285 // ...
286 // vsetvli
287 // ...
288 // vx = COPY vy
289 if (!FoundDef) {
290 if (!FirstVSetVLI) {
291 FirstVSetVLI = true;
292 unsigned FirstVType = MBBI->getOperand(2).getImm();
293 RISCVVType::VLMUL FirstLMul = RISCVVType::getVLMUL(FirstVType);
294 FirstSEW = RISCVVType::getSEW(FirstVType);
295 // The first encountered vsetvli must have the same lmul as the
296 // register class of COPY.
297 if (FirstLMul != LMul)
298 return false;
299 }
300 // Only permit `vsetvli x0, x0, vtype` between COPY and the source
301 // define instruction.
302 if (!RISCVInstrInfo::isVLPreservingConfig(*MBBI))
303 return false;
304 continue;
305 }
306
307 // MBBI is the first vsetvli before the producing instruction.
308 unsigned VType = MBBI->getOperand(2).getImm();
309 // If there is a vsetvli between COPY and the producing instruction.
310 if (FirstVSetVLI) {
311 // If SEW is different, return false.
312 if (RISCVVType::getSEW(VType) != FirstSEW)
313 return false;
314 }
315
316 // If the vsetvli is tail undisturbed, keep the whole register move.
317 if (!RISCVVType::isTailAgnostic(VType))
318 return false;
319
320 // The checking is conservative. We only have register classes for
321 // LMUL = 1/2/4/8. We should be able to convert vmv1r.v to vmv.v.v
322 // for fractional LMUL operations. However, we could not use the vsetvli
323 // lmul for widening operations. The result of widening operation is
324 // 2 x LMUL.
325 return LMul == RISCVVType::getVLMUL(VType);
326 } else if (MBBI->isInlineAsm() || MBBI->isCall()) {
327 return false;
328 } else if (MBBI->getNumDefs()) {
329 // Check all the instructions which will change VL.
330 // For example, vleff has implicit def VL.
331 if (MBBI->modifiesRegister(RISCV::VL, /*TRI=*/nullptr))
332 return false;
333
334 // Only converting whole register copies to vmv.v.v when the defining
335 // value appears in the explicit operands.
336 for (const MachineOperand &MO : MBBI->explicit_operands()) {
337 if (!MO.isReg() || !MO.isDef())
338 continue;
339 if (!FoundDef && TRI->regsOverlap(MO.getReg(), SrcReg)) {
340 // We only permit the source of COPY has the same LMUL as the defined
341 // operand.
342 // There are cases we need to keep the whole register copy if the LMUL
343 // is different.
344 // For example,
345 // $x0 = PseudoVSETIVLI 4, 73 // vsetivli zero, 4, e16,m2,ta,m
346 // $v28m4 = PseudoVWADD_VV_M2 $v26m2, $v8m2
347 // # The COPY may be created by vlmul_trunc intrinsic.
348 // $v26m2 = COPY renamable $v28m2, implicit killed $v28m4
349 //
350 // After widening, the valid value will be 4 x e32 elements. If we
351 // convert the COPY to vmv.v.v, it will only copy 4 x e16 elements.
352 // FIXME: The COPY of subregister of Zvlsseg register will not be able
353 // to convert to vmv.v.[v|i] under the constraint.
354 if (MO.getReg() != SrcReg)
355 return false;
356
357 // In widening reduction instructions with LMUL_1 input vector case,
358 // only checking the LMUL is insufficient due to reduction result is
359 // always LMUL_1.
360 // For example,
361 // $x11 = PseudoVSETIVLI 1, 64 // vsetivli a1, 1, e8, m1, ta, mu
362 // $v8m1 = PseudoVWREDSUM_VS_M1 $v26, $v27
363 // $v26 = COPY killed renamable $v8
364 // After widening, The valid value will be 1 x e16 elements. If we
365 // convert the COPY to vmv.v.v, it will only copy 1 x e8 elements.
366 uint64_t TSFlags = MBBI->getDesc().TSFlags;
368 return false;
369
370 // If the producing instruction does not depend on vsetvli, do not
371 // convert COPY to vmv.v.v. For example, VL1R_V or PseudoVRELOAD.
372 if (!RISCVII::hasSEWOp(TSFlags) || !RISCVII::hasVLOp(TSFlags))
373 return false;
374
375 // Found the definition.
376 FoundDef = true;
377 DefMBBI = MBBI;
378 break;
379 }
380 }
381 }
382 }
383
384 return false;
385}
386
389 const DebugLoc &DL, MCRegister DstReg, MCRegister SrcReg, bool KillSrc,
390 const TargetRegisterClass *RegClass) const {
391 const RISCVRegisterInfo *TRI = STI.getRegisterInfo();
393 unsigned NF = RISCVRI::getNF(RegClass->TSFlags);
394
395 uint16_t SrcEncoding = TRI->getEncodingValue(SrcReg);
396 uint16_t DstEncoding = TRI->getEncodingValue(DstReg);
397 auto [LMulVal, Fractional] = RISCVVType::decodeVLMUL(LMul);
398 assert(!Fractional && "It is impossible be fractional lmul here.");
399 unsigned NumRegs = NF * LMulVal;
400 bool ReversedCopy =
401 forwardCopyWillClobberTuple(DstEncoding, SrcEncoding, NumRegs);
402 if (ReversedCopy) {
403 // If the src and dest overlap when copying a tuple, we need to copy the
404 // registers in reverse.
405 SrcEncoding += NumRegs - 1;
406 DstEncoding += NumRegs - 1;
407 }
408
409 unsigned I = 0;
410 auto GetCopyInfo = [&](uint16_t SrcEncoding, uint16_t DstEncoding)
411 -> std::tuple<RISCVVType::VLMUL, const TargetRegisterClass &, unsigned,
412 unsigned, unsigned> {
413 if (ReversedCopy) {
414 // For reversed copying, if there are enough aligned registers(8/4/2), we
415 // can do a larger copy(LMUL8/4/2).
416 // Besides, we have already known that DstEncoding is larger than
417 // SrcEncoding in forwardCopyWillClobberTuple, so the difference between
418 // DstEncoding and SrcEncoding should be >= LMUL value we try to use to
419 // avoid clobbering.
420 uint16_t Diff = DstEncoding - SrcEncoding;
421 if (I + 8 <= NumRegs && Diff >= 8 && SrcEncoding % 8 == 7 &&
422 DstEncoding % 8 == 7)
423 return {RISCVVType::LMUL_8, RISCV::VRM8RegClass, RISCV::VMV8R_V,
424 RISCV::PseudoVMV_V_V_M8, RISCV::PseudoVMV_V_I_M8};
425 if (I + 4 <= NumRegs && Diff >= 4 && SrcEncoding % 4 == 3 &&
426 DstEncoding % 4 == 3)
427 return {RISCVVType::LMUL_4, RISCV::VRM4RegClass, RISCV::VMV4R_V,
428 RISCV::PseudoVMV_V_V_M4, RISCV::PseudoVMV_V_I_M4};
429 if (I + 2 <= NumRegs && Diff >= 2 && SrcEncoding % 2 == 1 &&
430 DstEncoding % 2 == 1)
431 return {RISCVVType::LMUL_2, RISCV::VRM2RegClass, RISCV::VMV2R_V,
432 RISCV::PseudoVMV_V_V_M2, RISCV::PseudoVMV_V_I_M2};
433 // Or we should do LMUL1 copying.
434 return {RISCVVType::LMUL_1, RISCV::VRRegClass, RISCV::VMV1R_V,
435 RISCV::PseudoVMV_V_V_M1, RISCV::PseudoVMV_V_I_M1};
436 }
437
438 // For forward copying, if source register encoding and destination register
439 // encoding are aligned to 8/4/2, we can do a LMUL8/4/2 copying.
440 if (I + 8 <= NumRegs && SrcEncoding % 8 == 0 && DstEncoding % 8 == 0)
441 return {RISCVVType::LMUL_8, RISCV::VRM8RegClass, RISCV::VMV8R_V,
442 RISCV::PseudoVMV_V_V_M8, RISCV::PseudoVMV_V_I_M8};
443 if (I + 4 <= NumRegs && SrcEncoding % 4 == 0 && DstEncoding % 4 == 0)
444 return {RISCVVType::LMUL_4, RISCV::VRM4RegClass, RISCV::VMV4R_V,
445 RISCV::PseudoVMV_V_V_M4, RISCV::PseudoVMV_V_I_M4};
446 if (I + 2 <= NumRegs && SrcEncoding % 2 == 0 && DstEncoding % 2 == 0)
447 return {RISCVVType::LMUL_2, RISCV::VRM2RegClass, RISCV::VMV2R_V,
448 RISCV::PseudoVMV_V_V_M2, RISCV::PseudoVMV_V_I_M2};
449 // Or we should do LMUL1 copying.
450 return {RISCVVType::LMUL_1, RISCV::VRRegClass, RISCV::VMV1R_V,
451 RISCV::PseudoVMV_V_V_M1, RISCV::PseudoVMV_V_I_M1};
452 };
453
454 while (I != NumRegs) {
455 // For non-segment copying, we only do this once as the registers are always
456 // aligned.
457 // For segment copying, we may do this several times. If the registers are
458 // aligned to larger LMUL, we can eliminate some copyings.
459 auto [LMulCopied, RegClass, Opc, VVOpc, VIOpc] =
460 GetCopyInfo(SrcEncoding, DstEncoding);
461 auto [NumCopied, _] = RISCVVType::decodeVLMUL(LMulCopied);
462
464 if (LMul == LMulCopied &&
465 isConvertibleToVMV_V_V(STI, MBB, MBBI, DefMBBI, LMul)) {
466 Opc = VVOpc;
467 if (DefMBBI->getOpcode() == VIOpc)
468 Opc = VIOpc;
469 }
470
471 // Emit actual copying.
472 // For reversed copying, the encoding should be decreased.
473 MCRegister ActualSrcReg = TRI->findVRegWithEncoding(
474 RegClass, ReversedCopy ? (SrcEncoding - NumCopied + 1) : SrcEncoding);
475 MCRegister ActualDstReg = TRI->findVRegWithEncoding(
476 RegClass, ReversedCopy ? (DstEncoding - NumCopied + 1) : DstEncoding);
477
478 auto MIB = BuildMI(MBB, MBBI, DL, get(Opc), ActualDstReg);
479 bool UseVMV_V_I = RISCV::getRVVMCOpcode(Opc) == RISCV::VMV_V_I;
480 bool UseVMV = UseVMV_V_I || RISCV::getRVVMCOpcode(Opc) == RISCV::VMV_V_V;
481 if (UseVMV)
482 MIB.addReg(ActualDstReg, RegState::Undef);
483 if (UseVMV_V_I)
484 MIB = MIB.add(DefMBBI->getOperand(2));
485 else
486 MIB = MIB.addReg(ActualSrcReg, getKillRegState(KillSrc));
487 if (UseVMV) {
488 const MCInstrDesc &Desc = DefMBBI->getDesc();
489 MIB.add(DefMBBI->getOperand(RISCVII::getVLOpNum(Desc))); // AVL
490 unsigned Log2SEW =
491 DefMBBI->getOperand(RISCVII::getSEWOpNum(Desc)).getImm();
492 MIB.addImm(Log2SEW ? Log2SEW : 3); // SEW
493 MIB.addImm(0); // tu, mu
494 MIB.addReg(RISCV::VL, RegState::Implicit);
495 MIB.addReg(RISCV::VTYPE, RegState::Implicit);
496 }
497 // Add an implicit read of the original source to silence the verifier
498 // in the cases where some of the smaller VRs we're copying from might be
499 // undef, caused by the fact that the original, larger source VR might not
500 // be fully initialized at the time this COPY happens.
501 MIB.addReg(SrcReg, RegState::Implicit);
502
503 // If we are copying reversely, we should decrease the encoding.
504 SrcEncoding += (ReversedCopy ? -NumCopied : NumCopied);
505 DstEncoding += (ReversedCopy ? -NumCopied : NumCopied);
506 I += NumCopied;
507 }
508}
509
512 const DebugLoc &DL, Register DstReg,
513 Register SrcReg, bool KillSrc,
514 bool RenamableDest, bool RenamableSrc) const {
515 const TargetRegisterInfo *TRI = STI.getRegisterInfo();
516 RegState KillFlag = getKillRegState(KillSrc);
517
518 if (RISCV::GPRRegClass.contains(DstReg, SrcReg)) {
519 BuildMI(MBB, MBBI, DL, get(RISCV::ADDI), DstReg)
520 .addReg(SrcReg, KillFlag | getRenamableRegState(RenamableSrc))
521 .addImm(0);
522 return;
523 }
524
525 if (RISCV::GPRF16RegClass.contains(DstReg, SrcReg)) {
526 BuildMI(MBB, MBBI, DL, get(RISCV::PseudoMV_FPR16INX), DstReg)
527 .addReg(SrcReg, KillFlag | getRenamableRegState(RenamableSrc));
528 return;
529 }
530
531 if (RISCV::GPRF32RegClass.contains(DstReg, SrcReg)) {
532 BuildMI(MBB, MBBI, DL, get(RISCV::PseudoMV_FPR32INX), DstReg)
533 .addReg(SrcReg, KillFlag | getRenamableRegState(RenamableSrc));
534 return;
535 }
536
537 if (RISCV::GPRPairRegClass.contains(DstReg, SrcReg)) {
538 if (STI.isRV32()) {
539 if (STI.hasStdExtZdinx()) {
540 // On RV32_Zdinx, FMV.D will move a pair of registers to another pair of
541 // registers, in one instruction.
542 BuildMI(MBB, MBBI, DL, get(RISCV::FSGNJ_D_IN32X), DstReg)
543 .addReg(SrcReg, getRenamableRegState(RenamableSrc))
544 .addReg(SrcReg, KillFlag | getRenamableRegState(RenamableSrc));
545 return;
546 }
547
548 if (STI.hasStdExtP()) {
549 // On RV32P, `padd.dw` is a GPR Pair Add
550 BuildMI(MBB, MBBI, DL, get(RISCV::PADD_DW), DstReg)
551 .addReg(SrcReg, KillFlag | getRenamableRegState(RenamableSrc))
552 .addReg(RISCV::X0_Pair);
553 return;
554 }
555 }
556
557 MCRegister EvenReg = TRI->getSubReg(SrcReg, RISCV::sub_gpr_even);
558 MCRegister OddReg = TRI->getSubReg(SrcReg, RISCV::sub_gpr_odd);
559 // We need to correct the odd register of X0_Pair.
560 if (OddReg == RISCV::DUMMY_REG_PAIR_WITH_X0)
561 OddReg = RISCV::X0;
562 assert(DstReg != RISCV::X0_Pair && "Cannot write to X0_Pair");
563
564 // Emit an ADDI for both parts of GPRPair.
565 BuildMI(MBB, MBBI, DL, get(RISCV::ADDI),
566 TRI->getSubReg(DstReg, RISCV::sub_gpr_even))
567 .addReg(EvenReg, KillFlag)
568 .addImm(0);
569 BuildMI(MBB, MBBI, DL, get(RISCV::ADDI),
570 TRI->getSubReg(DstReg, RISCV::sub_gpr_odd))
571 .addReg(OddReg, KillFlag)
572 .addImm(0);
573 return;
574 }
575
576 // Handle copy from csr
577 if (RISCV::VCSRRegClass.contains(SrcReg) &&
578 RISCV::GPRRegClass.contains(DstReg)) {
579 BuildMI(MBB, MBBI, DL, get(RISCV::CSRRS), DstReg)
580 .addImm(RISCVSysReg::lookupSysRegByName(TRI->getName(SrcReg))->Encoding)
581 .addReg(RISCV::X0);
582 return;
583 }
584
585 if (RISCV::FPR16RegClass.contains(DstReg, SrcReg)) {
586 unsigned Opc;
587 if (STI.hasStdExtZfh()) {
588 Opc = RISCV::FSGNJ_H;
589 } else {
590 assert(STI.hasStdExtF() &&
591 (STI.hasStdExtZfhmin() || STI.hasStdExtZfbfmin()) &&
592 "Unexpected extensions");
593 // Zfhmin/Zfbfmin doesn't have FSGNJ_H, replace FSGNJ_H with FSGNJ_S.
594 DstReg = TRI->getMatchingSuperReg(DstReg, RISCV::sub_16,
595 &RISCV::FPR32RegClass);
596 SrcReg = TRI->getMatchingSuperReg(SrcReg, RISCV::sub_16,
597 &RISCV::FPR32RegClass);
598 Opc = RISCV::FSGNJ_S;
599 }
600 BuildMI(MBB, MBBI, DL, get(Opc), DstReg)
601 .addReg(SrcReg, KillFlag)
602 .addReg(SrcReg, KillFlag);
603 return;
604 }
605
606 if (RISCV::FPR32RegClass.contains(DstReg, SrcReg)) {
607 BuildMI(MBB, MBBI, DL, get(RISCV::FSGNJ_S), DstReg)
608 .addReg(SrcReg, KillFlag)
609 .addReg(SrcReg, KillFlag);
610 return;
611 }
612
613 if (RISCV::FPR64RegClass.contains(DstReg, SrcReg)) {
614 BuildMI(MBB, MBBI, DL, get(RISCV::FSGNJ_D), DstReg)
615 .addReg(SrcReg, KillFlag)
616 .addReg(SrcReg, KillFlag);
617 return;
618 }
619
620 if (RISCV::FPR32RegClass.contains(DstReg) &&
621 RISCV::GPRRegClass.contains(SrcReg)) {
622 BuildMI(MBB, MBBI, DL, get(RISCV::FMV_W_X), DstReg)
623 .addReg(SrcReg, KillFlag);
624 return;
625 }
626
627 if (RISCV::GPRRegClass.contains(DstReg) &&
628 RISCV::FPR32RegClass.contains(SrcReg)) {
629 BuildMI(MBB, MBBI, DL, get(RISCV::FMV_X_W), DstReg)
630 .addReg(SrcReg, KillFlag);
631 return;
632 }
633
634 if (RISCV::FPR64RegClass.contains(DstReg) &&
635 RISCV::GPRRegClass.contains(SrcReg)) {
636 assert(STI.getXLen() == 64 && "Unexpected GPR size");
637 BuildMI(MBB, MBBI, DL, get(RISCV::FMV_D_X), DstReg)
638 .addReg(SrcReg, KillFlag);
639 return;
640 }
641
642 if (RISCV::GPRRegClass.contains(DstReg) &&
643 RISCV::FPR64RegClass.contains(SrcReg)) {
644 assert(STI.getXLen() == 64 && "Unexpected GPR size");
645 BuildMI(MBB, MBBI, DL, get(RISCV::FMV_X_D), DstReg)
646 .addReg(SrcReg, KillFlag);
647 return;
648 }
649
650 // VR->VR copies.
651 const TargetRegisterClass *RegClass =
652 TRI->getCommonMinimalPhysRegClass(SrcReg, DstReg);
653 if (RISCVRegisterInfo::isRVVRegClass(RegClass)) {
654 copyPhysRegVector(MBB, MBBI, DL, DstReg, SrcReg, KillSrc, RegClass);
655 return;
656 }
657
658 llvm_unreachable("Impossible reg-to-reg copy");
659}
660
663 Register SrcReg, bool IsKill, int FI,
664 const TargetRegisterClass *RC,
665 Register VReg,
666 MachineInstr::MIFlag Flags) const {
667 MachineFunction *MF = MBB.getParent();
668 MachineFrameInfo &MFI = MF->getFrameInfo();
669 Align Alignment = MFI.getObjectAlign(FI);
670
671 unsigned Opcode;
672 if (RISCV::GPRRegClass.hasSubClassEq(RC)) {
673 Opcode = RegInfo.getRegSizeInBits(RISCV::GPRRegClass) == 32 ? RISCV::SW
674 : RISCV::SD;
675 } else if (RISCV::GPRF16RegClass.hasSubClassEq(RC)) {
676 Opcode = RISCV::SH_INX;
677 } else if (RISCV::GPRF32RegClass.hasSubClassEq(RC)) {
678 Opcode = RISCV::SW_INX;
679 } else if (RISCV::GPRPairRegClass.hasSubClassEq(RC)) {
680 if (!STI.is64Bit() && STI.hasStdExtZilsd() &&
681 Alignment >= STI.getZilsdAlign()) {
682 Opcode = RISCV::SD_RV32;
683 } else {
684 Opcode = RISCV::PseudoRV32ZdinxSD;
685 }
686 } else if (RISCV::FPR16RegClass.hasSubClassEq(RC)) {
687 Opcode = RISCV::FSH;
688 } else if (RISCV::FPR32RegClass.hasSubClassEq(RC)) {
689 Opcode = RISCV::FSW;
690 } else if (RISCV::FPR64RegClass.hasSubClassEq(RC)) {
691 Opcode = RISCV::FSD;
692 } else if (RISCV::VRRegClass.hasSubClassEq(RC)) {
693 Opcode = RISCV::VS1R_V;
694 } else if (RISCV::VRM2RegClass.hasSubClassEq(RC)) {
695 Opcode = RISCV::VS2R_V;
696 } else if (RISCV::VRM4RegClass.hasSubClassEq(RC)) {
697 Opcode = RISCV::VS4R_V;
698 } else if (RISCV::VRM8RegClass.hasSubClassEq(RC)) {
699 Opcode = RISCV::VS8R_V;
700 } else if (RISCV::VRN2M1RegClass.hasSubClassEq(RC))
701 Opcode = RISCV::PseudoVSPILL2_M1;
702 else if (RISCV::VRN2M2RegClass.hasSubClassEq(RC))
703 Opcode = RISCV::PseudoVSPILL2_M2;
704 else if (RISCV::VRN2M4RegClass.hasSubClassEq(RC))
705 Opcode = RISCV::PseudoVSPILL2_M4;
706 else if (RISCV::VRN3M1RegClass.hasSubClassEq(RC))
707 Opcode = RISCV::PseudoVSPILL3_M1;
708 else if (RISCV::VRN3M2RegClass.hasSubClassEq(RC))
709 Opcode = RISCV::PseudoVSPILL3_M2;
710 else if (RISCV::VRN4M1RegClass.hasSubClassEq(RC))
711 Opcode = RISCV::PseudoVSPILL4_M1;
712 else if (RISCV::VRN4M2RegClass.hasSubClassEq(RC))
713 Opcode = RISCV::PseudoVSPILL4_M2;
714 else if (RISCV::VRN5M1RegClass.hasSubClassEq(RC))
715 Opcode = RISCV::PseudoVSPILL5_M1;
716 else if (RISCV::VRN6M1RegClass.hasSubClassEq(RC))
717 Opcode = RISCV::PseudoVSPILL6_M1;
718 else if (RISCV::VRN7M1RegClass.hasSubClassEq(RC))
719 Opcode = RISCV::PseudoVSPILL7_M1;
720 else if (RISCV::VRN8M1RegClass.hasSubClassEq(RC))
721 Opcode = RISCV::PseudoVSPILL8_M1;
722 else
723 llvm_unreachable("Can't store this register to stack slot");
724
728 TypeSize::getScalable(MFI.getObjectSize(FI)), Alignment);
729
731 BuildMI(MBB, I, DebugLoc(), get(Opcode))
732 .addReg(SrcReg, getKillRegState(IsKill))
733 .addFrameIndex(FI)
734 .addMemOperand(MMO)
735 .setMIFlag(Flags);
736 NumVRegSpilled += RegInfo.getRegSizeInBits(*RC) / RISCV::RVVBitsPerBlock;
737 } else {
740 MFI.getObjectSize(FI), Alignment);
741
742 BuildMI(MBB, I, DebugLoc(), get(Opcode))
743 .addReg(SrcReg, getKillRegState(IsKill))
744 .addFrameIndex(FI)
745 .addImm(0)
746 .addMemOperand(MMO)
747 .setMIFlag(Flags);
748 }
749}
750
753 Register DstReg, int FI,
754 const TargetRegisterClass *RC,
755 Register VReg, unsigned SubReg,
756 MachineInstr::MIFlag Flags) const {
757 MachineFunction *MF = MBB.getParent();
758 MachineFrameInfo &MFI = MF->getFrameInfo();
759 Align Alignment = MFI.getObjectAlign(FI);
760 DebugLoc DL =
761 Flags & MachineInstr::FrameDestroy ? MBB.findDebugLoc(I) : DebugLoc();
762
763 unsigned Opcode;
764 if (RISCV::GPRRegClass.hasSubClassEq(RC)) {
765 Opcode = RegInfo.getRegSizeInBits(RISCV::GPRRegClass) == 32 ? RISCV::LW
766 : RISCV::LD;
767 } else if (RISCV::GPRF16RegClass.hasSubClassEq(RC)) {
768 Opcode = RISCV::LH_INX;
769 } else if (RISCV::GPRF32RegClass.hasSubClassEq(RC)) {
770 Opcode = RISCV::LW_INX;
771 } else if (RISCV::GPRPairRegClass.hasSubClassEq(RC)) {
772 if (!STI.is64Bit() && STI.hasStdExtZilsd() &&
773 Alignment >= STI.getZilsdAlign()) {
774 Opcode = RISCV::LD_RV32;
775 } else {
776 Opcode = RISCV::PseudoRV32ZdinxLD;
777 }
778 } else if (RISCV::FPR16RegClass.hasSubClassEq(RC)) {
779 Opcode = RISCV::FLH;
780 } else if (RISCV::FPR32RegClass.hasSubClassEq(RC)) {
781 Opcode = RISCV::FLW;
782 } else if (RISCV::FPR64RegClass.hasSubClassEq(RC)) {
783 Opcode = RISCV::FLD;
784 } else if (RISCV::VRRegClass.hasSubClassEq(RC)) {
785 Opcode = RISCV::VL1RE8_V;
786 } else if (RISCV::VRM2RegClass.hasSubClassEq(RC)) {
787 Opcode = RISCV::VL2RE8_V;
788 } else if (RISCV::VRM4RegClass.hasSubClassEq(RC)) {
789 Opcode = RISCV::VL4RE8_V;
790 } else if (RISCV::VRM8RegClass.hasSubClassEq(RC)) {
791 Opcode = RISCV::VL8RE8_V;
792 } else if (RISCV::VRN2M1RegClass.hasSubClassEq(RC))
793 Opcode = RISCV::PseudoVRELOAD2_M1;
794 else if (RISCV::VRN2M2RegClass.hasSubClassEq(RC))
795 Opcode = RISCV::PseudoVRELOAD2_M2;
796 else if (RISCV::VRN2M4RegClass.hasSubClassEq(RC))
797 Opcode = RISCV::PseudoVRELOAD2_M4;
798 else if (RISCV::VRN3M1RegClass.hasSubClassEq(RC))
799 Opcode = RISCV::PseudoVRELOAD3_M1;
800 else if (RISCV::VRN3M2RegClass.hasSubClassEq(RC))
801 Opcode = RISCV::PseudoVRELOAD3_M2;
802 else if (RISCV::VRN4M1RegClass.hasSubClassEq(RC))
803 Opcode = RISCV::PseudoVRELOAD4_M1;
804 else if (RISCV::VRN4M2RegClass.hasSubClassEq(RC))
805 Opcode = RISCV::PseudoVRELOAD4_M2;
806 else if (RISCV::VRN5M1RegClass.hasSubClassEq(RC))
807 Opcode = RISCV::PseudoVRELOAD5_M1;
808 else if (RISCV::VRN6M1RegClass.hasSubClassEq(RC))
809 Opcode = RISCV::PseudoVRELOAD6_M1;
810 else if (RISCV::VRN7M1RegClass.hasSubClassEq(RC))
811 Opcode = RISCV::PseudoVRELOAD7_M1;
812 else if (RISCV::VRN8M1RegClass.hasSubClassEq(RC))
813 Opcode = RISCV::PseudoVRELOAD8_M1;
814 else
815 llvm_unreachable("Can't load this register from stack slot");
816
820 TypeSize::getScalable(MFI.getObjectSize(FI)), Alignment);
821
823 BuildMI(MBB, I, DL, get(Opcode), DstReg)
824 .addFrameIndex(FI)
825 .addMemOperand(MMO)
826 .setMIFlag(Flags);
827 NumVRegReloaded += RegInfo.getRegSizeInBits(*RC) / RISCV::RVVBitsPerBlock;
828 } else {
831 MFI.getObjectSize(FI), Alignment);
832
833 BuildMI(MBB, I, DL, get(Opcode), DstReg)
834 .addFrameIndex(FI)
835 .addImm(0)
836 .addMemOperand(MMO)
837 .setMIFlag(Flags);
838 }
839}
840std::optional<unsigned> getFoldedOpcode(MachineFunction &MF, MachineInstr &MI,
842 const RISCVSubtarget &ST) {
843
844 // The below optimizations narrow the load so they are only valid for little
845 // endian.
846 // TODO: Support big endian by adding an offset into the frame object?
847 if (MF.getDataLayout().isBigEndian())
848 return std::nullopt;
849
850 // Fold load from stack followed by sext.b/sext.h/sext.w/zext.b/zext.h/zext.w.
851 if (Ops.size() != 1 || Ops[0] != 1)
852 return std::nullopt;
853
854 switch (MI.getOpcode()) {
855 default:
856 if (RISCVInstrInfo::isSEXT_W(MI))
857 return RISCV::LW;
858 if (RISCVInstrInfo::isZEXT_W(MI))
859 return RISCV::LWU;
860 if (RISCVInstrInfo::isZEXT_B(MI))
861 return RISCV::LBU;
862 break;
863 case RISCV::SEXT_H:
864 return RISCV::LH;
865 case RISCV::SEXT_B:
866 return RISCV::LB;
867 case RISCV::ZEXT_H_RV32:
868 case RISCV::ZEXT_H_RV64:
869 return RISCV::LHU;
870 }
871
872 switch (RISCV::getRVVMCOpcode(MI.getOpcode())) {
873 default:
874 return std::nullopt;
875 case RISCV::VMV_X_S: {
876 unsigned Log2SEW =
877 MI.getOperand(RISCVII::getSEWOpNum(MI.getDesc())).getImm();
878 if (ST.getXLen() < (1U << Log2SEW))
879 return std::nullopt;
880 switch (Log2SEW) {
881 case 3:
882 return RISCV::LB;
883 case 4:
884 return RISCV::LH;
885 case 5:
886 return RISCV::LW;
887 case 6:
888 return RISCV::LD;
889 default:
890 llvm_unreachable("Unexpected SEW");
891 }
892 }
893 case RISCV::VFMV_F_S: {
894 unsigned Log2SEW =
895 MI.getOperand(RISCVII::getSEWOpNum(MI.getDesc())).getImm();
896 switch (Log2SEW) {
897 case 4:
898 return RISCV::FLH;
899 case 5:
900 return RISCV::FLW;
901 case 6:
902 return RISCV::FLD;
903 default:
904 llvm_unreachable("Unexpected SEW");
905 }
906 }
907 }
908}
909
910// This is the version used during InlineSpiller::spillAroundUses
913 MachineBasicBlock::iterator InsertPt, int FrameIndex, MachineInstr *&CopyMI,
914 LiveIntervals *LIS, VirtRegMap *VRM) const {
915
916 std::optional<unsigned> LoadOpc = getFoldedOpcode(MF, MI, Ops, STI);
917 if (!LoadOpc)
918 return nullptr;
919 Register DstReg = MI.getOperand(0).getReg();
920 return BuildMI(*MI.getParent(), InsertPt, MI.getDebugLoc(), get(*LoadOpc),
921 DstReg)
922 .addFrameIndex(FrameIndex)
923 .addImm(0);
924}
925
926static unsigned getLoadPredicatedOpcode(unsigned Opcode) {
927 switch (Opcode) {
928 case RISCV::LB:
929 return RISCV::PseudoCCLB;
930 case RISCV::LBU:
931 return RISCV::PseudoCCLBU;
932 case RISCV::LH:
933 return RISCV::PseudoCCLH;
934 case RISCV::LHU:
935 return RISCV::PseudoCCLHU;
936 case RISCV::LW:
937 return RISCV::PseudoCCLW;
938 case RISCV::LWU:
939 return RISCV::PseudoCCLWU;
940 case RISCV::LD:
941 return RISCV::PseudoCCLD;
942 case RISCV::QC_E_LB:
943 return RISCV::PseudoCCQC_E_LB;
944 case RISCV::QC_E_LBU:
945 return RISCV::PseudoCCQC_E_LBU;
946 case RISCV::QC_E_LH:
947 return RISCV::PseudoCCQC_E_LH;
948 case RISCV::QC_E_LHU:
949 return RISCV::PseudoCCQC_E_LHU;
950 case RISCV::QC_E_LW:
951 return RISCV::PseudoCCQC_E_LW;
952 default:
953 return 0;
954 }
955}
956
960 MachineInstr *&CopyMI, LiveIntervals *LIS) const {
961 // For now, only handle RISCV::PseudoCCMOVGPR.
962 if (MI.getOpcode() != RISCV::PseudoCCMOVGPR)
963 return nullptr;
964
965 unsigned PredOpc = getLoadPredicatedOpcode(LoadMI.getOpcode());
966
967 if (!STI.hasShortForwardBranchILoad() || !PredOpc)
968 return nullptr;
969
971 if (Ops.size() != 1 || (Ops[0] != 1 && Ops[0] != 2))
972 return nullptr;
973
974 bool Invert = Ops[0] == 2;
975 const MachineOperand &FalseReg = MI.getOperand(!Invert ? 2 : 1);
976 Register DestReg = MI.getOperand(0).getReg();
977 const TargetRegisterClass *PreviousClass = MRI.getRegClass(FalseReg.getReg());
978 if (!MRI.constrainRegClass(DestReg, PreviousClass))
979 return nullptr;
980
981 // Create a new predicated version of DefMI.
982 MachineInstrBuilder NewMI = BuildMI(*MI.getParent(), InsertPt,
983 MI.getDebugLoc(), get(PredOpc), DestReg);
984
985 // Copy the false register.
986 NewMI.add(FalseReg);
987
988 // Copy all the DefMI operands.
989 const MCInstrDesc &DefDesc = LoadMI.getDesc();
990 for (unsigned i = 1, e = DefDesc.getNumOperands(); i != e; ++i)
991 NewMI.add(LoadMI.getOperand(i));
992
993 // Add branch opcode, inverting if necessary.
994 unsigned BCC = MI.getOperand(MI.getNumExplicitOperands() - 3).getImm();
995 if (!Invert)
997 NewMI.addImm(BCC);
998
999 // Copy condition portion
1000 NewMI.add({MI.getOperand(MI.getNumExplicitOperands() - 2),
1001 MI.getOperand(MI.getNumExplicitOperands() - 1)});
1002 NewMI.cloneMemRefs(LoadMI);
1003 return NewMI;
1004}
1005
1008 const DebugLoc &DL, Register DstReg, uint64_t Val,
1009 MachineInstr::MIFlag Flag, bool DstRenamable,
1010 bool DstIsDead) const {
1011 Register SrcReg = RISCV::X0;
1012
1013 // For RV32, allow a sign or unsigned 32 bit value.
1014 if (!STI.is64Bit() && !isInt<32>(Val)) {
1015 // If have a uimm32 it will still fit in a register so we can allow it.
1016 if (!isUInt<32>(Val))
1017 report_fatal_error("Should only materialize 32-bit constants for RV32");
1018
1019 // Sign extend for generateInstSeq.
1020 Val = SignExtend64<32>(Val);
1021 }
1022
1024 assert(!Seq.empty());
1025
1026 bool SrcRenamable = false;
1027 unsigned Num = 0;
1028
1029 for (const RISCVMatInt::Inst &Inst : Seq) {
1030 bool LastItem = ++Num == Seq.size();
1031 RegState DstRegState = getDeadRegState(DstIsDead && LastItem) |
1032 getRenamableRegState(DstRenamable);
1033 RegState SrcRegState = getKillRegState(SrcReg != RISCV::X0) |
1034 getRenamableRegState(SrcRenamable);
1035 switch (Inst.getOpndKind()) {
1036 case RISCVMatInt::Imm:
1037 BuildMI(MBB, MBBI, DL, get(Inst.getOpcode()))
1038 .addReg(DstReg, RegState::Define | DstRegState)
1039 .addImm(Inst.getImm())
1040 .setMIFlag(Flag);
1041 break;
1042 case RISCVMatInt::RegX0:
1043 BuildMI(MBB, MBBI, DL, get(Inst.getOpcode()))
1044 .addReg(DstReg, RegState::Define | DstRegState)
1045 .addReg(SrcReg, SrcRegState)
1046 .addReg(RISCV::X0)
1047 .setMIFlag(Flag);
1048 break;
1050 BuildMI(MBB, MBBI, DL, get(Inst.getOpcode()))
1051 .addReg(DstReg, RegState::Define | DstRegState)
1052 .addReg(SrcReg, SrcRegState)
1053 .addReg(SrcReg, SrcRegState)
1054 .setMIFlag(Flag);
1055 break;
1057 BuildMI(MBB, MBBI, DL, get(Inst.getOpcode()))
1058 .addReg(DstReg, RegState::Define | DstRegState)
1059 .addReg(SrcReg, SrcRegState)
1060 .addImm(Inst.getImm())
1061 .setMIFlag(Flag);
1062 break;
1063 }
1064
1065 // Only the first instruction has X0 as its source.
1066 SrcReg = DstReg;
1067 SrcRenamable = DstRenamable;
1068 }
1069}
1070
1072 switch (Opc) {
1073 default:
1074 return RISCVCC::COND_INVALID;
1075 case RISCV::BEQ:
1076 case RISCV::BEQI:
1077 case RISCV::CV_BEQIMM:
1078 case RISCV::QC_BEQI:
1079 case RISCV::QC_E_BEQI:
1080 case RISCV::NDS_BBC:
1081 case RISCV::NDS_BEQC:
1082 return RISCVCC::COND_EQ;
1083 case RISCV::BNE:
1084 case RISCV::BNEI:
1085 case RISCV::QC_BNEI:
1086 case RISCV::QC_E_BNEI:
1087 case RISCV::CV_BNEIMM:
1088 case RISCV::NDS_BBS:
1089 case RISCV::NDS_BNEC:
1090 return RISCVCC::COND_NE;
1091 case RISCV::BLT:
1092 case RISCV::QC_BLTI:
1093 case RISCV::QC_E_BLTI:
1094 return RISCVCC::COND_LT;
1095 case RISCV::BGE:
1096 case RISCV::QC_BGEI:
1097 case RISCV::QC_E_BGEI:
1098 return RISCVCC::COND_GE;
1099 case RISCV::BLTU:
1100 case RISCV::QC_BLTUI:
1101 case RISCV::QC_E_BLTUI:
1102 return RISCVCC::COND_LTU;
1103 case RISCV::BGEU:
1104 case RISCV::QC_BGEUI:
1105 case RISCV::QC_E_BGEUI:
1106 return RISCVCC::COND_GEU;
1107 }
1108}
1109
1111 int64_t C1) {
1112 switch (CC) {
1113 default:
1114 llvm_unreachable("Unexpected CC");
1115 case RISCVCC::COND_EQ:
1116 return C0 == C1;
1117 case RISCVCC::COND_NE:
1118 return C0 != C1;
1119 case RISCVCC::COND_LT:
1120 return C0 < C1;
1121 case RISCVCC::COND_GE:
1122 return C0 >= C1;
1123 case RISCVCC::COND_LTU:
1124 return (uint64_t)C0 < (uint64_t)C1;
1125 case RISCVCC::COND_GEU:
1126 return (uint64_t)C0 >= (uint64_t)C1;
1127 }
1128}
1129
1130// The contents of values added to Cond are not examined outside of
1131// RISCVInstrInfo, giving us flexibility in what to push to it. For RISCV, we
1132// push BranchOpcode, Reg1, Reg2.
1135 // Block ends with fall-through condbranch.
1136 assert(LastInst.getDesc().isConditionalBranch() &&
1137 "Unknown conditional branch");
1138 Target = LastInst.getOperand(2).getMBB();
1139 Cond.push_back(MachineOperand::CreateImm(LastInst.getOpcode()));
1140 Cond.push_back(LastInst.getOperand(0));
1141 Cond.push_back(LastInst.getOperand(1));
1142}
1143
1144static unsigned getInverseXqcicmOpcode(unsigned Opcode) {
1145 switch (Opcode) {
1146 default:
1147 llvm_unreachable("Unexpected Opcode");
1148 case RISCV::QC_MVEQ:
1149 return RISCV::QC_MVNE;
1150 case RISCV::QC_MVNE:
1151 return RISCV::QC_MVEQ;
1152 case RISCV::QC_MVLT:
1153 return RISCV::QC_MVGE;
1154 case RISCV::QC_MVGE:
1155 return RISCV::QC_MVLT;
1156 case RISCV::QC_MVLTU:
1157 return RISCV::QC_MVGEU;
1158 case RISCV::QC_MVGEU:
1159 return RISCV::QC_MVLTU;
1160 case RISCV::QC_MVEQI:
1161 return RISCV::QC_MVNEI;
1162 case RISCV::QC_MVNEI:
1163 return RISCV::QC_MVEQI;
1164 case RISCV::QC_MVLTI:
1165 return RISCV::QC_MVGEI;
1166 case RISCV::QC_MVGEI:
1167 return RISCV::QC_MVLTI;
1168 case RISCV::QC_MVLTUI:
1169 return RISCV::QC_MVGEUI;
1170 case RISCV::QC_MVGEUI:
1171 return RISCV::QC_MVLTUI;
1172 }
1173}
1174
1175unsigned RISCVCC::getBrCond(RISCVCC::CondCode CC, unsigned SelectOpc) {
1176 switch (SelectOpc) {
1177 default:
1178 switch (CC) {
1179 default:
1180 llvm_unreachable("Unexpected condition code!");
1181 case RISCVCC::COND_EQ:
1182 return RISCV::BEQ;
1183 case RISCVCC::COND_NE:
1184 return RISCV::BNE;
1185 case RISCVCC::COND_LT:
1186 return RISCV::BLT;
1187 case RISCVCC::COND_GE:
1188 return RISCV::BGE;
1189 case RISCVCC::COND_LTU:
1190 return RISCV::BLTU;
1191 case RISCVCC::COND_GEU:
1192 return RISCV::BGEU;
1193 }
1194 break;
1195 case RISCV::Select_GPR_Using_CC_Imm5_Zibi:
1196 switch (CC) {
1197 default:
1198 llvm_unreachable("Unexpected condition code!");
1199 case RISCVCC::COND_EQ:
1200 return RISCV::BEQI;
1201 case RISCVCC::COND_NE:
1202 return RISCV::BNEI;
1203 }
1204 break;
1205 case RISCV::Select_GPR_Using_CC_SImm5_CV:
1206 switch (CC) {
1207 default:
1208 llvm_unreachable("Unexpected condition code!");
1209 case RISCVCC::COND_EQ:
1210 return RISCV::CV_BEQIMM;
1211 case RISCVCC::COND_NE:
1212 return RISCV::CV_BNEIMM;
1213 }
1214 break;
1215 case RISCV::Select_GPRNoX0_Using_CC_SImm5NonZero_QC:
1216 switch (CC) {
1217 default:
1218 llvm_unreachable("Unexpected condition code!");
1219 case RISCVCC::COND_EQ:
1220 return RISCV::QC_BEQI;
1221 case RISCVCC::COND_NE:
1222 return RISCV::QC_BNEI;
1223 case RISCVCC::COND_LT:
1224 return RISCV::QC_BLTI;
1225 case RISCVCC::COND_GE:
1226 return RISCV::QC_BGEI;
1227 }
1228 break;
1229 case RISCV::Select_GPRNoX0_Using_CC_UImm5NonZero_QC:
1230 switch (CC) {
1231 default:
1232 llvm_unreachable("Unexpected condition code!");
1233 case RISCVCC::COND_LTU:
1234 return RISCV::QC_BLTUI;
1235 case RISCVCC::COND_GEU:
1236 return RISCV::QC_BGEUI;
1237 }
1238 break;
1239 case RISCV::Select_GPRNoX0_Using_CC_SImm16NonZero_QC:
1240 switch (CC) {
1241 default:
1242 llvm_unreachable("Unexpected condition code!");
1243 case RISCVCC::COND_EQ:
1244 return RISCV::QC_E_BEQI;
1245 case RISCVCC::COND_NE:
1246 return RISCV::QC_E_BNEI;
1247 case RISCVCC::COND_LT:
1248 return RISCV::QC_E_BLTI;
1249 case RISCVCC::COND_GE:
1250 return RISCV::QC_E_BGEI;
1251 }
1252 break;
1253 case RISCV::Select_GPRNoX0_Using_CC_UImm16NonZero_QC:
1254 switch (CC) {
1255 default:
1256 llvm_unreachable("Unexpected condition code!");
1257 case RISCVCC::COND_LTU:
1258 return RISCV::QC_E_BLTUI;
1259 case RISCVCC::COND_GEU:
1260 return RISCV::QC_E_BGEUI;
1261 }
1262 break;
1263 case RISCV::Select_GPR_Using_CC_UImmLog2XLen_NDS:
1264 switch (CC) {
1265 default:
1266 llvm_unreachable("Unexpected condition code!");
1267 case RISCVCC::COND_EQ:
1268 return RISCV::NDS_BBC;
1269 case RISCVCC::COND_NE:
1270 return RISCV::NDS_BBS;
1271 }
1272 break;
1273 case RISCV::Select_GPR_Using_CC_UImm7_NDS:
1274 switch (CC) {
1275 default:
1276 llvm_unreachable("Unexpected condition code!");
1277 case RISCVCC::COND_EQ:
1278 return RISCV::NDS_BEQC;
1279 case RISCVCC::COND_NE:
1280 return RISCV::NDS_BNEC;
1281 }
1282 break;
1283 }
1284}
1285
1287 switch (CC) {
1288 default:
1289 llvm_unreachable("Unrecognized conditional branch");
1290 case RISCVCC::COND_EQ:
1291 return RISCVCC::COND_NE;
1292 case RISCVCC::COND_NE:
1293 return RISCVCC::COND_EQ;
1294 case RISCVCC::COND_LT:
1295 return RISCVCC::COND_GE;
1296 case RISCVCC::COND_GE:
1297 return RISCVCC::COND_LT;
1298 case RISCVCC::COND_LTU:
1299 return RISCVCC::COND_GEU;
1300 case RISCVCC::COND_GEU:
1301 return RISCVCC::COND_LTU;
1302 }
1303}
1304
1305// Return inverse branch
1306unsigned RISCVCC::getInverseBranchOpcode(unsigned BCC) {
1307 switch (BCC) {
1308 default:
1309 llvm_unreachable("Unexpected branch opcode!");
1310 case RISCV::BEQ:
1311 return RISCV::BNE;
1312 case RISCV::BEQI:
1313 return RISCV::BNEI;
1314 case RISCV::BNE:
1315 return RISCV::BEQ;
1316 case RISCV::BNEI:
1317 return RISCV::BEQI;
1318 case RISCV::BLT:
1319 return RISCV::BGE;
1320 case RISCV::BGE:
1321 return RISCV::BLT;
1322 case RISCV::BLTU:
1323 return RISCV::BGEU;
1324 case RISCV::BGEU:
1325 return RISCV::BLTU;
1326 case RISCV::CV_BEQIMM:
1327 return RISCV::CV_BNEIMM;
1328 case RISCV::CV_BNEIMM:
1329 return RISCV::CV_BEQIMM;
1330 case RISCV::QC_BEQI:
1331 return RISCV::QC_BNEI;
1332 case RISCV::QC_BNEI:
1333 return RISCV::QC_BEQI;
1334 case RISCV::QC_BLTI:
1335 return RISCV::QC_BGEI;
1336 case RISCV::QC_BGEI:
1337 return RISCV::QC_BLTI;
1338 case RISCV::QC_BLTUI:
1339 return RISCV::QC_BGEUI;
1340 case RISCV::QC_BGEUI:
1341 return RISCV::QC_BLTUI;
1342 case RISCV::QC_E_BEQI:
1343 return RISCV::QC_E_BNEI;
1344 case RISCV::QC_E_BNEI:
1345 return RISCV::QC_E_BEQI;
1346 case RISCV::QC_E_BLTI:
1347 return RISCV::QC_E_BGEI;
1348 case RISCV::QC_E_BGEI:
1349 return RISCV::QC_E_BLTI;
1350 case RISCV::QC_E_BLTUI:
1351 return RISCV::QC_E_BGEUI;
1352 case RISCV::QC_E_BGEUI:
1353 return RISCV::QC_E_BLTUI;
1354 case RISCV::NDS_BBC:
1355 return RISCV::NDS_BBS;
1356 case RISCV::NDS_BBS:
1357 return RISCV::NDS_BBC;
1358 case RISCV::NDS_BEQC:
1359 return RISCV::NDS_BNEC;
1360 case RISCV::NDS_BNEC:
1361 return RISCV::NDS_BEQC;
1362 }
1363}
1364
1367 MachineBasicBlock *&FBB,
1369 bool AllowModify) const {
1370 TBB = FBB = nullptr;
1371 Cond.clear();
1372
1373 // If the block has no terminators, it just falls into the block after it.
1374 MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
1375 if (I == MBB.end() || !isUnpredicatedTerminator(*I))
1376 return false;
1377
1378 // Count the number of terminators and find the first unconditional or
1379 // indirect branch.
1380 MachineBasicBlock::iterator FirstUncondOrIndirectBr = MBB.end();
1381 int NumTerminators = 0;
1382 for (auto J = I.getReverse(); J != MBB.rend() && isUnpredicatedTerminator(*J);
1383 J++) {
1384 NumTerminators++;
1385 if (J->getDesc().isUnconditionalBranch() ||
1386 J->getDesc().isIndirectBranch()) {
1387 FirstUncondOrIndirectBr = J.getReverse();
1388 }
1389 }
1390
1391 // If AllowModify is true, we can erase any terminators after
1392 // FirstUncondOrIndirectBR.
1393 if (AllowModify && FirstUncondOrIndirectBr != MBB.end()) {
1394 while (std::next(FirstUncondOrIndirectBr) != MBB.end()) {
1395 std::next(FirstUncondOrIndirectBr)->eraseFromParent();
1396 NumTerminators--;
1397 }
1398 I = FirstUncondOrIndirectBr;
1399 }
1400
1401 // We can't handle blocks that end in an indirect branch.
1402 if (I->getDesc().isIndirectBranch())
1403 return true;
1404
1405 // We can't handle Generic branch opcodes from Global ISel.
1406 if (I->isPreISelOpcode())
1407 return true;
1408
1409 // We can't handle blocks with more than 2 terminators.
1410 if (NumTerminators > 2)
1411 return true;
1412
1413 // Handle a single unconditional branch.
1414 if (NumTerminators == 1 && I->getDesc().isUnconditionalBranch()) {
1416 return false;
1417 }
1418
1419 // Handle a single conditional branch.
1420 if (NumTerminators == 1 && I->getDesc().isConditionalBranch()) {
1422 return false;
1423 }
1424
1425 // Handle a conditional branch followed by an unconditional branch.
1426 if (NumTerminators == 2 && std::prev(I)->getDesc().isConditionalBranch() &&
1427 I->getDesc().isUnconditionalBranch()) {
1428 parseCondBranch(*std::prev(I), TBB, Cond);
1429 FBB = getBranchDestBlock(*I);
1430 return false;
1431 }
1432
1433 // Otherwise, we can't handle this.
1434 return true;
1435}
1436
1438 int *BytesRemoved) const {
1439 if (BytesRemoved)
1440 *BytesRemoved = 0;
1441 MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
1442 if (I == MBB.end())
1443 return 0;
1444
1445 if (!I->getDesc().isUnconditionalBranch() &&
1446 !I->getDesc().isConditionalBranch())
1447 return 0;
1448
1449 // Remove the branch.
1450 if (BytesRemoved)
1451 *BytesRemoved += getInstSizeInBytes(*I);
1452 I->eraseFromParent();
1453
1454 I = MBB.end();
1455
1456 if (I == MBB.begin())
1457 return 1;
1458 --I;
1459 if (!I->getDesc().isConditionalBranch())
1460 return 1;
1461
1462 // Remove the branch.
1463 if (BytesRemoved)
1464 *BytesRemoved += getInstSizeInBytes(*I);
1465 I->eraseFromParent();
1466 return 2;
1467}
1468
1469// Inserts a branch into the end of the specific MachineBasicBlock, returning
1470// the number of instructions inserted.
1473 ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const {
1474 if (BytesAdded)
1475 *BytesAdded = 0;
1476
1477 // Shouldn't be a fall through.
1478 assert(TBB && "insertBranch must not be told to insert a fallthrough");
1479 assert((Cond.size() == 3 || Cond.size() == 0) &&
1480 "RISC-V branch conditions have two components!");
1481
1482 // Unconditional branch.
1483 if (Cond.empty()) {
1484 MachineInstr &MI = *BuildMI(&MBB, DL, get(RISCV::PseudoBR)).addMBB(TBB);
1485 if (BytesAdded)
1486 *BytesAdded += getInstSizeInBytes(MI);
1487 return 1;
1488 }
1489
1490 // Either a one or two-way conditional branch.
1491 MachineInstr &CondMI = *BuildMI(&MBB, DL, get(Cond[0].getImm()))
1492 .add(Cond[1])
1493 .add(Cond[2])
1494 .addMBB(TBB);
1495 if (BytesAdded)
1496 *BytesAdded += getInstSizeInBytes(CondMI);
1497
1498 // One-way conditional branch.
1499 if (!FBB)
1500 return 1;
1501
1502 // Two-way conditional branch.
1503 MachineInstr &MI = *BuildMI(&MBB, DL, get(RISCV::PseudoBR)).addMBB(FBB);
1504 if (BytesAdded)
1505 *BytesAdded += getInstSizeInBytes(MI);
1506 return 2;
1507}
1508
1510 MachineBasicBlock &DestBB,
1511 MachineBasicBlock &RestoreBB,
1512 const DebugLoc &DL, int64_t BrOffset,
1513 RegScavenger *RS) const {
1514 assert(RS && "RegScavenger required for long branching");
1515 assert(MBB.empty() &&
1516 "new block should be inserted for expanding unconditional branch");
1517 assert(MBB.pred_size() == 1);
1518 assert(RestoreBB.empty() &&
1519 "restore block should be inserted for restoring clobbered registers");
1520
1521 MachineFunction *MF = MBB.getParent();
1522 MachineRegisterInfo &MRI = MF->getRegInfo();
1525
1526 if (!isInt<32>(BrOffset))
1528 "Branch offsets outside of the signed 32-bit range not supported");
1529
1530 // FIXME: A virtual register must be used initially, as the register
1531 // scavenger won't work with empty blocks (SIInstrInfo::insertIndirectBranch
1532 // uses the same workaround).
1533 Register ScratchReg = MRI.createVirtualRegister(&RISCV::GPRJALRRegClass);
1534 auto II = MBB.end();
1535 // We may also update the jump target to RestoreBB later.
1536 MachineInstr &MI = *BuildMI(MBB, II, DL, get(RISCV::PseudoJump))
1537 .addReg(ScratchReg, RegState::Define | RegState::Dead)
1538 .addMBB(&DestBB, RISCVII::MO_CALL);
1539
1540 RS->enterBasicBlockEnd(MBB);
1541 // When cf-protection-branch is enabled, we must use t2 (x7) for software
1542 // guarded branches to hold the landing pad label.
1543 bool HasCFBranch =
1544 MF->getInfo<RISCVMachineFunctionInfo>()->hasCFProtectionBranch();
1545 const TargetRegisterClass *RC = &RISCV::GPRRegClass;
1546 if (HasCFBranch)
1547 RC = &RISCV::GPRX7RegClass;
1548 Register TmpGPR =
1549 RS->scavengeRegisterBackwards(*RC, MI.getIterator(),
1550 /*RestoreAfter=*/false, /*SpAdj=*/0,
1551 /*AllowSpill=*/false);
1552 if (TmpGPR.isValid())
1553 RS->setRegUsed(TmpGPR);
1554 else {
1555 // The case when there is no scavenged register needs special handling.
1556
1557 // Pick s11(or s1 for rve) because it doesn't make a difference.
1558 TmpGPR = STI.hasStdExtE() ? RISCV::X9 : RISCV::X27;
1559 // Force t2 if cf-protection-branch is enabled
1560 if (HasCFBranch)
1561 TmpGPR = RISCV::X7;
1562
1563 int FrameIndex = RVFI->getBranchRelaxationScratchFrameIndex();
1564 if (FrameIndex == -1)
1565 report_fatal_error("underestimated function size");
1566
1567 storeRegToStackSlot(MBB, MI, TmpGPR, /*IsKill=*/true, FrameIndex,
1568 &RISCV::GPRRegClass, Register());
1569 TRI->eliminateFrameIndex(std::prev(MI.getIterator()),
1570 /*SpAdj=*/0, /*FIOperandNum=*/1);
1571
1572 MI.getOperand(1).setMBB(&RestoreBB);
1573
1574 loadRegFromStackSlot(RestoreBB, RestoreBB.end(), TmpGPR, FrameIndex,
1575 &RISCV::GPRRegClass, Register());
1576 TRI->eliminateFrameIndex(RestoreBB.back(),
1577 /*SpAdj=*/0, /*FIOperandNum=*/1);
1578 }
1579
1580 MRI.replaceRegWith(ScratchReg, TmpGPR);
1581 MRI.clearVirtRegs();
1582}
1583
1586 assert((Cond.size() == 3) && "Invalid branch condition!");
1587
1589
1590 return false;
1591}
1592
1593// Return true if the instruction is a load immediate instruction (i.e.
1594// (ADDI x0, imm) or (BSETI x0, imm)).
1595static bool isLoadImm(const MachineInstr *MI, int64_t &Imm) {
1596 if (MI->getOpcode() == RISCV::ADDI && MI->getOperand(1).isReg() &&
1597 MI->getOperand(1).getReg() == RISCV::X0) {
1598 Imm = MI->getOperand(2).getImm();
1599 return true;
1600 }
1601 // BSETI can be used to create power of 2 constants. Only 2048 is currently
1602 // interesting because it is 1 more than the maximum ADDI constant.
1603 if (MI->getOpcode() == RISCV::BSETI && MI->getOperand(1).isReg() &&
1604 MI->getOperand(1).getReg() == RISCV::X0 &&
1605 MI->getOperand(2).getImm() == 11) {
1606 Imm = 2048;
1607 return true;
1608 }
1609 return false;
1610}
1611
1613 const MachineOperand &Op, int64_t &Imm) {
1614 // Either a load from immediate instruction or X0.
1615 if (!Op.isReg())
1616 return false;
1617
1618 Register Reg = Op.getReg();
1619 if (Reg == RISCV::X0) {
1620 Imm = 0;
1621 return true;
1622 }
1623 return Reg.isVirtual() && isLoadImm(MRI.getVRegDef(Reg), Imm);
1624}
1625
1627 bool IsSigned = false;
1628 bool IsEquality = false;
1629 switch (MI.getOpcode()) {
1630 default:
1631 return false;
1632 case RISCV::BEQ:
1633 case RISCV::BNE:
1634 IsEquality = true;
1635 break;
1636 case RISCV::BGE:
1637 case RISCV::BLT:
1638 IsSigned = true;
1639 break;
1640 case RISCV::BGEU:
1641 case RISCV::BLTU:
1642 break;
1643 }
1644
1645 MachineBasicBlock *MBB = MI.getParent();
1646 MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
1647
1648 const MachineOperand &LHS = MI.getOperand(0);
1649 const MachineOperand &RHS = MI.getOperand(1);
1650 MachineBasicBlock *TBB = MI.getOperand(2).getMBB();
1651
1652 RISCVCC::CondCode CC = getCondFromBranchOpc(MI.getOpcode());
1654
1655 // Canonicalize conditional branches which can be constant folded into
1656 // beqz or bnez. We can't modify the CFG here.
1657 int64_t C0, C1;
1658 if (isFromLoadImm(MRI, LHS, C0) && isFromLoadImm(MRI, RHS, C1)) {
1659 unsigned NewOpc = evaluateCondBranch(CC, C0, C1) ? RISCV::BEQ : RISCV::BNE;
1660 // Build the new branch and remove the old one.
1661 BuildMI(*MBB, MI, MI.getDebugLoc(), get(NewOpc))
1662 .addReg(RISCV::X0)
1663 .addReg(RISCV::X0)
1664 .addMBB(TBB);
1665 MI.eraseFromParent();
1666 return true;
1667 }
1668
1669 if (IsEquality)
1670 return false;
1671
1672 // For two constants C0 and C1 from
1673 // ```
1674 // li Y, C0
1675 // li Z, C1
1676 // ```
1677 // 1. if C1 = C0 + 1
1678 // we can turn:
1679 // (a) blt Y, X -> bge X, Z
1680 // (b) bge Y, X -> blt X, Z
1681 //
1682 // 2. if C1 = C0 - 1
1683 // we can turn:
1684 // (a) blt X, Y -> bge Z, X
1685 // (b) bge X, Y -> blt Z, X
1686 //
1687 // To make sure this optimization is really beneficial, we only
1688 // optimize for cases where Y had only one use (i.e. only used by the branch).
1689 // Try to find the register for constant Z; return
1690 // invalid register otherwise.
1691 auto searchConst = [&](int64_t C1) -> Register {
1693 auto DefC1 = std::find_if(++II, E, [&](const MachineInstr &I) -> bool {
1694 int64_t Imm;
1695 return isLoadImm(&I, Imm) && Imm == C1 &&
1696 I.getOperand(0).getReg().isVirtual();
1697 });
1698 if (DefC1 != E)
1699 return DefC1->getOperand(0).getReg();
1700
1701 return Register();
1702 };
1703
1704 unsigned NewOpc = RISCVCC::getBrCond(getInverseBranchCondition(CC));
1705
1706 // Might be case 1.
1707 // Don't change 0 to 1 since we can use x0.
1708 // For unsigned cases changing -1U to 0 would be incorrect.
1709 // The incorrect case for signed would be INT_MAX, but isFromLoadImm can't
1710 // return that.
1711 if (isFromLoadImm(MRI, LHS, C0) && C0 != 0 && LHS.getReg().isVirtual() &&
1712 MRI.hasOneUse(LHS.getReg()) && (IsSigned || C0 != -1)) {
1713 assert((isInt<12>(C0) || C0 == 2048) && "Unexpected immediate");
1714 if (Register RegZ = searchConst(C0 + 1)) {
1715 BuildMI(*MBB, MI, MI.getDebugLoc(), get(NewOpc))
1716 .add(RHS)
1717 .addReg(RegZ)
1718 .addMBB(TBB);
1719 // We might extend the live range of Z, clear its kill flag to
1720 // account for this.
1721 MRI.clearKillFlags(RegZ);
1722 MI.eraseFromParent();
1723 return true;
1724 }
1725 }
1726
1727 // Might be case 2.
1728 // For signed cases we don't want to change 0 since we can use x0.
1729 // For unsigned cases changing 0 to -1U would be incorrect.
1730 // The incorrect case for signed would be INT_MIN, but isFromLoadImm can't
1731 // return that.
1732 if (isFromLoadImm(MRI, RHS, C0) && C0 != 0 && RHS.getReg().isVirtual() &&
1733 MRI.hasOneUse(RHS.getReg())) {
1734 assert((isInt<12>(C0) || C0 == 2048) && "Unexpected immediate");
1735 if (Register RegZ = searchConst(C0 - 1)) {
1736 BuildMI(*MBB, MI, MI.getDebugLoc(), get(NewOpc))
1737 .addReg(RegZ)
1738 .add(LHS)
1739 .addMBB(TBB);
1740 // We might extend the live range of Z, clear its kill flag to
1741 // account for this.
1742 MRI.clearKillFlags(RegZ);
1743 MI.eraseFromParent();
1744 return true;
1745 }
1746 }
1747
1748 return false;
1749}
1750
1753 assert(MI.getDesc().isBranch() && "Unexpected opcode!");
1754 // The branch target is always the last operand.
1755 int NumOp = MI.getNumExplicitOperands();
1756 return MI.getOperand(NumOp - 1).getMBB();
1757}
1758
1760 int64_t BrOffset) const {
1761 unsigned XLen = STI.getXLen();
1762 // Ideally we could determine the supported branch offset from the
1763 // RISCVII::FormMask, but this can't be used for Pseudo instructions like
1764 // PseudoBR.
1765 switch (BranchOp) {
1766 default:
1767 llvm_unreachable("Unexpected opcode!");
1768 case RISCV::NDS_BBC:
1769 case RISCV::NDS_BBS:
1770 case RISCV::NDS_BEQC:
1771 case RISCV::NDS_BNEC:
1772 return isInt<11>(BrOffset);
1773 case RISCV::BEQ:
1774 case RISCV::BNE:
1775 case RISCV::BLT:
1776 case RISCV::BGE:
1777 case RISCV::BLTU:
1778 case RISCV::BGEU:
1779 case RISCV::BEQI:
1780 case RISCV::BNEI:
1781 case RISCV::CV_BEQIMM:
1782 case RISCV::CV_BNEIMM:
1783 case RISCV::QC_BEQI:
1784 case RISCV::QC_BNEI:
1785 case RISCV::QC_BGEI:
1786 case RISCV::QC_BLTI:
1787 case RISCV::QC_BLTUI:
1788 case RISCV::QC_BGEUI:
1789 case RISCV::QC_E_BEQI:
1790 case RISCV::QC_E_BNEI:
1791 case RISCV::QC_E_BGEI:
1792 case RISCV::QC_E_BLTI:
1793 case RISCV::QC_E_BLTUI:
1794 case RISCV::QC_E_BGEUI:
1795 return isInt<13>(BrOffset);
1796 case RISCV::JAL:
1797 case RISCV::PseudoBR:
1798 return isInt<21>(BrOffset);
1799 case RISCV::PseudoJump:
1800 return isInt<32>(SignExtend64(BrOffset + 0x800, XLen));
1801 }
1802}
1803
1804// If the operation has a predicated pseudo instruction, return the pseudo
1805// instruction opcode. Otherwise, return RISCV::INSTRUCTION_LIST_END.
1806// TODO: Support more operations.
1807unsigned getPredicatedOpcode(unsigned Opcode) {
1808 // clang-format off
1809 switch (Opcode) {
1810 case RISCV::ADD: return RISCV::PseudoCCADD;
1811 case RISCV::SUB: return RISCV::PseudoCCSUB;
1812 case RISCV::SLL: return RISCV::PseudoCCSLL;
1813 case RISCV::SRL: return RISCV::PseudoCCSRL;
1814 case RISCV::SRA: return RISCV::PseudoCCSRA;
1815 case RISCV::AND: return RISCV::PseudoCCAND;
1816 case RISCV::OR: return RISCV::PseudoCCOR;
1817 case RISCV::XOR: return RISCV::PseudoCCXOR;
1818 case RISCV::MAX: return RISCV::PseudoCCMAX;
1819 case RISCV::MAXU: return RISCV::PseudoCCMAXU;
1820 case RISCV::MIN: return RISCV::PseudoCCMIN;
1821 case RISCV::MINU: return RISCV::PseudoCCMINU;
1822 case RISCV::MUL: return RISCV::PseudoCCMUL;
1823 case RISCV::LUI: return RISCV::PseudoCCLUI;
1824 case RISCV::QC_LI: return RISCV::PseudoCCQC_LI;
1825 case RISCV::QC_E_LI: return RISCV::PseudoCCQC_E_LI;
1826
1827 case RISCV::ADDI: return RISCV::PseudoCCADDI;
1828 case RISCV::SLLI: return RISCV::PseudoCCSLLI;
1829 case RISCV::SRLI: return RISCV::PseudoCCSRLI;
1830 case RISCV::SRAI: return RISCV::PseudoCCSRAI;
1831 case RISCV::ANDI: return RISCV::PseudoCCANDI;
1832 case RISCV::ORI: return RISCV::PseudoCCORI;
1833 case RISCV::XORI: return RISCV::PseudoCCXORI;
1834
1835 case RISCV::ADDW: return RISCV::PseudoCCADDW;
1836 case RISCV::SUBW: return RISCV::PseudoCCSUBW;
1837 case RISCV::SLLW: return RISCV::PseudoCCSLLW;
1838 case RISCV::SRLW: return RISCV::PseudoCCSRLW;
1839 case RISCV::SRAW: return RISCV::PseudoCCSRAW;
1840
1841 case RISCV::ADDIW: return RISCV::PseudoCCADDIW;
1842 case RISCV::SLLIW: return RISCV::PseudoCCSLLIW;
1843 case RISCV::SRLIW: return RISCV::PseudoCCSRLIW;
1844 case RISCV::SRAIW: return RISCV::PseudoCCSRAIW;
1845
1846 case RISCV::ANDN: return RISCV::PseudoCCANDN;
1847 case RISCV::ORN: return RISCV::PseudoCCORN;
1848 case RISCV::XNOR: return RISCV::PseudoCCXNOR;
1849
1850 case RISCV::NDS_BFOS: return RISCV::PseudoCCNDS_BFOS;
1851 case RISCV::NDS_BFOZ: return RISCV::PseudoCCNDS_BFOZ;
1852 }
1853 // clang-format on
1854
1855 return RISCV::INSTRUCTION_LIST_END;
1856}
1857
1858/// Identify instructions that can be folded into a CCMOV instruction, and
1859/// return the defining instruction.
1861 const MachineRegisterInfo &MRI,
1862 const TargetInstrInfo *TII,
1863 const RISCVSubtarget &STI) {
1864 if (!Reg.isVirtual())
1865 return nullptr;
1866 if (!MRI.hasOneNonDBGUse(Reg))
1867 return nullptr;
1868 MachineInstr *MI = MRI.getVRegDef(Reg);
1869 if (!MI)
1870 return nullptr;
1871
1872 if (!STI.hasShortForwardBranchIMinMax() &&
1873 (MI->getOpcode() == RISCV::MAX || MI->getOpcode() == RISCV::MIN ||
1874 MI->getOpcode() == RISCV::MINU || MI->getOpcode() == RISCV::MAXU))
1875 return nullptr;
1876
1877 if (!STI.hasShortForwardBranchIMul() && MI->getOpcode() == RISCV::MUL)
1878 return nullptr;
1879
1880 // Check if MI can be predicated and folded into the CCMOV.
1881 if (getPredicatedOpcode(MI->getOpcode()) == RISCV::INSTRUCTION_LIST_END)
1882 return nullptr;
1883 // Don't predicate li idiom.
1884 if (MI->getOpcode() == RISCV::ADDI && MI->getOperand(1).isReg() &&
1885 MI->getOperand(1).getReg() == RISCV::X0)
1886 return nullptr;
1887 // Check if MI has any other defs or physreg uses.
1888 for (const MachineOperand &MO : llvm::drop_begin(MI->operands())) {
1889 // Reject frame index operands, PEI can't handle the predicated pseudos.
1890 if (MO.isFI() || MO.isCPI() || MO.isJTI())
1891 return nullptr;
1892 if (!MO.isReg())
1893 continue;
1894 // MI can't have any tied operands, that would conflict with predication.
1895 if (MO.isTied())
1896 return nullptr;
1897 if (MO.isDef())
1898 return nullptr;
1899 // Allow constant physregs.
1900 if (MO.getReg().isPhysical() && !MRI.isConstantPhysReg(MO.getReg()))
1901 return nullptr;
1902 }
1903 bool DontMoveAcrossStores = true;
1904 if (!MI->isSafeToMove(DontMoveAcrossStores))
1905 return nullptr;
1906 return MI;
1907}
1908
1912 bool PreferFalse) const {
1913 assert(MI.getOpcode() == RISCV::PseudoCCMOVGPR &&
1914 "Unknown select instruction");
1915 if (!STI.hasShortForwardBranchIALU())
1916 return nullptr;
1917
1918 MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
1920 canFoldAsPredicatedOp(MI.getOperand(2).getReg(), MRI, this, STI);
1921 bool Invert = !DefMI;
1922 if (!DefMI)
1923 DefMI = canFoldAsPredicatedOp(MI.getOperand(1).getReg(), MRI, this, STI);
1924 if (!DefMI)
1925 return nullptr;
1926
1927 // Find new register class to use.
1928 MachineOperand FalseReg = MI.getOperand(Invert ? 2 : 1);
1929 Register DestReg = MI.getOperand(0).getReg();
1930 const TargetRegisterClass *PreviousClass = MRI.getRegClass(FalseReg.getReg());
1931 if (!MRI.constrainRegClass(DestReg, PreviousClass))
1932 return nullptr;
1933
1934 unsigned PredOpc = getPredicatedOpcode(DefMI->getOpcode());
1935 assert(PredOpc != RISCV::INSTRUCTION_LIST_END && "Unexpected opcode!");
1936
1937 // Create a new predicated version of DefMI.
1938 MachineInstrBuilder NewMI =
1939 BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), get(PredOpc), DestReg);
1940
1941 // Copy the false register.
1942 NewMI.add(FalseReg);
1943
1944 // Copy all the DefMI operands.
1945 const MCInstrDesc &DefDesc = DefMI->getDesc();
1946 for (unsigned i = 1, e = DefDesc.getNumOperands(); i != e; ++i)
1947 NewMI.add(DefMI->getOperand(i));
1948
1949 // Add branch opcode, inverting if necessary.
1950 unsigned BCCOpcode = MI.getOperand(MI.getNumExplicitOperands() - 3).getImm();
1951 if (Invert)
1952 BCCOpcode = RISCVCC::getInverseBranchOpcode(BCCOpcode);
1953 NewMI.addImm(BCCOpcode);
1954
1955 // Copy the condition portion.
1956 NewMI.add(MI.getOperand(MI.getNumExplicitOperands() - 2));
1957 NewMI.add(MI.getOperand(MI.getNumExplicitOperands() - 1));
1958
1959 // Update SeenMIs set: register newly created MI and erase removed DefMI.
1960 SeenMIs.insert(NewMI);
1961 SeenMIs.erase(DefMI);
1962
1963 // If MI is inside a loop, and DefMI is outside the loop, then kill flags on
1964 // DefMI would be invalid when transferred inside the loop. Checking for a
1965 // loop is expensive, but at least remove kill flags if they are in different
1966 // BBs.
1967 if (DefMI->getParent() != MI.getParent())
1968 NewMI->clearKillInfo();
1969
1970 // The caller will erase MI, but not DefMI.
1971 DefMI->eraseFromParent();
1972 return NewMI;
1973}
1974
1976 if (MI.isMetaInstruction())
1977 return 0;
1978
1979 unsigned Opcode = MI.getOpcode();
1980
1981 if (Opcode == TargetOpcode::INLINEASM ||
1982 Opcode == TargetOpcode::INLINEASM_BR) {
1983 const MachineFunction &MF = *MI.getParent()->getParent();
1984 return getInlineAsmLength(MI.getOperand(0).getSymbolName(),
1985 *MF.getTarget().getMCAsmInfo());
1986 }
1987
1988 if (requiresNTLHint(MI)) {
1989 if (STI.hasStdExtZca()) {
1990 if (isCompressibleInst(MI, STI))
1991 return 4; // c.ntl.all + c.load/c.store
1992 return 6; // c.ntl.all + load/store
1993 }
1994 return 8; // ntl.all + load/store
1995 }
1996
1997 if (Opcode == TargetOpcode::BUNDLE)
1998 return getInstBundleLength(MI);
1999
2000 if (MI.getParent() && MI.getParent()->getParent()) {
2001 if (isCompressibleInst(MI, STI))
2002 return 2;
2003 }
2004
2005 switch (Opcode) {
2006 case RISCV::PseudoMV_FPR16INX:
2007 case RISCV::PseudoMV_FPR32INX:
2008 // MV is always compressible to either c.mv or c.li rd, 0.
2009 return STI.hasStdExtZca() ? 2 : 4;
2010 // Below cases are for short forward branch pseudos
2011 case RISCV::PseudoCCMOVGPRNoX0:
2012 return get(MI.getOperand(MI.getNumExplicitOperands() - 3).getImm())
2013 .getSize() +
2014 2;
2015 case RISCV::PseudoCCMOVGPR:
2016 case RISCV::PseudoCCADD:
2017 case RISCV::PseudoCCSUB:
2018 case RISCV::PseudoCCSLL:
2019 case RISCV::PseudoCCSRL:
2020 case RISCV::PseudoCCSRA:
2021 case RISCV::PseudoCCAND:
2022 case RISCV::PseudoCCOR:
2023 case RISCV::PseudoCCXOR:
2024 case RISCV::PseudoCCADDI:
2025 case RISCV::PseudoCCANDI:
2026 case RISCV::PseudoCCORI:
2027 case RISCV::PseudoCCXORI:
2028 case RISCV::PseudoCCLUI:
2029 case RISCV::PseudoCCSLLI:
2030 case RISCV::PseudoCCSRLI:
2031 case RISCV::PseudoCCSRAI:
2032 case RISCV::PseudoCCADDW:
2033 case RISCV::PseudoCCSUBW:
2034 case RISCV::PseudoCCSLLW:
2035 case RISCV::PseudoCCSRLW:
2036 case RISCV::PseudoCCSRAW:
2037 case RISCV::PseudoCCADDIW:
2038 case RISCV::PseudoCCSLLIW:
2039 case RISCV::PseudoCCSRLIW:
2040 case RISCV::PseudoCCSRAIW:
2041 case RISCV::PseudoCCANDN:
2042 case RISCV::PseudoCCORN:
2043 case RISCV::PseudoCCXNOR:
2044 case RISCV::PseudoCCMAX:
2045 case RISCV::PseudoCCMIN:
2046 case RISCV::PseudoCCMAXU:
2047 case RISCV::PseudoCCMINU:
2048 case RISCV::PseudoCCMUL:
2049 case RISCV::PseudoCCLB:
2050 case RISCV::PseudoCCLH:
2051 case RISCV::PseudoCCLW:
2052 case RISCV::PseudoCCLHU:
2053 case RISCV::PseudoCCLBU:
2054 case RISCV::PseudoCCLWU:
2055 case RISCV::PseudoCCLD:
2056 case RISCV::PseudoCCQC_LI:
2057 return get(MI.getOperand(MI.getNumExplicitOperands() - 3).getImm())
2058 .getSize() +
2059 4;
2060 case RISCV::PseudoCCQC_E_LI:
2061 case RISCV::PseudoCCQC_E_LB:
2062 case RISCV::PseudoCCQC_E_LH:
2063 case RISCV::PseudoCCQC_E_LW:
2064 case RISCV::PseudoCCQC_E_LHU:
2065 case RISCV::PseudoCCQC_E_LBU:
2066 return get(MI.getOperand(MI.getNumExplicitOperands() - 3).getImm())
2067 .getSize() +
2068 6;
2069 case TargetOpcode::STACKMAP:
2070 // The upper bound for a stackmap intrinsic is the full length of its shadow
2072 case TargetOpcode::PATCHPOINT:
2073 // The size of the patchpoint intrinsic is the number of bytes requested
2075 case TargetOpcode::STATEPOINT: {
2076 // The size of the statepoint intrinsic is the number of bytes requested
2077 unsigned NumBytes = StatepointOpers(&MI).getNumPatchBytes();
2078 // No patch bytes means at most a PseudoCall is emitted
2079 return std::max(NumBytes, 8U);
2080 }
2081 case TargetOpcode::PATCHABLE_FUNCTION_ENTER:
2082 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
2083 case TargetOpcode::PATCHABLE_TAIL_CALL: {
2084 const MachineFunction &MF = *MI.getParent()->getParent();
2085 const Function &F = MF.getFunction();
2086 if (Opcode == TargetOpcode::PATCHABLE_FUNCTION_ENTER &&
2087 F.hasFnAttribute("patchable-function-entry")) {
2088 unsigned Num;
2089 if (F.getFnAttribute("patchable-function-entry")
2090 .getValueAsString()
2091 .getAsInteger(10, Num))
2092 return get(Opcode).getSize();
2093
2094 // Number of C.NOP or NOP
2095 return (STI.hasStdExtZca() ? 2 : 4) * Num;
2096 }
2097 // XRay uses C.JAL + 21 or 33 C.NOP for each sled in RV32 and RV64,
2098 // respectively.
2099 return STI.is64Bit() ? 68 : 44;
2100 }
2101 default:
2102 return get(Opcode).getSize();
2103 }
2104}
2105
2106unsigned RISCVInstrInfo::getInstBundleLength(const MachineInstr &MI) const {
2107 unsigned Size = 0;
2109 MachineBasicBlock::const_instr_iterator E = MI.getParent()->instr_end();
2110 while (++I != E && I->isInsideBundle()) {
2111 assert(!I->isBundle() && "No nested bundle!");
2113 }
2114 return Size;
2115}
2116
2118 const unsigned Opcode = MI.getOpcode();
2119 switch (Opcode) {
2120 default:
2121 break;
2122 case RISCV::FSGNJ_D:
2123 case RISCV::FSGNJ_S:
2124 case RISCV::FSGNJ_H:
2125 case RISCV::FSGNJ_D_INX:
2126 case RISCV::FSGNJ_D_IN32X:
2127 case RISCV::FSGNJ_S_INX:
2128 case RISCV::FSGNJ_H_INX:
2129 // The canonical floating-point move is fsgnj rd, rs, rs.
2130 return MI.getOperand(1).isReg() && MI.getOperand(2).isReg() &&
2131 MI.getOperand(1).getReg() == MI.getOperand(2).getReg();
2132 case RISCV::ADDI:
2133 case RISCV::ORI:
2134 case RISCV::XORI:
2135 return (MI.getOperand(1).isReg() &&
2136 MI.getOperand(1).getReg() == RISCV::X0) ||
2137 (MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0);
2138 }
2139 return MI.isAsCheapAsAMove();
2140}
2141
2142std::optional<DestSourcePair>
2144 if (MI.isMoveReg())
2145 return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
2146 switch (MI.getOpcode()) {
2147 default:
2148 break;
2149 case RISCV::ADD:
2150 case RISCV::OR:
2151 case RISCV::XOR:
2152 if (MI.getOperand(1).isReg() && MI.getOperand(1).getReg() == RISCV::X0 &&
2153 MI.getOperand(2).isReg())
2154 return DestSourcePair{MI.getOperand(0), MI.getOperand(2)};
2155 if (MI.getOperand(2).isReg() && MI.getOperand(2).getReg() == RISCV::X0 &&
2156 MI.getOperand(1).isReg())
2157 return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
2158 break;
2159 case RISCV::ADDI:
2160 // Operand 1 can be a frameindex but callers expect registers
2161 if (MI.getOperand(1).isReg() && MI.getOperand(2).isImm() &&
2162 MI.getOperand(2).getImm() == 0)
2163 return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
2164 break;
2165 case RISCV::SUB:
2166 if (MI.getOperand(2).isReg() && MI.getOperand(2).getReg() == RISCV::X0 &&
2167 MI.getOperand(1).isReg())
2168 return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
2169 break;
2170 case RISCV::SH1ADD:
2171 case RISCV::SH1ADD_UW:
2172 case RISCV::SH2ADD:
2173 case RISCV::SH2ADD_UW:
2174 case RISCV::SH3ADD:
2175 case RISCV::SH3ADD_UW:
2176 if (MI.getOperand(1).isReg() && MI.getOperand(1).getReg() == RISCV::X0 &&
2177 MI.getOperand(2).isReg())
2178 return DestSourcePair{MI.getOperand(0), MI.getOperand(2)};
2179 break;
2180 case RISCV::FSGNJ_D:
2181 case RISCV::FSGNJ_S:
2182 case RISCV::FSGNJ_H:
2183 case RISCV::FSGNJ_D_INX:
2184 case RISCV::FSGNJ_D_IN32X:
2185 case RISCV::FSGNJ_S_INX:
2186 case RISCV::FSGNJ_H_INX:
2187 // The canonical floating-point move is fsgnj rd, rs, rs.
2188 if (MI.getOperand(1).isReg() && MI.getOperand(2).isReg() &&
2189 MI.getOperand(1).getReg() == MI.getOperand(2).getReg())
2190 return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
2191 break;
2192 }
2193 return std::nullopt;
2194}
2195
2197 if (ForceMachineCombinerStrategy.getNumOccurrences() == 0) {
2198 // The option is unused. Choose Local strategy only for in-order cores. When
2199 // scheduling model is unspecified, use MinInstrCount strategy as more
2200 // generic one.
2201 const auto &SchedModel = STI.getSchedModel();
2202 return (!SchedModel.hasInstrSchedModel() || SchedModel.isOutOfOrder())
2205 }
2206 // The strategy was forced by the option.
2208}
2209
2211 MachineInstr &Root, unsigned &Pattern,
2212 SmallVectorImpl<MachineInstr *> &InsInstrs) const {
2213 int16_t FrmOpIdx =
2214 RISCV::getNamedOperandIdx(Root.getOpcode(), RISCV::OpName::frm);
2215 if (FrmOpIdx < 0) {
2216 assert(all_of(InsInstrs,
2217 [](MachineInstr *MI) {
2218 return RISCV::getNamedOperandIdx(MI->getOpcode(),
2219 RISCV::OpName::frm) < 0;
2220 }) &&
2221 "New instructions require FRM whereas the old one does not have it");
2222 return;
2223 }
2224
2225 const MachineOperand &FRM = Root.getOperand(FrmOpIdx);
2226 MachineFunction &MF = *Root.getMF();
2227
2228 for (auto *NewMI : InsInstrs) {
2229 // We'd already added the FRM operand.
2230 if (static_cast<unsigned>(RISCV::getNamedOperandIdx(
2231 NewMI->getOpcode(), RISCV::OpName::frm)) != NewMI->getNumOperands())
2232 continue;
2233 MachineInstrBuilder MIB(MF, NewMI);
2234 MIB.add(FRM);
2235 if (FRM.getImm() == RISCVFPRndMode::DYN)
2236 MIB.addUse(RISCV::FRM, RegState::Implicit);
2237 }
2238}
2239
2240static bool isFADD(unsigned Opc) {
2241 switch (Opc) {
2242 default:
2243 return false;
2244 case RISCV::FADD_H:
2245 case RISCV::FADD_S:
2246 case RISCV::FADD_D:
2247 return true;
2248 }
2249}
2250
2251static bool isFSUB(unsigned Opc) {
2252 switch (Opc) {
2253 default:
2254 return false;
2255 case RISCV::FSUB_H:
2256 case RISCV::FSUB_S:
2257 case RISCV::FSUB_D:
2258 return true;
2259 }
2260}
2261
2262static bool isFMUL(unsigned Opc) {
2263 switch (Opc) {
2264 default:
2265 return false;
2266 case RISCV::FMUL_H:
2267 case RISCV::FMUL_S:
2268 case RISCV::FMUL_D:
2269 return true;
2270 }
2271}
2272
2273bool RISCVInstrInfo::isVectorAssociativeAndCommutative(const MachineInstr &Inst,
2274 bool Invert) const {
2275#define OPCODE_LMUL_CASE(OPC) \
2276 case RISCV::OPC##_M1: \
2277 case RISCV::OPC##_M2: \
2278 case RISCV::OPC##_M4: \
2279 case RISCV::OPC##_M8: \
2280 case RISCV::OPC##_MF2: \
2281 case RISCV::OPC##_MF4: \
2282 case RISCV::OPC##_MF8
2283
2284#define OPCODE_LMUL_MASK_CASE(OPC) \
2285 case RISCV::OPC##_M1_MASK: \
2286 case RISCV::OPC##_M2_MASK: \
2287 case RISCV::OPC##_M4_MASK: \
2288 case RISCV::OPC##_M8_MASK: \
2289 case RISCV::OPC##_MF2_MASK: \
2290 case RISCV::OPC##_MF4_MASK: \
2291 case RISCV::OPC##_MF8_MASK
2292
2293 unsigned Opcode = Inst.getOpcode();
2294 if (Invert) {
2295 if (auto InvOpcode = getInverseOpcode(Opcode))
2296 Opcode = *InvOpcode;
2297 else
2298 return false;
2299 }
2300
2301 // clang-format off
2302 switch (Opcode) {
2303 default:
2304 return false;
2305 OPCODE_LMUL_CASE(PseudoVADD_VV):
2306 OPCODE_LMUL_MASK_CASE(PseudoVADD_VV):
2307 OPCODE_LMUL_CASE(PseudoVMUL_VV):
2308 OPCODE_LMUL_MASK_CASE(PseudoVMUL_VV):
2309 return true;
2310 }
2311 // clang-format on
2312
2313#undef OPCODE_LMUL_MASK_CASE
2314#undef OPCODE_LMUL_CASE
2315}
2316
2317bool RISCVInstrInfo::areRVVInstsReassociable(const MachineInstr &Root,
2318 const MachineInstr &Prev) const {
2319 if (!areOpcodesEqualOrInverse(Root.getOpcode(), Prev.getOpcode()))
2320 return false;
2321
2322 assert(Root.getMF() == Prev.getMF());
2323 const MachineRegisterInfo *MRI = &Root.getMF()->getRegInfo();
2324 const TargetRegisterInfo *TRI = MRI->getTargetRegisterInfo();
2325
2326 // Make sure vtype operands are also the same.
2327 const MCInstrDesc &Desc = get(Root.getOpcode());
2328 const uint64_t TSFlags = Desc.TSFlags;
2329
2330 auto checkImmOperand = [&](unsigned OpIdx) {
2331 return Root.getOperand(OpIdx).getImm() == Prev.getOperand(OpIdx).getImm();
2332 };
2333
2334 auto checkRegOperand = [&](unsigned OpIdx) {
2335 return Root.getOperand(OpIdx).getReg() == Prev.getOperand(OpIdx).getReg();
2336 };
2337
2338 // PassThru
2339 // TODO: Potentially we can loosen the condition to consider Root to be
2340 // associable with Prev if Root has NoReg as passthru. In which case we
2341 // also need to loosen the condition on vector policies between these.
2342 if (!checkRegOperand(1))
2343 return false;
2344
2345 // SEW
2346 if (RISCVII::hasSEWOp(TSFlags) &&
2347 !checkImmOperand(RISCVII::getSEWOpNum(Desc)))
2348 return false;
2349
2350 // Mask
2351 if (RISCVII::usesMaskPolicy(TSFlags)) {
2352 const MachineBasicBlock *MBB = Root.getParent();
2355 Register MI1VReg;
2356
2357 bool SeenMI2 = false;
2358 for (auto End = MBB->rend(), It = It1; It != End; ++It) {
2359 if (It == It2) {
2360 SeenMI2 = true;
2361 if (!MI1VReg.isValid())
2362 // There is no V0 def between Root and Prev; they're sharing the
2363 // same V0.
2364 break;
2365 }
2366
2367 if (It->modifiesRegister(RISCV::V0, TRI)) {
2368 Register SrcReg = It->getOperand(1).getReg();
2369 // If it's not VReg it'll be more difficult to track its defs, so
2370 // bailing out here just to be safe.
2371 if (!SrcReg.isVirtual())
2372 return false;
2373
2374 if (!MI1VReg.isValid()) {
2375 // This is the V0 def for Root.
2376 MI1VReg = SrcReg;
2377 continue;
2378 }
2379
2380 // Some random mask updates.
2381 if (!SeenMI2)
2382 continue;
2383
2384 // This is the V0 def for Prev; check if it's the same as that of
2385 // Root.
2386 if (MI1VReg != SrcReg)
2387 return false;
2388 else
2389 break;
2390 }
2391 }
2392
2393 // If we haven't encountered Prev, it's likely that this function was
2394 // called in a wrong way (e.g. Root is before Prev).
2395 assert(SeenMI2 && "Prev is expected to appear before Root");
2396 }
2397
2398 // Tail / Mask policies
2399 if (RISCVII::hasVecPolicyOp(TSFlags) &&
2400 !checkImmOperand(RISCVII::getVecPolicyOpNum(Desc)))
2401 return false;
2402
2403 // VL
2404 if (RISCVII::hasVLOp(TSFlags)) {
2405 unsigned OpIdx = RISCVII::getVLOpNum(Desc);
2406 const MachineOperand &Op1 = Root.getOperand(OpIdx);
2407 const MachineOperand &Op2 = Prev.getOperand(OpIdx);
2408 if (Op1.getType() != Op2.getType())
2409 return false;
2410 switch (Op1.getType()) {
2412 if (Op1.getReg() != Op2.getReg())
2413 return false;
2414 break;
2416 if (Op1.getImm() != Op2.getImm())
2417 return false;
2418 break;
2419 default:
2420 llvm_unreachable("Unrecognized VL operand type");
2421 }
2422 }
2423
2424 // Rounding modes
2425 if (int Idx = RISCVII::getFRMOpNum(Desc); Idx >= 0 && !checkImmOperand(Idx))
2426 return false;
2427 if (int Idx = RISCVII::getVXRMOpNum(Desc); Idx >= 0 && !checkImmOperand(Idx))
2428 return false;
2429
2430 return true;
2431}
2432
2433// Most of our RVV pseudos have passthru operand, so the real operands
2434// start from index = 2.
2435bool RISCVInstrInfo::hasReassociableVectorSibling(const MachineInstr &Inst,
2436 bool &Commuted) const {
2437 const MachineBasicBlock *MBB = Inst.getParent();
2438 const MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
2440 "Expect the present of passthrough operand.");
2441 MachineInstr *MI1 = MRI.getUniqueVRegDef(Inst.getOperand(2).getReg());
2442 MachineInstr *MI2 = MRI.getUniqueVRegDef(Inst.getOperand(3).getReg());
2443
2444 // If only one operand has the same or inverse opcode and it's the second
2445 // source operand, the operands must be commuted.
2446 Commuted = !areRVVInstsReassociable(Inst, *MI1) &&
2447 areRVVInstsReassociable(Inst, *MI2);
2448 if (Commuted)
2449 std::swap(MI1, MI2);
2450
2451 return areRVVInstsReassociable(Inst, *MI1) &&
2452 (isVectorAssociativeAndCommutative(*MI1) ||
2453 isVectorAssociativeAndCommutative(*MI1, /* Invert */ true)) &&
2455 MRI.hasOneNonDBGUse(MI1->getOperand(0).getReg());
2456}
2457
2459 const MachineInstr &Inst, const MachineBasicBlock *MBB) const {
2460 if (!isVectorAssociativeAndCommutative(Inst) &&
2461 !isVectorAssociativeAndCommutative(Inst, /*Invert=*/true))
2463
2464 const MachineOperand &Op1 = Inst.getOperand(2);
2465 const MachineOperand &Op2 = Inst.getOperand(3);
2466 const MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
2467
2468 // We need virtual register definitions for the operands that we will
2469 // reassociate.
2470 MachineInstr *MI1 = nullptr;
2471 MachineInstr *MI2 = nullptr;
2472 if (Op1.isReg() && Op1.getReg().isVirtual())
2473 MI1 = MRI.getUniqueVRegDef(Op1.getReg());
2474 if (Op2.isReg() && Op2.getReg().isVirtual())
2475 MI2 = MRI.getUniqueVRegDef(Op2.getReg());
2476
2477 // And at least one operand must be defined in MBB.
2478 return MI1 && MI2 && (MI1->getParent() == MBB || MI2->getParent() == MBB);
2479}
2480
2482 const MachineInstr &Root, unsigned Pattern,
2483 std::array<unsigned, 5> &OperandIndices) const {
2485 if (RISCV::getRVVMCOpcode(Root.getOpcode())) {
2486 // Skip the passthrough operand, so increment all indices by one.
2487 for (unsigned I = 0; I < 5; ++I)
2488 ++OperandIndices[I];
2489 }
2490}
2491
2493 bool &Commuted) const {
2494 if (isVectorAssociativeAndCommutative(Inst) ||
2495 isVectorAssociativeAndCommutative(Inst, /*Invert=*/true))
2496 return hasReassociableVectorSibling(Inst, Commuted);
2497
2498 if (!TargetInstrInfo::hasReassociableSibling(Inst, Commuted))
2499 return false;
2500
2501 const MachineRegisterInfo &MRI = Inst.getMF()->getRegInfo();
2502 unsigned OperandIdx = Commuted ? 2 : 1;
2503 const MachineInstr &Sibling =
2504 *MRI.getVRegDef(Inst.getOperand(OperandIdx).getReg());
2505
2506 int16_t InstFrmOpIdx =
2507 RISCV::getNamedOperandIdx(Inst.getOpcode(), RISCV::OpName::frm);
2508 int16_t SiblingFrmOpIdx =
2509 RISCV::getNamedOperandIdx(Sibling.getOpcode(), RISCV::OpName::frm);
2510
2511 return (InstFrmOpIdx < 0 && SiblingFrmOpIdx < 0) ||
2512 RISCV::hasEqualFRM(Inst, Sibling);
2513}
2514
2516 bool Invert) const {
2517 if (isVectorAssociativeAndCommutative(Inst, Invert))
2518 return true;
2519
2520 unsigned Opc = Inst.getOpcode();
2521 if (Invert) {
2522 auto InverseOpcode = getInverseOpcode(Opc);
2523 if (!InverseOpcode)
2524 return false;
2525 Opc = *InverseOpcode;
2526 }
2527
2528 if (isFADD(Opc) || isFMUL(Opc))
2531
2532 switch (Opc) {
2533 default:
2534 return false;
2535 case RISCV::ADD:
2536 case RISCV::ADDW:
2537 case RISCV::AND:
2538 case RISCV::OR:
2539 case RISCV::XOR:
2540 // From RISC-V ISA spec, if both the high and low bits of the same product
2541 // are required, then the recommended code sequence is:
2542 //
2543 // MULH[[S]U] rdh, rs1, rs2
2544 // MUL rdl, rs1, rs2
2545 // (source register specifiers must be in same order and rdh cannot be the
2546 // same as rs1 or rs2)
2547 //
2548 // Microarchitectures can then fuse these into a single multiply operation
2549 // instead of performing two separate multiplies.
2550 // MachineCombiner may reassociate MUL operands and lose the fusion
2551 // opportunity.
2552 case RISCV::MUL:
2553 case RISCV::MULW:
2554 case RISCV::MIN:
2555 case RISCV::MINU:
2556 case RISCV::MAX:
2557 case RISCV::MAXU:
2558 case RISCV::FMIN_H:
2559 case RISCV::FMIN_S:
2560 case RISCV::FMIN_D:
2561 case RISCV::FMAX_H:
2562 case RISCV::FMAX_S:
2563 case RISCV::FMAX_D:
2564 return true;
2565 }
2566
2567 return false;
2568}
2569
2570std::optional<unsigned>
2571RISCVInstrInfo::getInverseOpcode(unsigned Opcode) const {
2572#define RVV_OPC_LMUL_CASE(OPC, INV) \
2573 case RISCV::OPC##_M1: \
2574 return RISCV::INV##_M1; \
2575 case RISCV::OPC##_M2: \
2576 return RISCV::INV##_M2; \
2577 case RISCV::OPC##_M4: \
2578 return RISCV::INV##_M4; \
2579 case RISCV::OPC##_M8: \
2580 return RISCV::INV##_M8; \
2581 case RISCV::OPC##_MF2: \
2582 return RISCV::INV##_MF2; \
2583 case RISCV::OPC##_MF4: \
2584 return RISCV::INV##_MF4; \
2585 case RISCV::OPC##_MF8: \
2586 return RISCV::INV##_MF8
2587
2588#define RVV_OPC_LMUL_MASK_CASE(OPC, INV) \
2589 case RISCV::OPC##_M1_MASK: \
2590 return RISCV::INV##_M1_MASK; \
2591 case RISCV::OPC##_M2_MASK: \
2592 return RISCV::INV##_M2_MASK; \
2593 case RISCV::OPC##_M4_MASK: \
2594 return RISCV::INV##_M4_MASK; \
2595 case RISCV::OPC##_M8_MASK: \
2596 return RISCV::INV##_M8_MASK; \
2597 case RISCV::OPC##_MF2_MASK: \
2598 return RISCV::INV##_MF2_MASK; \
2599 case RISCV::OPC##_MF4_MASK: \
2600 return RISCV::INV##_MF4_MASK; \
2601 case RISCV::OPC##_MF8_MASK: \
2602 return RISCV::INV##_MF8_MASK
2603
2604 switch (Opcode) {
2605 default:
2606 return std::nullopt;
2607 case RISCV::FADD_H:
2608 return RISCV::FSUB_H;
2609 case RISCV::FADD_S:
2610 return RISCV::FSUB_S;
2611 case RISCV::FADD_D:
2612 return RISCV::FSUB_D;
2613 case RISCV::FSUB_H:
2614 return RISCV::FADD_H;
2615 case RISCV::FSUB_S:
2616 return RISCV::FADD_S;
2617 case RISCV::FSUB_D:
2618 return RISCV::FADD_D;
2619 case RISCV::ADD:
2620 return RISCV::SUB;
2621 case RISCV::SUB:
2622 return RISCV::ADD;
2623 case RISCV::ADDW:
2624 return RISCV::SUBW;
2625 case RISCV::SUBW:
2626 return RISCV::ADDW;
2627 // clang-format off
2628 RVV_OPC_LMUL_CASE(PseudoVADD_VV, PseudoVSUB_VV);
2629 RVV_OPC_LMUL_MASK_CASE(PseudoVADD_VV, PseudoVSUB_VV);
2630 RVV_OPC_LMUL_CASE(PseudoVSUB_VV, PseudoVADD_VV);
2631 RVV_OPC_LMUL_MASK_CASE(PseudoVSUB_VV, PseudoVADD_VV);
2632 // clang-format on
2633 }
2634
2635#undef RVV_OPC_LMUL_MASK_CASE
2636#undef RVV_OPC_LMUL_CASE
2637}
2638
2640 const MachineOperand &MO,
2641 bool DoRegPressureReduce) {
2642 if (!MO.isReg() || !MO.getReg().isVirtual())
2643 return false;
2644 const MachineRegisterInfo &MRI = Root.getMF()->getRegInfo();
2645 MachineInstr *MI = MRI.getVRegDef(MO.getReg());
2646 if (!MI || !isFMUL(MI->getOpcode()))
2647 return false;
2648
2651 return false;
2652
2653 // Try combining even if fmul has more than one use as it eliminates
2654 // dependency between fadd(fsub) and fmul. However, it can extend liveranges
2655 // for fmul operands, so reject the transformation in register pressure
2656 // reduction mode.
2657 if (DoRegPressureReduce && !MRI.hasOneNonDBGUse(MI->getOperand(0).getReg()))
2658 return false;
2659
2660 // Do not combine instructions from different basic blocks.
2661 if (Root.getParent() != MI->getParent())
2662 return false;
2663 return RISCV::hasEqualFRM(Root, *MI);
2664}
2665
2667 SmallVectorImpl<unsigned> &Patterns,
2668 bool DoRegPressureReduce) {
2669 unsigned Opc = Root.getOpcode();
2670 bool IsFAdd = isFADD(Opc);
2671 if (!IsFAdd && !isFSUB(Opc))
2672 return false;
2673 bool Added = false;
2674 if (canCombineFPFusedMultiply(Root, Root.getOperand(1),
2675 DoRegPressureReduce)) {
2678 Added = true;
2679 }
2680 if (canCombineFPFusedMultiply(Root, Root.getOperand(2),
2681 DoRegPressureReduce)) {
2684 Added = true;
2685 }
2686 return Added;
2687}
2688
2689static bool getFPPatterns(MachineInstr &Root,
2690 SmallVectorImpl<unsigned> &Patterns,
2691 bool DoRegPressureReduce) {
2692 return getFPFusedMultiplyPatterns(Root, Patterns, DoRegPressureReduce);
2693}
2694
2695/// Utility routine that checks if \param MO is defined by an
2696/// \param CombineOpc instruction in the basic block \param MBB
2698 const MachineOperand &MO,
2699 unsigned CombineOpc) {
2700 const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
2701 const MachineInstr *MI = nullptr;
2702
2703 if (MO.isReg() && MO.getReg().isVirtual())
2704 MI = MRI.getUniqueVRegDef(MO.getReg());
2705 // And it needs to be in the trace (otherwise, it won't have a depth).
2706 if (!MI || MI->getParent() != &MBB || MI->getOpcode() != CombineOpc)
2707 return nullptr;
2708 // Must only used by the user we combine with.
2709 if (!MRI.hasOneNonDBGUse(MI->getOperand(0).getReg()))
2710 return nullptr;
2711
2712 return MI;
2713}
2714
2715/// Utility routine that checks if \param MO is defined by a SLLI in \param
2716/// MBB that can be combined by splitting across 2 SHXADD instructions. The
2717/// first SHXADD shift amount is given by \param OuterShiftAmt.
2719 const MachineOperand &MO,
2720 unsigned OuterShiftAmt) {
2721 const MachineInstr *ShiftMI = canCombine(MBB, MO, RISCV::SLLI);
2722 if (!ShiftMI)
2723 return false;
2724
2725 unsigned InnerShiftAmt = ShiftMI->getOperand(2).getImm();
2726 if (InnerShiftAmt < OuterShiftAmt || (InnerShiftAmt - OuterShiftAmt) > 3)
2727 return false;
2728
2729 return true;
2730}
2731
2732// Returns the shift amount from a SHXADD instruction. Returns 0 if the
2733// instruction is not a SHXADD.
2734static unsigned getSHXADDShiftAmount(unsigned Opc) {
2735 switch (Opc) {
2736 default:
2737 return 0;
2738 case RISCV::SH1ADD:
2739 return 1;
2740 case RISCV::SH2ADD:
2741 return 2;
2742 case RISCV::SH3ADD:
2743 return 3;
2744 }
2745}
2746
2747// Returns the shift amount from a SHXADD.UW instruction. Returns 0 if the
2748// instruction is not a SHXADD.UW.
2749static unsigned getSHXADDUWShiftAmount(unsigned Opc) {
2750 switch (Opc) {
2751 default:
2752 return 0;
2753 case RISCV::SH1ADD_UW:
2754 return 1;
2755 case RISCV::SH2ADD_UW:
2756 return 2;
2757 case RISCV::SH3ADD_UW:
2758 return 3;
2759 }
2760}
2761
2762// Look for opportunities to combine (sh3add Z, (add X, (slli Y, 5))) into
2763// (sh3add (sh2add Y, Z), X).
2764static bool getSHXADDPatterns(const MachineInstr &Root,
2765 SmallVectorImpl<unsigned> &Patterns) {
2766 unsigned ShiftAmt = getSHXADDShiftAmount(Root.getOpcode());
2767 if (!ShiftAmt)
2768 return false;
2769
2770 const MachineBasicBlock &MBB = *Root.getParent();
2771
2772 const MachineInstr *AddMI = canCombine(MBB, Root.getOperand(2), RISCV::ADD);
2773 if (!AddMI)
2774 return false;
2775
2776 bool Found = false;
2777 if (canCombineShiftIntoShXAdd(MBB, AddMI->getOperand(1), ShiftAmt)) {
2779 Found = true;
2780 }
2781 if (canCombineShiftIntoShXAdd(MBB, AddMI->getOperand(2), ShiftAmt)) {
2783 Found = true;
2784 }
2785
2786 return Found;
2787}
2788
2800
2802 MachineInstr &Root, SmallVectorImpl<unsigned> &Patterns,
2803 bool DoRegPressureReduce) const {
2804
2805 if (getFPPatterns(Root, Patterns, DoRegPressureReduce))
2806 return true;
2807
2808 if (getSHXADDPatterns(Root, Patterns))
2809 return true;
2810
2811 return TargetInstrInfo::getMachineCombinerPatterns(Root, Patterns,
2812 DoRegPressureReduce);
2813}
2814
2815static unsigned getFPFusedMultiplyOpcode(unsigned RootOpc, unsigned Pattern) {
2816 switch (RootOpc) {
2817 default:
2818 llvm_unreachable("Unexpected opcode");
2819 case RISCV::FADD_H:
2820 return RISCV::FMADD_H;
2821 case RISCV::FADD_S:
2822 return RISCV::FMADD_S;
2823 case RISCV::FADD_D:
2824 return RISCV::FMADD_D;
2825 case RISCV::FSUB_H:
2826 return Pattern == RISCVMachineCombinerPattern::FMSUB ? RISCV::FMSUB_H
2827 : RISCV::FNMSUB_H;
2828 case RISCV::FSUB_S:
2829 return Pattern == RISCVMachineCombinerPattern::FMSUB ? RISCV::FMSUB_S
2830 : RISCV::FNMSUB_S;
2831 case RISCV::FSUB_D:
2832 return Pattern == RISCVMachineCombinerPattern::FMSUB ? RISCV::FMSUB_D
2833 : RISCV::FNMSUB_D;
2834 }
2835}
2836
2837static unsigned getAddendOperandIdx(unsigned Pattern) {
2838 switch (Pattern) {
2839 default:
2840 llvm_unreachable("Unexpected pattern");
2843 return 2;
2846 return 1;
2847 }
2848}
2849
2851 unsigned Pattern,
2854 MachineFunction *MF = Root.getMF();
2855 MachineRegisterInfo &MRI = MF->getRegInfo();
2857
2858 MachineOperand &Mul1 = Prev.getOperand(1);
2859 MachineOperand &Mul2 = Prev.getOperand(2);
2860 MachineOperand &Dst = Root.getOperand(0);
2862
2863 Register DstReg = Dst.getReg();
2864 unsigned FusedOpc = getFPFusedMultiplyOpcode(Root.getOpcode(), Pattern);
2865 uint32_t IntersectedFlags = Root.getFlags() & Prev.getFlags();
2866 DebugLoc MergedLoc =
2868
2869 bool Mul1IsKill = Mul1.isKill();
2870 bool Mul2IsKill = Mul2.isKill();
2871 bool AddendIsKill = Addend.isKill();
2872
2873 // We need to clear kill flags since we may be extending the live range past
2874 // a kill. If the mul had kill flags, we can preserve those since we know
2875 // where the previous range stopped.
2876 MRI.clearKillFlags(Mul1.getReg());
2877 MRI.clearKillFlags(Mul2.getReg());
2878
2880 BuildMI(*MF, MergedLoc, TII->get(FusedOpc), DstReg)
2881 .addReg(Mul1.getReg(), getKillRegState(Mul1IsKill))
2882 .addReg(Mul2.getReg(), getKillRegState(Mul2IsKill))
2883 .addReg(Addend.getReg(), getKillRegState(AddendIsKill))
2884 .setMIFlags(IntersectedFlags);
2885
2886 InsInstrs.push_back(MIB);
2887 if (MRI.hasOneNonDBGUse(Prev.getOperand(0).getReg()))
2888 DelInstrs.push_back(&Prev);
2889 DelInstrs.push_back(&Root);
2890}
2891
2892// Combine patterns like (sh3add Z, (add X, (slli Y, 5))) to
2893// (sh3add (sh2add Y, Z), X) if the shift amount can be split across two
2894// shXadd instructions. The outer shXadd keeps its original opcode.
2895static void
2896genShXAddAddShift(MachineInstr &Root, unsigned AddOpIdx,
2899 DenseMap<Register, unsigned> &InstrIdxForVirtReg) {
2900 MachineFunction *MF = Root.getMF();
2901 MachineRegisterInfo &MRI = MF->getRegInfo();
2903
2904 unsigned OuterShiftAmt = getSHXADDShiftAmount(Root.getOpcode());
2905 assert(OuterShiftAmt != 0 && "Unexpected opcode");
2906
2907 MachineInstr *AddMI = MRI.getUniqueVRegDef(Root.getOperand(2).getReg());
2908 MachineInstr *ShiftMI =
2909 MRI.getUniqueVRegDef(AddMI->getOperand(AddOpIdx).getReg());
2910
2911 unsigned InnerShiftAmt = ShiftMI->getOperand(2).getImm();
2912 assert(InnerShiftAmt >= OuterShiftAmt && "Unexpected shift amount");
2913
2914 unsigned InnerOpc;
2915 switch (InnerShiftAmt - OuterShiftAmt) {
2916 default:
2917 llvm_unreachable("Unexpected shift amount");
2918 case 0:
2919 InnerOpc = RISCV::ADD;
2920 break;
2921 case 1:
2922 InnerOpc = RISCV::SH1ADD;
2923 break;
2924 case 2:
2925 InnerOpc = RISCV::SH2ADD;
2926 break;
2927 case 3:
2928 InnerOpc = RISCV::SH3ADD;
2929 break;
2930 }
2931
2932 const MachineOperand &X = AddMI->getOperand(3 - AddOpIdx);
2933 const MachineOperand &Y = ShiftMI->getOperand(1);
2934 const MachineOperand &Z = Root.getOperand(1);
2935
2936 Register NewVR = MRI.createVirtualRegister(&RISCV::GPRRegClass);
2937
2938 auto MIB1 = BuildMI(*MF, MIMetadata(Root), TII->get(InnerOpc), NewVR)
2939 .addReg(Y.getReg(), getKillRegState(Y.isKill()))
2940 .addReg(Z.getReg(), getKillRegState(Z.isKill()));
2941 auto MIB2 = BuildMI(*MF, MIMetadata(Root), TII->get(Root.getOpcode()),
2942 Root.getOperand(0).getReg())
2943 .addReg(NewVR, RegState::Kill)
2944 .addReg(X.getReg(), getKillRegState(X.isKill()));
2945
2946 InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0));
2947 InsInstrs.push_back(MIB1);
2948 InsInstrs.push_back(MIB2);
2949 DelInstrs.push_back(ShiftMI);
2950 DelInstrs.push_back(AddMI);
2951 DelInstrs.push_back(&Root);
2952}
2953
2955 MachineInstr &Root, unsigned Pattern,
2958 DenseMap<Register, unsigned> &InstrIdxForVirtReg) const {
2959 MachineRegisterInfo &MRI = Root.getMF()->getRegInfo();
2960 switch (Pattern) {
2961 default:
2963 DelInstrs, InstrIdxForVirtReg);
2964 return;
2967 MachineInstr &Prev = *MRI.getVRegDef(Root.getOperand(1).getReg());
2968 combineFPFusedMultiply(Root, Prev, Pattern, InsInstrs, DelInstrs);
2969 return;
2970 }
2973 MachineInstr &Prev = *MRI.getVRegDef(Root.getOperand(2).getReg());
2974 combineFPFusedMultiply(Root, Prev, Pattern, InsInstrs, DelInstrs);
2975 return;
2976 }
2978 genShXAddAddShift(Root, 1, InsInstrs, DelInstrs, InstrIdxForVirtReg);
2979 return;
2981 genShXAddAddShift(Root, 2, InsInstrs, DelInstrs, InstrIdxForVirtReg);
2982 return;
2983 }
2984}
2985
2987 StringRef &ErrInfo) const {
2988 MCInstrDesc const &Desc = MI.getDesc();
2989
2990 for (const auto &[Index, Operand] : enumerate(Desc.operands())) {
2991 const MachineOperand &MO = MI.getOperand(Index);
2992 unsigned OpType = Operand.OperandType;
2993 switch (OpType) {
2994 default:
2995 if (OpType >= RISCVOp::OPERAND_FIRST_RISCV_IMM &&
2997 if (!MO.isImm()) {
2998 ErrInfo = "Expected an immediate operand.";
2999 return false;
3000 }
3001 int64_t Imm = MO.getImm();
3002 bool Ok;
3003 switch (OpType) {
3004 default:
3005 llvm_unreachable("Unexpected operand type");
3006
3007#define CASE_OPERAND_UIMM(NUM) \
3008 case RISCVOp::OPERAND_UIMM##NUM: \
3009 Ok = isUInt<NUM>(Imm); \
3010 break;
3011#define CASE_OPERAND_UIMM_LSB_ZEROS(BITS, SUFFIX) \
3012 case RISCVOp::OPERAND_UIMM##BITS##_LSB##SUFFIX: { \
3013 constexpr size_t NumZeros = sizeof(#SUFFIX) - 1; \
3014 Ok = isShiftedUInt<BITS - NumZeros, NumZeros>(Imm); \
3015 break; \
3016 }
3017#define CASE_OPERAND_SIMM(NUM) \
3018 case RISCVOp::OPERAND_SIMM##NUM: \
3019 Ok = isInt<NUM>(Imm); \
3020 break;
3021 // clang-format off
3045 // clang-format on
3047 Ok = isUInt<5>(Imm) && (Imm != 0);
3048 break;
3050 Ok = isUInt<5>(Imm) && (Imm > 3);
3051 break;
3053 Ok = Imm >= 1 && Imm <= 32;
3054 break;
3056 Ok = Imm >= 1 && Imm <= 64;
3057 break;
3059 Ok = isUInt<8>(Imm) && Imm >= 32;
3060 break;
3062 Ok = isShiftedInt<6, 4>(Imm) && (Imm != 0);
3063 break;
3065 Ok = isShiftedUInt<8, 2>(Imm) && (Imm != 0);
3066 break;
3068 Ok = isUInt<16>(Imm) && (Imm != 0);
3069 break;
3071 Ok = Imm == 3;
3072 break;
3074 Ok = Imm == 4;
3075 break;
3077 Ok = (isUInt<5>(Imm) && Imm != 0) || Imm == -1;
3078 break;
3079 // clang-format off
3086 // clang-format on
3088 Ok = Imm >= -15 && Imm <= 16;
3089 break;
3091 Ok = isInt<5>(Imm) && (Imm != 0);
3092 break;
3094 Ok = Imm != 0 && isInt<6>(Imm);
3095 break;
3097 Ok = isUInt<10>(Imm) && RISCVVType::isValidVType(Imm);
3098 break;
3100 Ok = isUInt<11>(Imm) && RISCVVType::isValidVType(Imm);
3101 break;
3103 Ok = isShiftedInt<7, 5>(Imm);
3104 break;
3106 Ok = isInt<16>(Imm) && (Imm != 0);
3107 break;
3109 Ok = isInt<20>(Imm);
3110 break;
3112 Ok = STI.is64Bit() ? isUInt<6>(Imm) : isUInt<5>(Imm);
3113 break;
3115 Ok = STI.is64Bit() ? isUInt<6>(Imm) : isUInt<5>(Imm);
3116 Ok = Ok && Imm != 0;
3117 break;
3119 Ok = (isUInt<5>(Imm) && Imm != 0) || (Imm >= 0xfffe0 && Imm <= 0xfffff);
3120 break;
3122 Ok = Imm >= 0 && Imm <= 10;
3123 break;
3125 Ok = Imm >= 0 && Imm <= 7;
3126 break;
3128 Ok = Imm >= 1 && Imm <= 10;
3129 break;
3131 Ok = Imm >= 2 && Imm <= 14;
3132 break;
3134 Ok = Imm >= RISCVZC::RA && Imm <= RISCVZC::RA_S0_S11;
3135 break;
3137 Ok = Imm >= RISCVZC::RA_S0 && Imm <= RISCVZC::RA_S0_S11;
3138 break;
3140 Ok = Imm >= 0 && Imm <= 48 && Imm % 16 == 0;
3141 break;
3144 break;
3146 Ok = Imm == RISCVFPRndMode::RTZ;
3147 break;
3149 Ok = Imm >= 0 && Imm < RISCVCC::COND_INVALID;
3150 break;
3152 Ok = isValidAtomicOrdering(Imm);
3153 break;
3156 Imm;
3157 break;
3159 Ok = (isUInt<5>(Imm) && RISCVVType::isValidSEW(1 << Imm));
3160 break;
3162 Ok = Imm == 0;
3163 break;
3166 if (RISCVII::usesVXRM(Desc.TSFlags))
3167 Ok = isUInt<2>(Imm);
3168 else
3170 break;
3173 break;
3175 Ok = Imm == 1 || Imm == 2 || Imm == 4;
3176 break;
3177 }
3178 if (!Ok) {
3179 ErrInfo = "Invalid immediate";
3180 return false;
3181 }
3182 }
3183 break;
3185 // TODO: We could be stricter about what non-register operands are
3186 // allowed.
3187 if (MO.isReg()) {
3188 ErrInfo = "Expected a non-register operand.";
3189 return false;
3190 }
3191 if (MO.isImm() && !isInt<12>(MO.getImm())) {
3192 ErrInfo = "Invalid immediate";
3193 return false;
3194 }
3195 break;
3198 // TODO: We could be stricter about what non-register operands are
3199 // allowed.
3200 if (MO.isReg()) {
3201 ErrInfo = "Expected a non-register operand.";
3202 return false;
3203 }
3204 if (MO.isImm() && !isUInt<20>(MO.getImm())) {
3205 ErrInfo = "Invalid immediate";
3206 return false;
3207 }
3208 break;
3210 // TODO: We could be stricter about what non-register operands are
3211 // allowed.
3212 if (MO.isReg()) {
3213 ErrInfo = "Expected a non-register operand.";
3214 return false;
3215 }
3216 if (MO.isImm() && !isInt<32>(MO.getImm())) {
3217 ErrInfo = "Invalid immediate";
3218 return false;
3219 }
3220 break;
3222 if (MO.isImm()) {
3223 int64_t Imm = MO.getImm();
3224 // VLMAX is represented as -1.
3225 if (!isUInt<5>(Imm) && Imm != -1) {
3226 ErrInfo = "Invalid immediate";
3227 return false;
3228 }
3229 } else if (!MO.isReg()) {
3230 ErrInfo = "Expected a register or immediate operand.";
3231 return false;
3232 }
3233 break;
3235 if (!MO.isReg() && !MO.isImm()) {
3236 ErrInfo = "Expected a register or immediate operand.";
3237 return false;
3238 }
3239 break;
3240 }
3241 }
3242
3243 const uint64_t TSFlags = Desc.TSFlags;
3244 if (RISCVII::hasVLOp(TSFlags)) {
3245 const MachineOperand &Op = MI.getOperand(RISCVII::getVLOpNum(Desc));
3246 if (!Op.isImm() && !Op.isReg()) {
3247 ErrInfo = "Invalid operand type for VL operand";
3248 return false;
3249 }
3250 if (Op.isReg() && Op.getReg().isValid()) {
3251 const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
3252 auto *RC = MRI.getRegClass(Op.getReg());
3253 if (!RISCV::GPRNoX0RegClass.hasSubClassEq(RC)) {
3254 ErrInfo = "Invalid register class for VL operand";
3255 return false;
3256 }
3257 }
3258 if (!RISCVII::hasSEWOp(TSFlags)) {
3259 ErrInfo = "VL operand w/o SEW operand?";
3260 return false;
3261 }
3262 }
3263 if (RISCVII::hasSEWOp(TSFlags)) {
3264 unsigned OpIdx = RISCVII::getSEWOpNum(Desc);
3265 if (!MI.getOperand(OpIdx).isImm()) {
3266 ErrInfo = "SEW value expected to be an immediate";
3267 return false;
3268 }
3269 uint64_t Log2SEW = MI.getOperand(OpIdx).getImm();
3270 if (Log2SEW > 31) {
3271 ErrInfo = "Unexpected SEW value";
3272 return false;
3273 }
3274 unsigned SEW = Log2SEW ? 1 << Log2SEW : 8;
3275 if (!RISCVVType::isValidSEW(SEW)) {
3276 ErrInfo = "Unexpected SEW value";
3277 return false;
3278 }
3279 }
3280 if (RISCVII::hasVecPolicyOp(TSFlags)) {
3282 if (!MI.getOperand(OpIdx).isImm()) {
3283 ErrInfo = "Policy operand expected to be an immediate";
3284 return false;
3285 }
3286 uint64_t Policy = MI.getOperand(OpIdx).getImm();
3288 ErrInfo = "Invalid Policy Value";
3289 return false;
3290 }
3291 if (!RISCVII::hasVLOp(TSFlags)) {
3292 ErrInfo = "policy operand w/o VL operand?";
3293 return false;
3294 }
3295
3296 // VecPolicy operands can only exist on instructions with passthru/merge
3297 // arguments. Note that not all arguments with passthru have vec policy
3298 // operands- some instructions have implicit policies.
3299 unsigned UseOpIdx;
3300 if (!MI.isRegTiedToUseOperand(0, &UseOpIdx)) {
3301 ErrInfo = "policy operand w/o tied operand?";
3302 return false;
3303 }
3304 }
3305
3306 if (int Idx = RISCVII::getFRMOpNum(Desc);
3307 Idx >= 0 && MI.getOperand(Idx).getImm() == RISCVFPRndMode::DYN &&
3308 !MI.readsRegister(RISCV::FRM, /*TRI=*/nullptr)) {
3309 ErrInfo = "dynamic rounding mode should read FRM";
3310 return false;
3311 }
3312
3313 return true;
3314}
3315
3317 const MachineInstr &AddrI,
3318 ExtAddrMode &AM) const {
3319 switch (MemI.getOpcode()) {
3320 default:
3321 return false;
3322 case RISCV::LB:
3323 case RISCV::LBU:
3324 case RISCV::LH:
3325 case RISCV::LH_INX:
3326 case RISCV::LHU:
3327 case RISCV::LW:
3328 case RISCV::LW_INX:
3329 case RISCV::LWU:
3330 case RISCV::LD:
3331 case RISCV::LD_RV32:
3332 case RISCV::FLH:
3333 case RISCV::FLW:
3334 case RISCV::FLD:
3335 case RISCV::SB:
3336 case RISCV::SH:
3337 case RISCV::SH_INX:
3338 case RISCV::SW:
3339 case RISCV::SW_INX:
3340 case RISCV::SD:
3341 case RISCV::SD_RV32:
3342 case RISCV::FSH:
3343 case RISCV::FSW:
3344 case RISCV::FSD:
3345 break;
3346 }
3347
3348 if (MemI.getOperand(0).getReg() == Reg)
3349 return false;
3350
3351 if (AddrI.getOpcode() != RISCV::ADDI || !AddrI.getOperand(1).isReg() ||
3352 !AddrI.getOperand(2).isImm())
3353 return false;
3354
3355 int64_t OldOffset = MemI.getOperand(2).getImm();
3356 int64_t Disp = AddrI.getOperand(2).getImm();
3357 int64_t NewOffset = OldOffset + Disp;
3358 if (!STI.is64Bit())
3359 NewOffset = SignExtend64<32>(NewOffset);
3360
3361 if (!isInt<12>(NewOffset))
3362 return false;
3363
3364 AM.BaseReg = AddrI.getOperand(1).getReg();
3365 AM.ScaledReg = 0;
3366 AM.Scale = 0;
3367 AM.Displacement = NewOffset;
3369 return true;
3370}
3371
3373 const ExtAddrMode &AM) const {
3374
3375 const DebugLoc &DL = MemI.getDebugLoc();
3376 MachineBasicBlock &MBB = *MemI.getParent();
3377
3378 assert(AM.ScaledReg == 0 && AM.Scale == 0 &&
3379 "Addressing mode not supported for folding");
3380
3381 return BuildMI(MBB, MemI, DL, get(MemI.getOpcode()))
3382 .addReg(MemI.getOperand(0).getReg(), getDefRegState(MemI.mayLoad()))
3383 .addReg(AM.BaseReg)
3384 .addImm(AM.Displacement)
3385 .setMemRefs(MemI.memoperands())
3386 .setMIFlags(MemI.getFlags());
3387}
3388
3389// TODO: At the moment, MIPS introduced paring of instructions operating with
3390// word or double word. This should be extended with more instructions when more
3391// vendors support load/store pairing.
3393 switch (Opc) {
3394 default:
3395 return false;
3396 case RISCV::SW:
3397 case RISCV::SD:
3398 case RISCV::LD:
3399 case RISCV::LW:
3400 return true;
3401 }
3402}
3403
3405 const TargetRegisterInfo *TRI) {
3406 // If this is a volatile load/store, don't mess with it.
3407 if (LdSt.hasOrderedMemoryRef() || LdSt.getNumExplicitOperands() != 3)
3408 return false;
3409
3410 if (LdSt.getOperand(1).isFI())
3411 return true;
3412
3413 assert(LdSt.getOperand(1).isReg() && "Expected a reg operand.");
3414 // Can't cluster if the instruction modifies the base register
3415 // or it is update form. e.g. ld x5,8(x5)
3416 if (LdSt.modifiesRegister(LdSt.getOperand(1).getReg(), TRI))
3417 return false;
3418
3419 if (!LdSt.getOperand(2).isImm())
3420 return false;
3421
3422 return true;
3423}
3424
3427 int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width,
3428 const TargetRegisterInfo *TRI) const {
3429 if (!LdSt.mayLoadOrStore())
3430 return false;
3431
3432 // Conservatively, only handle scalar loads/stores for now.
3433 switch (LdSt.getOpcode()) {
3434 case RISCV::LB:
3435 case RISCV::LBU:
3436 case RISCV::SB:
3437 case RISCV::LH:
3438 case RISCV::LH_INX:
3439 case RISCV::LHU:
3440 case RISCV::FLH:
3441 case RISCV::SH:
3442 case RISCV::SH_INX:
3443 case RISCV::FSH:
3444 case RISCV::LW:
3445 case RISCV::LW_INX:
3446 case RISCV::LWU:
3447 case RISCV::FLW:
3448 case RISCV::SW:
3449 case RISCV::SW_INX:
3450 case RISCV::FSW:
3451 case RISCV::LD:
3452 case RISCV::LD_RV32:
3453 case RISCV::FLD:
3454 case RISCV::SD:
3455 case RISCV::SD_RV32:
3456 case RISCV::FSD:
3457 break;
3458 default:
3459 return false;
3460 }
3461 const MachineOperand *BaseOp;
3462 OffsetIsScalable = false;
3463 if (!getMemOperandWithOffsetWidth(LdSt, BaseOp, Offset, Width, TRI))
3464 return false;
3465 BaseOps.push_back(BaseOp);
3466 return true;
3467}
3468
3469// TODO: This was copied from SIInstrInfo. Could it be lifted to a common
3470// helper?
3473 const MachineInstr &MI2,
3475 // Only examine the first "base" operand of each instruction, on the
3476 // assumption that it represents the real base address of the memory access.
3477 // Other operands are typically offsets or indices from this base address.
3478 if (BaseOps1.front()->isIdenticalTo(*BaseOps2.front()))
3479 return true;
3480
3481 if (!MI1.hasOneMemOperand() || !MI2.hasOneMemOperand())
3482 return false;
3483
3484 auto MO1 = *MI1.memoperands_begin();
3485 auto MO2 = *MI2.memoperands_begin();
3486 if (MO1->getAddrSpace() != MO2->getAddrSpace())
3487 return false;
3488
3489 auto Base1 = MO1->getValue();
3490 auto Base2 = MO2->getValue();
3491 if (!Base1 || !Base2)
3492 return false;
3493 Base1 = getUnderlyingObject(Base1);
3494 Base2 = getUnderlyingObject(Base2);
3495
3496 if (isa<UndefValue>(Base1) || isa<UndefValue>(Base2))
3497 return false;
3498
3499 return Base1 == Base2;
3500}
3501
3503 ArrayRef<const MachineOperand *> BaseOps1, int64_t Offset1,
3504 bool OffsetIsScalable1, ArrayRef<const MachineOperand *> BaseOps2,
3505 int64_t Offset2, bool OffsetIsScalable2, unsigned ClusterSize,
3506 unsigned NumBytes) const {
3507 // If the mem ops (to be clustered) do not have the same base ptr, then they
3508 // should not be clustered
3509 if (!BaseOps1.empty() && !BaseOps2.empty()) {
3510 const MachineInstr &FirstLdSt = *BaseOps1.front()->getParent();
3511 const MachineInstr &SecondLdSt = *BaseOps2.front()->getParent();
3512 if (!memOpsHaveSameBasePtr(FirstLdSt, BaseOps1, SecondLdSt, BaseOps2))
3513 return false;
3514 } else if (!BaseOps1.empty() || !BaseOps2.empty()) {
3515 // If only one base op is empty, they do not have the same base ptr
3516 return false;
3517 }
3518
3519 unsigned CacheLineSize =
3520 BaseOps1.front()->getParent()->getMF()->getSubtarget().getCacheLineSize();
3521 // Assume a cache line size of 64 bytes if no size is set in RISCVSubtarget.
3523 // Cluster if the memory operations are on the same or a neighbouring cache
3524 // line, but limit the maximum ClusterSize to avoid creating too much
3525 // additional register pressure.
3526 return ClusterSize <= 4 && std::abs(Offset1 - Offset2) < CacheLineSize;
3527}
3528
3529// Set BaseReg (the base register operand), Offset (the byte offset being
3530// accessed) and the access Width of the passed instruction that reads/writes
3531// memory. Returns false if the instruction does not read/write memory or the
3532// BaseReg/Offset/Width can't be determined. Is not guaranteed to always
3533// recognise base operands and offsets in all cases.
3534// TODO: Add an IsScalable bool ref argument (like the equivalent AArch64
3535// function) and set it as appropriate.
3537 const MachineInstr &LdSt, const MachineOperand *&BaseReg, int64_t &Offset,
3538 LocationSize &Width, const TargetRegisterInfo *TRI) const {
3539 if (!LdSt.mayLoadOrStore())
3540 return false;
3541
3542 // Here we assume the standard RISC-V ISA, which uses a base+offset
3543 // addressing mode. You'll need to relax these conditions to support custom
3544 // load/store instructions.
3545 if (LdSt.getNumExplicitOperands() != 3)
3546 return false;
3547 if ((!LdSt.getOperand(1).isReg() && !LdSt.getOperand(1).isFI()) ||
3548 !LdSt.getOperand(2).isImm())
3549 return false;
3550
3551 if (!LdSt.hasOneMemOperand())
3552 return false;
3553
3554 Width = (*LdSt.memoperands_begin())->getSize();
3555 BaseReg = &LdSt.getOperand(1);
3556 Offset = LdSt.getOperand(2).getImm();
3557 return true;
3558}
3559
3561 const MachineInstr &MIa, const MachineInstr &MIb) const {
3562 assert(MIa.mayLoadOrStore() && "MIa must be a load or store.");
3563 assert(MIb.mayLoadOrStore() && "MIb must be a load or store.");
3564
3567 return false;
3568
3569 // Retrieve the base register, offset from the base register and width. Width
3570 // is the size of memory that is being loaded/stored (e.g. 1, 2, 4). If
3571 // base registers are identical, and the offset of a lower memory access +
3572 // the width doesn't overlap the offset of a higher memory access,
3573 // then the memory accesses are different.
3574 const TargetRegisterInfo *TRI = STI.getRegisterInfo();
3575 const MachineOperand *BaseOpA = nullptr, *BaseOpB = nullptr;
3576 int64_t OffsetA = 0, OffsetB = 0;
3578 WidthB = LocationSize::precise(0);
3579 if (getMemOperandWithOffsetWidth(MIa, BaseOpA, OffsetA, WidthA, TRI) &&
3580 getMemOperandWithOffsetWidth(MIb, BaseOpB, OffsetB, WidthB, TRI)) {
3581 if (BaseOpA->isIdenticalTo(*BaseOpB)) {
3582 int LowOffset = std::min(OffsetA, OffsetB);
3583 int HighOffset = std::max(OffsetA, OffsetB);
3584 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
3585 if (LowWidth.hasValue() &&
3586 LowOffset + (int)LowWidth.getValue() <= HighOffset)
3587 return true;
3588 }
3589 }
3590 return false;
3591}
3592
3593std::pair<unsigned, unsigned>
3595 const unsigned Mask = RISCVII::MO_DIRECT_FLAG_MASK;
3596 return std::make_pair(TF & Mask, TF & ~Mask);
3597}
3598
3601 using namespace RISCVII;
3602 static const std::pair<unsigned, const char *> TargetFlags[] = {
3603 {MO_CALL, "riscv-call"},
3604 {MO_LO, "riscv-lo"},
3605 {MO_HI, "riscv-hi"},
3606 {MO_PCREL_LO, "riscv-pcrel-lo"},
3607 {MO_PCREL_HI, "riscv-pcrel-hi"},
3608 {MO_GOT_HI, "riscv-got-hi"},
3609 {MO_TPREL_LO, "riscv-tprel-lo"},
3610 {MO_TPREL_HI, "riscv-tprel-hi"},
3611 {MO_TPREL_ADD, "riscv-tprel-add"},
3612 {MO_TLS_GOT_HI, "riscv-tls-got-hi"},
3613 {MO_TLS_GD_HI, "riscv-tls-gd-hi"},
3614 {MO_TLSDESC_HI, "riscv-tlsdesc-hi"},
3615 {MO_TLSDESC_LOAD_LO, "riscv-tlsdesc-load-lo"},
3616 {MO_TLSDESC_ADD_LO, "riscv-tlsdesc-add-lo"},
3617 {MO_TLSDESC_CALL, "riscv-tlsdesc-call"}};
3618 return ArrayRef(TargetFlags);
3619}
3621 MachineFunction &MF, bool OutlineFromLinkOnceODRs) const {
3622 const Function &F = MF.getFunction();
3623
3624 // Can F be deduplicated by the linker? If it can, don't outline from it.
3625 if (!OutlineFromLinkOnceODRs && F.hasLinkOnceODRLinkage())
3626 return false;
3627
3628 // Don't outline from functions with section markings; the program could
3629 // expect that all the code is in the named section.
3630 if (F.hasSection())
3631 return false;
3632
3633 // It's safe to outline from MF.
3634 return true;
3635}
3636
3638 unsigned &Flags) const {
3639 // More accurate safety checking is done in getOutliningCandidateInfo.
3641}
3642
3643// Enum values indicating how an outlined call should be constructed.
3649
3654
3656 const MachineFunction *MF = MBB.getParent();
3657 const Function &F = MF->getFunction();
3658 return F.getFnAttribute("fentry-call").getValueAsBool() ||
3659 F.hasFnAttribute("patchable-function-entry");
3660}
3661
3663 MCRegister RegNo) {
3664 return MI.readsRegister(RegNo, TRI) ||
3665 MI.getDesc().hasImplicitUseOfPhysReg(RegNo);
3666}
3667
3669 const TargetRegisterInfo *TRI, MCRegister RegNo) {
3670 return MI.modifiesRegister(RegNo, TRI) ||
3671 MI.getDesc().hasImplicitDefOfPhysReg(RegNo);
3672}
3673
3675 if (!MBB.back().isReturn())
3676 return true;
3678 return true;
3679
3680 // If the candidate reads the pre-set register
3681 // that can be used for expanding PseudoTAIL instruction,
3682 // then we cannot insert tail call.
3683 const TargetSubtargetInfo &STI = MBB.getParent()->getSubtarget();
3684 MCRegister TailExpandUseRegNo =
3686 for (const MachineInstr &MI : MBB) {
3687 if (isMIReadsReg(MI, STI.getRegisterInfo(), TailExpandUseRegNo))
3688 return true;
3689 if (isMIModifiesReg(MI, STI.getRegisterInfo(), TailExpandUseRegNo))
3690 break;
3691 }
3692 return false;
3693}
3694
3696 const TargetRegisterInfo &TRI) {
3697 // Candidate registers for saving X5: t1-t6
3698 static const MCPhysReg TempRegs[] = {
3699 RISCV::X6, // t1
3700 RISCV::X7, // t2
3701 RISCV::X28, // t3
3702 RISCV::X29, // t4
3703 RISCV::X30, // t5
3704 RISCV::X31 // t6
3705 };
3706
3707 const MachineFunction *MF = C.getMF();
3708 const MachineRegisterInfo &MRI = MF->getRegInfo();
3709
3710 for (MCPhysReg Reg : TempRegs) {
3711 if (MRI.isReserved(Reg))
3712 continue;
3713
3714 if (C.isAvailableAcrossAndOutOfSeq(Reg, TRI) &&
3715 C.isAvailableInsideSeq(Reg, TRI)) {
3716 return Reg;
3717 }
3718 }
3719
3720 return Register();
3721}
3722
3724 // If the expansion register for tail calls is live across the candidate
3725 // outlined call site, we cannot outline that candidate as the expansion
3726 // would clobber the register.
3727 MCRegister TailExpandUseReg =
3728 RISCVII::getTailExpandUseRegNo(STI.getFeatureBits());
3729 if (C.back().isReturn() &&
3730 !C.isAvailableAcrossAndOutOfSeq(TailExpandUseReg, RegInfo)) {
3731 LLVM_DEBUG(dbgs() << "MBB:\n" << *C.getMBB());
3732 LLVM_DEBUG(dbgs() << "Cannot be outlined between: " << C.front() << "and "
3733 << C.back());
3734 LLVM_DEBUG(dbgs() << "Because the tail-call register is live across "
3735 "the proposed outlined function call\n");
3736 return true;
3737 }
3738
3739 // If last instruction is return then we can rely on
3740 // the verification already performed in the getOutliningTypeImpl.
3741 if (C.back().isReturn()) {
3742 assert(!cannotInsertTailCall(*C.getMBB()) &&
3743 "The candidate who uses return instruction must be outlined "
3744 "using tail call");
3745 return false;
3746 }
3747
3748 // Filter out candidates where the X5 register (t0) can't be used to setup
3749 // the function call.
3750 if (!C.isAvailableInsideSeq(RISCV::X5, RegInfo))
3751 return true;
3752
3753 // If X5 is available in the region, use X5 directly (MachineOutlinerDefault).
3754 if (C.isAvailableAcrossAndOutOfSeq(RISCV::X5, RegInfo))
3755 return false;
3756
3757 // Otherwise, try to save X5 into t1-t6 (MachineOutlinerRegSave).
3759 return false;
3760
3761 return true;
3762}
3763
3764std::optional<std::unique_ptr<outliner::OutlinedFunction>>
3766 const MachineModuleInfo &MMI,
3767 std::vector<outliner::Candidate> &RepeatedSequenceLocs,
3768 unsigned MinRepeats) const {
3769
3770 // Analyze each candidate and erase the ones that are not viable.
3771 llvm::erase_if(RepeatedSequenceLocs, [this](auto Candidate) {
3772 return analyzeCandidate(Candidate);
3773 });
3774
3775 // If the sequence doesn't have enough candidates left, then we're done.
3776 if (RepeatedSequenceLocs.size() < MinRepeats)
3777 return std::nullopt;
3778
3779 // Each RepeatedSequenceLoc is identical.
3780 outliner::Candidate &Candidate = RepeatedSequenceLocs[0];
3781 unsigned InstrSizeCExt =
3782 Candidate.getMF()->getSubtarget<RISCVSubtarget>().hasStdExtZca() ? 2 : 4;
3783 unsigned CallOverhead = 0, FrameOverhead = 0;
3784
3785 // Count the number of CFI instructions in the candidate, if present.
3786 unsigned CFICount = 0;
3787 for (auto &I : Candidate) {
3788 if (I.isCFIInstruction())
3789 CFICount++;
3790 }
3791
3792 // Ensure CFI coverage matches: comparing the number of CFIs in the candidate
3793 // with the total number of CFIs in the parent function for each candidate.
3794 // Outlining only a subset of a function’s CFIs would split the unwind state
3795 // across two code regions and lead to incorrect address offsets between the
3796 // outlined body and the remaining code. To preserve correct unwind info, we
3797 // only outline when all CFIs in the function can be outlined together.
3798 for (outliner::Candidate &C : RepeatedSequenceLocs) {
3799 std::vector<MCCFIInstruction> CFIInstructions =
3800 C.getMF()->getFrameInstructions();
3801
3802 if (CFICount > 0 && CFICount != CFIInstructions.size())
3803 return std::nullopt;
3804 }
3805
3807 if (Candidate.back().isReturn()) {
3809 // tail call = auipc + jalr in the worst case without linker relaxation.
3810 // FIXME: This code suggests the JALR can be compressed - how?
3811 CallOverhead = 4 + InstrSizeCExt;
3812 // Using tail call we move ret instruction from caller to callee.
3813 FrameOverhead = 0;
3814 } else {
3815 // call t0, function = 8 bytes.
3816 CallOverhead = 8;
3817 // jr t0 = 4 bytes, 2 bytes if compressed instructions are enabled.
3818 FrameOverhead = InstrSizeCExt;
3819 }
3820
3821 // If we have CFI instructions, we can only outline if the outlined section
3822 // can be a tail call.
3823 if (MOCI != MachineOutlinerTailCall && CFICount > 0)
3824 return std::nullopt;
3825
3827 // Set per-candidate overhead based on X5 availability
3828 for (auto &C : RepeatedSequenceLocs) {
3829
3830 if (C.isAvailableAcrossAndOutOfSeq(RISCV::X5, RegInfo)) {
3831 // X5 is available, just need the call
3832 unsigned CandCallOverhead = 8;
3833 C.setCallInfo(MachineOutlinerDefault, CandCallOverhead);
3834 } else {
3835 // X5 unavailable, need save + call + restore
3836 // Save (2-4) + Call (8) + Restore (2-4)
3837 unsigned CandCallOverhead = InstrSizeCExt + 8 + InstrSizeCExt;
3838 C.setCallInfo(MachineOutlinerRegSave, CandCallOverhead);
3839 }
3840 }
3841 } else {
3842 for (auto &C : RepeatedSequenceLocs)
3843 C.setCallInfo(MOCI, CallOverhead);
3844 }
3845
3846 unsigned SequenceSize = 0;
3847 for (auto &MI : Candidate)
3848 SequenceSize += getInstSizeInBytes(MI);
3849
3850 return std::make_unique<outliner::OutlinedFunction>(
3851 RepeatedSequenceLocs, SequenceSize, FrameOverhead, MOCI);
3852}
3853
3857 unsigned Flags) const {
3858 MachineInstr &MI = *MBBI;
3859 MachineBasicBlock *MBB = MI.getParent();
3860 const TargetRegisterInfo *TRI =
3861 MBB->getParent()->getSubtarget().getRegisterInfo();
3862 const auto &F = MI.getMF()->getFunction();
3863
3864 // We can only outline CFI instructions if we will tail call the outlined
3865 // function, or fix up the CFI offsets. Currently, CFI instructions are
3866 // outlined only if in a tail call.
3867 if (MI.isCFIInstruction())
3869
3870 if (cannotInsertTailCall(*MBB) &&
3871 (MI.isReturn() || isMIModifiesReg(MI, TRI, RISCV::X5)))
3873
3874 // Make sure the operands don't reference something unsafe.
3875 for (const auto &MO : MI.operands()) {
3876
3877 // pcrel-hi and pcrel-lo can't put in separate sections, filter that out
3878 // if any possible.
3879 if (MO.getTargetFlags() == RISCVII::MO_PCREL_LO &&
3880 (MI.getMF()->getTarget().getFunctionSections() || F.hasComdat() ||
3881 F.hasSection() || F.getSectionPrefix()))
3883 }
3884
3885 if (isLPAD(MI))
3887
3889}
3890
3893 const outliner::OutlinedFunction &OF) const {
3894
3895 if (OF.FrameConstructionID == MachineOutlinerTailCall)
3896 return;
3897
3898 MBB.addLiveIn(RISCV::X5);
3899
3900 // Add in a return instruction to the end of the outlined frame.
3901 MBB.insert(MBB.end(), BuildMI(MF, DebugLoc(), get(RISCV::JALR))
3902 .addReg(RISCV::X0, RegState::Define)
3903 .addReg(RISCV::X5)
3904 .addImm(0));
3905}
3906
3910
3911 if (C.CallConstructionID == MachineOutlinerTailCall) {
3912 It = MBB.insert(It, BuildMI(MF, DebugLoc(), get(RISCV::PseudoTAIL))
3913 .addGlobalAddress(M.getNamedValue(MF.getName()),
3914 /*Offset=*/0, RISCVII::MO_CALL));
3915 return It;
3916 }
3917
3918 if (C.CallConstructionID == MachineOutlinerRegSave) {
3919 Register SaveReg = findRegisterToSaveX5To(C, RegInfo);
3920 assert(SaveReg && "Cannot find an available register to save/restore X5.");
3921
3922 // Save: ADDI SaveReg, X5, 0 (equivalent to MV SaveReg, X5)
3923 It = MBB.insert(It, BuildMI(MF, DebugLoc(), get(RISCV::ADDI), SaveReg)
3924 .addReg(RISCV::X5)
3925 .addImm(0));
3926 It++;
3927
3928 // Call: PseudoCALLReg X5
3929 It = MBB.insert(
3930 It, BuildMI(MF, DebugLoc(), get(RISCV::PseudoCALLReg), RISCV::X5)
3931 .addGlobalAddress(M.getNamedValue(MF.getName()), 0,
3933 MachineBasicBlock::iterator CallPt = It;
3934 It++;
3935
3936 // Restore: ADDI X5, SaveReg, 0 (equivalent to MV X5, SaveReg)
3937 It = MBB.insert(It, BuildMI(MF, DebugLoc(), get(RISCV::ADDI), RISCV::X5)
3938 .addReg(SaveReg)
3939 .addImm(0));
3940
3941 return CallPt;
3942 }
3943
3944 // Add in a call instruction to the outlined function at the given location.
3945 It = MBB.insert(It,
3946 BuildMI(MF, DebugLoc(), get(RISCV::PseudoCALLReg), RISCV::X5)
3947 .addGlobalAddress(M.getNamedValue(MF.getName()), 0,
3949 return It;
3950}
3951
3952std::optional<RegImmPair> RISCVInstrInfo::isAddImmediate(const MachineInstr &MI,
3953 Register Reg) const {
3954 // TODO: Handle cases where Reg is a super- or sub-register of the
3955 // destination register.
3956 const MachineOperand &Op0 = MI.getOperand(0);
3957 if (!Op0.isReg() || Reg != Op0.getReg())
3958 return std::nullopt;
3959
3960 // Don't consider ADDIW as a candidate because the caller may not be aware
3961 // of its sign extension behaviour.
3962 if (MI.getOpcode() == RISCV::ADDI && MI.getOperand(1).isReg() &&
3963 MI.getOperand(2).isImm())
3964 return RegImmPair{MI.getOperand(1).getReg(), MI.getOperand(2).getImm()};
3965
3966 return std::nullopt;
3967}
3968
3969// MIR printer helper function to annotate Operands with a comment.
3971 const MachineInstr &MI, const MachineOperand &Op, unsigned OpIdx,
3972 const TargetRegisterInfo *TRI) const {
3973 // Print a generic comment for this operand if there is one.
3974 std::string GenericComment =
3976 if (!GenericComment.empty())
3977 return GenericComment;
3978
3979 const MCInstrDesc &Desc = MI.getDesc();
3980 if (OpIdx >= Desc.getNumOperands())
3981 return std::string();
3982
3983 std::string Comment;
3984 raw_string_ostream OS(Comment);
3985
3986 const MCOperandInfo &OpInfo = Desc.operands()[OpIdx];
3987
3988 // Print the full VType operand of vsetvli/vsetivli instructions, and the SEW
3989 // operand of vector codegen pseudos.
3990 switch (OpInfo.OperandType) {
3993 unsigned Imm = Op.getImm();
3994 RISCVVType::printVType(Imm, OS);
3995 break;
3996 }
3998 unsigned Imm = Op.getImm();
4000 break;
4001 }
4003 unsigned Imm = Op.getImm();
4004 OS << "w" << Imm;
4005 break;
4006 }
4009 unsigned Log2SEW = Op.getImm();
4010 unsigned SEW = Log2SEW ? 1 << Log2SEW : 8;
4011 assert(RISCVVType::isValidSEW(SEW) && "Unexpected SEW");
4012 OS << "e" << SEW;
4013 break;
4014 }
4016 unsigned Policy = Op.getImm();
4018 "Invalid Policy Value");
4019 OS << (Policy & RISCVVType::TAIL_AGNOSTIC ? "ta" : "tu") << ", "
4020 << (Policy & RISCVVType::MASK_AGNOSTIC ? "ma" : "mu");
4021 break;
4022 }
4024 if (Op.isImm() && Op.getImm() == -1)
4025 OS << "vl=VLMAX";
4026 else
4027 OS << "vl";
4028 break;
4030 if (RISCVII::usesVXRM(Desc.TSFlags)) {
4032 auto VXRM = static_cast<RISCVVXRndMode::RoundingMode>(Op.getImm());
4033 OS << "vxrm=" << RISCVVXRndMode::roundingModeToString(VXRM);
4034 } else {
4036 auto FRM = static_cast<RISCVFPRndMode::RoundingMode>(Op.getImm());
4037 OS << "frm=" << RISCVFPRndMode::roundingModeToString(FRM);
4038 }
4039 break;
4040 }
4041
4042 return Comment;
4043}
4044
4045// clang-format off
4046#define CASE_RVV_OPCODE_UNMASK_LMUL(OP, LMUL) \
4047 RISCV::Pseudo##OP##_##LMUL
4048
4049#define CASE_RVV_OPCODE_MASK_LMUL(OP, LMUL) \
4050 RISCV::Pseudo##OP##_##LMUL##_MASK
4051
4052#define CASE_RVV_OPCODE_LMUL(OP, LMUL) \
4053 CASE_RVV_OPCODE_UNMASK_LMUL(OP, LMUL): \
4054 case CASE_RVV_OPCODE_MASK_LMUL(OP, LMUL)
4055
4056#define CASE_RVV_OPCODE_UNMASK_WIDEN(OP) \
4057 CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF8): \
4058 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF4): \
4059 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF2): \
4060 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M1): \
4061 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M2): \
4062 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M4)
4063
4064#define CASE_RVV_OPCODE_UNMASK(OP) \
4065 CASE_RVV_OPCODE_UNMASK_WIDEN(OP): \
4066 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M8)
4067
4068#define CASE_RVV_OPCODE_MASK_WIDEN(OP) \
4069 CASE_RVV_OPCODE_MASK_LMUL(OP, MF8): \
4070 case CASE_RVV_OPCODE_MASK_LMUL(OP, MF4): \
4071 case CASE_RVV_OPCODE_MASK_LMUL(OP, MF2): \
4072 case CASE_RVV_OPCODE_MASK_LMUL(OP, M1): \
4073 case CASE_RVV_OPCODE_MASK_LMUL(OP, M2): \
4074 case CASE_RVV_OPCODE_MASK_LMUL(OP, M4)
4075
4076#define CASE_RVV_OPCODE_MASK(OP) \
4077 CASE_RVV_OPCODE_MASK_WIDEN(OP): \
4078 case CASE_RVV_OPCODE_MASK_LMUL(OP, M8)
4079
4080#define CASE_RVV_OPCODE_WIDEN(OP) \
4081 CASE_RVV_OPCODE_UNMASK_WIDEN(OP): \
4082 case CASE_RVV_OPCODE_MASK_WIDEN(OP)
4083
4084#define CASE_RVV_OPCODE(OP) \
4085 CASE_RVV_OPCODE_UNMASK(OP): \
4086 case CASE_RVV_OPCODE_MASK(OP)
4087// clang-format on
4088
4089// clang-format off
4090#define CASE_VMA_OPCODE_COMMON(OP, TYPE, LMUL) \
4091 RISCV::PseudoV##OP##_##TYPE##_##LMUL
4092
4093#define CASE_VMA_OPCODE_LMULS(OP, TYPE) \
4094 CASE_VMA_OPCODE_COMMON(OP, TYPE, MF8): \
4095 case CASE_VMA_OPCODE_COMMON(OP, TYPE, MF4): \
4096 case CASE_VMA_OPCODE_COMMON(OP, TYPE, MF2): \
4097 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M1): \
4098 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M2): \
4099 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M4): \
4100 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M8)
4101
4102// VFMA instructions are SEW specific.
4103#define CASE_VFMA_OPCODE_COMMON(OP, TYPE, LMUL, SEW) \
4104 RISCV::PseudoV##OP##_##TYPE##_##LMUL##_##SEW
4105
4106#define CASE_VFMA_OPCODE_LMULS_M1(OP, TYPE, SEW) \
4107 CASE_VFMA_OPCODE_COMMON(OP, TYPE, M1, SEW): \
4108 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M2, SEW): \
4109 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M4, SEW): \
4110 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M8, SEW)
4111
4112#define CASE_VFMA_OPCODE_LMULS_MF2(OP, TYPE, SEW) \
4113 CASE_VFMA_OPCODE_COMMON(OP, TYPE, MF2, SEW): \
4114 case CASE_VFMA_OPCODE_LMULS_M1(OP, TYPE, SEW)
4115
4116#define CASE_VFMA_OPCODE_LMULS_MF4(OP, TYPE, SEW) \
4117 CASE_VFMA_OPCODE_COMMON(OP, TYPE, MF4, SEW): \
4118 case CASE_VFMA_OPCODE_LMULS_MF2(OP, TYPE, SEW)
4119
4120#define CASE_VFMA_OPCODE_VV(OP) \
4121 CASE_VFMA_OPCODE_LMULS_MF4(OP, VV, E16): \
4122 case CASE_VFMA_OPCODE_LMULS_MF4(OP##_ALT, VV, E16): \
4123 case CASE_VFMA_OPCODE_LMULS_MF2(OP, VV, E32): \
4124 case CASE_VFMA_OPCODE_LMULS_M1(OP, VV, E64)
4125
4126#define CASE_VFMA_SPLATS(OP) \
4127 CASE_VFMA_OPCODE_LMULS_MF4(OP, VFPR16, E16): \
4128 case CASE_VFMA_OPCODE_LMULS_MF4(OP##_ALT, VFPR16, E16): \
4129 case CASE_VFMA_OPCODE_LMULS_MF2(OP, VFPR32, E32): \
4130 case CASE_VFMA_OPCODE_LMULS_M1(OP, VFPR64, E64)
4131// clang-format on
4132
4134 unsigned &SrcOpIdx1,
4135 unsigned &SrcOpIdx2) const {
4136 const MCInstrDesc &Desc = MI.getDesc();
4137 if (!Desc.isCommutable())
4138 return false;
4139
4140 switch (MI.getOpcode()) {
4141 case RISCV::TH_MVEQZ:
4142 case RISCV::TH_MVNEZ:
4143 // We can't commute operands if operand 2 (i.e., rs1 in
4144 // mveqz/mvnez rd,rs1,rs2) is the zero-register (as it is
4145 // not valid as the in/out-operand 1).
4146 if (MI.getOperand(2).getReg() == RISCV::X0)
4147 return false;
4148 // Operands 1 and 2 are commutable, if we switch the opcode.
4149 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 2);
4150 case RISCV::QC_SELECTIEQ:
4151 case RISCV::QC_SELECTINE:
4152 case RISCV::QC_SELECTIIEQ:
4153 case RISCV::QC_SELECTIINE:
4154 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 2);
4155 case RISCV::QC_MVEQ:
4156 case RISCV::QC_MVNE:
4157 case RISCV::QC_MVLT:
4158 case RISCV::QC_MVGE:
4159 case RISCV::QC_MVLTU:
4160 case RISCV::QC_MVGEU:
4161 case RISCV::QC_MVEQI:
4162 case RISCV::QC_MVNEI:
4163 case RISCV::QC_MVLTI:
4164 case RISCV::QC_MVGEI:
4165 case RISCV::QC_MVLTUI:
4166 case RISCV::QC_MVGEUI:
4167 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 4);
4168 case RISCV::TH_MULA:
4169 case RISCV::TH_MULAW:
4170 case RISCV::TH_MULAH:
4171 case RISCV::TH_MULS:
4172 case RISCV::TH_MULSW:
4173 case RISCV::TH_MULSH:
4174 // Operands 2 and 3 are commutable.
4175 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
4176 case RISCV::PseudoCCMOVGPRNoX0:
4177 case RISCV::PseudoCCMOVGPR:
4178 // Operands 1 and 2 are commutable.
4179 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 2);
4180 case CASE_RVV_OPCODE(VADD_VV):
4181 case CASE_RVV_OPCODE(VAND_VV):
4182 case CASE_RVV_OPCODE(VOR_VV):
4183 case CASE_RVV_OPCODE(VXOR_VV):
4184 case CASE_RVV_OPCODE_MASK(VMSEQ_VV):
4185 case CASE_RVV_OPCODE_MASK(VMSNE_VV):
4186 case CASE_RVV_OPCODE(VMIN_VV):
4187 case CASE_RVV_OPCODE(VMINU_VV):
4188 case CASE_RVV_OPCODE(VMAX_VV):
4189 case CASE_RVV_OPCODE(VMAXU_VV):
4190 case CASE_RVV_OPCODE(VMUL_VV):
4191 case CASE_RVV_OPCODE(VMULH_VV):
4192 case CASE_RVV_OPCODE(VMULHU_VV):
4193 case CASE_RVV_OPCODE_WIDEN(VWADD_VV):
4194 case CASE_RVV_OPCODE_WIDEN(VWADDU_VV):
4195 case CASE_RVV_OPCODE_WIDEN(VWMUL_VV):
4196 case CASE_RVV_OPCODE_WIDEN(VWMULU_VV):
4197 case CASE_RVV_OPCODE_WIDEN(VWMACC_VV):
4198 case CASE_RVV_OPCODE_WIDEN(VWMACCU_VV):
4199 case CASE_RVV_OPCODE(VABD_VV):
4200 case CASE_RVV_OPCODE(VABDU_VV):
4201 case CASE_RVV_OPCODE_WIDEN(VWABDA_VV):
4202 case CASE_RVV_OPCODE_WIDEN(VWABDAU_VV):
4203 case CASE_RVV_OPCODE_UNMASK(VADC_VVM):
4204 case CASE_RVV_OPCODE(VSADD_VV):
4205 case CASE_RVV_OPCODE(VSADDU_VV):
4206 case CASE_RVV_OPCODE(VAADD_VV):
4207 case CASE_RVV_OPCODE(VAADDU_VV):
4208 case CASE_RVV_OPCODE(VSMUL_VV):
4209 case CASE_RVV_OPCODE_LMUL(VDOTA4_VV, MF2):
4210 case CASE_RVV_OPCODE_LMUL(VDOTA4_VV, M1):
4211 case CASE_RVV_OPCODE_LMUL(VDOTA4_VV, M2):
4212 case CASE_RVV_OPCODE_LMUL(VDOTA4_VV, M4):
4213 case CASE_RVV_OPCODE_LMUL(VDOTA4_VV, M8):
4214 case CASE_RVV_OPCODE_LMUL(VDOTA4U_VV, MF2):
4215 case CASE_RVV_OPCODE_LMUL(VDOTA4U_VV, M1):
4216 case CASE_RVV_OPCODE_LMUL(VDOTA4U_VV, M2):
4217 case CASE_RVV_OPCODE_LMUL(VDOTA4U_VV, M4):
4218 case CASE_RVV_OPCODE_LMUL(VDOTA4U_VV, M8):
4219 // Operands 2 and 3 are commutable.
4220 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
4221 case CASE_VFMA_SPLATS(FMADD):
4222 case CASE_VFMA_SPLATS(FMSUB):
4223 case CASE_VFMA_SPLATS(FMACC):
4224 case CASE_VFMA_SPLATS(FMSAC):
4227 case CASE_VFMA_SPLATS(FNMACC):
4228 case CASE_VFMA_SPLATS(FNMSAC):
4229 case CASE_VFMA_OPCODE_VV(FMACC):
4230 case CASE_VFMA_OPCODE_VV(FMSAC):
4231 case CASE_VFMA_OPCODE_VV(FNMACC):
4232 case CASE_VFMA_OPCODE_VV(FNMSAC):
4233 case CASE_VMA_OPCODE_LMULS(MADD, VX):
4234 case CASE_VMA_OPCODE_LMULS(NMSUB, VX):
4235 case CASE_VMA_OPCODE_LMULS(MACC, VX):
4236 case CASE_VMA_OPCODE_LMULS(NMSAC, VX):
4237 case CASE_VMA_OPCODE_LMULS(MACC, VV):
4238 case CASE_VMA_OPCODE_LMULS(NMSAC, VV): {
4239 // If the tail policy is undisturbed we can't commute.
4240 assert(RISCVII::hasVecPolicyOp(MI.getDesc().TSFlags));
4241 if ((MI.getOperand(RISCVII::getVecPolicyOpNum(MI.getDesc())).getImm() &
4242 1) == 0)
4243 return false;
4244
4245 // For these instructions we can only swap operand 1 and operand 3 by
4246 // changing the opcode.
4247 unsigned CommutableOpIdx1 = 1;
4248 unsigned CommutableOpIdx2 = 3;
4249 if (!fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, CommutableOpIdx1,
4250 CommutableOpIdx2))
4251 return false;
4252 return true;
4253 }
4254 case CASE_VFMA_OPCODE_VV(FMADD):
4258 case CASE_VMA_OPCODE_LMULS(MADD, VV):
4259 case CASE_VMA_OPCODE_LMULS(NMSUB, VV): {
4260 // If the tail policy is undisturbed we can't commute.
4261 assert(RISCVII::hasVecPolicyOp(MI.getDesc().TSFlags));
4262 if ((MI.getOperand(RISCVII::getVecPolicyOpNum(MI.getDesc())).getImm() &
4263 1) == 0)
4264 return false;
4265
4266 // For these instructions we have more freedom. We can commute with the
4267 // other multiplicand or with the addend/subtrahend/minuend.
4268
4269 // Any fixed operand must be from source 1, 2 or 3.
4270 if (SrcOpIdx1 != CommuteAnyOperandIndex && SrcOpIdx1 > 3)
4271 return false;
4272 if (SrcOpIdx2 != CommuteAnyOperandIndex && SrcOpIdx2 > 3)
4273 return false;
4274
4275 // It both ops are fixed one must be the tied source.
4276 if (SrcOpIdx1 != CommuteAnyOperandIndex &&
4277 SrcOpIdx2 != CommuteAnyOperandIndex && SrcOpIdx1 != 1 && SrcOpIdx2 != 1)
4278 return false;
4279
4280 // Look for two different register operands assumed to be commutable
4281 // regardless of the FMA opcode. The FMA opcode is adjusted later if
4282 // needed.
4283 if (SrcOpIdx1 == CommuteAnyOperandIndex ||
4284 SrcOpIdx2 == CommuteAnyOperandIndex) {
4285 // At least one of operands to be commuted is not specified and
4286 // this method is free to choose appropriate commutable operands.
4287 unsigned CommutableOpIdx1 = SrcOpIdx1;
4288 if (SrcOpIdx1 == SrcOpIdx2) {
4289 // Both of operands are not fixed. Set one of commutable
4290 // operands to the tied source.
4291 CommutableOpIdx1 = 1;
4292 } else if (SrcOpIdx1 == CommuteAnyOperandIndex) {
4293 // Only one of the operands is not fixed.
4294 CommutableOpIdx1 = SrcOpIdx2;
4295 }
4296
4297 // CommutableOpIdx1 is well defined now. Let's choose another commutable
4298 // operand and assign its index to CommutableOpIdx2.
4299 unsigned CommutableOpIdx2;
4300 if (CommutableOpIdx1 != 1) {
4301 // If we haven't already used the tied source, we must use it now.
4302 CommutableOpIdx2 = 1;
4303 } else {
4304 Register Op1Reg = MI.getOperand(CommutableOpIdx1).getReg();
4305
4306 // The commuted operands should have different registers.
4307 // Otherwise, the commute transformation does not change anything and
4308 // is useless. We use this as a hint to make our decision.
4309 if (Op1Reg != MI.getOperand(2).getReg())
4310 CommutableOpIdx2 = 2;
4311 else
4312 CommutableOpIdx2 = 3;
4313 }
4314
4315 // Assign the found pair of commutable indices to SrcOpIdx1 and
4316 // SrcOpIdx2 to return those values.
4317 if (!fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, CommutableOpIdx1,
4318 CommutableOpIdx2))
4319 return false;
4320 }
4321
4322 return true;
4323 }
4324 }
4325
4326 return TargetInstrInfo::findCommutedOpIndices(MI, SrcOpIdx1, SrcOpIdx2);
4327}
4328
4329// clang-format off
4330#define CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, LMUL) \
4331 case RISCV::PseudoV##OLDOP##_##TYPE##_##LMUL: \
4332 Opc = RISCV::PseudoV##NEWOP##_##TYPE##_##LMUL; \
4333 break;
4334
4335#define CASE_VMA_CHANGE_OPCODE_LMULS(OLDOP, NEWOP, TYPE) \
4336 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF8) \
4337 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF4) \
4338 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF2) \
4339 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M1) \
4340 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M2) \
4341 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M4) \
4342 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M8)
4343
4344// VFMA depends on SEW.
4345#define CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, LMUL, SEW) \
4346 case RISCV::PseudoV##OLDOP##_##TYPE##_##LMUL##_##SEW: \
4347 Opc = RISCV::PseudoV##NEWOP##_##TYPE##_##LMUL##_##SEW; \
4348 break;
4349
4350#define CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, TYPE, SEW) \
4351 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M1, SEW) \
4352 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M2, SEW) \
4353 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M4, SEW) \
4354 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M8, SEW)
4355
4356#define CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, TYPE, SEW) \
4357 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF2, SEW) \
4358 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, TYPE, SEW)
4359
4360#define CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, TYPE, SEW) \
4361 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF4, SEW) \
4362 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, TYPE, SEW)
4363
4364#define CASE_VFMA_CHANGE_OPCODE_VV(OLDOP, NEWOP) \
4365 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, VV, E16) \
4366 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP##_ALT, NEWOP##_ALT, VV, E16) \
4367 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, VV, E32) \
4368 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, VV, E64)
4369
4370#define CASE_VFMA_CHANGE_OPCODE_SPLATS(OLDOP, NEWOP) \
4371 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, VFPR16, E16) \
4372 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP##_ALT, NEWOP##_ALT, VFPR16, E16) \
4373 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, VFPR32, E32) \
4374 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, VFPR64, E64)
4375// clang-format on
4376
4378 bool NewMI,
4379 unsigned OpIdx1,
4380 unsigned OpIdx2) const {
4381 auto cloneIfNew = [NewMI](MachineInstr &MI) -> MachineInstr & {
4382 if (NewMI)
4383 return *MI.getParent()->getParent()->CloneMachineInstr(&MI);
4384 return MI;
4385 };
4386
4387 switch (MI.getOpcode()) {
4388 case RISCV::TH_MVEQZ:
4389 case RISCV::TH_MVNEZ: {
4390 auto &WorkingMI = cloneIfNew(MI);
4391 WorkingMI.setDesc(get(MI.getOpcode() == RISCV::TH_MVEQZ ? RISCV::TH_MVNEZ
4392 : RISCV::TH_MVEQZ));
4393 return TargetInstrInfo::commuteInstructionImpl(WorkingMI, false, OpIdx1,
4394 OpIdx2);
4395 }
4396 case RISCV::QC_SELECTIEQ:
4397 case RISCV::QC_SELECTINE:
4398 case RISCV::QC_SELECTIIEQ:
4399 case RISCV::QC_SELECTIINE:
4400 return TargetInstrInfo::commuteInstructionImpl(MI, NewMI, OpIdx1, OpIdx2);
4401 case RISCV::QC_MVEQ:
4402 case RISCV::QC_MVNE:
4403 case RISCV::QC_MVLT:
4404 case RISCV::QC_MVGE:
4405 case RISCV::QC_MVLTU:
4406 case RISCV::QC_MVGEU:
4407 case RISCV::QC_MVEQI:
4408 case RISCV::QC_MVNEI:
4409 case RISCV::QC_MVLTI:
4410 case RISCV::QC_MVGEI:
4411 case RISCV::QC_MVLTUI:
4412 case RISCV::QC_MVGEUI: {
4413 auto &WorkingMI = cloneIfNew(MI);
4414 WorkingMI.setDesc(get(getInverseXqcicmOpcode(MI.getOpcode())));
4415 return TargetInstrInfo::commuteInstructionImpl(WorkingMI, false, OpIdx1,
4416 OpIdx2);
4417 }
4418 case RISCV::PseudoCCMOVGPRNoX0:
4419 case RISCV::PseudoCCMOVGPR: {
4420 // CCMOV can be commuted by inverting the condition.
4421 unsigned BCC = MI.getOperand(MI.getNumExplicitOperands() - 3).getImm();
4423 auto &WorkingMI = cloneIfNew(MI);
4424 WorkingMI.getOperand(MI.getNumExplicitOperands() - 3).setImm(BCC);
4425 return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI*/ false,
4426 OpIdx1, OpIdx2);
4427 }
4428 case CASE_VFMA_SPLATS(FMACC):
4429 case CASE_VFMA_SPLATS(FMADD):
4430 case CASE_VFMA_SPLATS(FMSAC):
4431 case CASE_VFMA_SPLATS(FMSUB):
4432 case CASE_VFMA_SPLATS(FNMACC):
4434 case CASE_VFMA_SPLATS(FNMSAC):
4436 case CASE_VFMA_OPCODE_VV(FMACC):
4437 case CASE_VFMA_OPCODE_VV(FMSAC):
4438 case CASE_VFMA_OPCODE_VV(FNMACC):
4439 case CASE_VFMA_OPCODE_VV(FNMSAC):
4440 case CASE_VMA_OPCODE_LMULS(MADD, VX):
4441 case CASE_VMA_OPCODE_LMULS(NMSUB, VX):
4442 case CASE_VMA_OPCODE_LMULS(MACC, VX):
4443 case CASE_VMA_OPCODE_LMULS(NMSAC, VX):
4444 case CASE_VMA_OPCODE_LMULS(MACC, VV):
4445 case CASE_VMA_OPCODE_LMULS(NMSAC, VV): {
4446 // It only make sense to toggle these between clobbering the
4447 // addend/subtrahend/minuend one of the multiplicands.
4448 assert((OpIdx1 == 1 || OpIdx2 == 1) && "Unexpected opcode index");
4449 assert((OpIdx1 == 3 || OpIdx2 == 3) && "Unexpected opcode index");
4450 unsigned Opc;
4451 switch (MI.getOpcode()) {
4452 default:
4453 llvm_unreachable("Unexpected opcode");
4454 CASE_VFMA_CHANGE_OPCODE_SPLATS(FMACC, FMADD)
4455 CASE_VFMA_CHANGE_OPCODE_SPLATS(FMADD, FMACC)
4462 CASE_VFMA_CHANGE_OPCODE_VV(FMACC, FMADD)
4466 CASE_VMA_CHANGE_OPCODE_LMULS(MACC, MADD, VX)
4467 CASE_VMA_CHANGE_OPCODE_LMULS(MADD, MACC, VX)
4468 CASE_VMA_CHANGE_OPCODE_LMULS(NMSAC, NMSUB, VX)
4469 CASE_VMA_CHANGE_OPCODE_LMULS(NMSUB, NMSAC, VX)
4470 CASE_VMA_CHANGE_OPCODE_LMULS(MACC, MADD, VV)
4471 CASE_VMA_CHANGE_OPCODE_LMULS(NMSAC, NMSUB, VV)
4472 }
4473
4474 auto &WorkingMI = cloneIfNew(MI);
4475 WorkingMI.setDesc(get(Opc));
4476 return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI=*/false,
4477 OpIdx1, OpIdx2);
4478 }
4479 case CASE_VFMA_OPCODE_VV(FMADD):
4483 case CASE_VMA_OPCODE_LMULS(MADD, VV):
4484 case CASE_VMA_OPCODE_LMULS(NMSUB, VV): {
4485 assert((OpIdx1 == 1 || OpIdx2 == 1) && "Unexpected opcode index");
4486 // If one of the operands, is the addend we need to change opcode.
4487 // Otherwise we're just swapping 2 of the multiplicands.
4488 if (OpIdx1 == 3 || OpIdx2 == 3) {
4489 unsigned Opc;
4490 switch (MI.getOpcode()) {
4491 default:
4492 llvm_unreachable("Unexpected opcode");
4493 CASE_VFMA_CHANGE_OPCODE_VV(FMADD, FMACC)
4497 CASE_VMA_CHANGE_OPCODE_LMULS(MADD, MACC, VV)
4498 CASE_VMA_CHANGE_OPCODE_LMULS(NMSUB, NMSAC, VV)
4499 }
4500
4501 auto &WorkingMI = cloneIfNew(MI);
4502 WorkingMI.setDesc(get(Opc));
4503 return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI=*/false,
4504 OpIdx1, OpIdx2);
4505 }
4506 // Let the default code handle it.
4507 break;
4508 }
4509 }
4510
4511 return TargetInstrInfo::commuteInstructionImpl(MI, NewMI, OpIdx1, OpIdx2);
4512}
4513
4514#undef CASE_VMA_CHANGE_OPCODE_COMMON
4515#undef CASE_VMA_CHANGE_OPCODE_LMULS
4516#undef CASE_VFMA_CHANGE_OPCODE_COMMON
4517#undef CASE_VFMA_CHANGE_OPCODE_LMULS_M1
4518#undef CASE_VFMA_CHANGE_OPCODE_LMULS_MF2
4519#undef CASE_VFMA_CHANGE_OPCODE_LMULS_MF4
4520#undef CASE_VFMA_CHANGE_OPCODE_VV
4521#undef CASE_VFMA_CHANGE_OPCODE_SPLATS
4522
4523#undef CASE_RVV_OPCODE_UNMASK_LMUL
4524#undef CASE_RVV_OPCODE_MASK_LMUL
4525#undef CASE_RVV_OPCODE_LMUL
4526#undef CASE_RVV_OPCODE_UNMASK_WIDEN
4527#undef CASE_RVV_OPCODE_UNMASK
4528#undef CASE_RVV_OPCODE_MASK_WIDEN
4529#undef CASE_RVV_OPCODE_MASK
4530#undef CASE_RVV_OPCODE_WIDEN
4531#undef CASE_RVV_OPCODE
4532
4533#undef CASE_VMA_OPCODE_COMMON
4534#undef CASE_VMA_OPCODE_LMULS
4535#undef CASE_VFMA_OPCODE_COMMON
4536#undef CASE_VFMA_OPCODE_LMULS_M1
4537#undef CASE_VFMA_OPCODE_LMULS_MF2
4538#undef CASE_VFMA_OPCODE_LMULS_MF4
4539#undef CASE_VFMA_OPCODE_VV
4540#undef CASE_VFMA_SPLATS
4541
4543 switch (MI.getOpcode()) {
4544 default:
4545 break;
4546 case RISCV::ADD:
4547 case RISCV::OR:
4548 case RISCV::XOR:
4549 // Normalize (so we hit the next if clause).
4550 // add/[x]or rd, zero, rs => add/[x]or rd, rs, zero
4551 if (MI.getOperand(1).getReg() == RISCV::X0)
4552 commuteInstruction(MI);
4553 // add/[x]or rd, rs, zero => addi rd, rs, 0
4554 if (MI.getOperand(2).getReg() == RISCV::X0) {
4555 MI.getOperand(2).ChangeToImmediate(0);
4556 MI.setDesc(get(RISCV::ADDI));
4557 return true;
4558 }
4559 // xor rd, rs, rs => addi rd, zero, 0
4560 if (MI.getOpcode() == RISCV::XOR &&
4561 MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) {
4562 MI.getOperand(1).setReg(RISCV::X0);
4563 MI.getOperand(2).ChangeToImmediate(0);
4564 MI.setDesc(get(RISCV::ADDI));
4565 return true;
4566 }
4567 break;
4568 case RISCV::ORI:
4569 case RISCV::XORI:
4570 // [x]ori rd, zero, N => addi rd, zero, N
4571 if (MI.getOperand(1).getReg() == RISCV::X0) {
4572 MI.setDesc(get(RISCV::ADDI));
4573 return true;
4574 }
4575 break;
4576 case RISCV::SUB:
4577 // sub rd, rs, zero => addi rd, rs, 0
4578 if (MI.getOperand(2).getReg() == RISCV::X0) {
4579 MI.getOperand(2).ChangeToImmediate(0);
4580 MI.setDesc(get(RISCV::ADDI));
4581 return true;
4582 }
4583 break;
4584 case RISCV::SUBW:
4585 // subw rd, rs, zero => addiw rd, rs, 0
4586 if (MI.getOperand(2).getReg() == RISCV::X0) {
4587 MI.getOperand(2).ChangeToImmediate(0);
4588 MI.setDesc(get(RISCV::ADDIW));
4589 return true;
4590 }
4591 break;
4592 case RISCV::ADDW:
4593 // Normalize (so we hit the next if clause).
4594 // addw rd, zero, rs => addw rd, rs, zero
4595 if (MI.getOperand(1).getReg() == RISCV::X0)
4596 commuteInstruction(MI);
4597 // addw rd, rs, zero => addiw rd, rs, 0
4598 if (MI.getOperand(2).getReg() == RISCV::X0) {
4599 MI.getOperand(2).ChangeToImmediate(0);
4600 MI.setDesc(get(RISCV::ADDIW));
4601 return true;
4602 }
4603 break;
4604 case RISCV::SH1ADD:
4605 case RISCV::SH1ADD_UW:
4606 case RISCV::SH2ADD:
4607 case RISCV::SH2ADD_UW:
4608 case RISCV::SH3ADD:
4609 case RISCV::SH3ADD_UW:
4610 // shNadd[.uw] rd, zero, rs => addi rd, rs, 0
4611 if (MI.getOperand(1).getReg() == RISCV::X0) {
4612 MI.removeOperand(1);
4613 MI.addOperand(MachineOperand::CreateImm(0));
4614 MI.setDesc(get(RISCV::ADDI));
4615 return true;
4616 }
4617 // shNadd[.uw] rd, rs, zero => slli[.uw] rd, rs, N
4618 if (MI.getOperand(2).getReg() == RISCV::X0) {
4619 MI.removeOperand(2);
4620 unsigned Opc = MI.getOpcode();
4621 if (Opc == RISCV::SH1ADD_UW || Opc == RISCV::SH2ADD_UW ||
4622 Opc == RISCV::SH3ADD_UW) {
4624 MI.setDesc(get(RISCV::SLLI_UW));
4625 return true;
4626 }
4628 MI.setDesc(get(RISCV::SLLI));
4629 return true;
4630 }
4631 break;
4632 case RISCV::AND:
4633 case RISCV::MUL:
4634 case RISCV::MULH:
4635 case RISCV::MULHSU:
4636 case RISCV::MULHU:
4637 case RISCV::MULW:
4638 // and rd, zero, rs => addi rd, zero, 0
4639 // mul* rd, zero, rs => addi rd, zero, 0
4640 // and rd, rs, zero => addi rd, zero, 0
4641 // mul* rd, rs, zero => addi rd, zero, 0
4642 if (MI.getOperand(1).getReg() == RISCV::X0 ||
4643 MI.getOperand(2).getReg() == RISCV::X0) {
4644 MI.getOperand(1).setReg(RISCV::X0);
4645 MI.getOperand(2).ChangeToImmediate(0);
4646 MI.setDesc(get(RISCV::ADDI));
4647 return true;
4648 }
4649 break;
4650 case RISCV::ANDI:
4651 // andi rd, zero, C => addi rd, zero, 0
4652 if (MI.getOperand(1).getReg() == RISCV::X0) {
4653 MI.getOperand(2).setImm(0);
4654 MI.setDesc(get(RISCV::ADDI));
4655 return true;
4656 }
4657 break;
4658 case RISCV::SLL:
4659 case RISCV::SRL:
4660 case RISCV::SRA:
4661 // shift rd, zero, rs => addi rd, zero, 0
4662 if (MI.getOperand(1).getReg() == RISCV::X0) {
4663 MI.getOperand(2).ChangeToImmediate(0);
4664 MI.setDesc(get(RISCV::ADDI));
4665 return true;
4666 }
4667 // shift rd, rs, zero => addi rd, rs, 0
4668 if (MI.getOperand(2).getReg() == RISCV::X0) {
4669 MI.getOperand(2).ChangeToImmediate(0);
4670 MI.setDesc(get(RISCV::ADDI));
4671 return true;
4672 }
4673 break;
4674 case RISCV::SLLW:
4675 case RISCV::SRLW:
4676 case RISCV::SRAW:
4677 // shiftw rd, zero, rs => addi rd, zero, 0
4678 if (MI.getOperand(1).getReg() == RISCV::X0) {
4679 MI.getOperand(2).ChangeToImmediate(0);
4680 MI.setDesc(get(RISCV::ADDI));
4681 return true;
4682 }
4683 break;
4684 case RISCV::SLLI:
4685 case RISCV::SRLI:
4686 case RISCV::SRAI:
4687 case RISCV::SLLIW:
4688 case RISCV::SRLIW:
4689 case RISCV::SRAIW:
4690 case RISCV::SLLI_UW:
4691 // shiftimm rd, zero, N => addi rd, zero, 0
4692 if (MI.getOperand(1).getReg() == RISCV::X0) {
4693 MI.getOperand(2).setImm(0);
4694 MI.setDesc(get(RISCV::ADDI));
4695 return true;
4696 }
4697 break;
4698 case RISCV::SLTU:
4699 case RISCV::ADD_UW:
4700 // sltu rd, zero, zero => addi rd, zero, 0
4701 // add.uw rd, zero, zero => addi rd, zero, 0
4702 if (MI.getOperand(1).getReg() == RISCV::X0 &&
4703 MI.getOperand(2).getReg() == RISCV::X0) {
4704 MI.getOperand(2).ChangeToImmediate(0);
4705 MI.setDesc(get(RISCV::ADDI));
4706 return true;
4707 }
4708 // add.uw rd, zero, rs => addi rd, rs, 0
4709 if (MI.getOpcode() == RISCV::ADD_UW &&
4710 MI.getOperand(1).getReg() == RISCV::X0) {
4711 MI.removeOperand(1);
4712 MI.addOperand(MachineOperand::CreateImm(0));
4713 MI.setDesc(get(RISCV::ADDI));
4714 }
4715 break;
4716 case RISCV::SLTIU:
4717 // sltiu rd, zero, NZC => addi rd, zero, 1
4718 // sltiu rd, zero, 0 => addi rd, zero, 0
4719 if (MI.getOperand(1).getReg() == RISCV::X0) {
4720 MI.getOperand(2).setImm(MI.getOperand(2).getImm() != 0);
4721 MI.setDesc(get(RISCV::ADDI));
4722 return true;
4723 }
4724 break;
4725 case RISCV::SEXT_H:
4726 case RISCV::SEXT_B:
4727 case RISCV::ZEXT_H_RV32:
4728 case RISCV::ZEXT_H_RV64:
4729 // sext.[hb] rd, zero => addi rd, zero, 0
4730 // zext.h rd, zero => addi rd, zero, 0
4731 if (MI.getOperand(1).getReg() == RISCV::X0) {
4732 MI.addOperand(MachineOperand::CreateImm(0));
4733 MI.setDesc(get(RISCV::ADDI));
4734 return true;
4735 }
4736 break;
4737 case RISCV::MIN:
4738 case RISCV::MINU:
4739 case RISCV::MAX:
4740 case RISCV::MAXU:
4741 // min|max rd, rs, rs => addi rd, rs, 0
4742 if (MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) {
4743 MI.getOperand(2).ChangeToImmediate(0);
4744 MI.setDesc(get(RISCV::ADDI));
4745 return true;
4746 }
4747 break;
4748 case RISCV::BEQ:
4749 case RISCV::BNE:
4750 // b{eq,ne} zero, rs, imm => b{eq,ne} rs, zero, imm
4751 if (MI.getOperand(0).getReg() == RISCV::X0) {
4752 MachineOperand MO0 = MI.getOperand(0);
4753 MI.removeOperand(0);
4754 MI.insert(MI.operands_begin() + 1, {MO0});
4755 }
4756 break;
4757 case RISCV::BLTU:
4758 // bltu zero, rs, imm => bne rs, zero, imm
4759 if (MI.getOperand(0).getReg() == RISCV::X0) {
4760 MachineOperand MO0 = MI.getOperand(0);
4761 MI.removeOperand(0);
4762 MI.insert(MI.operands_begin() + 1, {MO0});
4763 MI.setDesc(get(RISCV::BNE));
4764 }
4765 break;
4766 case RISCV::BGEU:
4767 // bgeu zero, rs, imm => beq rs, zero, imm
4768 if (MI.getOperand(0).getReg() == RISCV::X0) {
4769 MachineOperand MO0 = MI.getOperand(0);
4770 MI.removeOperand(0);
4771 MI.insert(MI.operands_begin() + 1, {MO0});
4772 MI.setDesc(get(RISCV::BEQ));
4773 }
4774 break;
4775 }
4776 return false;
4777}
4778
4779// clang-format off
4780#define CASE_WIDEOP_OPCODE_COMMON(OP, LMUL) \
4781 RISCV::PseudoV##OP##_##LMUL##_TIED
4782
4783#define CASE_WIDEOP_OPCODE_LMULS(OP) \
4784 CASE_WIDEOP_OPCODE_COMMON(OP, MF8): \
4785 case CASE_WIDEOP_OPCODE_COMMON(OP, MF4): \
4786 case CASE_WIDEOP_OPCODE_COMMON(OP, MF2): \
4787 case CASE_WIDEOP_OPCODE_COMMON(OP, M1): \
4788 case CASE_WIDEOP_OPCODE_COMMON(OP, M2): \
4789 case CASE_WIDEOP_OPCODE_COMMON(OP, M4)
4790
4791#define CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, LMUL) \
4792 case RISCV::PseudoV##OP##_##LMUL##_TIED: \
4793 NewOpc = RISCV::PseudoV##OP##_##LMUL; \
4794 break;
4795
4796#define CASE_WIDEOP_CHANGE_OPCODE_LMULS(OP) \
4797 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF8) \
4798 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF4) \
4799 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2) \
4800 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1) \
4801 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2) \
4802 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4)
4803
4804// FP Widening Ops may by SEW aware. Create SEW aware cases for these cases.
4805#define CASE_FP_WIDEOP_OPCODE_COMMON(OP, LMUL, SEW) \
4806 RISCV::PseudoV##OP##_##LMUL##_##SEW##_TIED
4807
4808#define CASE_FP_WIDEOP_OPCODE_LMULS(OP) \
4809 CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF4, E16): \
4810 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF2, E16): \
4811 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF2, E32): \
4812 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M1, E16): \
4813 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M1, E32): \
4814 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M2, E16): \
4815 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M2, E32): \
4816 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M4, E16): \
4817 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M4, E32) \
4818
4819#define CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, LMUL, SEW) \
4820 case RISCV::PseudoV##OP##_##LMUL##_##SEW##_TIED: \
4821 NewOpc = RISCV::PseudoV##OP##_##LMUL##_##SEW; \
4822 break;
4823
4824#define CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS(OP) \
4825 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF4, E16) \
4826 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2, E16) \
4827 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2, E32) \
4828 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1, E16) \
4829 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1, E32) \
4830 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2, E16) \
4831 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2, E32) \
4832 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4, E16) \
4833 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4, E32) \
4834
4835#define CASE_FP_WIDEOP_OPCODE_LMULS_ALT(OP) \
4836 CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF4, E16): \
4837 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF2, E16): \
4838 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M1, E16): \
4839 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M2, E16): \
4840 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M4, E16)
4841
4842#define CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS_ALT(OP) \
4843 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF4, E16) \
4844 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2, E16) \
4845 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1, E16) \
4846 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2, E16) \
4847 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4, E16)
4848// clang-format on
4849
4851 LiveVariables *LV,
4852 LiveIntervals *LIS) const {
4854 switch (MI.getOpcode()) {
4855 default:
4856 return nullptr;
4857 case CASE_FP_WIDEOP_OPCODE_LMULS_ALT(FWADD_ALT_WV):
4858 case CASE_FP_WIDEOP_OPCODE_LMULS_ALT(FWSUB_ALT_WV):
4859 case CASE_FP_WIDEOP_OPCODE_LMULS(FWADD_WV):
4860 case CASE_FP_WIDEOP_OPCODE_LMULS(FWSUB_WV): {
4861 assert(RISCVII::hasVecPolicyOp(MI.getDesc().TSFlags) &&
4862 MI.getNumExplicitOperands() == 7 &&
4863 "Expect 7 explicit operands rd, rs2, rs1, rm, vl, sew, policy");
4864 // If the tail policy is undisturbed we can't convert.
4865 if ((MI.getOperand(RISCVII::getVecPolicyOpNum(MI.getDesc())).getImm() &
4866 1) == 0)
4867 return nullptr;
4868 // clang-format off
4869 unsigned NewOpc;
4870 switch (MI.getOpcode()) {
4871 default:
4872 llvm_unreachable("Unexpected opcode");
4877 }
4878 // clang-format on
4879
4880 MachineBasicBlock &MBB = *MI.getParent();
4881 MIB = BuildMI(MBB, MI, MI.getDebugLoc(), get(NewOpc))
4882 .add(MI.getOperand(0))
4883 .addReg(MI.getOperand(0).getReg(), RegState::Undef)
4884 .add(MI.getOperand(1))
4885 .add(MI.getOperand(2))
4886 .add(MI.getOperand(3))
4887 .add(MI.getOperand(4))
4888 .add(MI.getOperand(5))
4889 .add(MI.getOperand(6));
4890 break;
4891 }
4892 case CASE_WIDEOP_OPCODE_LMULS(WADD_WV):
4893 case CASE_WIDEOP_OPCODE_LMULS(WADDU_WV):
4894 case CASE_WIDEOP_OPCODE_LMULS(WSUB_WV):
4895 case CASE_WIDEOP_OPCODE_LMULS(WSUBU_WV): {
4896 // If the tail policy is undisturbed we can't convert.
4897 assert(RISCVII::hasVecPolicyOp(MI.getDesc().TSFlags) &&
4898 MI.getNumExplicitOperands() == 6);
4899 if ((MI.getOperand(RISCVII::getVecPolicyOpNum(MI.getDesc())).getImm() &
4900 1) == 0)
4901 return nullptr;
4902
4903 // clang-format off
4904 unsigned NewOpc;
4905 switch (MI.getOpcode()) {
4906 default:
4907 llvm_unreachable("Unexpected opcode");
4912 }
4913 // clang-format on
4914
4915 MachineBasicBlock &MBB = *MI.getParent();
4916 MIB = BuildMI(MBB, MI, MI.getDebugLoc(), get(NewOpc))
4917 .add(MI.getOperand(0))
4918 .addReg(MI.getOperand(0).getReg(), RegState::Undef)
4919 .add(MI.getOperand(1))
4920 .add(MI.getOperand(2))
4921 .add(MI.getOperand(3))
4922 .add(MI.getOperand(4))
4923 .add(MI.getOperand(5));
4924 break;
4925 }
4926 }
4927 MIB.copyImplicitOps(MI);
4928
4929 if (LV) {
4930 unsigned NumOps = MI.getNumOperands();
4931 for (unsigned I = 1; I < NumOps; ++I) {
4932 MachineOperand &Op = MI.getOperand(I);
4933 if (Op.isReg() && Op.isKill())
4934 LV->replaceKillInstruction(Op.getReg(), MI, *MIB);
4935 }
4936 }
4937
4938 if (LIS) {
4939 SlotIndex Idx = LIS->ReplaceMachineInstrInMaps(MI, *MIB);
4940
4941 if (MI.getOperand(0).isEarlyClobber()) {
4942 // Use operand 1 was tied to early-clobber def operand 0, so its live
4943 // interval could have ended at an early-clobber slot. Now they are not
4944 // tied we need to update it to the normal register slot.
4945 LiveInterval &LI = LIS->getInterval(MI.getOperand(1).getReg());
4947 if (S->end == Idx.getRegSlot(true))
4948 S->end = Idx.getRegSlot();
4949 }
4950 }
4951
4952 return MIB;
4953}
4954
4955#undef CASE_WIDEOP_OPCODE_COMMON
4956#undef CASE_WIDEOP_OPCODE_LMULS
4957#undef CASE_WIDEOP_CHANGE_OPCODE_COMMON
4958#undef CASE_WIDEOP_CHANGE_OPCODE_LMULS
4959#undef CASE_FP_WIDEOP_OPCODE_COMMON
4960#undef CASE_FP_WIDEOP_OPCODE_LMULS
4961#undef CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON
4962#undef CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS
4963
4966 Register DestReg, uint32_t Amount,
4967 MachineInstr::MIFlag Flag) const {
4968 MachineRegisterInfo &MRI = MF.getRegInfo();
4969 if (llvm::has_single_bit<uint32_t>(Amount)) {
4970 uint32_t ShiftAmount = Log2_32(Amount);
4971 if (ShiftAmount == 0)
4972 return;
4973 BuildMI(MBB, II, DL, get(RISCV::SLLI), DestReg)
4974 .addReg(DestReg, RegState::Kill)
4975 .addImm(ShiftAmount)
4976 .setMIFlag(Flag);
4977 } else if (int ShXAmount, ShiftAmount;
4978 STI.hasShlAdd(3) &&
4979 (ShXAmount = isShifted359(Amount, ShiftAmount)) != 0) {
4980 // We can use Zba SHXADD+SLLI instructions for multiply in some cases.
4981 unsigned Opc;
4982 switch (ShXAmount) {
4983 case 1:
4984 Opc = RISCV::SH1ADD;
4985 break;
4986 case 2:
4987 Opc = RISCV::SH2ADD;
4988 break;
4989 case 3:
4990 Opc = RISCV::SH3ADD;
4991 break;
4992 default:
4993 llvm_unreachable("unexpected result of isShifted359");
4994 }
4995 if (ShiftAmount)
4996 BuildMI(MBB, II, DL, get(RISCV::SLLI), DestReg)
4997 .addReg(DestReg, RegState::Kill)
4998 .addImm(ShiftAmount)
4999 .setMIFlag(Flag);
5000 BuildMI(MBB, II, DL, get(Opc), DestReg)
5001 .addReg(DestReg, RegState::Kill)
5002 .addReg(DestReg)
5003 .setMIFlag(Flag);
5004 } else if (llvm::has_single_bit<uint32_t>(Amount - 1)) {
5005 Register ScaledRegister = MRI.createVirtualRegister(&RISCV::GPRRegClass);
5006 uint32_t ShiftAmount = Log2_32(Amount - 1);
5007 BuildMI(MBB, II, DL, get(RISCV::SLLI), ScaledRegister)
5008 .addReg(DestReg)
5009 .addImm(ShiftAmount)
5010 .setMIFlag(Flag);
5011 BuildMI(MBB, II, DL, get(RISCV::ADD), DestReg)
5012 .addReg(ScaledRegister, RegState::Kill)
5013 .addReg(DestReg, RegState::Kill)
5014 .setMIFlag(Flag);
5015 } else if (llvm::has_single_bit<uint32_t>(Amount + 1)) {
5016 Register ScaledRegister = MRI.createVirtualRegister(&RISCV::GPRRegClass);
5017 uint32_t ShiftAmount = Log2_32(Amount + 1);
5018 BuildMI(MBB, II, DL, get(RISCV::SLLI), ScaledRegister)
5019 .addReg(DestReg)
5020 .addImm(ShiftAmount)
5021 .setMIFlag(Flag);
5022 BuildMI(MBB, II, DL, get(RISCV::SUB), DestReg)
5023 .addReg(ScaledRegister, RegState::Kill)
5024 .addReg(DestReg, RegState::Kill)
5025 .setMIFlag(Flag);
5026 } else if (STI.hasStdExtZmmul()) {
5027 Register N = MRI.createVirtualRegister(&RISCV::GPRRegClass);
5028 movImm(MBB, II, DL, N, Amount, Flag);
5029 BuildMI(MBB, II, DL, get(RISCV::MUL), DestReg)
5030 .addReg(DestReg, RegState::Kill)
5032 .setMIFlag(Flag);
5033 } else {
5034 Register Acc;
5035 uint32_t PrevShiftAmount = 0;
5036 for (uint32_t ShiftAmount = 0; Amount >> ShiftAmount; ShiftAmount++) {
5037 if (Amount & (1U << ShiftAmount)) {
5038 if (ShiftAmount)
5039 BuildMI(MBB, II, DL, get(RISCV::SLLI), DestReg)
5040 .addReg(DestReg, RegState::Kill)
5041 .addImm(ShiftAmount - PrevShiftAmount)
5042 .setMIFlag(Flag);
5043 if (Amount >> (ShiftAmount + 1)) {
5044 // If we don't have an accmulator yet, create it and copy DestReg.
5045 if (!Acc) {
5046 Acc = MRI.createVirtualRegister(&RISCV::GPRRegClass);
5047 BuildMI(MBB, II, DL, get(TargetOpcode::COPY), Acc)
5048 .addReg(DestReg)
5049 .setMIFlag(Flag);
5050 } else {
5051 BuildMI(MBB, II, DL, get(RISCV::ADD), Acc)
5052 .addReg(Acc, RegState::Kill)
5053 .addReg(DestReg)
5054 .setMIFlag(Flag);
5055 }
5056 }
5057 PrevShiftAmount = ShiftAmount;
5058 }
5059 }
5060 assert(Acc && "Expected valid accumulator");
5061 BuildMI(MBB, II, DL, get(RISCV::ADD), DestReg)
5062 .addReg(DestReg, RegState::Kill)
5063 .addReg(Acc, RegState::Kill)
5064 .setMIFlag(Flag);
5065 }
5066}
5067
5070 static const std::pair<MachineMemOperand::Flags, const char *> TargetFlags[] =
5071 {{MONontemporalBit0, "riscv-nontemporal-domain-bit-0"},
5072 {MONontemporalBit1, "riscv-nontemporal-domain-bit-1"}};
5073 return ArrayRef(TargetFlags);
5074}
5075
5077 return OptLevel >= CodeGenOptLevel::Aggressive
5078 ? STI.getTailDupAggressiveThreshold()
5079 : 2;
5080}
5081
5083 // RVV lacks any support for immediate addressing for stack addresses, so be
5084 // conservative.
5085 unsigned Opcode = MI.getOpcode();
5086 if (!RISCVVPseudosTable::getPseudoInfo(Opcode) &&
5088 return false;
5089 return true;
5090}
5091
5092/// Return true if \p MI is a copy that will be lowered to one or more vmvNr.vs.
5094 const MachineInstr &MI) {
5095 return MI.isCopy() && MI.getOperand(0).getReg().isPhysical() &&
5097 TRI->getMinimalPhysRegClass(MI.getOperand(0).getReg()));
5098}
5099
5100std::optional<std::pair<unsigned, unsigned>>
5102 switch (Opcode) {
5103 default:
5104 return std::nullopt;
5105 case RISCV::PseudoVSPILL2_M1:
5106 case RISCV::PseudoVRELOAD2_M1:
5107 return std::make_pair(2u, 1u);
5108 case RISCV::PseudoVSPILL2_M2:
5109 case RISCV::PseudoVRELOAD2_M2:
5110 return std::make_pair(2u, 2u);
5111 case RISCV::PseudoVSPILL2_M4:
5112 case RISCV::PseudoVRELOAD2_M4:
5113 return std::make_pair(2u, 4u);
5114 case RISCV::PseudoVSPILL3_M1:
5115 case RISCV::PseudoVRELOAD3_M1:
5116 return std::make_pair(3u, 1u);
5117 case RISCV::PseudoVSPILL3_M2:
5118 case RISCV::PseudoVRELOAD3_M2:
5119 return std::make_pair(3u, 2u);
5120 case RISCV::PseudoVSPILL4_M1:
5121 case RISCV::PseudoVRELOAD4_M1:
5122 return std::make_pair(4u, 1u);
5123 case RISCV::PseudoVSPILL4_M2:
5124 case RISCV::PseudoVRELOAD4_M2:
5125 return std::make_pair(4u, 2u);
5126 case RISCV::PseudoVSPILL5_M1:
5127 case RISCV::PseudoVRELOAD5_M1:
5128 return std::make_pair(5u, 1u);
5129 case RISCV::PseudoVSPILL6_M1:
5130 case RISCV::PseudoVRELOAD6_M1:
5131 return std::make_pair(6u, 1u);
5132 case RISCV::PseudoVSPILL7_M1:
5133 case RISCV::PseudoVRELOAD7_M1:
5134 return std::make_pair(7u, 1u);
5135 case RISCV::PseudoVSPILL8_M1:
5136 case RISCV::PseudoVRELOAD8_M1:
5137 return std::make_pair(8u, 1u);
5138 }
5139}
5140
5141bool RISCV::hasEqualFRM(const MachineInstr &MI1, const MachineInstr &MI2) {
5142 int16_t MI1FrmOpIdx =
5143 RISCV::getNamedOperandIdx(MI1.getOpcode(), RISCV::OpName::frm);
5144 int16_t MI2FrmOpIdx =
5145 RISCV::getNamedOperandIdx(MI2.getOpcode(), RISCV::OpName::frm);
5146 if (MI1FrmOpIdx < 0 || MI2FrmOpIdx < 0)
5147 return false;
5148 MachineOperand FrmOp1 = MI1.getOperand(MI1FrmOpIdx);
5149 MachineOperand FrmOp2 = MI2.getOperand(MI2FrmOpIdx);
5150 return FrmOp1.getImm() == FrmOp2.getImm();
5151}
5152
5153std::optional<unsigned>
5154RISCV::getVectorLowDemandedScalarBits(unsigned Opcode, unsigned Log2SEW) {
5155 switch (Opcode) {
5156 default:
5157 return std::nullopt;
5158
5159 // 11.6. Vector Single-Width Shift Instructions
5160 case RISCV::VSLL_VX:
5161 case RISCV::VSRL_VX:
5162 case RISCV::VSRA_VX:
5163 // 12.4. Vector Single-Width Scaling Shift Instructions
5164 case RISCV::VSSRL_VX:
5165 case RISCV::VSSRA_VX:
5166 // Zvbb
5167 case RISCV::VROL_VX:
5168 case RISCV::VROR_VX:
5169 // Only the low lg2(SEW) bits of the shift-amount value are used.
5170 return Log2SEW;
5171
5172 // 11.7 Vector Narrowing Integer Right Shift Instructions
5173 case RISCV::VNSRL_WX:
5174 case RISCV::VNSRA_WX:
5175 // 12.5. Vector Narrowing Fixed-Point Clip Instructions
5176 case RISCV::VNCLIPU_WX:
5177 case RISCV::VNCLIP_WX:
5178 // Zvbb
5179 case RISCV::VWSLL_VX:
5180 // Only the low lg2(2*SEW) bits of the shift-amount value are used.
5181 return Log2SEW + 1;
5182
5183 // 11.1. Vector Single-Width Integer Add and Subtract
5184 case RISCV::VADD_VX:
5185 case RISCV::VSUB_VX:
5186 case RISCV::VRSUB_VX:
5187 // 11.2. Vector Widening Integer Add/Subtract
5188 case RISCV::VWADDU_VX:
5189 case RISCV::VWSUBU_VX:
5190 case RISCV::VWADD_VX:
5191 case RISCV::VWSUB_VX:
5192 case RISCV::VWADDU_WX:
5193 case RISCV::VWSUBU_WX:
5194 case RISCV::VWADD_WX:
5195 case RISCV::VWSUB_WX:
5196 // 11.4. Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions
5197 case RISCV::VADC_VXM:
5198 case RISCV::VADC_VIM:
5199 case RISCV::VMADC_VXM:
5200 case RISCV::VMADC_VIM:
5201 case RISCV::VMADC_VX:
5202 case RISCV::VSBC_VXM:
5203 case RISCV::VMSBC_VXM:
5204 case RISCV::VMSBC_VX:
5205 // 11.5 Vector Bitwise Logical Instructions
5206 case RISCV::VAND_VX:
5207 case RISCV::VOR_VX:
5208 case RISCV::VXOR_VX:
5209 // 11.8. Vector Integer Compare Instructions
5210 case RISCV::VMSEQ_VX:
5211 case RISCV::VMSNE_VX:
5212 case RISCV::VMSLTU_VX:
5213 case RISCV::VMSLT_VX:
5214 case RISCV::VMSLEU_VX:
5215 case RISCV::VMSLE_VX:
5216 case RISCV::VMSGTU_VX:
5217 case RISCV::VMSGT_VX:
5218 // 11.9. Vector Integer Min/Max Instructions
5219 case RISCV::VMINU_VX:
5220 case RISCV::VMIN_VX:
5221 case RISCV::VMAXU_VX:
5222 case RISCV::VMAX_VX:
5223 // 11.10. Vector Single-Width Integer Multiply Instructions
5224 case RISCV::VMUL_VX:
5225 case RISCV::VMULH_VX:
5226 case RISCV::VMULHU_VX:
5227 case RISCV::VMULHSU_VX:
5228 // 11.11. Vector Integer Divide Instructions
5229 case RISCV::VDIVU_VX:
5230 case RISCV::VDIV_VX:
5231 case RISCV::VREMU_VX:
5232 case RISCV::VREM_VX:
5233 // 11.12. Vector Widening Integer Multiply Instructions
5234 case RISCV::VWMUL_VX:
5235 case RISCV::VWMULU_VX:
5236 case RISCV::VWMULSU_VX:
5237 // 11.13. Vector Single-Width Integer Multiply-Add Instructions
5238 case RISCV::VMACC_VX:
5239 case RISCV::VNMSAC_VX:
5240 case RISCV::VMADD_VX:
5241 case RISCV::VNMSUB_VX:
5242 // 11.14. Vector Widening Integer Multiply-Add Instructions
5243 case RISCV::VWMACCU_VX:
5244 case RISCV::VWMACC_VX:
5245 case RISCV::VWMACCSU_VX:
5246 case RISCV::VWMACCUS_VX:
5247 // 11.15. Vector Integer Merge Instructions
5248 case RISCV::VMERGE_VXM:
5249 // 11.16. Vector Integer Move Instructions
5250 case RISCV::VMV_V_X:
5251 // 12.1. Vector Single-Width Saturating Add and Subtract
5252 case RISCV::VSADDU_VX:
5253 case RISCV::VSADD_VX:
5254 case RISCV::VSSUBU_VX:
5255 case RISCV::VSSUB_VX:
5256 // 12.2. Vector Single-Width Averaging Add and Subtract
5257 case RISCV::VAADDU_VX:
5258 case RISCV::VAADD_VX:
5259 case RISCV::VASUBU_VX:
5260 case RISCV::VASUB_VX:
5261 // 12.3. Vector Single-Width Fractional Multiply with Rounding and Saturation
5262 case RISCV::VSMUL_VX:
5263 // 16.1. Integer Scalar Move Instructions
5264 case RISCV::VMV_S_X:
5265 // Zvbb
5266 case RISCV::VANDN_VX:
5267 return 1U << Log2SEW;
5268 }
5269}
5270
5271unsigned RISCV::getRVVMCOpcode(unsigned RVVPseudoOpcode) {
5273 RISCVVPseudosTable::getPseudoInfo(RVVPseudoOpcode);
5274 if (!RVV)
5275 return 0;
5276 return RVV->BaseInstr;
5277}
5278
5279unsigned RISCV::getDestLog2EEW(const MCInstrDesc &Desc, unsigned Log2SEW) {
5280 unsigned DestEEW =
5282 // EEW = 1
5283 if (DestEEW == 0)
5284 return 0;
5285 // EEW = SEW * n
5286 unsigned Scaled = Log2SEW + (DestEEW - 1);
5287 assert(Scaled >= 3 && Scaled <= 6);
5288 return Scaled;
5289}
5290
5291static std::optional<int64_t> getEffectiveImm(const MachineOperand &MO) {
5292 assert(MO.isImm() || MO.getReg().isVirtual());
5293 if (MO.isImm())
5294 return MO.getImm();
5295 const MachineInstr *Def =
5296 MO.getParent()->getMF()->getRegInfo().getVRegDef(MO.getReg());
5297 int64_t Imm;
5298 if (isLoadImm(Def, Imm))
5299 return Imm;
5300 return std::nullopt;
5301}
5302
5303/// Given two VL operands, do we know that LHS <= RHS? Must be used in SSA form.
5305 assert((LHS.isImm() || LHS.getParent()->getMF()->getRegInfo().isSSA()) &&
5306 (RHS.isImm() || RHS.getParent()->getMF()->getRegInfo().isSSA()));
5307 if (LHS.isReg() && RHS.isReg() && LHS.getReg().isVirtual() &&
5308 LHS.getReg() == RHS.getReg())
5309 return true;
5310 if (RHS.isImm() && RHS.getImm() == RISCV::VLMaxSentinel)
5311 return true;
5312 if (LHS.isImm() && LHS.getImm() == 0)
5313 return true;
5314 if (LHS.isImm() && LHS.getImm() == RISCV::VLMaxSentinel)
5315 return false;
5316 std::optional<int64_t> LHSImm = getEffectiveImm(LHS),
5317 RHSImm = getEffectiveImm(RHS);
5318 if (!LHSImm || !RHSImm)
5319 return false;
5320 return LHSImm <= RHSImm;
5321}
5322
5323namespace {
5324class RISCVPipelinerLoopInfo : public TargetInstrInfo::PipelinerLoopInfo {
5325 const MachineInstr *LHS;
5326 const MachineInstr *RHS;
5328
5329public:
5330 RISCVPipelinerLoopInfo(const MachineInstr *LHS, const MachineInstr *RHS,
5332 : LHS(LHS), RHS(RHS), Cond(Cond.begin(), Cond.end()) {}
5333
5334 bool shouldIgnoreForPipelining(const MachineInstr *MI) const override {
5335 // Make the instructions for loop control be placed in stage 0.
5336 // The predecessors of LHS/RHS are considered by the caller.
5337 if (LHS && MI == LHS)
5338 return true;
5339 if (RHS && MI == RHS)
5340 return true;
5341 return false;
5342 }
5343
5344 std::optional<bool> createTripCountGreaterCondition(
5345 int TC, MachineBasicBlock &MBB,
5346 SmallVectorImpl<MachineOperand> &CondParam) override {
5347 // A branch instruction will be inserted as "if (Cond) goto epilogue".
5348 // Cond is normalized for such use.
5349 // The predecessors of the branch are assumed to have already been inserted.
5350 CondParam = Cond;
5351 return {};
5352 }
5353
5354 void setPreheader(MachineBasicBlock *NewPreheader) override {}
5355
5356 void adjustTripCount(int TripCountAdjust) override {}
5357};
5358} // namespace
5359
5360std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
5362 MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
5364 if (analyzeBranch(*LoopBB, TBB, FBB, Cond, /*AllowModify=*/false))
5365 return nullptr;
5366
5367 // Infinite loops are not supported
5368 if (TBB == LoopBB && FBB == LoopBB)
5369 return nullptr;
5370
5371 // Must be conditional branch
5372 if (FBB == nullptr)
5373 return nullptr;
5374
5375 assert((TBB == LoopBB || FBB == LoopBB) &&
5376 "The Loop must be a single-basic-block loop");
5377
5378 // Normalization for createTripCountGreaterCondition()
5379 if (TBB == LoopBB)
5381
5382 const MachineRegisterInfo &MRI = LoopBB->getParent()->getRegInfo();
5383 auto FindRegDef = [&MRI](MachineOperand &Op) -> const MachineInstr * {
5384 if (!Op.isReg())
5385 return nullptr;
5386 Register Reg = Op.getReg();
5387 if (!Reg.isVirtual())
5388 return nullptr;
5389 return MRI.getVRegDef(Reg);
5390 };
5391
5392 const MachineInstr *LHS = FindRegDef(Cond[1]);
5393 const MachineInstr *RHS = FindRegDef(Cond[2]);
5394 if (LHS && LHS->isPHI())
5395 return nullptr;
5396 if (RHS && RHS->isPHI())
5397 return nullptr;
5398
5399 return std::make_unique<RISCVPipelinerLoopInfo>(LHS, RHS, Cond);
5400}
5401
5402// FIXME: We should remove this if we have a default generic scheduling model.
5404 unsigned RVVMCOpcode = RISCV::getRVVMCOpcode(Opc);
5405 Opc = RVVMCOpcode ? RVVMCOpcode : Opc;
5406 switch (Opc) {
5407 default:
5408 return false;
5409 // Integer div/rem.
5410 case RISCV::DIV:
5411 case RISCV::DIVW:
5412 case RISCV::DIVU:
5413 case RISCV::DIVUW:
5414 case RISCV::REM:
5415 case RISCV::REMW:
5416 case RISCV::REMU:
5417 case RISCV::REMUW:
5418 // Floating-point div/sqrt.
5419 case RISCV::FDIV_H:
5420 case RISCV::FDIV_S:
5421 case RISCV::FDIV_D:
5422 case RISCV::FDIV_H_INX:
5423 case RISCV::FDIV_S_INX:
5424 case RISCV::FDIV_D_INX:
5425 case RISCV::FDIV_D_IN32X:
5426 case RISCV::FSQRT_H:
5427 case RISCV::FSQRT_S:
5428 case RISCV::FSQRT_D:
5429 case RISCV::FSQRT_H_INX:
5430 case RISCV::FSQRT_S_INX:
5431 case RISCV::FSQRT_D_INX:
5432 case RISCV::FSQRT_D_IN32X:
5433 // Vector integer div/rem
5434 case RISCV::VDIV_VV:
5435 case RISCV::VDIV_VX:
5436 case RISCV::VDIVU_VV:
5437 case RISCV::VDIVU_VX:
5438 case RISCV::VREM_VV:
5439 case RISCV::VREM_VX:
5440 case RISCV::VREMU_VV:
5441 case RISCV::VREMU_VX:
5442 // Vector floating-point div/sqrt.
5443 case RISCV::VFDIV_VV:
5444 case RISCV::VFDIV_VF:
5445 case RISCV::VFRDIV_VF:
5446 case RISCV::VFSQRT_V:
5447 case RISCV::VFRSQRT7_V:
5448 return true;
5449 }
5450}
5451
5452bool RISCVInstrInfo::isVRegCopy(const MachineInstr *MI, unsigned LMul) const {
5453 if (MI->getOpcode() != TargetOpcode::COPY)
5454 return false;
5455 const MachineRegisterInfo &MRI = MI->getMF()->getRegInfo();
5457
5458 Register DstReg = MI->getOperand(0).getReg();
5459 const TargetRegisterClass *RC = DstReg.isVirtual()
5460 ? MRI.getRegClass(DstReg)
5461 : TRI->getMinimalPhysRegClass(DstReg);
5462
5464 return false;
5465
5466 if (!LMul)
5467 return true;
5468
5469 // TODO: Perhaps we could distinguish segment register classes (e.g. VRN3M2)
5470 // in the future.
5471 auto [RCLMul, RCFractional] =
5473 return (!RCFractional && LMul == RCLMul) || (RCFractional && LMul == 1);
5474}
5475
5477 if (MI.memoperands_empty())
5478 return false;
5479
5480 MachineMemOperand *MMO = *(MI.memoperands_begin());
5481 if (!MMO->isNonTemporal())
5482 return false;
5483
5484 return true;
5485}
5486
5488 const MachineInstr &To) {
5489 assert(From.getParent() == To.getParent());
5490 SmallVector<Register> PhysUses, PhysDefs;
5491 for (const MachineOperand &MO : From.all_uses())
5492 if (MO.getReg().isPhysical())
5493 PhysUses.push_back(MO.getReg());
5494 for (const MachineOperand &MO : From.all_defs())
5495 if (MO.getReg().isPhysical())
5496 PhysDefs.push_back(MO.getReg());
5497 bool SawStore = false;
5498 for (auto II = std::next(From.getIterator()); II != To.getIterator(); II++) {
5499 for (Register PhysReg : PhysUses)
5500 if (II->definesRegister(PhysReg, nullptr))
5501 return false;
5502 for (Register PhysReg : PhysDefs)
5503 if (II->definesRegister(PhysReg, nullptr) ||
5504 II->readsRegister(PhysReg, nullptr))
5505 return false;
5506 if (II->mayStore()) {
5507 SawStore = true;
5508 break;
5509 }
5510 }
5511 return From.isSafeToMove(SawStore);
5512}
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.
@ MachineOutlinerRegSave
Emit a call and tail-call.
@ MachineOutlinerDefault
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
SmallVector< int16_t, MAX_SRC_OPERANDS_NUM > OperandIndices
@ Scaled
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
basic Basic Alias true
#define X(NUM, ENUM, NAME)
Definition ELF.h:851
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
const HexagonInstrInfo * TII
#define _
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
This file provides utility analysis objects describing memory locations.
MachineInstr unsigned OpIdx
uint64_t IntrinsicInst * II
static bool cannotInsertTailCall(const MachineBasicBlock &MBB)
#define CASE_VFMA_CHANGE_OPCODE_SPLATS(OLDOP, NEWOP)
#define CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS_ALT(OP)
#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 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_FP_WIDEOP_OPCODE_LMULS_ALT(OP)
#define CASE_WIDEOP_OPCODE_LMULS(OP)
static bool isMIReadsReg(const MachineInstr &MI, const TargetRegisterInfo *TRI, MCRegister RegNo)
#define OPCODE_LMUL_MASK_CASE(OPC)
#define CASE_OPERAND_UIMM_LSB_ZEROS(BITS, SUFFIX)
static bool isFSUB(unsigned Opc)
#define CASE_VMA_CHANGE_OPCODE_LMULS(OLDOP, NEWOP, TYPE)
#define CASE_RVV_OPCODE(OP)
static std::optional< int64_t > getEffectiveImm(const MachineOperand &MO)
#define CASE_VFMA_OPCODE_VV(OP)
static cl::opt< bool > OutlinerEnableRegSave("riscv-outliner-regsave", cl::init(true), cl::Hidden, cl::desc("Enable RegSave strategy in machine outliner (save X5 to a " "temporary register when X5 is live across outlined calls)."))
MachineOutlinerConstructionID
#define CASE_RVV_OPCODE_WIDEN(OP)
static unsigned getLoadPredicatedOpcode(unsigned Opcode)
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 unsigned getInverseXqcicmOpcode(unsigned Opcode)
static bool getFPPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce)
#define OPCODE_LMUL_CASE(OPC)
#define CASE_OPERAND_UIMM(NUM)
static Register findRegisterToSaveX5To(outliner::Candidate &C, const TargetRegisterInfo &TRI)
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)
#define CASE_RVV_OPCODE_LMUL(OP, LMUL)
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)
static MachineInstr * canFoldAsPredicatedOp(Register Reg, const MachineRegisterInfo &MRI, const TargetInstrInfo *TII, const RISCVSubtarget &STI)
Identify instructions that can be folded into a CCMOV instruction, and return the defining instructio...
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.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:483
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:171
#define LLVM_DEBUG(...)
Definition Debug.h:114
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
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
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
const T & front() const
front - Get the first element.
Definition ArrayRef.h:145
bool empty() const
empty - Check if the array is empty.
Definition ArrayRef.h:137
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...
bool isBigEndian() const
Definition DataLayout.h:216
A debug info location.
Definition DebugLoc.h:123
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition DenseMap.h:241
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
Definition Function.h:711
LiveInterval - This class represents the liveness of a register, or stack slot.
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.
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.
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
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.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
bool isConditionalBranch() const
Return true if this is a branch which may fall through to the next instruction or may transfer contro...
This holds information about one operand of a machine instruction, indicating the register class for ...
Definition MCInstrDesc.h:86
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
const FeatureBitset & getFeatureBits() const
Set of metadata that should be preserved when using BuildMI().
MachineInstrBundleIterator< const MachineInstr > const_iterator
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
Instructions::const_iterator const_instr_iterator
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineInstrBundleIterator< MachineInstr > iterator
MachineInstrBundleIterator< const MachineInstr, true > const_reverse_iterator
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 & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
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.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool isReturn(QueryType Type=AnyInBundle) const
bool mayLoadOrStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read or modify memory.
const MachineBasicBlock * getParent() const
filtered_mop_range all_defs()
Returns an iterator range over all operands that are (explicit or implicit) register defs.
bool getFlag(MIFlag Flag) const
Return whether an MI flag is set.
LLVM_ABI bool isSafeToMove(bool &SawStore) const
Return true if it is safe to move this instruction.
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.
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.
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
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.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
filtered_mop_range all_uses()
Returns an iterator range over all operands that are (explicit or implicit) register uses.
const MachineOperand & getOperand(unsigned i) const
uint32_t getFlags() const
Return the MI flags bitvector.
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.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
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,...
LLVM_ABI bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI void clearKillFlags(Register Reg) const
clearKillFlags - Iterate over all the uses of the given register and clear the kill flag from the Mac...
LLVM_ABI MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
bool isReserved(MCRegister PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
bool hasOneUse(Register RegNo) const
hasOneUse - Return true if there is exactly one instruction using the specified register.
LLVM_ABI void clearVirtRegs()
clearVirtRegs - Remove all virtual registers (after physreg assignment).
const TargetRegisterInfo * getTargetRegisterInfo() const
LLVM_ABI bool isConstantPhysReg(MCRegister PhysReg) const
Returns true if PhysReg is unallocatable and constant throughout the function.
LLVM_ABI const TargetRegisterClass * constrainRegClass(Register Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...
LLVM_ABI void replaceRegWith(Register FromReg, Register ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
LLVM_ABI MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
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
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool IsKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
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.
RISCVInstrInfo(const RISCVSubtarget &STI)
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DstReg, int FrameIndex, const TargetRegisterClass *RC, Register VReg, unsigned SubReg=0, 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
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
bool isReMaterializableImpl(const MachineInstr &MI) const override
MachineInstr * optimizeSelect(MachineInstr &MI, SmallPtrSetImpl< MachineInstr * > &SeenMIs, bool) const override
bool isVRegCopy(const MachineInstr *MI, unsigned LMul=0) const
Return true if MI is a COPY to a vector register of a specific LMul, or any kind of vector registers ...
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
static bool isSafeToMove(const MachineInstr &From, const MachineInstr &To)
Return true if moving From down to To won't cause any physical register reads or writes to be clobber...
std::optional< unsigned > getInverseOpcode(unsigned Opcode) const override
MachineInstr * foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, ArrayRef< unsigned > Ops, MachineBasicBlock::iterator InsertPt, int FrameIndex, MachineInstr *&CopyMI, LiveIntervals *LIS=nullptr, VirtRegMap *VRM=nullptr) 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
bool analyzeCandidate(outliner::Candidate &C) const
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
bool requiresNTLHint(const MachineInstr &MI) const
Return true if the instruction requires an NTL hint to be emitted.
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
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
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-...
const RISCVRegisterInfo * getRegisterInfo() const override
Wrapper class representing virtual and physical registers.
Definition Register.h:20
constexpr bool isValid() const
Definition Register.h:112
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition Register.h:79
SlotIndex - An opaque wrapper around machine indexes.
Definition SlotIndexes.h:66
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool erase(PtrType Ptr)
Remove pointer from the set.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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 isReMaterializableImpl(const MachineInstr &MI) const
For instructions with opcodes for which the M_REMATERIALIZABLE flag is set, this hook lets the target...
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 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:343
static constexpr TypeSize getZero()
Definition TypeSize.h:349
static constexpr TypeSize getScalable(ScalarTy MinimumSize)
Definition TypeSize.h:346
self_iterator getIterator()
Definition ilist_node.h:123
A raw_ostream that writes to an std::string.
#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 getInverseBranchCondition(CondCode)
unsigned getInverseBranchOpcode(unsigned BCC)
unsigned getBrCond(CondCode CC, unsigned SelectOpc=0)
static bool isValidRoundingMode(unsigned Mode)
static StringRef roundingModeToString(RoundingMode RndMode)
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 int getVXRMOpNum(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)
SmallVector< Inst, 8 > InstSeq
Definition RISCVMatInt.h:43
@ 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 void printXSfmmVType(unsigned VType, raw_ostream &OS)
LLVM_ABI std::pair< unsigned, bool > decodeVLMUL(VLMUL VLMul)
static bool isValidSEW(unsigned SEW)
static bool isValidVType(unsigned VType)
LLVM_ABI void printVType(unsigned VType, raw_ostream &OS)
static bool isValidXSfmmVType(unsigned VTypeI)
static unsigned getSEW(unsigned VType)
static VLMUL getVLMUL(unsigned VType)
static bool isValidRoundingMode(unsigned Mode)
static StringRef roundingModeToString(RoundingMode RndMode)
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
bool isVectorCopy(const TargetRegisterInfo *TRI, const MachineInstr &MI)
Return true if MI is a copy that will be lowered to one or more vmvNr.vs.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
InstrType
Represents how an instruction should be mapped by the outliner.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:316
@ Offset
Definition DWP.cpp:532
@ SHXADD_ADD_SLLI_OP2
@ 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:1739
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.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:165
RegState
Flags to represent properties of register accesses.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Dead
Unused definition.
@ Kill
The last use of a register.
@ Undef
Value of the register doesn't matter.
@ Define
Register definition.
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:2554
bool isValidAtomicOrdering(Int I)
constexpr RegState getKillRegState(bool B)
static const MachineMemOperand::Flags MONontemporalBit0
constexpr RegState getDeadRegState(bool B)
Op::Description Desc
unsigned M1(unsigned Val)
Definition VE.h:377
constexpr bool has_single_bit(T Value) noexcept
Definition bit.h:149
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:331
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr RegState getRenamableRegState(bool B)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
constexpr RegState getDefRegState(bool B)
CombinerObjective
The combiner's goal may differ based on which pattern it is attempting to optimize.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:189
CodeGenOptLevel
Code generation optimization level.
Definition CodeGen.h:82
int isShifted359(T Value, int &Shift)
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
Definition MathExtras.h:182
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:2192
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:572
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
Definition MathExtras.h:198
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:872
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Used to describe addressing mode similar to ExtAddrMode in CodeGenPrepare.
This represents a simple continuous liveness interval for a value.
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.