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