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