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