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