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