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 F.getFnAttributeAsParsedInteger("patchable-function-entry");
2091 // Number of C.NOP or NOP
2092 return (STI.hasStdExtZca() ? 2 : 4) * Num;
2093 }
2094 // XRay uses C.JAL + 21 or 33 C.NOP for each sled in RV32 and RV64,
2095 // respectively.
2096 return STI.is64Bit() ? 68 : 44;
2097 }
2098 default:
2099 return get(Opcode).getSize();
2100 }
2101}
2102
2104 const unsigned Opcode = MI.getOpcode();
2105 switch (Opcode) {
2106 default:
2107 break;
2108 case RISCV::FSGNJ_D:
2109 case RISCV::FSGNJ_S:
2110 case RISCV::FSGNJ_H:
2111 case RISCV::FSGNJ_D_INX:
2112 case RISCV::FSGNJ_D_IN32X:
2113 case RISCV::FSGNJ_S_INX:
2114 case RISCV::FSGNJ_H_INX:
2115 // The canonical floating-point move is fsgnj rd, rs, rs.
2116 return MI.getOperand(1).isReg() && MI.getOperand(2).isReg() &&
2117 MI.getOperand(1).getReg() == MI.getOperand(2).getReg();
2118 case RISCV::ADDI:
2119 case RISCV::ORI:
2120 case RISCV::XORI:
2121 return (MI.getOperand(1).isReg() &&
2122 MI.getOperand(1).getReg() == RISCV::X0) ||
2123 (MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0);
2124 }
2125 return MI.isAsCheapAsAMove();
2126}
2127
2128std::optional<DestSourcePair>
2130 if (MI.isMoveReg())
2131 return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
2132 switch (MI.getOpcode()) {
2133 default:
2134 break;
2135 case RISCV::ADD:
2136 case RISCV::OR:
2137 case RISCV::XOR:
2138 if (MI.getOperand(1).isReg() && MI.getOperand(1).getReg() == RISCV::X0 &&
2139 MI.getOperand(2).isReg())
2140 return DestSourcePair{MI.getOperand(0), MI.getOperand(2)};
2141 if (MI.getOperand(2).isReg() && MI.getOperand(2).getReg() == RISCV::X0 &&
2142 MI.getOperand(1).isReg())
2143 return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
2144 break;
2145 case RISCV::ADDI:
2146 // Operand 1 can be a frameindex but callers expect registers
2147 if (MI.getOperand(1).isReg() && MI.getOperand(2).isImm() &&
2148 MI.getOperand(2).getImm() == 0)
2149 return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
2150 break;
2151 case RISCV::SUB:
2152 if (MI.getOperand(2).isReg() && MI.getOperand(2).getReg() == RISCV::X0 &&
2153 MI.getOperand(1).isReg())
2154 return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
2155 break;
2156 case RISCV::SH1ADD:
2157 case RISCV::SH1ADD_UW:
2158 case RISCV::SH2ADD:
2159 case RISCV::SH2ADD_UW:
2160 case RISCV::SH3ADD:
2161 case RISCV::SH3ADD_UW:
2162 if (MI.getOperand(1).isReg() && MI.getOperand(1).getReg() == RISCV::X0 &&
2163 MI.getOperand(2).isReg())
2164 return DestSourcePair{MI.getOperand(0), MI.getOperand(2)};
2165 break;
2166 case RISCV::FSGNJ_D:
2167 case RISCV::FSGNJ_S:
2168 case RISCV::FSGNJ_H:
2169 case RISCV::FSGNJ_D_INX:
2170 case RISCV::FSGNJ_D_IN32X:
2171 case RISCV::FSGNJ_S_INX:
2172 case RISCV::FSGNJ_H_INX:
2173 // The canonical floating-point move is fsgnj rd, rs, rs.
2174 if (MI.getOperand(1).isReg() && MI.getOperand(2).isReg() &&
2175 MI.getOperand(1).getReg() == MI.getOperand(2).getReg())
2176 return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
2177 break;
2178 }
2179 return std::nullopt;
2180}
2181
2183 if (ForceMachineCombinerStrategy.getNumOccurrences() == 0) {
2184 // The option is unused. Choose Local strategy only for in-order cores. When
2185 // scheduling model is unspecified, use MinInstrCount strategy as more
2186 // generic one.
2187 const auto &SchedModel = STI.getSchedModel();
2188 return (!SchedModel.hasInstrSchedModel() || SchedModel.isOutOfOrder())
2191 }
2192 // The strategy was forced by the option.
2194}
2195
2197 MachineInstr &Root, unsigned &Pattern,
2198 SmallVectorImpl<MachineInstr *> &InsInstrs) const {
2199 int16_t FrmOpIdx =
2200 RISCV::getNamedOperandIdx(Root.getOpcode(), RISCV::OpName::frm);
2201 if (FrmOpIdx < 0) {
2202 assert(all_of(InsInstrs,
2203 [](MachineInstr *MI) {
2204 return RISCV::getNamedOperandIdx(MI->getOpcode(),
2205 RISCV::OpName::frm) < 0;
2206 }) &&
2207 "New instructions require FRM whereas the old one does not have it");
2208 return;
2209 }
2210
2211 const MachineOperand &FRM = Root.getOperand(FrmOpIdx);
2212 MachineFunction &MF = *Root.getMF();
2213
2214 for (auto *NewMI : InsInstrs) {
2215 // We'd already added the FRM operand.
2216 if (static_cast<unsigned>(RISCV::getNamedOperandIdx(
2217 NewMI->getOpcode(), RISCV::OpName::frm)) != NewMI->getNumOperands())
2218 continue;
2219 MachineInstrBuilder MIB(MF, NewMI);
2220 MIB.add(FRM);
2221 if (FRM.getImm() == RISCVFPRndMode::DYN)
2222 MIB.addUse(RISCV::FRM, RegState::Implicit);
2223 }
2224}
2225
2226static bool isFADD(unsigned Opc) {
2227 switch (Opc) {
2228 default:
2229 return false;
2230 case RISCV::FADD_H:
2231 case RISCV::FADD_S:
2232 case RISCV::FADD_D:
2233 return true;
2234 }
2235}
2236
2237static bool isFSUB(unsigned Opc) {
2238 switch (Opc) {
2239 default:
2240 return false;
2241 case RISCV::FSUB_H:
2242 case RISCV::FSUB_S:
2243 case RISCV::FSUB_D:
2244 return true;
2245 }
2246}
2247
2248static bool isFMUL(unsigned Opc) {
2249 switch (Opc) {
2250 default:
2251 return false;
2252 case RISCV::FMUL_H:
2253 case RISCV::FMUL_S:
2254 case RISCV::FMUL_D:
2255 return true;
2256 }
2257}
2258
2259bool RISCVInstrInfo::isVectorAssociativeAndCommutative(const MachineInstr &Inst,
2260 bool Invert) const {
2261#define OPCODE_LMUL_CASE(OPC) \
2262 case RISCV::OPC##_M1: \
2263 case RISCV::OPC##_M2: \
2264 case RISCV::OPC##_M4: \
2265 case RISCV::OPC##_M8: \
2266 case RISCV::OPC##_MF2: \
2267 case RISCV::OPC##_MF4: \
2268 case RISCV::OPC##_MF8
2269
2270#define OPCODE_LMUL_MASK_CASE(OPC) \
2271 case RISCV::OPC##_M1_MASK: \
2272 case RISCV::OPC##_M2_MASK: \
2273 case RISCV::OPC##_M4_MASK: \
2274 case RISCV::OPC##_M8_MASK: \
2275 case RISCV::OPC##_MF2_MASK: \
2276 case RISCV::OPC##_MF4_MASK: \
2277 case RISCV::OPC##_MF8_MASK
2278
2279 unsigned Opcode = Inst.getOpcode();
2280 if (Invert) {
2281 if (auto InvOpcode = getInverseOpcode(Opcode))
2282 Opcode = *InvOpcode;
2283 else
2284 return false;
2285 }
2286
2287 // clang-format off
2288 switch (Opcode) {
2289 default:
2290 return false;
2291 OPCODE_LMUL_CASE(PseudoVADD_VV):
2292 OPCODE_LMUL_MASK_CASE(PseudoVADD_VV):
2293 OPCODE_LMUL_CASE(PseudoVMUL_VV):
2294 OPCODE_LMUL_MASK_CASE(PseudoVMUL_VV):
2295 return true;
2296 }
2297 // clang-format on
2298
2299#undef OPCODE_LMUL_MASK_CASE
2300#undef OPCODE_LMUL_CASE
2301}
2302
2303bool RISCVInstrInfo::areRVVInstsReassociable(const MachineInstr &Root,
2304 const MachineInstr &Prev) const {
2305 if (!areOpcodesEqualOrInverse(Root.getOpcode(), Prev.getOpcode()))
2306 return false;
2307
2308 assert(Root.getMF() == Prev.getMF());
2309 const MachineRegisterInfo *MRI = &Root.getMF()->getRegInfo();
2310 const TargetRegisterInfo *TRI = MRI->getTargetRegisterInfo();
2311
2312 // Make sure vtype operands are also the same.
2313 const MCInstrDesc &Desc = get(Root.getOpcode());
2314 const uint64_t TSFlags = Desc.TSFlags;
2315
2316 auto checkImmOperand = [&](unsigned OpIdx) {
2317 return Root.getOperand(OpIdx).getImm() == Prev.getOperand(OpIdx).getImm();
2318 };
2319
2320 auto checkRegOperand = [&](unsigned OpIdx) {
2321 return Root.getOperand(OpIdx).getReg() == Prev.getOperand(OpIdx).getReg();
2322 };
2323
2324 // PassThru
2325 // TODO: Potentially we can loosen the condition to consider Root to be
2326 // associable with Prev if Root has NoReg as passthru. In which case we
2327 // also need to loosen the condition on vector policies between these.
2328 if (!checkRegOperand(1))
2329 return false;
2330
2331 // SEW
2332 if (RISCVII::hasSEWOp(TSFlags) &&
2333 !checkImmOperand(RISCVII::getSEWOpNum(Desc)))
2334 return false;
2335
2336 // Mask
2337 if (RISCVII::usesMaskPolicy(TSFlags)) {
2338 const MachineBasicBlock *MBB = Root.getParent();
2341 Register MI1VReg;
2342
2343 bool SeenMI2 = false;
2344 for (auto End = MBB->rend(), It = It1; It != End; ++It) {
2345 if (It == It2) {
2346 SeenMI2 = true;
2347 if (!MI1VReg.isValid())
2348 // There is no V0 def between Root and Prev; they're sharing the
2349 // same V0.
2350 break;
2351 }
2352
2353 if (It->modifiesRegister(RISCV::V0, TRI)) {
2354 Register SrcReg = It->getOperand(1).getReg();
2355 // If it's not VReg it'll be more difficult to track its defs, so
2356 // bailing out here just to be safe.
2357 if (!SrcReg.isVirtual())
2358 return false;
2359
2360 if (!MI1VReg.isValid()) {
2361 // This is the V0 def for Root.
2362 MI1VReg = SrcReg;
2363 continue;
2364 }
2365
2366 // Some random mask updates.
2367 if (!SeenMI2)
2368 continue;
2369
2370 // This is the V0 def for Prev; check if it's the same as that of
2371 // Root.
2372 if (MI1VReg != SrcReg)
2373 return false;
2374 else
2375 break;
2376 }
2377 }
2378
2379 // If we haven't encountered Prev, it's likely that this function was
2380 // called in a wrong way (e.g. Root is before Prev).
2381 assert(SeenMI2 && "Prev is expected to appear before Root");
2382 }
2383
2384 // Tail / Mask policies
2385 if (RISCVII::hasVecPolicyOp(TSFlags) &&
2386 !checkImmOperand(RISCVII::getVecPolicyOpNum(Desc)))
2387 return false;
2388
2389 // VL
2390 if (RISCVII::hasVLOp(TSFlags)) {
2391 unsigned OpIdx = RISCVII::getVLOpNum(Desc);
2392 const MachineOperand &Op1 = Root.getOperand(OpIdx);
2393 const MachineOperand &Op2 = Prev.getOperand(OpIdx);
2394 if (Op1.getType() != Op2.getType())
2395 return false;
2396 switch (Op1.getType()) {
2398 if (Op1.getReg() != Op2.getReg())
2399 return false;
2400 break;
2402 if (Op1.getImm() != Op2.getImm())
2403 return false;
2404 break;
2405 default:
2406 llvm_unreachable("Unrecognized VL operand type");
2407 }
2408 }
2409
2410 // Rounding modes
2411 if (int Idx = RISCVII::getFRMOpNum(Desc); Idx >= 0 && !checkImmOperand(Idx))
2412 return false;
2413 if (int Idx = RISCVII::getVXRMOpNum(Desc); Idx >= 0 && !checkImmOperand(Idx))
2414 return false;
2415
2416 return true;
2417}
2418
2419// Most of our RVV pseudos have passthru operand, so the real operands
2420// start from index = 2.
2421bool RISCVInstrInfo::hasReassociableVectorSibling(const MachineInstr &Inst,
2422 bool &Commuted) const {
2423 const MachineBasicBlock *MBB = Inst.getParent();
2424 const MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
2426 "Expect the present of passthrough operand.");
2427 MachineInstr *MI1 = MRI.getUniqueVRegDef(Inst.getOperand(2).getReg());
2428 MachineInstr *MI2 = MRI.getUniqueVRegDef(Inst.getOperand(3).getReg());
2429
2430 // If only one operand has the same or inverse opcode and it's the second
2431 // source operand, the operands must be commuted.
2432 Commuted = !areRVVInstsReassociable(Inst, *MI1) &&
2433 areRVVInstsReassociable(Inst, *MI2);
2434 if (Commuted)
2435 std::swap(MI1, MI2);
2436
2437 return areRVVInstsReassociable(Inst, *MI1) &&
2438 (isVectorAssociativeAndCommutative(*MI1) ||
2439 isVectorAssociativeAndCommutative(*MI1, /* Invert */ true)) &&
2441 MRI.hasOneNonDBGUse(MI1->getOperand(0).getReg());
2442}
2443
2445 const MachineInstr &Inst, const MachineBasicBlock *MBB) const {
2446 if (!isVectorAssociativeAndCommutative(Inst) &&
2447 !isVectorAssociativeAndCommutative(Inst, /*Invert=*/true))
2449
2450 const MachineOperand &Op1 = Inst.getOperand(2);
2451 const MachineOperand &Op2 = Inst.getOperand(3);
2452 const MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
2453
2454 // We need virtual register definitions for the operands that we will
2455 // reassociate.
2456 MachineInstr *MI1 = nullptr;
2457 MachineInstr *MI2 = nullptr;
2458 if (Op1.isReg() && Op1.getReg().isVirtual())
2459 MI1 = MRI.getUniqueVRegDef(Op1.getReg());
2460 if (Op2.isReg() && Op2.getReg().isVirtual())
2461 MI2 = MRI.getUniqueVRegDef(Op2.getReg());
2462
2463 // And at least one operand must be defined in MBB.
2464 return MI1 && MI2 && (MI1->getParent() == MBB || MI2->getParent() == MBB);
2465}
2466
2468 const MachineInstr &Root, unsigned Pattern,
2469 std::array<unsigned, 5> &OperandIndices) const {
2471 if (RISCV::getRVVMCOpcode(Root.getOpcode())) {
2472 // Skip the passthrough operand, so increment all indices by one.
2473 for (unsigned I = 0; I < 5; ++I)
2474 ++OperandIndices[I];
2475 }
2476}
2477
2479 bool &Commuted) const {
2480 if (isVectorAssociativeAndCommutative(Inst) ||
2481 isVectorAssociativeAndCommutative(Inst, /*Invert=*/true))
2482 return hasReassociableVectorSibling(Inst, Commuted);
2483
2484 if (!TargetInstrInfo::hasReassociableSibling(Inst, Commuted))
2485 return false;
2486
2487 const MachineRegisterInfo &MRI = Inst.getMF()->getRegInfo();
2488 unsigned OperandIdx = Commuted ? 2 : 1;
2489 const MachineInstr &Sibling =
2490 *MRI.getVRegDef(Inst.getOperand(OperandIdx).getReg());
2491
2492 int16_t InstFrmOpIdx =
2493 RISCV::getNamedOperandIdx(Inst.getOpcode(), RISCV::OpName::frm);
2494 int16_t SiblingFrmOpIdx =
2495 RISCV::getNamedOperandIdx(Sibling.getOpcode(), RISCV::OpName::frm);
2496
2497 return (InstFrmOpIdx < 0 && SiblingFrmOpIdx < 0) ||
2498 RISCV::hasEqualFRM(Inst, Sibling);
2499}
2500
2502 bool Invert) const {
2503 if (isVectorAssociativeAndCommutative(Inst, Invert))
2504 return true;
2505
2506 unsigned Opc = Inst.getOpcode();
2507 if (Invert) {
2508 auto InverseOpcode = getInverseOpcode(Opc);
2509 if (!InverseOpcode)
2510 return false;
2511 Opc = *InverseOpcode;
2512 }
2513
2514 if (isFADD(Opc) || isFMUL(Opc))
2517
2518 switch (Opc) {
2519 default:
2520 return false;
2521 case RISCV::ADD:
2522 case RISCV::ADDW:
2523 case RISCV::AND:
2524 case RISCV::OR:
2525 case RISCV::XOR:
2526 // From RISC-V ISA spec, if both the high and low bits of the same product
2527 // are required, then the recommended code sequence is:
2528 //
2529 // MULH[[S]U] rdh, rs1, rs2
2530 // MUL rdl, rs1, rs2
2531 // (source register specifiers must be in same order and rdh cannot be the
2532 // same as rs1 or rs2)
2533 //
2534 // Microarchitectures can then fuse these into a single multiply operation
2535 // instead of performing two separate multiplies.
2536 // MachineCombiner may reassociate MUL operands and lose the fusion
2537 // opportunity.
2538 case RISCV::MUL:
2539 case RISCV::MULW:
2540 case RISCV::MIN:
2541 case RISCV::MINU:
2542 case RISCV::MAX:
2543 case RISCV::MAXU:
2544 case RISCV::FMIN_H:
2545 case RISCV::FMIN_S:
2546 case RISCV::FMIN_D:
2547 case RISCV::FMAX_H:
2548 case RISCV::FMAX_S:
2549 case RISCV::FMAX_D:
2550 return true;
2551 }
2552
2553 return false;
2554}
2555
2556std::optional<unsigned>
2557RISCVInstrInfo::getInverseOpcode(unsigned Opcode) const {
2558#define RVV_OPC_LMUL_CASE(OPC, INV) \
2559 case RISCV::OPC##_M1: \
2560 return RISCV::INV##_M1; \
2561 case RISCV::OPC##_M2: \
2562 return RISCV::INV##_M2; \
2563 case RISCV::OPC##_M4: \
2564 return RISCV::INV##_M4; \
2565 case RISCV::OPC##_M8: \
2566 return RISCV::INV##_M8; \
2567 case RISCV::OPC##_MF2: \
2568 return RISCV::INV##_MF2; \
2569 case RISCV::OPC##_MF4: \
2570 return RISCV::INV##_MF4; \
2571 case RISCV::OPC##_MF8: \
2572 return RISCV::INV##_MF8
2573
2574#define RVV_OPC_LMUL_MASK_CASE(OPC, INV) \
2575 case RISCV::OPC##_M1_MASK: \
2576 return RISCV::INV##_M1_MASK; \
2577 case RISCV::OPC##_M2_MASK: \
2578 return RISCV::INV##_M2_MASK; \
2579 case RISCV::OPC##_M4_MASK: \
2580 return RISCV::INV##_M4_MASK; \
2581 case RISCV::OPC##_M8_MASK: \
2582 return RISCV::INV##_M8_MASK; \
2583 case RISCV::OPC##_MF2_MASK: \
2584 return RISCV::INV##_MF2_MASK; \
2585 case RISCV::OPC##_MF4_MASK: \
2586 return RISCV::INV##_MF4_MASK; \
2587 case RISCV::OPC##_MF8_MASK: \
2588 return RISCV::INV##_MF8_MASK
2589
2590 switch (Opcode) {
2591 default:
2592 return std::nullopt;
2593 case RISCV::FADD_H:
2594 return RISCV::FSUB_H;
2595 case RISCV::FADD_S:
2596 return RISCV::FSUB_S;
2597 case RISCV::FADD_D:
2598 return RISCV::FSUB_D;
2599 case RISCV::FSUB_H:
2600 return RISCV::FADD_H;
2601 case RISCV::FSUB_S:
2602 return RISCV::FADD_S;
2603 case RISCV::FSUB_D:
2604 return RISCV::FADD_D;
2605 case RISCV::ADD:
2606 return RISCV::SUB;
2607 case RISCV::SUB:
2608 return RISCV::ADD;
2609 case RISCV::ADDW:
2610 return RISCV::SUBW;
2611 case RISCV::SUBW:
2612 return RISCV::ADDW;
2613 // clang-format off
2614 RVV_OPC_LMUL_CASE(PseudoVADD_VV, PseudoVSUB_VV);
2615 RVV_OPC_LMUL_MASK_CASE(PseudoVADD_VV, PseudoVSUB_VV);
2616 RVV_OPC_LMUL_CASE(PseudoVSUB_VV, PseudoVADD_VV);
2617 RVV_OPC_LMUL_MASK_CASE(PseudoVSUB_VV, PseudoVADD_VV);
2618 // clang-format on
2619 }
2620
2621#undef RVV_OPC_LMUL_MASK_CASE
2622#undef RVV_OPC_LMUL_CASE
2623}
2624
2626 const MachineOperand &MO,
2627 bool DoRegPressureReduce) {
2628 if (!MO.isReg() || !MO.getReg().isVirtual())
2629 return false;
2630 const MachineRegisterInfo &MRI = Root.getMF()->getRegInfo();
2631 MachineInstr *MI = MRI.getVRegDef(MO.getReg());
2632 if (!MI || !isFMUL(MI->getOpcode()))
2633 return false;
2634
2637 return false;
2638
2639 // Try combining even if fmul has more than one use as it eliminates
2640 // dependency between fadd(fsub) and fmul. However, it can extend liveranges
2641 // for fmul operands, so reject the transformation in register pressure
2642 // reduction mode.
2643 if (DoRegPressureReduce && !MRI.hasOneNonDBGUse(MI->getOperand(0).getReg()))
2644 return false;
2645
2646 // Do not combine instructions from different basic blocks.
2647 if (Root.getParent() != MI->getParent())
2648 return false;
2649 return RISCV::hasEqualFRM(Root, *MI);
2650}
2651
2653 SmallVectorImpl<unsigned> &Patterns,
2654 bool DoRegPressureReduce) {
2655 unsigned Opc = Root.getOpcode();
2656 bool IsFAdd = isFADD(Opc);
2657 if (!IsFAdd && !isFSUB(Opc))
2658 return false;
2659 bool Added = false;
2660 if (canCombineFPFusedMultiply(Root, Root.getOperand(1),
2661 DoRegPressureReduce)) {
2664 Added = true;
2665 }
2666 if (canCombineFPFusedMultiply(Root, Root.getOperand(2),
2667 DoRegPressureReduce)) {
2670 Added = true;
2671 }
2672 return Added;
2673}
2674
2675static bool getFPPatterns(MachineInstr &Root,
2676 SmallVectorImpl<unsigned> &Patterns,
2677 bool DoRegPressureReduce) {
2678 return getFPFusedMultiplyPatterns(Root, Patterns, DoRegPressureReduce);
2679}
2680
2681/// Utility routine that checks if \param MO is defined by an
2682/// \param CombineOpc instruction in the basic block \param MBB
2684 const MachineOperand &MO,
2685 unsigned CombineOpc) {
2686 const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
2687 const MachineInstr *MI = nullptr;
2688
2689 if (MO.isReg() && MO.getReg().isVirtual())
2690 MI = MRI.getUniqueVRegDef(MO.getReg());
2691 // And it needs to be in the trace (otherwise, it won't have a depth).
2692 if (!MI || MI->getParent() != &MBB || MI->getOpcode() != CombineOpc)
2693 return nullptr;
2694 // Must only used by the user we combine with.
2695 if (!MRI.hasOneNonDBGUse(MI->getOperand(0).getReg()))
2696 return nullptr;
2697
2698 return MI;
2699}
2700
2701/// Utility routine that checks if \param MO is defined by a SLLI in \param
2702/// MBB that can be combined by splitting across 2 SHXADD instructions. The
2703/// first SHXADD shift amount is given by \param OuterShiftAmt.
2705 const MachineOperand &MO,
2706 unsigned OuterShiftAmt) {
2707 const MachineInstr *ShiftMI = canCombine(MBB, MO, RISCV::SLLI);
2708 if (!ShiftMI)
2709 return false;
2710
2711 unsigned InnerShiftAmt = ShiftMI->getOperand(2).getImm();
2712 if (InnerShiftAmt < OuterShiftAmt || (InnerShiftAmt - OuterShiftAmt) > 3)
2713 return false;
2714
2715 return true;
2716}
2717
2718// Returns the shift amount from a SHXADD instruction. Returns 0 if the
2719// instruction is not a SHXADD.
2720static unsigned getSHXADDShiftAmount(unsigned Opc) {
2721 switch (Opc) {
2722 default:
2723 return 0;
2724 case RISCV::SH1ADD:
2725 return 1;
2726 case RISCV::SH2ADD:
2727 return 2;
2728 case RISCV::SH3ADD:
2729 return 3;
2730 }
2731}
2732
2733// Returns the shift amount from a SHXADD.UW instruction. Returns 0 if the
2734// instruction is not a SHXADD.UW.
2735static unsigned getSHXADDUWShiftAmount(unsigned Opc) {
2736 switch (Opc) {
2737 default:
2738 return 0;
2739 case RISCV::SH1ADD_UW:
2740 return 1;
2741 case RISCV::SH2ADD_UW:
2742 return 2;
2743 case RISCV::SH3ADD_UW:
2744 return 3;
2745 }
2746}
2747
2748// Look for opportunities to combine (sh3add Z, (add X, (slli Y, 5))) into
2749// (sh3add (sh2add Y, Z), X).
2750static bool getSHXADDPatterns(const MachineInstr &Root,
2751 SmallVectorImpl<unsigned> &Patterns) {
2752 unsigned ShiftAmt = getSHXADDShiftAmount(Root.getOpcode());
2753 if (!ShiftAmt)
2754 return false;
2755
2756 const MachineBasicBlock &MBB = *Root.getParent();
2757
2758 const MachineInstr *AddMI = canCombine(MBB, Root.getOperand(2), RISCV::ADD);
2759 if (!AddMI)
2760 return false;
2761
2762 bool Found = false;
2763 if (canCombineShiftIntoShXAdd(MBB, AddMI->getOperand(1), ShiftAmt)) {
2765 Found = true;
2766 }
2767 if (canCombineShiftIntoShXAdd(MBB, AddMI->getOperand(2), ShiftAmt)) {
2769 Found = true;
2770 }
2771
2772 return Found;
2773}
2774
2786
2788 MachineInstr &Root, SmallVectorImpl<unsigned> &Patterns,
2789 bool DoRegPressureReduce) const {
2790
2791 if (getFPPatterns(Root, Patterns, DoRegPressureReduce))
2792 return true;
2793
2794 if (getSHXADDPatterns(Root, Patterns))
2795 return true;
2796
2797 return TargetInstrInfo::getMachineCombinerPatterns(Root, Patterns,
2798 DoRegPressureReduce);
2799}
2800
2801static unsigned getFPFusedMultiplyOpcode(unsigned RootOpc, unsigned Pattern) {
2802 switch (RootOpc) {
2803 default:
2804 llvm_unreachable("Unexpected opcode");
2805 case RISCV::FADD_H:
2806 return RISCV::FMADD_H;
2807 case RISCV::FADD_S:
2808 return RISCV::FMADD_S;
2809 case RISCV::FADD_D:
2810 return RISCV::FMADD_D;
2811 case RISCV::FSUB_H:
2812 return Pattern == RISCVMachineCombinerPattern::FMSUB ? RISCV::FMSUB_H
2813 : RISCV::FNMSUB_H;
2814 case RISCV::FSUB_S:
2815 return Pattern == RISCVMachineCombinerPattern::FMSUB ? RISCV::FMSUB_S
2816 : RISCV::FNMSUB_S;
2817 case RISCV::FSUB_D:
2818 return Pattern == RISCVMachineCombinerPattern::FMSUB ? RISCV::FMSUB_D
2819 : RISCV::FNMSUB_D;
2820 }
2821}
2822
2823static unsigned getAddendOperandIdx(unsigned Pattern) {
2824 switch (Pattern) {
2825 default:
2826 llvm_unreachable("Unexpected pattern");
2829 return 2;
2832 return 1;
2833 }
2834}
2835
2837 unsigned Pattern,
2840 MachineFunction *MF = Root.getMF();
2841 MachineRegisterInfo &MRI = MF->getRegInfo();
2843
2844 MachineOperand &Mul1 = Prev.getOperand(1);
2845 MachineOperand &Mul2 = Prev.getOperand(2);
2846 MachineOperand &Dst = Root.getOperand(0);
2848
2849 Register DstReg = Dst.getReg();
2850 unsigned FusedOpc = getFPFusedMultiplyOpcode(Root.getOpcode(), Pattern);
2851 uint32_t IntersectedFlags = Root.getFlags() & Prev.getFlags();
2852 DebugLoc MergedLoc =
2854
2855 bool Mul1IsKill = Mul1.isKill();
2856 bool Mul2IsKill = Mul2.isKill();
2857 bool AddendIsKill = Addend.isKill();
2858
2859 // We need to clear kill flags since we may be extending the live range past
2860 // a kill. If the mul had kill flags, we can preserve those since we know
2861 // where the previous range stopped.
2862 MRI.clearKillFlags(Mul1.getReg());
2863 MRI.clearKillFlags(Mul2.getReg());
2864
2866 BuildMI(*MF, MergedLoc, TII->get(FusedOpc), DstReg)
2867 .addReg(Mul1.getReg(), getKillRegState(Mul1IsKill))
2868 .addReg(Mul2.getReg(), getKillRegState(Mul2IsKill))
2869 .addReg(Addend.getReg(), getKillRegState(AddendIsKill))
2870 .setMIFlags(IntersectedFlags);
2871
2872 InsInstrs.push_back(MIB);
2873 if (MRI.hasOneNonDBGUse(Prev.getOperand(0).getReg()))
2874 DelInstrs.push_back(&Prev);
2875 DelInstrs.push_back(&Root);
2876}
2877
2878// Combine patterns like (sh3add Z, (add X, (slli Y, 5))) to
2879// (sh3add (sh2add Y, Z), X) if the shift amount can be split across two
2880// shXadd instructions. The outer shXadd keeps its original opcode.
2881static void
2882genShXAddAddShift(MachineInstr &Root, unsigned AddOpIdx,
2885 DenseMap<Register, unsigned> &InstrIdxForVirtReg) {
2886 MachineFunction *MF = Root.getMF();
2887 MachineRegisterInfo &MRI = MF->getRegInfo();
2889
2890 unsigned OuterShiftAmt = getSHXADDShiftAmount(Root.getOpcode());
2891 assert(OuterShiftAmt != 0 && "Unexpected opcode");
2892
2893 MachineInstr *AddMI = MRI.getUniqueVRegDef(Root.getOperand(2).getReg());
2894 MachineInstr *ShiftMI =
2895 MRI.getUniqueVRegDef(AddMI->getOperand(AddOpIdx).getReg());
2896
2897 unsigned InnerShiftAmt = ShiftMI->getOperand(2).getImm();
2898 assert(InnerShiftAmt >= OuterShiftAmt && "Unexpected shift amount");
2899
2900 unsigned InnerOpc;
2901 switch (InnerShiftAmt - OuterShiftAmt) {
2902 default:
2903 llvm_unreachable("Unexpected shift amount");
2904 case 0:
2905 InnerOpc = RISCV::ADD;
2906 break;
2907 case 1:
2908 InnerOpc = RISCV::SH1ADD;
2909 break;
2910 case 2:
2911 InnerOpc = RISCV::SH2ADD;
2912 break;
2913 case 3:
2914 InnerOpc = RISCV::SH3ADD;
2915 break;
2916 }
2917
2918 const MachineOperand &X = AddMI->getOperand(3 - AddOpIdx);
2919 const MachineOperand &Y = ShiftMI->getOperand(1);
2920 const MachineOperand &Z = Root.getOperand(1);
2921
2922 Register NewVR = MRI.createVirtualRegister(&RISCV::GPRRegClass);
2923
2924 auto MIB1 = BuildMI(*MF, MIMetadata(Root), TII->get(InnerOpc), NewVR)
2925 .addReg(Y.getReg(), getKillRegState(Y.isKill()))
2926 .addReg(Z.getReg(), getKillRegState(Z.isKill()));
2927 auto MIB2 = BuildMI(*MF, MIMetadata(Root), TII->get(Root.getOpcode()),
2928 Root.getOperand(0).getReg())
2929 .addReg(NewVR, RegState::Kill)
2930 .addReg(X.getReg(), getKillRegState(X.isKill()));
2931
2932 InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0));
2933 InsInstrs.push_back(MIB1);
2934 InsInstrs.push_back(MIB2);
2935 DelInstrs.push_back(ShiftMI);
2936 DelInstrs.push_back(AddMI);
2937 DelInstrs.push_back(&Root);
2938}
2939
2941 MachineInstr &Root, unsigned Pattern,
2944 DenseMap<Register, unsigned> &InstrIdxForVirtReg) const {
2945 MachineRegisterInfo &MRI = Root.getMF()->getRegInfo();
2946 switch (Pattern) {
2947 default:
2949 DelInstrs, InstrIdxForVirtReg);
2950 return;
2953 MachineInstr &Prev = *MRI.getVRegDef(Root.getOperand(1).getReg());
2954 combineFPFusedMultiply(Root, Prev, Pattern, InsInstrs, DelInstrs);
2955 return;
2956 }
2959 MachineInstr &Prev = *MRI.getVRegDef(Root.getOperand(2).getReg());
2960 combineFPFusedMultiply(Root, Prev, Pattern, InsInstrs, DelInstrs);
2961 return;
2962 }
2964 genShXAddAddShift(Root, 1, InsInstrs, DelInstrs, InstrIdxForVirtReg);
2965 return;
2967 genShXAddAddShift(Root, 2, InsInstrs, DelInstrs, InstrIdxForVirtReg);
2968 return;
2969 }
2970}
2971
2973 StringRef &ErrInfo) const {
2974 MCInstrDesc const &Desc = MI.getDesc();
2975
2976 for (const auto &[Index, Operand] : enumerate(Desc.operands())) {
2977 const MachineOperand &MO = MI.getOperand(Index);
2978 unsigned OpType = Operand.OperandType;
2979 switch (OpType) {
2980 default:
2981 if (OpType >= RISCVOp::OPERAND_FIRST_RISCV_IMM &&
2983 if (!MO.isImm()) {
2984 ErrInfo = "Expected an immediate operand.";
2985 return false;
2986 }
2987 int64_t Imm = MO.getImm();
2988 bool Ok;
2989 switch (OpType) {
2990 default:
2991 llvm_unreachable("Unexpected operand type");
2992
2993#define CASE_OPERAND_UIMM(NUM) \
2994 case RISCVOp::OPERAND_UIMM##NUM: \
2995 Ok = isUInt<NUM>(Imm); \
2996 break;
2997#define CASE_OPERAND_UIMM_LSB_ZEROS(BITS, SUFFIX) \
2998 case RISCVOp::OPERAND_UIMM##BITS##_LSB##SUFFIX: { \
2999 constexpr size_t NumZeros = sizeof(#SUFFIX) - 1; \
3000 Ok = isShiftedUInt<BITS - NumZeros, NumZeros>(Imm); \
3001 break; \
3002 }
3003#define CASE_OPERAND_SIMM(NUM) \
3004 case RISCVOp::OPERAND_SIMM##NUM: \
3005 Ok = isInt<NUM>(Imm); \
3006 break;
3007 // clang-format off
3031 // clang-format on
3033 Ok = isUInt<5>(Imm) && (Imm != 0);
3034 break;
3036 Ok = isUInt<5>(Imm) && (Imm > 3);
3037 break;
3039 Ok = Imm >= 1 && Imm <= 32;
3040 break;
3042 Ok = Imm >= 1 && Imm <= 64;
3043 break;
3045 Ok = isUInt<8>(Imm) && Imm >= 32;
3046 break;
3048 Ok = isShiftedInt<6, 4>(Imm) && (Imm != 0);
3049 break;
3051 Ok = isShiftedUInt<8, 2>(Imm) && (Imm != 0);
3052 break;
3054 Ok = isUInt<16>(Imm) && (Imm != 0);
3055 break;
3057 Ok = Imm == 3;
3058 break;
3060 Ok = Imm == 4;
3061 break;
3063 Ok = (isUInt<5>(Imm) && Imm != 0) || Imm == -1;
3064 break;
3065 // clang-format off
3072 // clang-format on
3074 Ok = Imm >= -15 && Imm <= 16;
3075 break;
3077 Ok = isInt<5>(Imm) && (Imm != 0);
3078 break;
3080 Ok = Imm != 0 && isInt<6>(Imm);
3081 break;
3083 Ok = isUInt<10>(Imm) && RISCVVType::isValidVType(Imm);
3084 break;
3086 Ok = isUInt<11>(Imm) && RISCVVType::isValidVType(Imm);
3087 break;
3089 Ok = isShiftedInt<7, 5>(Imm);
3090 break;
3092 Ok = isInt<16>(Imm) && (Imm != 0);
3093 break;
3095 Ok = isInt<20>(Imm);
3096 break;
3098 Ok = STI.is64Bit() ? isUInt<6>(Imm) : isUInt<5>(Imm);
3099 break;
3101 Ok = STI.is64Bit() ? isUInt<6>(Imm) : isUInt<5>(Imm);
3102 Ok = Ok && Imm != 0;
3103 break;
3105 Ok = (isUInt<5>(Imm) && Imm != 0) || (Imm >= 0xfffe0 && Imm <= 0xfffff);
3106 break;
3108 Ok = Imm >= 0 && Imm <= 10;
3109 break;
3111 Ok = Imm >= 0 && Imm <= 7;
3112 break;
3114 Ok = Imm >= 1 && Imm <= 10;
3115 break;
3117 Ok = Imm >= 2 && Imm <= 14;
3118 break;
3120 Ok = Imm >= RISCVZC::RA && Imm <= RISCVZC::RA_S0_S11;
3121 break;
3123 Ok = Imm >= RISCVZC::RA_S0 && Imm <= RISCVZC::RA_S0_S11;
3124 break;
3126 Ok = Imm >= 0 && Imm <= 48 && Imm % 16 == 0;
3127 break;
3130 break;
3132 Ok = Imm == RISCVFPRndMode::RTZ;
3133 break;
3135 Ok = Imm >= 0 && Imm < RISCVCC::COND_INVALID;
3136 break;
3138 Ok = isValidAtomicOrdering(Imm);
3139 break;
3142 Imm;
3143 break;
3145 Ok = (isUInt<5>(Imm) && RISCVVType::isValidSEW(1 << Imm));
3146 break;
3148 Ok = Imm == 0;
3149 break;
3152 if (RISCVII::usesVXRM(Desc.TSFlags))
3153 Ok = isUInt<2>(Imm);
3154 else
3156 break;
3159 break;
3161 Ok = Imm == 1 || Imm == 2 || Imm == 4;
3162 break;
3163 }
3164 if (!Ok) {
3165 ErrInfo = "Invalid immediate";
3166 return false;
3167 }
3168 }
3169 break;
3171 // TODO: We could be stricter about what non-register operands are
3172 // allowed.
3173 if (MO.isReg()) {
3174 ErrInfo = "Expected a non-register operand.";
3175 return false;
3176 }
3177 if (MO.isImm() && !isInt<12>(MO.getImm())) {
3178 ErrInfo = "Invalid immediate";
3179 return false;
3180 }
3181 break;
3184 // TODO: We could be stricter about what non-register operands are
3185 // allowed.
3186 if (MO.isReg()) {
3187 ErrInfo = "Expected a non-register operand.";
3188 return false;
3189 }
3190 if (MO.isImm() && !isUInt<20>(MO.getImm())) {
3191 ErrInfo = "Invalid immediate";
3192 return false;
3193 }
3194 break;
3196 // TODO: We could be stricter about what non-register operands are
3197 // allowed.
3198 if (MO.isReg()) {
3199 ErrInfo = "Expected a non-register operand.";
3200 return false;
3201 }
3202 if (MO.isImm() && !isInt<32>(MO.getImm())) {
3203 ErrInfo = "Invalid immediate";
3204 return false;
3205 }
3206 break;
3208 if (MO.isImm()) {
3209 int64_t Imm = MO.getImm();
3210 // VLMAX is represented as -1.
3211 if (!isUInt<5>(Imm) && Imm != -1) {
3212 ErrInfo = "Invalid immediate";
3213 return false;
3214 }
3215 } else if (!MO.isReg()) {
3216 ErrInfo = "Expected a register or immediate operand.";
3217 return false;
3218 }
3219 break;
3221 if (!MO.isReg() && !MO.isImm()) {
3222 ErrInfo = "Expected a register or immediate operand.";
3223 return false;
3224 }
3225 break;
3226 }
3227 }
3228
3229 const uint64_t TSFlags = Desc.TSFlags;
3230 if (RISCVII::hasVLOp(TSFlags)) {
3231 const MachineOperand &Op = MI.getOperand(RISCVII::getVLOpNum(Desc));
3232 if (!Op.isImm() && !Op.isReg()) {
3233 ErrInfo = "Invalid operand type for VL operand";
3234 return false;
3235 }
3236 if (Op.isReg() && Op.getReg().isValid()) {
3237 const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
3238 auto *RC = MRI.getRegClass(Op.getReg());
3239 if (!RISCV::GPRNoX0RegClass.hasSubClassEq(RC)) {
3240 ErrInfo = "Invalid register class for VL operand";
3241 return false;
3242 }
3243 }
3244 if (!RISCVII::hasSEWOp(TSFlags)) {
3245 ErrInfo = "VL operand w/o SEW operand?";
3246 return false;
3247 }
3248 }
3249 if (RISCVII::hasSEWOp(TSFlags)) {
3250 unsigned OpIdx = RISCVII::getSEWOpNum(Desc);
3251 if (!MI.getOperand(OpIdx).isImm()) {
3252 ErrInfo = "SEW value expected to be an immediate";
3253 return false;
3254 }
3255 uint64_t Log2SEW = MI.getOperand(OpIdx).getImm();
3256 if (Log2SEW > 31) {
3257 ErrInfo = "Unexpected SEW value";
3258 return false;
3259 }
3260 unsigned SEW = Log2SEW ? 1 << Log2SEW : 8;
3261 if (!RISCVVType::isValidSEW(SEW)) {
3262 ErrInfo = "Unexpected SEW value";
3263 return false;
3264 }
3265 }
3266 if (RISCVII::hasVecPolicyOp(TSFlags)) {
3268 if (!MI.getOperand(OpIdx).isImm()) {
3269 ErrInfo = "Policy operand expected to be an immediate";
3270 return false;
3271 }
3272 uint64_t Policy = MI.getOperand(OpIdx).getImm();
3274 ErrInfo = "Invalid Policy Value";
3275 return false;
3276 }
3277 if (!RISCVII::hasVLOp(TSFlags)) {
3278 ErrInfo = "policy operand w/o VL operand?";
3279 return false;
3280 }
3281
3282 // VecPolicy operands can only exist on instructions with passthru/merge
3283 // arguments. Note that not all arguments with passthru have vec policy
3284 // operands- some instructions have implicit policies.
3285 unsigned UseOpIdx;
3286 if (!MI.isRegTiedToUseOperand(0, &UseOpIdx)) {
3287 ErrInfo = "policy operand w/o tied operand?";
3288 return false;
3289 }
3290 }
3291
3292 if (int Idx = RISCVII::getFRMOpNum(Desc);
3293 Idx >= 0 && MI.getOperand(Idx).getImm() == RISCVFPRndMode::DYN &&
3294 !MI.readsRegister(RISCV::FRM, /*TRI=*/nullptr)) {
3295 ErrInfo = "dynamic rounding mode should read FRM";
3296 return false;
3297 }
3298
3299 return true;
3300}
3301
3303 const MachineInstr &AddrI,
3304 ExtAddrMode &AM) const {
3305 switch (MemI.getOpcode()) {
3306 default:
3307 return false;
3308 case RISCV::LB:
3309 case RISCV::LBU:
3310 case RISCV::LH:
3311 case RISCV::LH_INX:
3312 case RISCV::LHU:
3313 case RISCV::LW:
3314 case RISCV::LW_INX:
3315 case RISCV::LWU:
3316 case RISCV::LD:
3317 case RISCV::LD_RV32:
3318 case RISCV::FLH:
3319 case RISCV::FLW:
3320 case RISCV::FLD:
3321 case RISCV::SB:
3322 case RISCV::SH:
3323 case RISCV::SH_INX:
3324 case RISCV::SW:
3325 case RISCV::SW_INX:
3326 case RISCV::SD:
3327 case RISCV::SD_RV32:
3328 case RISCV::FSH:
3329 case RISCV::FSW:
3330 case RISCV::FSD:
3331 break;
3332 }
3333
3334 if (MemI.getOperand(0).getReg() == Reg)
3335 return false;
3336
3337 if (AddrI.getOpcode() != RISCV::ADDI || !AddrI.getOperand(1).isReg() ||
3338 !AddrI.getOperand(2).isImm())
3339 return false;
3340
3341 int64_t OldOffset = MemI.getOperand(2).getImm();
3342 int64_t Disp = AddrI.getOperand(2).getImm();
3343 int64_t NewOffset = OldOffset + Disp;
3344 if (!STI.is64Bit())
3345 NewOffset = SignExtend64<32>(NewOffset);
3346
3347 if (!isInt<12>(NewOffset))
3348 return false;
3349
3350 AM.BaseReg = AddrI.getOperand(1).getReg();
3351 AM.ScaledReg = 0;
3352 AM.Scale = 0;
3353 AM.Displacement = NewOffset;
3355 return true;
3356}
3357
3359 const ExtAddrMode &AM) const {
3360
3361 const DebugLoc &DL = MemI.getDebugLoc();
3362 MachineBasicBlock &MBB = *MemI.getParent();
3363
3364 assert(AM.ScaledReg == 0 && AM.Scale == 0 &&
3365 "Addressing mode not supported for folding");
3366
3367 return BuildMI(MBB, MemI, DL, get(MemI.getOpcode()))
3368 .addReg(MemI.getOperand(0).getReg(), getDefRegState(MemI.mayLoad()))
3369 .addReg(AM.BaseReg)
3370 .addImm(AM.Displacement)
3371 .setMemRefs(MemI.memoperands())
3372 .setMIFlags(MemI.getFlags());
3373}
3374
3375// TODO: At the moment, MIPS introduced paring of instructions operating with
3376// word or double word. This should be extended with more instructions when more
3377// vendors support load/store pairing.
3379 switch (Opc) {
3380 default:
3381 return false;
3382 case RISCV::SW:
3383 case RISCV::SD:
3384 case RISCV::LD:
3385 case RISCV::LW:
3386 return true;
3387 }
3388}
3389
3391 const TargetRegisterInfo *TRI) {
3392 // If this is a volatile load/store, don't mess with it.
3393 if (LdSt.hasOrderedMemoryRef() || LdSt.getNumExplicitOperands() != 3)
3394 return false;
3395
3396 if (LdSt.getOperand(1).isFI())
3397 return true;
3398
3399 assert(LdSt.getOperand(1).isReg() && "Expected a reg operand.");
3400 // Can't cluster if the instruction modifies the base register
3401 // or it is update form. e.g. ld x5,8(x5)
3402 if (LdSt.modifiesRegister(LdSt.getOperand(1).getReg(), TRI))
3403 return false;
3404
3405 if (!LdSt.getOperand(2).isImm())
3406 return false;
3407
3408 return true;
3409}
3410
3413 int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width,
3414 const TargetRegisterInfo *TRI) const {
3415 if (!LdSt.mayLoadOrStore())
3416 return false;
3417
3418 // Conservatively, only handle scalar loads/stores for now.
3419 switch (LdSt.getOpcode()) {
3420 case RISCV::LB:
3421 case RISCV::LBU:
3422 case RISCV::SB:
3423 case RISCV::LH:
3424 case RISCV::LH_INX:
3425 case RISCV::LHU:
3426 case RISCV::FLH:
3427 case RISCV::SH:
3428 case RISCV::SH_INX:
3429 case RISCV::FSH:
3430 case RISCV::LW:
3431 case RISCV::LW_INX:
3432 case RISCV::LWU:
3433 case RISCV::FLW:
3434 case RISCV::SW:
3435 case RISCV::SW_INX:
3436 case RISCV::FSW:
3437 case RISCV::LD:
3438 case RISCV::LD_RV32:
3439 case RISCV::FLD:
3440 case RISCV::SD:
3441 case RISCV::SD_RV32:
3442 case RISCV::FSD:
3443 break;
3444 default:
3445 return false;
3446 }
3447 const MachineOperand *BaseOp;
3448 OffsetIsScalable = false;
3449 if (!getMemOperandWithOffsetWidth(LdSt, BaseOp, Offset, Width, TRI))
3450 return false;
3451 BaseOps.push_back(BaseOp);
3452 return true;
3453}
3454
3455// TODO: This was copied from SIInstrInfo. Could it be lifted to a common
3456// helper?
3459 const MachineInstr &MI2,
3461 // Only examine the first "base" operand of each instruction, on the
3462 // assumption that it represents the real base address of the memory access.
3463 // Other operands are typically offsets or indices from this base address.
3464 if (BaseOps1.front()->isIdenticalTo(*BaseOps2.front()))
3465 return true;
3466
3467 if (!MI1.hasOneMemOperand() || !MI2.hasOneMemOperand())
3468 return false;
3469
3470 auto MO1 = *MI1.memoperands_begin();
3471 auto MO2 = *MI2.memoperands_begin();
3472 if (MO1->getAddrSpace() != MO2->getAddrSpace())
3473 return false;
3474
3475 auto Base1 = MO1->getValue();
3476 auto Base2 = MO2->getValue();
3477 if (!Base1 || !Base2)
3478 return false;
3479 Base1 = getUnderlyingObject(Base1);
3480 Base2 = getUnderlyingObject(Base2);
3481
3482 if (isa<UndefValue>(Base1) || isa<UndefValue>(Base2))
3483 return false;
3484
3485 return Base1 == Base2;
3486}
3487
3489 ArrayRef<const MachineOperand *> BaseOps1, int64_t Offset1,
3490 bool OffsetIsScalable1, ArrayRef<const MachineOperand *> BaseOps2,
3491 int64_t Offset2, bool OffsetIsScalable2, unsigned ClusterSize,
3492 unsigned NumBytes) const {
3493 // If the mem ops (to be clustered) do not have the same base ptr, then they
3494 // should not be clustered
3495 if (!BaseOps1.empty() && !BaseOps2.empty()) {
3496 const MachineInstr &FirstLdSt = *BaseOps1.front()->getParent();
3497 const MachineInstr &SecondLdSt = *BaseOps2.front()->getParent();
3498 if (!memOpsHaveSameBasePtr(FirstLdSt, BaseOps1, SecondLdSt, BaseOps2))
3499 return false;
3500 } else if (!BaseOps1.empty() || !BaseOps2.empty()) {
3501 // If only one base op is empty, they do not have the same base ptr
3502 return false;
3503 }
3504
3505 unsigned CacheLineSize =
3506 BaseOps1.front()->getParent()->getMF()->getSubtarget().getCacheLineSize();
3507 // Assume a cache line size of 64 bytes if no size is set in RISCVSubtarget.
3509 // Cluster if the memory operations are on the same or a neighbouring cache
3510 // line, but limit the maximum ClusterSize to avoid creating too much
3511 // additional register pressure.
3512 return ClusterSize <= 4 && std::abs(Offset1 - Offset2) < CacheLineSize;
3513}
3514
3515// Set BaseReg (the base register operand), Offset (the byte offset being
3516// accessed) and the access Width of the passed instruction that reads/writes
3517// memory. Returns false if the instruction does not read/write memory or the
3518// BaseReg/Offset/Width can't be determined. Is not guaranteed to always
3519// recognise base operands and offsets in all cases.
3520// TODO: Add an IsScalable bool ref argument (like the equivalent AArch64
3521// function) and set it as appropriate.
3523 const MachineInstr &LdSt, const MachineOperand *&BaseReg, int64_t &Offset,
3524 LocationSize &Width, const TargetRegisterInfo *TRI) const {
3525 if (!LdSt.mayLoadOrStore())
3526 return false;
3527
3528 // Here we assume the standard RISC-V ISA, which uses a base+offset
3529 // addressing mode. You'll need to relax these conditions to support custom
3530 // load/store instructions.
3531 if (LdSt.getNumExplicitOperands() != 3)
3532 return false;
3533 if ((!LdSt.getOperand(1).isReg() && !LdSt.getOperand(1).isFI()) ||
3534 !LdSt.getOperand(2).isImm())
3535 return false;
3536
3537 if (!LdSt.hasOneMemOperand())
3538 return false;
3539
3540 Width = (*LdSt.memoperands_begin())->getSize();
3541 BaseReg = &LdSt.getOperand(1);
3542 Offset = LdSt.getOperand(2).getImm();
3543 return true;
3544}
3545
3547 const MachineInstr &MIa, const MachineInstr &MIb) const {
3548 assert(MIa.mayLoadOrStore() && "MIa must be a load or store.");
3549 assert(MIb.mayLoadOrStore() && "MIb must be a load or store.");
3550
3553 return false;
3554
3555 // Retrieve the base register, offset from the base register and width. Width
3556 // is the size of memory that is being loaded/stored (e.g. 1, 2, 4). If
3557 // base registers are identical, and the offset of a lower memory access +
3558 // the width doesn't overlap the offset of a higher memory access,
3559 // then the memory accesses are different.
3560 const TargetRegisterInfo *TRI = STI.getRegisterInfo();
3561 const MachineOperand *BaseOpA = nullptr, *BaseOpB = nullptr;
3562 int64_t OffsetA = 0, OffsetB = 0;
3564 WidthB = LocationSize::precise(0);
3565 if (getMemOperandWithOffsetWidth(MIa, BaseOpA, OffsetA, WidthA, TRI) &&
3566 getMemOperandWithOffsetWidth(MIb, BaseOpB, OffsetB, WidthB, TRI)) {
3567 if (BaseOpA->isIdenticalTo(*BaseOpB)) {
3568 int LowOffset = std::min(OffsetA, OffsetB);
3569 int HighOffset = std::max(OffsetA, OffsetB);
3570 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
3571 if (LowWidth.hasValue() &&
3572 LowOffset + (int)LowWidth.getValue() <= HighOffset)
3573 return true;
3574 }
3575 }
3576 return false;
3577}
3578
3579std::pair<unsigned, unsigned>
3581 const unsigned Mask = RISCVII::MO_DIRECT_FLAG_MASK;
3582 return std::make_pair(TF & Mask, TF & ~Mask);
3583}
3584
3587 using namespace RISCVII;
3588 static const std::pair<unsigned, const char *> TargetFlags[] = {
3589 {MO_CALL, "riscv-call"},
3590 {MO_LO, "riscv-lo"},
3591 {MO_HI, "riscv-hi"},
3592 {MO_PCREL_LO, "riscv-pcrel-lo"},
3593 {MO_PCREL_HI, "riscv-pcrel-hi"},
3594 {MO_GOT_HI, "riscv-got-hi"},
3595 {MO_TPREL_LO, "riscv-tprel-lo"},
3596 {MO_TPREL_HI, "riscv-tprel-hi"},
3597 {MO_TPREL_ADD, "riscv-tprel-add"},
3598 {MO_TLS_GOT_HI, "riscv-tls-got-hi"},
3599 {MO_TLS_GD_HI, "riscv-tls-gd-hi"},
3600 {MO_TLSDESC_HI, "riscv-tlsdesc-hi"},
3601 {MO_TLSDESC_LOAD_LO, "riscv-tlsdesc-load-lo"},
3602 {MO_TLSDESC_ADD_LO, "riscv-tlsdesc-add-lo"},
3603 {MO_TLSDESC_CALL, "riscv-tlsdesc-call"}};
3604 return ArrayRef(TargetFlags);
3605}
3607 MachineFunction &MF, bool OutlineFromLinkOnceODRs) const {
3608 const Function &F = MF.getFunction();
3609
3610 // Can F be deduplicated by the linker? If it can, don't outline from it.
3611 if (!OutlineFromLinkOnceODRs && F.hasLinkOnceODRLinkage())
3612 return false;
3613
3614 // Don't outline from functions with section markings; the program could
3615 // expect that all the code is in the named section.
3616 if (F.hasSection())
3617 return false;
3618
3619 // It's safe to outline from MF.
3620 return true;
3621}
3622
3624 unsigned &Flags) const {
3625 // More accurate safety checking is done in getOutliningCandidateInfo.
3627}
3628
3629// Enum values indicating how an outlined call should be constructed.
3635
3640
3642 const MachineFunction *MF = MBB.getParent();
3643 const Function &F = MF->getFunction();
3644 return F.getFnAttribute("fentry-call").getValueAsBool() ||
3645 F.hasFnAttribute("patchable-function-entry");
3646}
3647
3649 MCRegister RegNo) {
3650 return MI.readsRegister(RegNo, TRI) ||
3651 MI.getDesc().hasImplicitUseOfPhysReg(RegNo);
3652}
3653
3655 const TargetRegisterInfo *TRI, MCRegister RegNo) {
3656 return MI.modifiesRegister(RegNo, TRI) ||
3657 MI.getDesc().hasImplicitDefOfPhysReg(RegNo);
3658}
3659
3661 if (!MBB.back().isReturn())
3662 return true;
3664 return true;
3665
3666 // If the candidate reads the pre-set register
3667 // that can be used for expanding PseudoTAIL instruction,
3668 // then we cannot insert tail call.
3669 const TargetSubtargetInfo &STI = MBB.getParent()->getSubtarget();
3670 MCRegister TailExpandUseRegNo =
3672 for (const MachineInstr &MI : MBB) {
3673 if (isMIReadsReg(MI, STI.getRegisterInfo(), TailExpandUseRegNo))
3674 return true;
3675 if (isMIModifiesReg(MI, STI.getRegisterInfo(), TailExpandUseRegNo))
3676 break;
3677 }
3678 return false;
3679}
3680
3682 const TargetRegisterInfo &TRI) {
3683 // Candidate registers for saving X5: t1-t6
3684 static const MCPhysReg TempRegs[] = {
3685 RISCV::X6, // t1
3686 RISCV::X7, // t2
3687 RISCV::X28, // t3
3688 RISCV::X29, // t4
3689 RISCV::X30, // t5
3690 RISCV::X31 // t6
3691 };
3692
3693 const MachineFunction *MF = C.getMF();
3694 const MachineRegisterInfo &MRI = MF->getRegInfo();
3695
3696 for (MCPhysReg Reg : TempRegs) {
3697 if (MRI.isReserved(Reg))
3698 continue;
3699
3700 if (C.isAvailableAcrossAndOutOfSeq(Reg, TRI) &&
3701 C.isAvailableInsideSeq(Reg, TRI)) {
3702 return Reg;
3703 }
3704 }
3705
3706 return Register();
3707}
3708
3710 // If the expansion register for tail calls is live across the candidate
3711 // outlined call site, we cannot outline that candidate as the expansion
3712 // would clobber the register.
3713 MCRegister TailExpandUseReg =
3714 RISCVII::getTailExpandUseRegNo(STI.getFeatureBits());
3715 if (C.back().isReturn() &&
3716 !C.isAvailableAcrossAndOutOfSeq(TailExpandUseReg, RegInfo)) {
3717 LLVM_DEBUG(dbgs() << "MBB:\n" << *C.getMBB());
3718 LLVM_DEBUG(dbgs() << "Cannot be outlined between: " << C.front() << "and "
3719 << C.back());
3720 LLVM_DEBUG(dbgs() << "Because the tail-call register is live across "
3721 "the proposed outlined function call\n");
3722 return true;
3723 }
3724
3725 // If last instruction is return then we can rely on
3726 // the verification already performed in the getOutliningTypeImpl.
3727 if (C.back().isReturn()) {
3728 assert(!cannotInsertTailCall(*C.getMBB()) &&
3729 "The candidate who uses return instruction must be outlined "
3730 "using tail call");
3731 return false;
3732 }
3733
3734 // Filter out candidates where the X5 register (t0) can't be used to setup
3735 // the function call.
3736 if (!C.isAvailableInsideSeq(RISCV::X5, RegInfo))
3737 return true;
3738
3739 // If X5 is available in the region, use X5 directly (MachineOutlinerDefault).
3740 if (C.isAvailableAcrossAndOutOfSeq(RISCV::X5, RegInfo))
3741 return false;
3742
3743 // Otherwise, try to save X5 into t1-t6 (MachineOutlinerRegSave).
3745 return false;
3746
3747 return true;
3748}
3749
3750std::optional<std::unique_ptr<outliner::OutlinedFunction>>
3752 const MachineModuleInfo &MMI,
3753 std::vector<outliner::Candidate> &RepeatedSequenceLocs,
3754 unsigned MinRepeats) const {
3755
3756 // Analyze each candidate and erase the ones that are not viable.
3757 llvm::erase_if(RepeatedSequenceLocs, [this](auto Candidate) {
3758 return analyzeCandidate(Candidate);
3759 });
3760
3761 // If the sequence doesn't have enough candidates left, then we're done.
3762 if (RepeatedSequenceLocs.size() < MinRepeats)
3763 return std::nullopt;
3764
3765 // Each RepeatedSequenceLoc is identical.
3766 outliner::Candidate &Candidate = RepeatedSequenceLocs[0];
3767 unsigned InstrSizeCExt =
3768 Candidate.getMF()->getSubtarget<RISCVSubtarget>().hasStdExtZca() ? 2 : 4;
3769 unsigned CallOverhead = 0, FrameOverhead = 0;
3770
3771 // Count the number of CFI instructions in the candidate, if present.
3772 unsigned CFICount = 0;
3773 for (auto &I : Candidate) {
3774 if (I.isCFIInstruction())
3775 CFICount++;
3776 }
3777
3778 // Ensure CFI coverage matches: comparing the number of CFIs in the candidate
3779 // with the total number of CFIs in the parent function for each candidate.
3780 // Outlining only a subset of a function’s CFIs would split the unwind state
3781 // across two code regions and lead to incorrect address offsets between the
3782 // outlined body and the remaining code. To preserve correct unwind info, we
3783 // only outline when all CFIs in the function can be outlined together.
3784 for (outliner::Candidate &C : RepeatedSequenceLocs) {
3785 std::vector<MCCFIInstruction> CFIInstructions =
3786 C.getMF()->getFrameInstructions();
3787
3788 if (CFICount > 0 && CFICount != CFIInstructions.size())
3789 return std::nullopt;
3790 }
3791
3793 if (Candidate.back().isReturn()) {
3795 // tail call = auipc + jalr in the worst case without linker relaxation.
3796 // FIXME: This code suggests the JALR can be compressed - how?
3797 CallOverhead = 4 + InstrSizeCExt;
3798 // Using tail call we move ret instruction from caller to callee.
3799 FrameOverhead = 0;
3800 } else {
3801 // call t0, function = 8 bytes.
3802 CallOverhead = 8;
3803 // jr t0 = 4 bytes, 2 bytes if compressed instructions are enabled.
3804 FrameOverhead = InstrSizeCExt;
3805 }
3806
3807 // If we have CFI instructions, we can only outline if the outlined section
3808 // can be a tail call.
3809 if (MOCI != MachineOutlinerTailCall && CFICount > 0)
3810 return std::nullopt;
3811
3813 // Set per-candidate overhead based on X5 availability
3814 for (auto &C : RepeatedSequenceLocs) {
3815
3816 if (C.isAvailableAcrossAndOutOfSeq(RISCV::X5, RegInfo)) {
3817 // X5 is available, just need the call
3818 unsigned CandCallOverhead = 8;
3819 C.setCallInfo(MachineOutlinerDefault, CandCallOverhead);
3820 } else {
3821 // X5 unavailable, need save + call + restore
3822 // Save (2-4) + Call (8) + Restore (2-4)
3823 unsigned CandCallOverhead = InstrSizeCExt + 8 + InstrSizeCExt;
3824 C.setCallInfo(MachineOutlinerRegSave, CandCallOverhead);
3825 }
3826 }
3827 } else {
3828 for (auto &C : RepeatedSequenceLocs)
3829 C.setCallInfo(MOCI, CallOverhead);
3830 }
3831
3832 unsigned SequenceSize = 0;
3833 for (auto &MI : Candidate)
3834 SequenceSize += getInstSizeInBytes(MI);
3835
3836 return std::make_unique<outliner::OutlinedFunction>(
3837 RepeatedSequenceLocs, SequenceSize, FrameOverhead, MOCI);
3838}
3839
3843 unsigned Flags) const {
3844 MachineInstr &MI = *MBBI;
3845 MachineBasicBlock *MBB = MI.getParent();
3846 const TargetRegisterInfo *TRI =
3847 MBB->getParent()->getSubtarget().getRegisterInfo();
3848 const auto &F = MI.getMF()->getFunction();
3849
3850 // We can only outline CFI instructions if we will tail call the outlined
3851 // function, or fix up the CFI offsets. Currently, CFI instructions are
3852 // outlined only if in a tail call.
3853 if (MI.isCFIInstruction())
3855
3856 if (cannotInsertTailCall(*MBB) &&
3857 (MI.isReturn() || isMIModifiesReg(MI, TRI, RISCV::X5)))
3859
3860 // Make sure the operands don't reference something unsafe.
3861 for (const auto &MO : MI.operands()) {
3862
3863 // pcrel-hi and pcrel-lo can't put in separate sections, filter that out
3864 // if any possible.
3865 if (MO.getTargetFlags() == RISCVII::MO_PCREL_LO &&
3866 (MI.getMF()->getTarget().getFunctionSections() || F.hasComdat() ||
3867 F.hasSection() || F.getSectionPrefix()))
3869 }
3870
3871 if (isLPAD(MI))
3873
3875}
3876
3879 const outliner::OutlinedFunction &OF) const {
3880
3881 if (OF.FrameConstructionID == MachineOutlinerTailCall)
3882 return;
3883
3884 MBB.addLiveIn(RISCV::X5);
3885
3886 // Add in a return instruction to the end of the outlined frame.
3887 MBB.insert(MBB.end(), BuildMI(MF, DebugLoc(), get(RISCV::JALR))
3888 .addReg(RISCV::X0, RegState::Define)
3889 .addReg(RISCV::X5)
3890 .addImm(0));
3891}
3892
3896
3897 if (C.CallConstructionID == MachineOutlinerTailCall) {
3898 It = MBB.insert(It, BuildMI(MF, DebugLoc(), get(RISCV::PseudoTAIL))
3899 .addGlobalAddress(M.getNamedValue(MF.getName()),
3900 /*Offset=*/0, RISCVII::MO_CALL));
3901 return It;
3902 }
3903
3904 if (C.CallConstructionID == MachineOutlinerRegSave) {
3905 Register SaveReg = findRegisterToSaveX5To(C, RegInfo);
3906 assert(SaveReg && "Cannot find an available register to save/restore X5.");
3907
3908 // Save: ADDI SaveReg, X5, 0 (equivalent to MV SaveReg, X5)
3909 It = MBB.insert(It, BuildMI(MF, DebugLoc(), get(RISCV::ADDI), SaveReg)
3910 .addReg(RISCV::X5)
3911 .addImm(0));
3912 It++;
3913
3914 // Call: PseudoCALLReg X5
3915 It = MBB.insert(
3916 It, BuildMI(MF, DebugLoc(), get(RISCV::PseudoCALLReg), RISCV::X5)
3917 .addGlobalAddress(M.getNamedValue(MF.getName()), 0,
3919 MachineBasicBlock::iterator CallPt = It;
3920 It++;
3921
3922 // Restore: ADDI X5, SaveReg, 0 (equivalent to MV X5, SaveReg)
3923 It = MBB.insert(It, BuildMI(MF, DebugLoc(), get(RISCV::ADDI), RISCV::X5)
3924 .addReg(SaveReg)
3925 .addImm(0));
3926
3927 return CallPt;
3928 }
3929
3930 // Add in a call instruction to the outlined function at the given location.
3931 It = MBB.insert(It,
3932 BuildMI(MF, DebugLoc(), get(RISCV::PseudoCALLReg), RISCV::X5)
3933 .addGlobalAddress(M.getNamedValue(MF.getName()), 0,
3935 return It;
3936}
3937
3938std::optional<RegImmPair> RISCVInstrInfo::isAddImmediate(const MachineInstr &MI,
3939 Register Reg) const {
3940 // TODO: Handle cases where Reg is a super- or sub-register of the
3941 // destination register.
3942 const MachineOperand &Op0 = MI.getOperand(0);
3943 if (!Op0.isReg() || Reg != Op0.getReg())
3944 return std::nullopt;
3945
3946 // Don't consider ADDIW as a candidate because the caller may not be aware
3947 // of its sign extension behaviour.
3948 if (MI.getOpcode() == RISCV::ADDI && MI.getOperand(1).isReg() &&
3949 MI.getOperand(2).isImm())
3950 return RegImmPair{MI.getOperand(1).getReg(), MI.getOperand(2).getImm()};
3951
3952 return std::nullopt;
3953}
3954
3955// MIR printer helper function to annotate Operands with a comment.
3957 const MachineInstr &MI, const MachineOperand &Op, unsigned OpIdx,
3958 const TargetRegisterInfo *TRI) const {
3959 // Print a generic comment for this operand if there is one.
3960 std::string GenericComment =
3962 if (!GenericComment.empty())
3963 return GenericComment;
3964
3965 const MCInstrDesc &Desc = MI.getDesc();
3966 if (OpIdx >= Desc.getNumOperands())
3967 return std::string();
3968
3969 std::string Comment;
3970 raw_string_ostream OS(Comment);
3971
3972 const MCOperandInfo &OpInfo = Desc.operands()[OpIdx];
3973
3974 // Print the full VType operand of vsetvli/vsetivli instructions, and the SEW
3975 // operand of vector codegen pseudos.
3976 switch (OpInfo.OperandType) {
3979 unsigned Imm = Op.getImm();
3980 RISCVVType::printVType(Imm, OS);
3981 break;
3982 }
3984 unsigned Imm = Op.getImm();
3986 break;
3987 }
3989 unsigned Imm = Op.getImm();
3990 OS << "w" << Imm;
3991 break;
3992 }
3995 unsigned Log2SEW = Op.getImm();
3996 unsigned SEW = Log2SEW ? 1 << Log2SEW : 8;
3997 assert(RISCVVType::isValidSEW(SEW) && "Unexpected SEW");
3998 OS << "e" << SEW;
3999 break;
4000 }
4002 unsigned Policy = Op.getImm();
4004 "Invalid Policy Value");
4005 OS << (Policy & RISCVVType::TAIL_AGNOSTIC ? "ta" : "tu") << ", "
4006 << (Policy & RISCVVType::MASK_AGNOSTIC ? "ma" : "mu");
4007 break;
4008 }
4010 if (Op.isImm() && Op.getImm() == -1)
4011 OS << "vl=VLMAX";
4012 else
4013 OS << "vl";
4014 break;
4016 if (RISCVII::usesVXRM(Desc.TSFlags)) {
4018 auto VXRM = static_cast<RISCVVXRndMode::RoundingMode>(Op.getImm());
4019 OS << "vxrm=" << RISCVVXRndMode::roundingModeToString(VXRM);
4020 } else {
4022 auto FRM = static_cast<RISCVFPRndMode::RoundingMode>(Op.getImm());
4023 OS << "frm=" << RISCVFPRndMode::roundingModeToString(FRM);
4024 }
4025 break;
4026 }
4027
4028 return Comment;
4029}
4030
4031// clang-format off
4032#define CASE_RVV_OPCODE_UNMASK_LMUL(OP, LMUL) \
4033 RISCV::Pseudo##OP##_##LMUL
4034
4035#define CASE_RVV_OPCODE_MASK_LMUL(OP, LMUL) \
4036 RISCV::Pseudo##OP##_##LMUL##_MASK
4037
4038#define CASE_RVV_OPCODE_LMUL(OP, LMUL) \
4039 CASE_RVV_OPCODE_UNMASK_LMUL(OP, LMUL): \
4040 case CASE_RVV_OPCODE_MASK_LMUL(OP, LMUL)
4041
4042#define CASE_RVV_OPCODE_UNMASK_WIDEN(OP) \
4043 CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF8): \
4044 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF4): \
4045 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF2): \
4046 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M1): \
4047 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M2): \
4048 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M4)
4049
4050#define CASE_RVV_OPCODE_UNMASK(OP) \
4051 CASE_RVV_OPCODE_UNMASK_WIDEN(OP): \
4052 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M8)
4053
4054#define CASE_RVV_OPCODE_MASK_WIDEN(OP) \
4055 CASE_RVV_OPCODE_MASK_LMUL(OP, MF8): \
4056 case CASE_RVV_OPCODE_MASK_LMUL(OP, MF4): \
4057 case CASE_RVV_OPCODE_MASK_LMUL(OP, MF2): \
4058 case CASE_RVV_OPCODE_MASK_LMUL(OP, M1): \
4059 case CASE_RVV_OPCODE_MASK_LMUL(OP, M2): \
4060 case CASE_RVV_OPCODE_MASK_LMUL(OP, M4)
4061
4062#define CASE_RVV_OPCODE_MASK(OP) \
4063 CASE_RVV_OPCODE_MASK_WIDEN(OP): \
4064 case CASE_RVV_OPCODE_MASK_LMUL(OP, M8)
4065
4066#define CASE_RVV_OPCODE_WIDEN(OP) \
4067 CASE_RVV_OPCODE_UNMASK_WIDEN(OP): \
4068 case CASE_RVV_OPCODE_MASK_WIDEN(OP)
4069
4070#define CASE_RVV_OPCODE(OP) \
4071 CASE_RVV_OPCODE_UNMASK(OP): \
4072 case CASE_RVV_OPCODE_MASK(OP)
4073// clang-format on
4074
4075// clang-format off
4076#define CASE_VMA_OPCODE_COMMON(OP, TYPE, LMUL) \
4077 RISCV::PseudoV##OP##_##TYPE##_##LMUL
4078
4079#define CASE_VMA_OPCODE_LMULS(OP, TYPE) \
4080 CASE_VMA_OPCODE_COMMON(OP, TYPE, MF8): \
4081 case CASE_VMA_OPCODE_COMMON(OP, TYPE, MF4): \
4082 case CASE_VMA_OPCODE_COMMON(OP, TYPE, MF2): \
4083 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M1): \
4084 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M2): \
4085 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M4): \
4086 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M8)
4087
4088// VFMA instructions are SEW specific.
4089#define CASE_VFMA_OPCODE_COMMON(OP, TYPE, LMUL, SEW) \
4090 RISCV::PseudoV##OP##_##TYPE##_##LMUL##_##SEW
4091
4092#define CASE_VFMA_OPCODE_LMULS_M1(OP, TYPE, SEW) \
4093 CASE_VFMA_OPCODE_COMMON(OP, TYPE, M1, SEW): \
4094 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M2, SEW): \
4095 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M4, SEW): \
4096 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M8, SEW)
4097
4098#define CASE_VFMA_OPCODE_LMULS_MF2(OP, TYPE, SEW) \
4099 CASE_VFMA_OPCODE_COMMON(OP, TYPE, MF2, SEW): \
4100 case CASE_VFMA_OPCODE_LMULS_M1(OP, TYPE, SEW)
4101
4102#define CASE_VFMA_OPCODE_LMULS_MF4(OP, TYPE, SEW) \
4103 CASE_VFMA_OPCODE_COMMON(OP, TYPE, MF4, SEW): \
4104 case CASE_VFMA_OPCODE_LMULS_MF2(OP, TYPE, SEW)
4105
4106#define CASE_VFMA_OPCODE_VV(OP) \
4107 CASE_VFMA_OPCODE_LMULS_MF4(OP, VV, E16): \
4108 case CASE_VFMA_OPCODE_LMULS_MF4(OP##_ALT, VV, E16): \
4109 case CASE_VFMA_OPCODE_LMULS_MF2(OP, VV, E32): \
4110 case CASE_VFMA_OPCODE_LMULS_M1(OP, VV, E64)
4111
4112#define CASE_VFMA_SPLATS(OP) \
4113 CASE_VFMA_OPCODE_LMULS_MF4(OP, VFPR16, E16): \
4114 case CASE_VFMA_OPCODE_LMULS_MF4(OP##_ALT, VFPR16, E16): \
4115 case CASE_VFMA_OPCODE_LMULS_MF2(OP, VFPR32, E32): \
4116 case CASE_VFMA_OPCODE_LMULS_M1(OP, VFPR64, E64)
4117// clang-format on
4118
4120 unsigned &SrcOpIdx1,
4121 unsigned &SrcOpIdx2) const {
4122 const MCInstrDesc &Desc = MI.getDesc();
4123 if (!Desc.isCommutable())
4124 return false;
4125
4126 switch (MI.getOpcode()) {
4127 case RISCV::TH_MVEQZ:
4128 case RISCV::TH_MVNEZ:
4129 // We can't commute operands if operand 2 (i.e., rs1 in
4130 // mveqz/mvnez rd,rs1,rs2) is the zero-register (as it is
4131 // not valid as the in/out-operand 1).
4132 if (MI.getOperand(2).getReg() == RISCV::X0)
4133 return false;
4134 // Operands 1 and 2 are commutable, if we switch the opcode.
4135 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 2);
4136 case RISCV::QC_SELECTIEQ:
4137 case RISCV::QC_SELECTINE:
4138 case RISCV::QC_SELECTIIEQ:
4139 case RISCV::QC_SELECTIINE:
4140 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 2);
4141 case RISCV::QC_MVEQ:
4142 case RISCV::QC_MVNE:
4143 case RISCV::QC_MVLT:
4144 case RISCV::QC_MVGE:
4145 case RISCV::QC_MVLTU:
4146 case RISCV::QC_MVGEU:
4147 case RISCV::QC_MVEQI:
4148 case RISCV::QC_MVNEI:
4149 case RISCV::QC_MVLTI:
4150 case RISCV::QC_MVGEI:
4151 case RISCV::QC_MVLTUI:
4152 case RISCV::QC_MVGEUI:
4153 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 4);
4154 case RISCV::TH_MULA:
4155 case RISCV::TH_MULAW:
4156 case RISCV::TH_MULAH:
4157 case RISCV::TH_MULS:
4158 case RISCV::TH_MULSW:
4159 case RISCV::TH_MULSH:
4160 // Operands 2 and 3 are commutable.
4161 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
4162 case RISCV::PseudoCCMOVGPRNoX0:
4163 case RISCV::PseudoCCMOVGPR:
4164 // Operands 1 and 2 are commutable.
4165 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 2);
4166 case CASE_RVV_OPCODE(VADD_VV):
4167 case CASE_RVV_OPCODE(VAND_VV):
4168 case CASE_RVV_OPCODE(VOR_VV):
4169 case CASE_RVV_OPCODE(VXOR_VV):
4170 case CASE_RVV_OPCODE_MASK(VMSEQ_VV):
4171 case CASE_RVV_OPCODE_MASK(VMSNE_VV):
4172 case CASE_RVV_OPCODE(VMIN_VV):
4173 case CASE_RVV_OPCODE(VMINU_VV):
4174 case CASE_RVV_OPCODE(VMAX_VV):
4175 case CASE_RVV_OPCODE(VMAXU_VV):
4176 case CASE_RVV_OPCODE(VMUL_VV):
4177 case CASE_RVV_OPCODE(VMULH_VV):
4178 case CASE_RVV_OPCODE(VMULHU_VV):
4179 case CASE_RVV_OPCODE_WIDEN(VWADD_VV):
4180 case CASE_RVV_OPCODE_WIDEN(VWADDU_VV):
4181 case CASE_RVV_OPCODE_WIDEN(VWMUL_VV):
4182 case CASE_RVV_OPCODE_WIDEN(VWMULU_VV):
4183 case CASE_RVV_OPCODE_WIDEN(VWMACC_VV):
4184 case CASE_RVV_OPCODE_WIDEN(VWMACCU_VV):
4185 case CASE_RVV_OPCODE(VABD_VV):
4186 case CASE_RVV_OPCODE(VABDU_VV):
4187 case CASE_RVV_OPCODE_WIDEN(VWABDA_VV):
4188 case CASE_RVV_OPCODE_WIDEN(VWABDAU_VV):
4189 case CASE_RVV_OPCODE_UNMASK(VADC_VVM):
4190 case CASE_RVV_OPCODE(VSADD_VV):
4191 case CASE_RVV_OPCODE(VSADDU_VV):
4192 case CASE_RVV_OPCODE(VAADD_VV):
4193 case CASE_RVV_OPCODE(VAADDU_VV):
4194 case CASE_RVV_OPCODE(VSMUL_VV):
4195 case CASE_RVV_OPCODE_LMUL(VDOTA4_VV, MF2):
4196 case CASE_RVV_OPCODE_LMUL(VDOTA4_VV, M1):
4197 case CASE_RVV_OPCODE_LMUL(VDOTA4_VV, M2):
4198 case CASE_RVV_OPCODE_LMUL(VDOTA4_VV, M4):
4199 case CASE_RVV_OPCODE_LMUL(VDOTA4_VV, M8):
4200 case CASE_RVV_OPCODE_LMUL(VDOTA4U_VV, MF2):
4201 case CASE_RVV_OPCODE_LMUL(VDOTA4U_VV, M1):
4202 case CASE_RVV_OPCODE_LMUL(VDOTA4U_VV, M2):
4203 case CASE_RVV_OPCODE_LMUL(VDOTA4U_VV, M4):
4204 case CASE_RVV_OPCODE_LMUL(VDOTA4U_VV, M8):
4205 // Operands 2 and 3 are commutable.
4206 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
4207 case CASE_VFMA_SPLATS(FMADD):
4208 case CASE_VFMA_SPLATS(FMSUB):
4209 case CASE_VFMA_SPLATS(FMACC):
4210 case CASE_VFMA_SPLATS(FMSAC):
4213 case CASE_VFMA_SPLATS(FNMACC):
4214 case CASE_VFMA_SPLATS(FNMSAC):
4215 case CASE_VFMA_OPCODE_VV(FMACC):
4216 case CASE_VFMA_OPCODE_VV(FMSAC):
4217 case CASE_VFMA_OPCODE_VV(FNMACC):
4218 case CASE_VFMA_OPCODE_VV(FNMSAC):
4219 case CASE_VMA_OPCODE_LMULS(MADD, VX):
4220 case CASE_VMA_OPCODE_LMULS(NMSUB, VX):
4221 case CASE_VMA_OPCODE_LMULS(MACC, VX):
4222 case CASE_VMA_OPCODE_LMULS(NMSAC, VX):
4223 case CASE_VMA_OPCODE_LMULS(MACC, VV):
4224 case CASE_VMA_OPCODE_LMULS(NMSAC, VV): {
4225 // If the tail policy is undisturbed we can't commute.
4226 assert(RISCVII::hasVecPolicyOp(MI.getDesc().TSFlags));
4227 if ((MI.getOperand(RISCVII::getVecPolicyOpNum(MI.getDesc())).getImm() &
4228 1) == 0)
4229 return false;
4230
4231 // For these instructions we can only swap operand 1 and operand 3 by
4232 // changing the opcode.
4233 unsigned CommutableOpIdx1 = 1;
4234 unsigned CommutableOpIdx2 = 3;
4235 if (!fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, CommutableOpIdx1,
4236 CommutableOpIdx2))
4237 return false;
4238 return true;
4239 }
4240 case CASE_VFMA_OPCODE_VV(FMADD):
4244 case CASE_VMA_OPCODE_LMULS(MADD, VV):
4245 case CASE_VMA_OPCODE_LMULS(NMSUB, VV): {
4246 // If the tail policy is undisturbed we can't commute.
4247 assert(RISCVII::hasVecPolicyOp(MI.getDesc().TSFlags));
4248 if ((MI.getOperand(RISCVII::getVecPolicyOpNum(MI.getDesc())).getImm() &
4249 1) == 0)
4250 return false;
4251
4252 // For these instructions we have more freedom. We can commute with the
4253 // other multiplicand or with the addend/subtrahend/minuend.
4254
4255 // Any fixed operand must be from source 1, 2 or 3.
4256 if (SrcOpIdx1 != CommuteAnyOperandIndex && SrcOpIdx1 > 3)
4257 return false;
4258 if (SrcOpIdx2 != CommuteAnyOperandIndex && SrcOpIdx2 > 3)
4259 return false;
4260
4261 // It both ops are fixed one must be the tied source.
4262 if (SrcOpIdx1 != CommuteAnyOperandIndex &&
4263 SrcOpIdx2 != CommuteAnyOperandIndex && SrcOpIdx1 != 1 && SrcOpIdx2 != 1)
4264 return false;
4265
4266 // Look for two different register operands assumed to be commutable
4267 // regardless of the FMA opcode. The FMA opcode is adjusted later if
4268 // needed.
4269 if (SrcOpIdx1 == CommuteAnyOperandIndex ||
4270 SrcOpIdx2 == CommuteAnyOperandIndex) {
4271 // At least one of operands to be commuted is not specified and
4272 // this method is free to choose appropriate commutable operands.
4273 unsigned CommutableOpIdx1 = SrcOpIdx1;
4274 if (SrcOpIdx1 == SrcOpIdx2) {
4275 // Both of operands are not fixed. Set one of commutable
4276 // operands to the tied source.
4277 CommutableOpIdx1 = 1;
4278 } else if (SrcOpIdx1 == CommuteAnyOperandIndex) {
4279 // Only one of the operands is not fixed.
4280 CommutableOpIdx1 = SrcOpIdx2;
4281 }
4282
4283 // CommutableOpIdx1 is well defined now. Let's choose another commutable
4284 // operand and assign its index to CommutableOpIdx2.
4285 unsigned CommutableOpIdx2;
4286 if (CommutableOpIdx1 != 1) {
4287 // If we haven't already used the tied source, we must use it now.
4288 CommutableOpIdx2 = 1;
4289 } else {
4290 Register Op1Reg = MI.getOperand(CommutableOpIdx1).getReg();
4291
4292 // The commuted operands should have different registers.
4293 // Otherwise, the commute transformation does not change anything and
4294 // is useless. We use this as a hint to make our decision.
4295 if (Op1Reg != MI.getOperand(2).getReg())
4296 CommutableOpIdx2 = 2;
4297 else
4298 CommutableOpIdx2 = 3;
4299 }
4300
4301 // Assign the found pair of commutable indices to SrcOpIdx1 and
4302 // SrcOpIdx2 to return those values.
4303 if (!fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, CommutableOpIdx1,
4304 CommutableOpIdx2))
4305 return false;
4306 }
4307
4308 return true;
4309 }
4310 }
4311
4312 return TargetInstrInfo::findCommutedOpIndices(MI, SrcOpIdx1, SrcOpIdx2);
4313}
4314
4315// clang-format off
4316#define CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, LMUL) \
4317 case RISCV::PseudoV##OLDOP##_##TYPE##_##LMUL: \
4318 Opc = RISCV::PseudoV##NEWOP##_##TYPE##_##LMUL; \
4319 break;
4320
4321#define CASE_VMA_CHANGE_OPCODE_LMULS(OLDOP, NEWOP, TYPE) \
4322 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF8) \
4323 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF4) \
4324 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF2) \
4325 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M1) \
4326 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M2) \
4327 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M4) \
4328 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M8)
4329
4330// VFMA depends on SEW.
4331#define CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, LMUL, SEW) \
4332 case RISCV::PseudoV##OLDOP##_##TYPE##_##LMUL##_##SEW: \
4333 Opc = RISCV::PseudoV##NEWOP##_##TYPE##_##LMUL##_##SEW; \
4334 break;
4335
4336#define CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, TYPE, SEW) \
4337 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M1, SEW) \
4338 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M2, SEW) \
4339 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M4, SEW) \
4340 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M8, SEW)
4341
4342#define CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, TYPE, SEW) \
4343 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF2, SEW) \
4344 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, TYPE, SEW)
4345
4346#define CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, TYPE, SEW) \
4347 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF4, SEW) \
4348 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, TYPE, SEW)
4349
4350#define CASE_VFMA_CHANGE_OPCODE_VV(OLDOP, NEWOP) \
4351 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, VV, E16) \
4352 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP##_ALT, NEWOP##_ALT, VV, E16) \
4353 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, VV, E32) \
4354 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, VV, E64)
4355
4356#define CASE_VFMA_CHANGE_OPCODE_SPLATS(OLDOP, NEWOP) \
4357 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, VFPR16, E16) \
4358 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP##_ALT, NEWOP##_ALT, VFPR16, E16) \
4359 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, VFPR32, E32) \
4360 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, VFPR64, E64)
4361// clang-format on
4362
4364 bool NewMI,
4365 unsigned OpIdx1,
4366 unsigned OpIdx2) const {
4367 auto cloneIfNew = [NewMI](MachineInstr &MI) -> MachineInstr & {
4368 if (NewMI)
4369 return *MI.getParent()->getParent()->CloneMachineInstr(&MI);
4370 return MI;
4371 };
4372
4373 switch (MI.getOpcode()) {
4374 case RISCV::TH_MVEQZ:
4375 case RISCV::TH_MVNEZ: {
4376 auto &WorkingMI = cloneIfNew(MI);
4377 WorkingMI.setDesc(get(MI.getOpcode() == RISCV::TH_MVEQZ ? RISCV::TH_MVNEZ
4378 : RISCV::TH_MVEQZ));
4379 return TargetInstrInfo::commuteInstructionImpl(WorkingMI, false, OpIdx1,
4380 OpIdx2);
4381 }
4382 case RISCV::QC_SELECTIEQ:
4383 case RISCV::QC_SELECTINE:
4384 case RISCV::QC_SELECTIIEQ:
4385 case RISCV::QC_SELECTIINE:
4386 return TargetInstrInfo::commuteInstructionImpl(MI, NewMI, OpIdx1, OpIdx2);
4387 case RISCV::QC_MVEQ:
4388 case RISCV::QC_MVNE:
4389 case RISCV::QC_MVLT:
4390 case RISCV::QC_MVGE:
4391 case RISCV::QC_MVLTU:
4392 case RISCV::QC_MVGEU:
4393 case RISCV::QC_MVEQI:
4394 case RISCV::QC_MVNEI:
4395 case RISCV::QC_MVLTI:
4396 case RISCV::QC_MVGEI:
4397 case RISCV::QC_MVLTUI:
4398 case RISCV::QC_MVGEUI: {
4399 auto &WorkingMI = cloneIfNew(MI);
4400 WorkingMI.setDesc(get(getInverseXqcicmOpcode(MI.getOpcode())));
4401 return TargetInstrInfo::commuteInstructionImpl(WorkingMI, false, OpIdx1,
4402 OpIdx2);
4403 }
4404 case RISCV::PseudoCCMOVGPRNoX0:
4405 case RISCV::PseudoCCMOVGPR: {
4406 // CCMOV can be commuted by inverting the condition.
4407 unsigned BCC = MI.getOperand(MI.getNumExplicitOperands() - 3).getImm();
4409 auto &WorkingMI = cloneIfNew(MI);
4410 WorkingMI.getOperand(MI.getNumExplicitOperands() - 3).setImm(BCC);
4411 return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI*/ false,
4412 OpIdx1, OpIdx2);
4413 }
4414 case CASE_VFMA_SPLATS(FMACC):
4415 case CASE_VFMA_SPLATS(FMADD):
4416 case CASE_VFMA_SPLATS(FMSAC):
4417 case CASE_VFMA_SPLATS(FMSUB):
4418 case CASE_VFMA_SPLATS(FNMACC):
4420 case CASE_VFMA_SPLATS(FNMSAC):
4422 case CASE_VFMA_OPCODE_VV(FMACC):
4423 case CASE_VFMA_OPCODE_VV(FMSAC):
4424 case CASE_VFMA_OPCODE_VV(FNMACC):
4425 case CASE_VFMA_OPCODE_VV(FNMSAC):
4426 case CASE_VMA_OPCODE_LMULS(MADD, VX):
4427 case CASE_VMA_OPCODE_LMULS(NMSUB, VX):
4428 case CASE_VMA_OPCODE_LMULS(MACC, VX):
4429 case CASE_VMA_OPCODE_LMULS(NMSAC, VX):
4430 case CASE_VMA_OPCODE_LMULS(MACC, VV):
4431 case CASE_VMA_OPCODE_LMULS(NMSAC, VV): {
4432 // It only make sense to toggle these between clobbering the
4433 // addend/subtrahend/minuend one of the multiplicands.
4434 assert((OpIdx1 == 1 || OpIdx2 == 1) && "Unexpected opcode index");
4435 assert((OpIdx1 == 3 || OpIdx2 == 3) && "Unexpected opcode index");
4436 unsigned Opc;
4437 switch (MI.getOpcode()) {
4438 default:
4439 llvm_unreachable("Unexpected opcode");
4440 CASE_VFMA_CHANGE_OPCODE_SPLATS(FMACC, FMADD)
4441 CASE_VFMA_CHANGE_OPCODE_SPLATS(FMADD, FMACC)
4448 CASE_VFMA_CHANGE_OPCODE_VV(FMACC, FMADD)
4452 CASE_VMA_CHANGE_OPCODE_LMULS(MACC, MADD, VX)
4453 CASE_VMA_CHANGE_OPCODE_LMULS(MADD, MACC, VX)
4454 CASE_VMA_CHANGE_OPCODE_LMULS(NMSAC, NMSUB, VX)
4455 CASE_VMA_CHANGE_OPCODE_LMULS(NMSUB, NMSAC, VX)
4456 CASE_VMA_CHANGE_OPCODE_LMULS(MACC, MADD, VV)
4457 CASE_VMA_CHANGE_OPCODE_LMULS(NMSAC, NMSUB, VV)
4458 }
4459
4460 auto &WorkingMI = cloneIfNew(MI);
4461 WorkingMI.setDesc(get(Opc));
4462 return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI=*/false,
4463 OpIdx1, OpIdx2);
4464 }
4465 case CASE_VFMA_OPCODE_VV(FMADD):
4469 case CASE_VMA_OPCODE_LMULS(MADD, VV):
4470 case CASE_VMA_OPCODE_LMULS(NMSUB, VV): {
4471 assert((OpIdx1 == 1 || OpIdx2 == 1) && "Unexpected opcode index");
4472 // If one of the operands, is the addend we need to change opcode.
4473 // Otherwise we're just swapping 2 of the multiplicands.
4474 if (OpIdx1 == 3 || OpIdx2 == 3) {
4475 unsigned Opc;
4476 switch (MI.getOpcode()) {
4477 default:
4478 llvm_unreachable("Unexpected opcode");
4479 CASE_VFMA_CHANGE_OPCODE_VV(FMADD, FMACC)
4483 CASE_VMA_CHANGE_OPCODE_LMULS(MADD, MACC, VV)
4484 CASE_VMA_CHANGE_OPCODE_LMULS(NMSUB, NMSAC, VV)
4485 }
4486
4487 auto &WorkingMI = cloneIfNew(MI);
4488 WorkingMI.setDesc(get(Opc));
4489 return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI=*/false,
4490 OpIdx1, OpIdx2);
4491 }
4492 // Let the default code handle it.
4493 break;
4494 }
4495 }
4496
4497 return TargetInstrInfo::commuteInstructionImpl(MI, NewMI, OpIdx1, OpIdx2);
4498}
4499
4500#undef CASE_VMA_CHANGE_OPCODE_COMMON
4501#undef CASE_VMA_CHANGE_OPCODE_LMULS
4502#undef CASE_VFMA_CHANGE_OPCODE_COMMON
4503#undef CASE_VFMA_CHANGE_OPCODE_LMULS_M1
4504#undef CASE_VFMA_CHANGE_OPCODE_LMULS_MF2
4505#undef CASE_VFMA_CHANGE_OPCODE_LMULS_MF4
4506#undef CASE_VFMA_CHANGE_OPCODE_VV
4507#undef CASE_VFMA_CHANGE_OPCODE_SPLATS
4508
4509#undef CASE_RVV_OPCODE_UNMASK_LMUL
4510#undef CASE_RVV_OPCODE_MASK_LMUL
4511#undef CASE_RVV_OPCODE_LMUL
4512#undef CASE_RVV_OPCODE_UNMASK_WIDEN
4513#undef CASE_RVV_OPCODE_UNMASK
4514#undef CASE_RVV_OPCODE_MASK_WIDEN
4515#undef CASE_RVV_OPCODE_MASK
4516#undef CASE_RVV_OPCODE_WIDEN
4517#undef CASE_RVV_OPCODE
4518
4519#undef CASE_VMA_OPCODE_COMMON
4520#undef CASE_VMA_OPCODE_LMULS
4521#undef CASE_VFMA_OPCODE_COMMON
4522#undef CASE_VFMA_OPCODE_LMULS_M1
4523#undef CASE_VFMA_OPCODE_LMULS_MF2
4524#undef CASE_VFMA_OPCODE_LMULS_MF4
4525#undef CASE_VFMA_OPCODE_VV
4526#undef CASE_VFMA_SPLATS
4527
4529 switch (MI.getOpcode()) {
4530 default:
4531 break;
4532 case RISCV::ADD:
4533 case RISCV::OR:
4534 case RISCV::XOR:
4535 // Normalize (so we hit the next if clause).
4536 // add/[x]or rd, zero, rs => add/[x]or rd, rs, zero
4537 if (MI.getOperand(1).getReg() == RISCV::X0)
4538 commuteInstruction(MI);
4539 // add/[x]or rd, rs, zero => addi rd, rs, 0
4540 if (MI.getOperand(2).getReg() == RISCV::X0) {
4541 MI.getOperand(2).ChangeToImmediate(0);
4542 MI.setDesc(get(RISCV::ADDI));
4543 return true;
4544 }
4545 // xor rd, rs, rs => addi rd, zero, 0
4546 if (MI.getOpcode() == RISCV::XOR &&
4547 MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) {
4548 MI.getOperand(1).setReg(RISCV::X0);
4549 MI.getOperand(2).ChangeToImmediate(0);
4550 MI.setDesc(get(RISCV::ADDI));
4551 return true;
4552 }
4553 break;
4554 case RISCV::ORI:
4555 case RISCV::XORI:
4556 // [x]ori rd, zero, N => addi rd, zero, N
4557 if (MI.getOperand(1).getReg() == RISCV::X0) {
4558 MI.setDesc(get(RISCV::ADDI));
4559 return true;
4560 }
4561 break;
4562 case RISCV::SUB:
4563 // sub rd, rs, zero => addi rd, rs, 0
4564 if (MI.getOperand(2).getReg() == RISCV::X0) {
4565 MI.getOperand(2).ChangeToImmediate(0);
4566 MI.setDesc(get(RISCV::ADDI));
4567 return true;
4568 }
4569 break;
4570 case RISCV::SUBW:
4571 // subw rd, rs, zero => addiw rd, rs, 0
4572 if (MI.getOperand(2).getReg() == RISCV::X0) {
4573 MI.getOperand(2).ChangeToImmediate(0);
4574 MI.setDesc(get(RISCV::ADDIW));
4575 return true;
4576 }
4577 break;
4578 case RISCV::ADDW:
4579 // Normalize (so we hit the next if clause).
4580 // addw rd, zero, rs => addw rd, rs, zero
4581 if (MI.getOperand(1).getReg() == RISCV::X0)
4582 commuteInstruction(MI);
4583 // addw rd, rs, zero => addiw rd, rs, 0
4584 if (MI.getOperand(2).getReg() == RISCV::X0) {
4585 MI.getOperand(2).ChangeToImmediate(0);
4586 MI.setDesc(get(RISCV::ADDIW));
4587 return true;
4588 }
4589 break;
4590 case RISCV::SH1ADD:
4591 case RISCV::SH1ADD_UW:
4592 case RISCV::SH2ADD:
4593 case RISCV::SH2ADD_UW:
4594 case RISCV::SH3ADD:
4595 case RISCV::SH3ADD_UW:
4596 // shNadd[.uw] rd, zero, rs => addi rd, rs, 0
4597 if (MI.getOperand(1).getReg() == RISCV::X0) {
4598 MI.removeOperand(1);
4599 MI.addOperand(MachineOperand::CreateImm(0));
4600 MI.setDesc(get(RISCV::ADDI));
4601 return true;
4602 }
4603 // shNadd[.uw] rd, rs, zero => slli[.uw] rd, rs, N
4604 if (MI.getOperand(2).getReg() == RISCV::X0) {
4605 MI.removeOperand(2);
4606 unsigned Opc = MI.getOpcode();
4607 if (Opc == RISCV::SH1ADD_UW || Opc == RISCV::SH2ADD_UW ||
4608 Opc == RISCV::SH3ADD_UW) {
4610 MI.setDesc(get(RISCV::SLLI_UW));
4611 return true;
4612 }
4614 MI.setDesc(get(RISCV::SLLI));
4615 return true;
4616 }
4617 break;
4618 case RISCV::AND:
4619 case RISCV::MUL:
4620 case RISCV::MULH:
4621 case RISCV::MULHSU:
4622 case RISCV::MULHU:
4623 case RISCV::MULW:
4624 // and rd, zero, rs => addi rd, zero, 0
4625 // mul* rd, zero, rs => addi rd, zero, 0
4626 // and rd, rs, zero => addi rd, zero, 0
4627 // mul* rd, rs, zero => addi rd, zero, 0
4628 if (MI.getOperand(1).getReg() == RISCV::X0 ||
4629 MI.getOperand(2).getReg() == RISCV::X0) {
4630 MI.getOperand(1).setReg(RISCV::X0);
4631 MI.getOperand(2).ChangeToImmediate(0);
4632 MI.setDesc(get(RISCV::ADDI));
4633 return true;
4634 }
4635 break;
4636 case RISCV::ANDI:
4637 // andi rd, zero, C => addi rd, zero, 0
4638 if (MI.getOperand(1).getReg() == RISCV::X0) {
4639 MI.getOperand(2).setImm(0);
4640 MI.setDesc(get(RISCV::ADDI));
4641 return true;
4642 }
4643 break;
4644 case RISCV::SLL:
4645 case RISCV::SRL:
4646 case RISCV::SRA:
4647 // shift rd, zero, rs => addi rd, zero, 0
4648 if (MI.getOperand(1).getReg() == RISCV::X0) {
4649 MI.getOperand(2).ChangeToImmediate(0);
4650 MI.setDesc(get(RISCV::ADDI));
4651 return true;
4652 }
4653 // shift rd, rs, zero => addi rd, rs, 0
4654 if (MI.getOperand(2).getReg() == RISCV::X0) {
4655 MI.getOperand(2).ChangeToImmediate(0);
4656 MI.setDesc(get(RISCV::ADDI));
4657 return true;
4658 }
4659 break;
4660 case RISCV::SLLW:
4661 case RISCV::SRLW:
4662 case RISCV::SRAW:
4663 // shiftw rd, zero, rs => addi rd, zero, 0
4664 if (MI.getOperand(1).getReg() == RISCV::X0) {
4665 MI.getOperand(2).ChangeToImmediate(0);
4666 MI.setDesc(get(RISCV::ADDI));
4667 return true;
4668 }
4669 break;
4670 case RISCV::SLLI:
4671 case RISCV::SRLI:
4672 case RISCV::SRAI:
4673 case RISCV::SLLIW:
4674 case RISCV::SRLIW:
4675 case RISCV::SRAIW:
4676 case RISCV::SLLI_UW:
4677 // shiftimm rd, zero, N => addi rd, zero, 0
4678 if (MI.getOperand(1).getReg() == RISCV::X0) {
4679 MI.getOperand(2).setImm(0);
4680 MI.setDesc(get(RISCV::ADDI));
4681 return true;
4682 }
4683 break;
4684 case RISCV::SLTU:
4685 case RISCV::ADD_UW:
4686 // sltu rd, zero, zero => addi rd, zero, 0
4687 // add.uw rd, zero, zero => addi rd, zero, 0
4688 if (MI.getOperand(1).getReg() == RISCV::X0 &&
4689 MI.getOperand(2).getReg() == RISCV::X0) {
4690 MI.getOperand(2).ChangeToImmediate(0);
4691 MI.setDesc(get(RISCV::ADDI));
4692 return true;
4693 }
4694 // add.uw rd, zero, rs => addi rd, rs, 0
4695 if (MI.getOpcode() == RISCV::ADD_UW &&
4696 MI.getOperand(1).getReg() == RISCV::X0) {
4697 MI.removeOperand(1);
4698 MI.addOperand(MachineOperand::CreateImm(0));
4699 MI.setDesc(get(RISCV::ADDI));
4700 }
4701 break;
4702 case RISCV::SLTIU:
4703 // sltiu rd, zero, NZC => addi rd, zero, 1
4704 // sltiu rd, zero, 0 => addi rd, zero, 0
4705 if (MI.getOperand(1).getReg() == RISCV::X0) {
4706 MI.getOperand(2).setImm(MI.getOperand(2).getImm() != 0);
4707 MI.setDesc(get(RISCV::ADDI));
4708 return true;
4709 }
4710 break;
4711 case RISCV::SEXT_H:
4712 case RISCV::SEXT_B:
4713 case RISCV::ZEXT_H_RV32:
4714 case RISCV::ZEXT_H_RV64:
4715 // sext.[hb] rd, zero => addi rd, zero, 0
4716 // zext.h rd, zero => addi rd, zero, 0
4717 if (MI.getOperand(1).getReg() == RISCV::X0) {
4718 MI.addOperand(MachineOperand::CreateImm(0));
4719 MI.setDesc(get(RISCV::ADDI));
4720 return true;
4721 }
4722 break;
4723 case RISCV::MIN:
4724 case RISCV::MINU:
4725 case RISCV::MAX:
4726 case RISCV::MAXU:
4727 // min|max rd, rs, rs => addi rd, rs, 0
4728 if (MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) {
4729 MI.getOperand(2).ChangeToImmediate(0);
4730 MI.setDesc(get(RISCV::ADDI));
4731 return true;
4732 }
4733 break;
4734 case RISCV::BEQ:
4735 case RISCV::BNE:
4736 // b{eq,ne} zero, rs, imm => b{eq,ne} rs, zero, imm
4737 if (MI.getOperand(0).getReg() == RISCV::X0) {
4738 MachineOperand MO0 = MI.getOperand(0);
4739 MI.removeOperand(0);
4740 MI.insert(MI.operands_begin() + 1, {MO0});
4741 }
4742 break;
4743 case RISCV::BLTU:
4744 // bltu zero, rs, imm => bne rs, zero, imm
4745 if (MI.getOperand(0).getReg() == RISCV::X0) {
4746 MachineOperand MO0 = MI.getOperand(0);
4747 MI.removeOperand(0);
4748 MI.insert(MI.operands_begin() + 1, {MO0});
4749 MI.setDesc(get(RISCV::BNE));
4750 }
4751 break;
4752 case RISCV::BGEU:
4753 // bgeu zero, rs, imm => beq rs, zero, imm
4754 if (MI.getOperand(0).getReg() == RISCV::X0) {
4755 MachineOperand MO0 = MI.getOperand(0);
4756 MI.removeOperand(0);
4757 MI.insert(MI.operands_begin() + 1, {MO0});
4758 MI.setDesc(get(RISCV::BEQ));
4759 }
4760 break;
4761 }
4762 return false;
4763}
4764
4765// clang-format off
4766#define CASE_WIDEOP_OPCODE_COMMON(OP, LMUL) \
4767 RISCV::PseudoV##OP##_##LMUL##_TIED
4768
4769#define CASE_WIDEOP_OPCODE_LMULS(OP) \
4770 CASE_WIDEOP_OPCODE_COMMON(OP, MF8): \
4771 case CASE_WIDEOP_OPCODE_COMMON(OP, MF4): \
4772 case CASE_WIDEOP_OPCODE_COMMON(OP, MF2): \
4773 case CASE_WIDEOP_OPCODE_COMMON(OP, M1): \
4774 case CASE_WIDEOP_OPCODE_COMMON(OP, M2): \
4775 case CASE_WIDEOP_OPCODE_COMMON(OP, M4)
4776
4777#define CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, LMUL) \
4778 case RISCV::PseudoV##OP##_##LMUL##_TIED: \
4779 NewOpc = RISCV::PseudoV##OP##_##LMUL; \
4780 break;
4781
4782#define CASE_WIDEOP_CHANGE_OPCODE_LMULS(OP) \
4783 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF8) \
4784 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF4) \
4785 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2) \
4786 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1) \
4787 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2) \
4788 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4)
4789
4790// FP Widening Ops may by SEW aware. Create SEW aware cases for these cases.
4791#define CASE_FP_WIDEOP_OPCODE_COMMON(OP, LMUL, SEW) \
4792 RISCV::PseudoV##OP##_##LMUL##_##SEW##_TIED
4793
4794#define CASE_FP_WIDEOP_OPCODE_LMULS(OP) \
4795 CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF4, E16): \
4796 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF2, E16): \
4797 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF2, E32): \
4798 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M1, E16): \
4799 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M1, E32): \
4800 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M2, E16): \
4801 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M2, E32): \
4802 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M4, E16): \
4803 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M4, E32) \
4804
4805#define CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, LMUL, SEW) \
4806 case RISCV::PseudoV##OP##_##LMUL##_##SEW##_TIED: \
4807 NewOpc = RISCV::PseudoV##OP##_##LMUL##_##SEW; \
4808 break;
4809
4810#define CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS(OP) \
4811 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF4, E16) \
4812 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2, E16) \
4813 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2, E32) \
4814 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1, E16) \
4815 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1, E32) \
4816 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2, E16) \
4817 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2, E32) \
4818 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4, E16) \
4819 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4, E32) \
4820
4821#define CASE_FP_WIDEOP_OPCODE_LMULS_ALT(OP) \
4822 CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF4, E16): \
4823 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF2, E16): \
4824 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M1, E16): \
4825 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M2, E16): \
4826 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M4, E16)
4827
4828#define CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS_ALT(OP) \
4829 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF4, E16) \
4830 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2, E16) \
4831 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1, E16) \
4832 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2, E16) \
4833 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4, E16)
4834// clang-format on
4835
4837 LiveVariables *LV,
4838 LiveIntervals *LIS) const {
4840 switch (MI.getOpcode()) {
4841 default:
4842 return nullptr;
4843 case CASE_FP_WIDEOP_OPCODE_LMULS_ALT(FWADD_ALT_WV):
4844 case CASE_FP_WIDEOP_OPCODE_LMULS_ALT(FWSUB_ALT_WV):
4845 case CASE_FP_WIDEOP_OPCODE_LMULS(FWADD_WV):
4846 case CASE_FP_WIDEOP_OPCODE_LMULS(FWSUB_WV): {
4847 assert(RISCVII::hasVecPolicyOp(MI.getDesc().TSFlags) &&
4848 MI.getNumExplicitOperands() == 7 &&
4849 "Expect 7 explicit operands rd, rs2, rs1, rm, vl, sew, policy");
4850 // If the tail policy is undisturbed we can't convert.
4851 if ((MI.getOperand(RISCVII::getVecPolicyOpNum(MI.getDesc())).getImm() &
4852 1) == 0)
4853 return nullptr;
4854 // clang-format off
4855 unsigned NewOpc;
4856 switch (MI.getOpcode()) {
4857 default:
4858 llvm_unreachable("Unexpected opcode");
4863 }
4864 // clang-format on
4865
4866 MachineBasicBlock &MBB = *MI.getParent();
4867 MIB = BuildMI(MBB, MI, MI.getDebugLoc(), get(NewOpc))
4868 .add(MI.getOperand(0))
4869 .addReg(MI.getOperand(0).getReg(), RegState::Undef)
4870 .add(MI.getOperand(1))
4871 .add(MI.getOperand(2))
4872 .add(MI.getOperand(3))
4873 .add(MI.getOperand(4))
4874 .add(MI.getOperand(5))
4875 .add(MI.getOperand(6));
4876 break;
4877 }
4878 case CASE_WIDEOP_OPCODE_LMULS(WADD_WV):
4879 case CASE_WIDEOP_OPCODE_LMULS(WADDU_WV):
4880 case CASE_WIDEOP_OPCODE_LMULS(WSUB_WV):
4881 case CASE_WIDEOP_OPCODE_LMULS(WSUBU_WV): {
4882 // If the tail policy is undisturbed we can't convert.
4883 assert(RISCVII::hasVecPolicyOp(MI.getDesc().TSFlags) &&
4884 MI.getNumExplicitOperands() == 6);
4885 if ((MI.getOperand(RISCVII::getVecPolicyOpNum(MI.getDesc())).getImm() &
4886 1) == 0)
4887 return nullptr;
4888
4889 // clang-format off
4890 unsigned NewOpc;
4891 switch (MI.getOpcode()) {
4892 default:
4893 llvm_unreachable("Unexpected opcode");
4898 }
4899 // clang-format on
4900
4901 MachineBasicBlock &MBB = *MI.getParent();
4902 MIB = BuildMI(MBB, MI, MI.getDebugLoc(), get(NewOpc))
4903 .add(MI.getOperand(0))
4904 .addReg(MI.getOperand(0).getReg(), RegState::Undef)
4905 .add(MI.getOperand(1))
4906 .add(MI.getOperand(2))
4907 .add(MI.getOperand(3))
4908 .add(MI.getOperand(4))
4909 .add(MI.getOperand(5));
4910 break;
4911 }
4912 }
4913 MIB.copyImplicitOps(MI);
4914
4915 if (LV) {
4916 unsigned NumOps = MI.getNumOperands();
4917 for (unsigned I = 1; I < NumOps; ++I) {
4918 MachineOperand &Op = MI.getOperand(I);
4919 if (Op.isReg() && Op.isKill())
4920 LV->replaceKillInstruction(Op.getReg(), MI, *MIB);
4921 }
4922 }
4923
4924 if (LIS) {
4925 SlotIndex Idx = LIS->ReplaceMachineInstrInMaps(MI, *MIB);
4926
4927 if (MI.getOperand(0).isEarlyClobber()) {
4928 // Use operand 1 was tied to early-clobber def operand 0, so its live
4929 // interval could have ended at an early-clobber slot. Now they are not
4930 // tied we need to update it to the normal register slot.
4931 LiveInterval &LI = LIS->getInterval(MI.getOperand(1).getReg());
4933 if (S->end == Idx.getRegSlot(true))
4934 S->end = Idx.getRegSlot();
4935 }
4936 }
4937
4938 return MIB;
4939}
4940
4941#undef CASE_WIDEOP_OPCODE_COMMON
4942#undef CASE_WIDEOP_OPCODE_LMULS
4943#undef CASE_WIDEOP_CHANGE_OPCODE_COMMON
4944#undef CASE_WIDEOP_CHANGE_OPCODE_LMULS
4945#undef CASE_FP_WIDEOP_OPCODE_COMMON
4946#undef CASE_FP_WIDEOP_OPCODE_LMULS
4947#undef CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON
4948#undef CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS
4949
4952 Register DestReg, uint32_t Amount,
4953 MachineInstr::MIFlag Flag) const {
4954 MachineRegisterInfo &MRI = MF.getRegInfo();
4955 if (llvm::has_single_bit<uint32_t>(Amount)) {
4956 uint32_t ShiftAmount = Log2_32(Amount);
4957 if (ShiftAmount == 0)
4958 return;
4959 BuildMI(MBB, II, DL, get(RISCV::SLLI), DestReg)
4960 .addReg(DestReg, RegState::Kill)
4961 .addImm(ShiftAmount)
4962 .setMIFlag(Flag);
4963 } else if (int ShXAmount, ShiftAmount;
4964 STI.hasShlAdd(3) &&
4965 (ShXAmount = isShifted359(Amount, ShiftAmount)) != 0) {
4966 // We can use Zba SHXADD+SLLI instructions for multiply in some cases.
4967 unsigned Opc;
4968 switch (ShXAmount) {
4969 case 1:
4970 Opc = RISCV::SH1ADD;
4971 break;
4972 case 2:
4973 Opc = RISCV::SH2ADD;
4974 break;
4975 case 3:
4976 Opc = RISCV::SH3ADD;
4977 break;
4978 default:
4979 llvm_unreachable("unexpected result of isShifted359");
4980 }
4981 if (ShiftAmount)
4982 BuildMI(MBB, II, DL, get(RISCV::SLLI), DestReg)
4983 .addReg(DestReg, RegState::Kill)
4984 .addImm(ShiftAmount)
4985 .setMIFlag(Flag);
4986 BuildMI(MBB, II, DL, get(Opc), DestReg)
4987 .addReg(DestReg, RegState::Kill)
4988 .addReg(DestReg)
4989 .setMIFlag(Flag);
4990 } else if (llvm::has_single_bit<uint32_t>(Amount - 1)) {
4991 Register ScaledRegister = MRI.createVirtualRegister(&RISCV::GPRRegClass);
4992 uint32_t ShiftAmount = Log2_32(Amount - 1);
4993 BuildMI(MBB, II, DL, get(RISCV::SLLI), ScaledRegister)
4994 .addReg(DestReg)
4995 .addImm(ShiftAmount)
4996 .setMIFlag(Flag);
4997 BuildMI(MBB, II, DL, get(RISCV::ADD), DestReg)
4998 .addReg(ScaledRegister, RegState::Kill)
4999 .addReg(DestReg, RegState::Kill)
5000 .setMIFlag(Flag);
5001 } else if (llvm::has_single_bit<uint32_t>(Amount + 1)) {
5002 Register ScaledRegister = MRI.createVirtualRegister(&RISCV::GPRRegClass);
5003 uint32_t ShiftAmount = Log2_32(Amount + 1);
5004 BuildMI(MBB, II, DL, get(RISCV::SLLI), ScaledRegister)
5005 .addReg(DestReg)
5006 .addImm(ShiftAmount)
5007 .setMIFlag(Flag);
5008 BuildMI(MBB, II, DL, get(RISCV::SUB), DestReg)
5009 .addReg(ScaledRegister, RegState::Kill)
5010 .addReg(DestReg, RegState::Kill)
5011 .setMIFlag(Flag);
5012 } else if (STI.hasStdExtZmmul()) {
5013 Register N = MRI.createVirtualRegister(&RISCV::GPRRegClass);
5014 movImm(MBB, II, DL, N, Amount, Flag);
5015 BuildMI(MBB, II, DL, get(RISCV::MUL), DestReg)
5016 .addReg(DestReg, RegState::Kill)
5018 .setMIFlag(Flag);
5019 } else {
5020 Register Acc;
5021 uint32_t PrevShiftAmount = 0;
5022 for (uint32_t ShiftAmount = 0; Amount >> ShiftAmount; ShiftAmount++) {
5023 if (Amount & (1U << ShiftAmount)) {
5024 if (ShiftAmount)
5025 BuildMI(MBB, II, DL, get(RISCV::SLLI), DestReg)
5026 .addReg(DestReg, RegState::Kill)
5027 .addImm(ShiftAmount - PrevShiftAmount)
5028 .setMIFlag(Flag);
5029 if (Amount >> (ShiftAmount + 1)) {
5030 // If we don't have an accmulator yet, create it and copy DestReg.
5031 if (!Acc) {
5032 Acc = MRI.createVirtualRegister(&RISCV::GPRRegClass);
5033 BuildMI(MBB, II, DL, get(TargetOpcode::COPY), Acc)
5034 .addReg(DestReg)
5035 .setMIFlag(Flag);
5036 } else {
5037 BuildMI(MBB, II, DL, get(RISCV::ADD), Acc)
5038 .addReg(Acc, RegState::Kill)
5039 .addReg(DestReg)
5040 .setMIFlag(Flag);
5041 }
5042 }
5043 PrevShiftAmount = ShiftAmount;
5044 }
5045 }
5046 assert(Acc && "Expected valid accumulator");
5047 BuildMI(MBB, II, DL, get(RISCV::ADD), DestReg)
5048 .addReg(DestReg, RegState::Kill)
5049 .addReg(Acc, RegState::Kill)
5050 .setMIFlag(Flag);
5051 }
5052}
5053
5056 static const std::pair<MachineMemOperand::Flags, const char *> TargetFlags[] =
5057 {{MONontemporalBit0, "riscv-nontemporal-domain-bit-0"},
5058 {MONontemporalBit1, "riscv-nontemporal-domain-bit-1"}};
5059 return ArrayRef(TargetFlags);
5060}
5061
5063 return OptLevel >= CodeGenOptLevel::Aggressive
5064 ? STI.getTailDupAggressiveThreshold()
5065 : 2;
5066}
5067
5069 // RVV lacks any support for immediate addressing for stack addresses, so be
5070 // conservative.
5071 unsigned Opcode = MI.getOpcode();
5072 if (!RISCVVPseudosTable::getPseudoInfo(Opcode) &&
5074 return false;
5075 return true;
5076}
5077
5078/// Return true if \p MI is a copy that will be lowered to one or more vmvNr.vs.
5080 const MachineInstr &MI) {
5081 return MI.isCopy() && MI.getOperand(0).getReg().isPhysical() &&
5083 TRI->getMinimalPhysRegClass(MI.getOperand(0).getReg()));
5084}
5085
5086std::optional<std::pair<unsigned, unsigned>>
5088 switch (Opcode) {
5089 default:
5090 return std::nullopt;
5091 case RISCV::PseudoVSPILL2_M1:
5092 case RISCV::PseudoVRELOAD2_M1:
5093 return std::make_pair(2u, 1u);
5094 case RISCV::PseudoVSPILL2_M2:
5095 case RISCV::PseudoVRELOAD2_M2:
5096 return std::make_pair(2u, 2u);
5097 case RISCV::PseudoVSPILL2_M4:
5098 case RISCV::PseudoVRELOAD2_M4:
5099 return std::make_pair(2u, 4u);
5100 case RISCV::PseudoVSPILL3_M1:
5101 case RISCV::PseudoVRELOAD3_M1:
5102 return std::make_pair(3u, 1u);
5103 case RISCV::PseudoVSPILL3_M2:
5104 case RISCV::PseudoVRELOAD3_M2:
5105 return std::make_pair(3u, 2u);
5106 case RISCV::PseudoVSPILL4_M1:
5107 case RISCV::PseudoVRELOAD4_M1:
5108 return std::make_pair(4u, 1u);
5109 case RISCV::PseudoVSPILL4_M2:
5110 case RISCV::PseudoVRELOAD4_M2:
5111 return std::make_pair(4u, 2u);
5112 case RISCV::PseudoVSPILL5_M1:
5113 case RISCV::PseudoVRELOAD5_M1:
5114 return std::make_pair(5u, 1u);
5115 case RISCV::PseudoVSPILL6_M1:
5116 case RISCV::PseudoVRELOAD6_M1:
5117 return std::make_pair(6u, 1u);
5118 case RISCV::PseudoVSPILL7_M1:
5119 case RISCV::PseudoVRELOAD7_M1:
5120 return std::make_pair(7u, 1u);
5121 case RISCV::PseudoVSPILL8_M1:
5122 case RISCV::PseudoVRELOAD8_M1:
5123 return std::make_pair(8u, 1u);
5124 }
5125}
5126
5127bool RISCV::hasEqualFRM(const MachineInstr &MI1, const MachineInstr &MI2) {
5128 int16_t MI1FrmOpIdx =
5129 RISCV::getNamedOperandIdx(MI1.getOpcode(), RISCV::OpName::frm);
5130 int16_t MI2FrmOpIdx =
5131 RISCV::getNamedOperandIdx(MI2.getOpcode(), RISCV::OpName::frm);
5132 if (MI1FrmOpIdx < 0 || MI2FrmOpIdx < 0)
5133 return false;
5134 MachineOperand FrmOp1 = MI1.getOperand(MI1FrmOpIdx);
5135 MachineOperand FrmOp2 = MI2.getOperand(MI2FrmOpIdx);
5136 return FrmOp1.getImm() == FrmOp2.getImm();
5137}
5138
5139std::optional<unsigned>
5140RISCV::getVectorLowDemandedScalarBits(unsigned Opcode, unsigned Log2SEW) {
5141 switch (Opcode) {
5142 default:
5143 return std::nullopt;
5144
5145 // 11.6. Vector Single-Width Shift Instructions
5146 case RISCV::VSLL_VX:
5147 case RISCV::VSRL_VX:
5148 case RISCV::VSRA_VX:
5149 // 12.4. Vector Single-Width Scaling Shift Instructions
5150 case RISCV::VSSRL_VX:
5151 case RISCV::VSSRA_VX:
5152 // Zvbb
5153 case RISCV::VROL_VX:
5154 case RISCV::VROR_VX:
5155 // Only the low lg2(SEW) bits of the shift-amount value are used.
5156 return Log2SEW;
5157
5158 // 11.7 Vector Narrowing Integer Right Shift Instructions
5159 case RISCV::VNSRL_WX:
5160 case RISCV::VNSRA_WX:
5161 // 12.5. Vector Narrowing Fixed-Point Clip Instructions
5162 case RISCV::VNCLIPU_WX:
5163 case RISCV::VNCLIP_WX:
5164 // Zvbb
5165 case RISCV::VWSLL_VX:
5166 // Only the low lg2(2*SEW) bits of the shift-amount value are used.
5167 return Log2SEW + 1;
5168
5169 // 11.1. Vector Single-Width Integer Add and Subtract
5170 case RISCV::VADD_VX:
5171 case RISCV::VSUB_VX:
5172 case RISCV::VRSUB_VX:
5173 // 11.2. Vector Widening Integer Add/Subtract
5174 case RISCV::VWADDU_VX:
5175 case RISCV::VWSUBU_VX:
5176 case RISCV::VWADD_VX:
5177 case RISCV::VWSUB_VX:
5178 case RISCV::VWADDU_WX:
5179 case RISCV::VWSUBU_WX:
5180 case RISCV::VWADD_WX:
5181 case RISCV::VWSUB_WX:
5182 // 11.4. Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions
5183 case RISCV::VADC_VXM:
5184 case RISCV::VADC_VIM:
5185 case RISCV::VMADC_VXM:
5186 case RISCV::VMADC_VIM:
5187 case RISCV::VMADC_VX:
5188 case RISCV::VSBC_VXM:
5189 case RISCV::VMSBC_VXM:
5190 case RISCV::VMSBC_VX:
5191 // 11.5 Vector Bitwise Logical Instructions
5192 case RISCV::VAND_VX:
5193 case RISCV::VOR_VX:
5194 case RISCV::VXOR_VX:
5195 // 11.8. Vector Integer Compare Instructions
5196 case RISCV::VMSEQ_VX:
5197 case RISCV::VMSNE_VX:
5198 case RISCV::VMSLTU_VX:
5199 case RISCV::VMSLT_VX:
5200 case RISCV::VMSLEU_VX:
5201 case RISCV::VMSLE_VX:
5202 case RISCV::VMSGTU_VX:
5203 case RISCV::VMSGT_VX:
5204 // 11.9. Vector Integer Min/Max Instructions
5205 case RISCV::VMINU_VX:
5206 case RISCV::VMIN_VX:
5207 case RISCV::VMAXU_VX:
5208 case RISCV::VMAX_VX:
5209 // 11.10. Vector Single-Width Integer Multiply Instructions
5210 case RISCV::VMUL_VX:
5211 case RISCV::VMULH_VX:
5212 case RISCV::VMULHU_VX:
5213 case RISCV::VMULHSU_VX:
5214 // 11.11. Vector Integer Divide Instructions
5215 case RISCV::VDIVU_VX:
5216 case RISCV::VDIV_VX:
5217 case RISCV::VREMU_VX:
5218 case RISCV::VREM_VX:
5219 // 11.12. Vector Widening Integer Multiply Instructions
5220 case RISCV::VWMUL_VX:
5221 case RISCV::VWMULU_VX:
5222 case RISCV::VWMULSU_VX:
5223 // 11.13. Vector Single-Width Integer Multiply-Add Instructions
5224 case RISCV::VMACC_VX:
5225 case RISCV::VNMSAC_VX:
5226 case RISCV::VMADD_VX:
5227 case RISCV::VNMSUB_VX:
5228 // 11.14. Vector Widening Integer Multiply-Add Instructions
5229 case RISCV::VWMACCU_VX:
5230 case RISCV::VWMACC_VX:
5231 case RISCV::VWMACCSU_VX:
5232 case RISCV::VWMACCUS_VX:
5233 // 11.15. Vector Integer Merge Instructions
5234 case RISCV::VMERGE_VXM:
5235 // 11.16. Vector Integer Move Instructions
5236 case RISCV::VMV_V_X:
5237 // 12.1. Vector Single-Width Saturating Add and Subtract
5238 case RISCV::VSADDU_VX:
5239 case RISCV::VSADD_VX:
5240 case RISCV::VSSUBU_VX:
5241 case RISCV::VSSUB_VX:
5242 // 12.2. Vector Single-Width Averaging Add and Subtract
5243 case RISCV::VAADDU_VX:
5244 case RISCV::VAADD_VX:
5245 case RISCV::VASUBU_VX:
5246 case RISCV::VASUB_VX:
5247 // 12.3. Vector Single-Width Fractional Multiply with Rounding and Saturation
5248 case RISCV::VSMUL_VX:
5249 // 16.1. Integer Scalar Move Instructions
5250 case RISCV::VMV_S_X:
5251 // Zvbb
5252 case RISCV::VANDN_VX:
5253 return 1U << Log2SEW;
5254 }
5255}
5256
5257unsigned RISCV::getRVVMCOpcode(unsigned RVVPseudoOpcode) {
5259 RISCVVPseudosTable::getPseudoInfo(RVVPseudoOpcode);
5260 if (!RVV)
5261 return 0;
5262 return RVV->BaseInstr;
5263}
5264
5265unsigned RISCV::getDestLog2EEW(const MCInstrDesc &Desc, unsigned Log2SEW) {
5266 unsigned DestEEW =
5268 // EEW = 1
5269 if (DestEEW == 0)
5270 return 0;
5271 // EEW = SEW * n
5272 unsigned Scaled = Log2SEW + (DestEEW - 1);
5273 assert(Scaled >= 3 && Scaled <= 6);
5274 return Scaled;
5275}
5276
5277static std::optional<int64_t> getEffectiveImm(const MachineOperand &MO) {
5278 assert(MO.isImm() || MO.getReg().isVirtual());
5279 if (MO.isImm())
5280 return MO.getImm();
5281 const MachineInstr *Def =
5282 MO.getParent()->getMF()->getRegInfo().getVRegDef(MO.getReg());
5283 int64_t Imm;
5284 if (isLoadImm(Def, Imm))
5285 return Imm;
5286 return std::nullopt;
5287}
5288
5289/// Given two VL operands, do we know that LHS <= RHS? Must be used in SSA form.
5291 assert((LHS.isImm() || LHS.getParent()->getMF()->getRegInfo().isSSA()) &&
5292 (RHS.isImm() || RHS.getParent()->getMF()->getRegInfo().isSSA()));
5293 if (LHS.isReg() && RHS.isReg() && LHS.getReg().isVirtual() &&
5294 LHS.getReg() == RHS.getReg())
5295 return true;
5296 if (RHS.isImm() && RHS.getImm() == RISCV::VLMaxSentinel)
5297 return true;
5298 if (LHS.isImm() && LHS.getImm() == 0)
5299 return true;
5300 if (LHS.isImm() && LHS.getImm() == RISCV::VLMaxSentinel)
5301 return false;
5302 std::optional<int64_t> LHSImm = getEffectiveImm(LHS),
5303 RHSImm = getEffectiveImm(RHS);
5304 if (!LHSImm || !RHSImm)
5305 return false;
5306 return LHSImm <= RHSImm;
5307}
5308
5309namespace {
5310class RISCVPipelinerLoopInfo : public TargetInstrInfo::PipelinerLoopInfo {
5311 const MachineInstr *LHS;
5312 const MachineInstr *RHS;
5314
5315public:
5316 RISCVPipelinerLoopInfo(const MachineInstr *LHS, const MachineInstr *RHS,
5318 : LHS(LHS), RHS(RHS), Cond(Cond.begin(), Cond.end()) {}
5319
5320 bool shouldIgnoreForPipelining(const MachineInstr *MI) const override {
5321 // Make the instructions for loop control be placed in stage 0.
5322 // The predecessors of LHS/RHS are considered by the caller.
5323 if (LHS && MI == LHS)
5324 return true;
5325 if (RHS && MI == RHS)
5326 return true;
5327 return false;
5328 }
5329
5330 std::optional<bool> createTripCountGreaterCondition(
5331 int TC, MachineBasicBlock &MBB,
5332 SmallVectorImpl<MachineOperand> &CondParam) override {
5333 // A branch instruction will be inserted as "if (Cond) goto epilogue".
5334 // Cond is normalized for such use.
5335 // The predecessors of the branch are assumed to have already been inserted.
5336 CondParam = Cond;
5337 return {};
5338 }
5339
5340 void setPreheader(MachineBasicBlock *NewPreheader) override {}
5341
5342 void adjustTripCount(int TripCountAdjust) override {}
5343};
5344} // namespace
5345
5346std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
5348 MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
5350 if (analyzeBranch(*LoopBB, TBB, FBB, Cond, /*AllowModify=*/false))
5351 return nullptr;
5352
5353 // Infinite loops are not supported
5354 if (TBB == LoopBB && FBB == LoopBB)
5355 return nullptr;
5356
5357 // Must be conditional branch
5358 if (FBB == nullptr)
5359 return nullptr;
5360
5361 assert((TBB == LoopBB || FBB == LoopBB) &&
5362 "The Loop must be a single-basic-block loop");
5363
5364 // Normalization for createTripCountGreaterCondition()
5365 if (TBB == LoopBB)
5367
5368 const MachineRegisterInfo &MRI = LoopBB->getParent()->getRegInfo();
5369 auto FindRegDef = [&MRI](MachineOperand &Op) -> const MachineInstr * {
5370 if (!Op.isReg())
5371 return nullptr;
5372 Register Reg = Op.getReg();
5373 if (!Reg.isVirtual())
5374 return nullptr;
5375 return MRI.getVRegDef(Reg);
5376 };
5377
5378 const MachineInstr *LHS = FindRegDef(Cond[1]);
5379 const MachineInstr *RHS = FindRegDef(Cond[2]);
5380 if (LHS && LHS->isPHI())
5381 return nullptr;
5382 if (RHS && RHS->isPHI())
5383 return nullptr;
5384
5385 return std::make_unique<RISCVPipelinerLoopInfo>(LHS, RHS, Cond);
5386}
5387
5388// FIXME: We should remove this if we have a default generic scheduling model.
5390 unsigned RVVMCOpcode = RISCV::getRVVMCOpcode(Opc);
5391 Opc = RVVMCOpcode ? RVVMCOpcode : Opc;
5392 switch (Opc) {
5393 default:
5394 return false;
5395 // Integer div/rem.
5396 case RISCV::DIV:
5397 case RISCV::DIVW:
5398 case RISCV::DIVU:
5399 case RISCV::DIVUW:
5400 case RISCV::REM:
5401 case RISCV::REMW:
5402 case RISCV::REMU:
5403 case RISCV::REMUW:
5404 // Floating-point div/sqrt.
5405 case RISCV::FDIV_H:
5406 case RISCV::FDIV_S:
5407 case RISCV::FDIV_D:
5408 case RISCV::FDIV_H_INX:
5409 case RISCV::FDIV_S_INX:
5410 case RISCV::FDIV_D_INX:
5411 case RISCV::FDIV_D_IN32X:
5412 case RISCV::FSQRT_H:
5413 case RISCV::FSQRT_S:
5414 case RISCV::FSQRT_D:
5415 case RISCV::FSQRT_H_INX:
5416 case RISCV::FSQRT_S_INX:
5417 case RISCV::FSQRT_D_INX:
5418 case RISCV::FSQRT_D_IN32X:
5419 // Vector integer div/rem
5420 case RISCV::VDIV_VV:
5421 case RISCV::VDIV_VX:
5422 case RISCV::VDIVU_VV:
5423 case RISCV::VDIVU_VX:
5424 case RISCV::VREM_VV:
5425 case RISCV::VREM_VX:
5426 case RISCV::VREMU_VV:
5427 case RISCV::VREMU_VX:
5428 // Vector floating-point div/sqrt.
5429 case RISCV::VFDIV_VV:
5430 case RISCV::VFDIV_VF:
5431 case RISCV::VFRDIV_VF:
5432 case RISCV::VFSQRT_V:
5433 case RISCV::VFRSQRT7_V:
5434 return true;
5435 }
5436}
5437
5438bool RISCVInstrInfo::isVRegCopy(const MachineInstr *MI, unsigned LMul) const {
5439 if (MI->getOpcode() != TargetOpcode::COPY)
5440 return false;
5441 const MachineRegisterInfo &MRI = MI->getMF()->getRegInfo();
5443
5444 Register DstReg = MI->getOperand(0).getReg();
5445 const TargetRegisterClass *RC = DstReg.isVirtual()
5446 ? MRI.getRegClass(DstReg)
5447 : TRI->getMinimalPhysRegClass(DstReg);
5448
5450 return false;
5451
5452 if (!LMul)
5453 return true;
5454
5455 // TODO: Perhaps we could distinguish segment register classes (e.g. VRN3M2)
5456 // in the future.
5457 auto [RCLMul, RCFractional] =
5459 return (!RCFractional && LMul == RCLMul) || (RCFractional && LMul == 1);
5460}
5461
5463 if (MI.memoperands_empty())
5464 return false;
5465
5466 MachineMemOperand *MMO = *(MI.memoperands_begin());
5467 if (!MMO->isNonTemporal())
5468 return false;
5469
5470 return true;
5471}
5472
5474 const MachineBasicBlock::iterator &To) {
5475 assert(To == From.getParent()->end() || From.getParent() == To->getParent());
5476 SmallVector<Register> PhysUses, PhysDefs;
5477 for (const MachineOperand &MO : From.all_uses())
5478 if (MO.getReg().isPhysical())
5479 PhysUses.push_back(MO.getReg());
5480 for (const MachineOperand &MO : From.all_defs())
5481 if (MO.getReg().isPhysical())
5482 PhysDefs.push_back(MO.getReg());
5483 bool SawStore = false;
5484 for (auto II = std::next(From.getIterator()); II != To; II++) {
5485 for (Register PhysReg : PhysUses)
5486 if (II->definesRegister(PhysReg, nullptr))
5487 return false;
5488 for (Register PhysReg : PhysDefs)
5489 if (II->definesRegister(PhysReg, nullptr) ||
5490 II->readsRegister(PhysReg, nullptr))
5491 return false;
5492 if (II->mayStore()) {
5493 SawStore = true;
5494 break;
5495 }
5496 }
5497 return From.isSafeToMove(SawStore);
5498}
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:218
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
static bool isSafeToMove(const MachineInstr &From, const MachineBasicBlock::iterator &To)
Return true if moving From down to To won't cause any physical register reads or writes to be clobber...
MachineInstr * convertToThreeAddress(MachineInstr &MI, LiveVariables *LV, LiveIntervals *LIS) const override
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
std::optional< std::unique_ptr< outliner::OutlinedFunction > > getOutliningCandidateInfo(const MachineModuleInfo &MMI, std::vector< outliner::Candidate > &RepeatedSequenceLocs, unsigned MinRepeats) const override
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
void genAlternativeCodeSequence(MachineInstr &Root, unsigned Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs, DenseMap< Register, unsigned > &InstrIdxForVirtReg) const override
void movImm(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, Register DstReg, uint64_t Val, MachineInstr::MIFlag Flag=MachineInstr::NoFlags, bool DstRenamable=false, bool DstIsDead=false) const
MachineInstr * emitLdStWithAddr(MachineInstr &MemI, const ExtAddrMode &AM) const override
void mulImm(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator II, const DebugLoc &DL, Register DestReg, uint32_t Amt, MachineInstr::MIFlag Flag) const
Generate code to multiply the value in DestReg by Amt - handles all the common optimizations for this...
static bool isPairableLdStInstOpc(unsigned Opc)
Return true if pairing the given load or store may be paired with another.
RISCVInstrInfo(const RISCVSubtarget &STI)
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DstReg, int FrameIndex, const TargetRegisterClass *RC, Register VReg, unsigned SubReg=0, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
bool isFunctionSafeToOutlineFrom(MachineFunction &MF, bool OutlineFromLinkOnceODRs) const override
std::unique_ptr< TargetInstrInfo::PipelinerLoopInfo > analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const override
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &dl, int *BytesAdded=nullptr) const override
bool hasReassociableSibling(const MachineInstr &Inst, bool &Commuted) const override
static bool isLdStSafeToPair(const MachineInstr &LdSt, const TargetRegisterInfo *TRI)
void copyPhysRegVector(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, MCRegister DstReg, MCRegister SrcReg, bool KillSrc, const TargetRegisterClass *RegClass) const
bool isReMaterializableImpl(const MachineInstr &MI) const override
MachineInstr * optimizeSelect(MachineInstr &MI, SmallPtrSetImpl< MachineInstr * > &SeenMIs, bool) const override
bool isVRegCopy(const MachineInstr *MI, unsigned LMul=0) const
Return true if MI is a COPY to a vector register of a specific LMul, or any kind of vector registers ...
bool canFoldIntoAddrMode(const MachineInstr &MemI, Register Reg, const MachineInstr &AddrI, ExtAddrMode &AM) const override
void insertIndirectBranch(MachineBasicBlock &MBB, MachineBasicBlock &NewDestBB, MachineBasicBlock &RestoreBB, const DebugLoc &DL, int64_t BrOffset, RegScavenger *RS) const override
bool isAsCheapAsAMove(const MachineInstr &MI) const override
bool verifyInstruction(const MachineInstr &MI, StringRef &ErrInfo) const override
bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt, const MachineOperand *&BaseOp, int64_t &Offset, LocationSize &Width, const TargetRegisterInfo *TRI) const
unsigned getTailDuplicateSize(CodeGenOptLevel OptLevel) const override
void getReassociateOperandIndices(const MachineInstr &Root, unsigned Pattern, std::array< unsigned, 5 > &OperandIndices) const override
const RISCVSubtarget & STI
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
std::optional< unsigned > getInverseOpcode(unsigned Opcode) const override
bool simplifyInstruction(MachineInstr &MI) const override
ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override
outliner::InstrType getOutliningTypeImpl(const MachineModuleInfo &MMI, MachineBasicBlock::iterator &MBBI, unsigned Flags) const override
MachineTraceStrategy getMachineCombinerTraceStrategy() const override
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
std::optional< RegImmPair > isAddImmediate(const MachineInstr &MI, Register Reg) const override
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
ArrayRef< std::pair< MachineMemOperand::Flags, const char * > > getSerializableMachineMemOperandTargetFlags() const override
MCInst getNop() const override
bool analyzeCandidate(outliner::Candidate &C) const
bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB, unsigned &Flags) const override
bool getMemOperandsWithOffsetWidth(const MachineInstr &MI, SmallVectorImpl< const MachineOperand * > &BaseOps, int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width, const TargetRegisterInfo *TRI) const override
void buildOutlinedFrame(MachineBasicBlock &MBB, MachineFunction &MF, const outliner::OutlinedFunction &OF) const override
bool requiresNTLHint(const MachineInstr &MI) const
Return true if the instruction requires an NTL hint to be emitted.
void finalizeInsInstrs(MachineInstr &Root, unsigned &Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs) const override
std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override
MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const override
bool hasReassociableOperands(const MachineInstr &Inst, const MachineBasicBlock *MBB) const override
MachineBasicBlock * getBranchDestBlock(const MachineInstr &MI) const override
std::string createMIROperandComment(const MachineInstr &MI, const MachineOperand &Op, unsigned OpIdx, const TargetRegisterInfo *TRI) const override
bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, Register DstReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const override
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
MachineBasicBlock::iterator insertOutlinedCall(Module &M, MachineBasicBlock &MBB, MachineBasicBlock::iterator &It, MachineFunction &MF, outliner::Candidate &C) const override
MachineInstr * foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, ArrayRef< unsigned > Ops, int FrameIndex, MachineInstr *&CopyMI, LiveIntervals *LIS=nullptr, VirtRegMap *VRM=nullptr) const override
bool isBranchOffsetInRange(unsigned BranchOpc, int64_t BrOffset) const override
static RISCVCC::CondCode getCondFromBranchOpc(unsigned Opc)
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:315
@ Offset
Definition DWP.cpp:557
@ 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:1738
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:2553
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:2191
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.