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