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