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