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 case RISCV::QC_E_LB:
917 return RISCV::PseudoCCQC_E_LB;
918 case RISCV::QC_E_LBU:
919 return RISCV::PseudoCCQC_E_LBU;
920 case RISCV::QC_E_LH:
921 return RISCV::PseudoCCQC_E_LH;
922 case RISCV::QC_E_LHU:
923 return RISCV::PseudoCCQC_E_LHU;
924 case RISCV::QC_E_LW:
925 return RISCV::PseudoCCQC_E_LW;
926 default:
927 return 0;
928 }
929}
930
934 LiveIntervals *LIS) const {
935 // For now, only handle RISCV::PseudoCCMOVGPR.
936 if (MI.getOpcode() != RISCV::PseudoCCMOVGPR)
937 return nullptr;
938
939 unsigned PredOpc = getLoadPredicatedOpcode(LoadMI.getOpcode());
940
941 if (!STI.hasShortForwardBranchILoad() || !PredOpc)
942 return nullptr;
943
945 if (Ops.size() != 1 || (Ops[0] != 4 && Ops[0] != 5))
946 return nullptr;
947
948 bool Invert = Ops[0] == 5;
949 const MachineOperand &FalseReg = MI.getOperand(!Invert ? 5 : 4);
950 Register DestReg = MI.getOperand(0).getReg();
951 const TargetRegisterClass *PreviousClass = MRI.getRegClass(FalseReg.getReg());
952 if (!MRI.constrainRegClass(DestReg, PreviousClass))
953 return nullptr;
954
955 // Create a new predicated version of DefMI.
956 MachineInstrBuilder NewMI = BuildMI(*MI.getParent(), InsertPt,
957 MI.getDebugLoc(), get(PredOpc), DestReg)
958 .add({MI.getOperand(1), MI.getOperand(2)});
959
960 // Add condition code, inverting if necessary.
961 auto CC = static_cast<RISCVCC::CondCode>(MI.getOperand(3).getImm());
962 if (!Invert)
964 NewMI.addImm(CC);
965
966 // Copy the false register.
967 NewMI.add(FalseReg);
968
969 // Copy all the DefMI operands.
970 const MCInstrDesc &DefDesc = LoadMI.getDesc();
971 for (unsigned i = 1, e = DefDesc.getNumOperands(); i != e; ++i)
972 NewMI.add(LoadMI.getOperand(i));
973
974 NewMI.cloneMemRefs(LoadMI);
975 return NewMI;
976}
977
980 const DebugLoc &DL, Register DstReg, uint64_t Val,
981 MachineInstr::MIFlag Flag, bool DstRenamable,
982 bool DstIsDead) const {
983 Register SrcReg = RISCV::X0;
984
985 // For RV32, allow a sign or unsigned 32 bit value.
986 if (!STI.is64Bit() && !isInt<32>(Val)) {
987 // If have a uimm32 it will still fit in a register so we can allow it.
988 if (!isUInt<32>(Val))
989 report_fatal_error("Should only materialize 32-bit constants for RV32");
990
991 // Sign extend for generateInstSeq.
992 Val = SignExtend64<32>(Val);
993 }
994
996 assert(!Seq.empty());
997
998 bool SrcRenamable = false;
999 unsigned Num = 0;
1000
1001 for (const RISCVMatInt::Inst &Inst : Seq) {
1002 bool LastItem = ++Num == Seq.size();
1003 unsigned DstRegState = getDeadRegState(DstIsDead && LastItem) |
1004 getRenamableRegState(DstRenamable);
1005 unsigned SrcRegState = getKillRegState(SrcReg != RISCV::X0) |
1006 getRenamableRegState(SrcRenamable);
1007 switch (Inst.getOpndKind()) {
1008 case RISCVMatInt::Imm:
1009 BuildMI(MBB, MBBI, DL, get(Inst.getOpcode()))
1010 .addReg(DstReg, RegState::Define | DstRegState)
1011 .addImm(Inst.getImm())
1012 .setMIFlag(Flag);
1013 break;
1014 case RISCVMatInt::RegX0:
1015 BuildMI(MBB, MBBI, DL, get(Inst.getOpcode()))
1016 .addReg(DstReg, RegState::Define | DstRegState)
1017 .addReg(SrcReg, SrcRegState)
1018 .addReg(RISCV::X0)
1019 .setMIFlag(Flag);
1020 break;
1022 BuildMI(MBB, MBBI, DL, get(Inst.getOpcode()))
1023 .addReg(DstReg, RegState::Define | DstRegState)
1024 .addReg(SrcReg, SrcRegState)
1025 .addReg(SrcReg, SrcRegState)
1026 .setMIFlag(Flag);
1027 break;
1029 BuildMI(MBB, MBBI, DL, get(Inst.getOpcode()))
1030 .addReg(DstReg, RegState::Define | DstRegState)
1031 .addReg(SrcReg, SrcRegState)
1032 .addImm(Inst.getImm())
1033 .setMIFlag(Flag);
1034 break;
1035 }
1036
1037 // Only the first instruction has X0 as its source.
1038 SrcReg = DstReg;
1039 SrcRenamable = DstRenamable;
1040 }
1041}
1042
1044 switch (Opc) {
1045 default:
1046 return RISCVCC::COND_INVALID;
1047 case RISCV::BEQ:
1048 case RISCV::BEQI:
1049 case RISCV::CV_BEQIMM:
1050 case RISCV::QC_BEQI:
1051 case RISCV::QC_E_BEQI:
1052 case RISCV::NDS_BBC:
1053 case RISCV::NDS_BEQC:
1054 return RISCVCC::COND_EQ;
1055 case RISCV::BNE:
1056 case RISCV::BNEI:
1057 case RISCV::QC_BNEI:
1058 case RISCV::QC_E_BNEI:
1059 case RISCV::CV_BNEIMM:
1060 case RISCV::NDS_BBS:
1061 case RISCV::NDS_BNEC:
1062 return RISCVCC::COND_NE;
1063 case RISCV::BLT:
1064 case RISCV::QC_BLTI:
1065 case RISCV::QC_E_BLTI:
1066 return RISCVCC::COND_LT;
1067 case RISCV::BGE:
1068 case RISCV::QC_BGEI:
1069 case RISCV::QC_E_BGEI:
1070 return RISCVCC::COND_GE;
1071 case RISCV::BLTU:
1072 case RISCV::QC_BLTUI:
1073 case RISCV::QC_E_BLTUI:
1074 return RISCVCC::COND_LTU;
1075 case RISCV::BGEU:
1076 case RISCV::QC_BGEUI:
1077 case RISCV::QC_E_BGEUI:
1078 return RISCVCC::COND_GEU;
1079 }
1080}
1081
1083 int64_t C1) {
1084 switch (CC) {
1085 default:
1086 llvm_unreachable("Unexpected CC");
1087 case RISCVCC::COND_EQ:
1088 return C0 == C1;
1089 case RISCVCC::COND_NE:
1090 return C0 != C1;
1091 case RISCVCC::COND_LT:
1092 return C0 < C1;
1093 case RISCVCC::COND_GE:
1094 return C0 >= C1;
1095 case RISCVCC::COND_LTU:
1096 return (uint64_t)C0 < (uint64_t)C1;
1097 case RISCVCC::COND_GEU:
1098 return (uint64_t)C0 >= (uint64_t)C1;
1099 }
1100}
1101
1102// The contents of values added to Cond are not examined outside of
1103// RISCVInstrInfo, giving us flexibility in what to push to it. For RISCV, we
1104// push BranchOpcode, Reg1, Reg2.
1107 // Block ends with fall-through condbranch.
1108 assert(LastInst.getDesc().isConditionalBranch() &&
1109 "Unknown conditional branch");
1110 Target = LastInst.getOperand(2).getMBB();
1111 Cond.push_back(MachineOperand::CreateImm(LastInst.getOpcode()));
1112 Cond.push_back(LastInst.getOperand(0));
1113 Cond.push_back(LastInst.getOperand(1));
1114}
1115
1116static unsigned getInverseXqcicmOpcode(unsigned Opcode) {
1117 switch (Opcode) {
1118 default:
1119 llvm_unreachable("Unexpected Opcode");
1120 case RISCV::QC_MVEQ:
1121 return RISCV::QC_MVNE;
1122 case RISCV::QC_MVNE:
1123 return RISCV::QC_MVEQ;
1124 case RISCV::QC_MVLT:
1125 return RISCV::QC_MVGE;
1126 case RISCV::QC_MVGE:
1127 return RISCV::QC_MVLT;
1128 case RISCV::QC_MVLTU:
1129 return RISCV::QC_MVGEU;
1130 case RISCV::QC_MVGEU:
1131 return RISCV::QC_MVLTU;
1132 case RISCV::QC_MVEQI:
1133 return RISCV::QC_MVNEI;
1134 case RISCV::QC_MVNEI:
1135 return RISCV::QC_MVEQI;
1136 case RISCV::QC_MVLTI:
1137 return RISCV::QC_MVGEI;
1138 case RISCV::QC_MVGEI:
1139 return RISCV::QC_MVLTI;
1140 case RISCV::QC_MVLTUI:
1141 return RISCV::QC_MVGEUI;
1142 case RISCV::QC_MVGEUI:
1143 return RISCV::QC_MVLTUI;
1144 }
1145}
1146
1147unsigned RISCVCC::getBrCond(RISCVCC::CondCode CC, unsigned SelectOpc) {
1148 switch (SelectOpc) {
1149 default:
1150 switch (CC) {
1151 default:
1152 llvm_unreachable("Unexpected condition code!");
1153 case RISCVCC::COND_EQ:
1154 return RISCV::BEQ;
1155 case RISCVCC::COND_NE:
1156 return RISCV::BNE;
1157 case RISCVCC::COND_LT:
1158 return RISCV::BLT;
1159 case RISCVCC::COND_GE:
1160 return RISCV::BGE;
1161 case RISCVCC::COND_LTU:
1162 return RISCV::BLTU;
1163 case RISCVCC::COND_GEU:
1164 return RISCV::BGEU;
1165 }
1166 break;
1167 case RISCV::Select_GPR_Using_CC_Imm5_Zibi:
1168 switch (CC) {
1169 default:
1170 llvm_unreachable("Unexpected condition code!");
1171 case RISCVCC::COND_EQ:
1172 return RISCV::BEQI;
1173 case RISCVCC::COND_NE:
1174 return RISCV::BNEI;
1175 }
1176 break;
1177 case RISCV::Select_GPR_Using_CC_SImm5_CV:
1178 switch (CC) {
1179 default:
1180 llvm_unreachable("Unexpected condition code!");
1181 case RISCVCC::COND_EQ:
1182 return RISCV::CV_BEQIMM;
1183 case RISCVCC::COND_NE:
1184 return RISCV::CV_BNEIMM;
1185 }
1186 break;
1187 case RISCV::Select_GPRNoX0_Using_CC_SImm5NonZero_QC:
1188 switch (CC) {
1189 default:
1190 llvm_unreachable("Unexpected condition code!");
1191 case RISCVCC::COND_EQ:
1192 return RISCV::QC_BEQI;
1193 case RISCVCC::COND_NE:
1194 return RISCV::QC_BNEI;
1195 case RISCVCC::COND_LT:
1196 return RISCV::QC_BLTI;
1197 case RISCVCC::COND_GE:
1198 return RISCV::QC_BGEI;
1199 }
1200 break;
1201 case RISCV::Select_GPRNoX0_Using_CC_UImm5NonZero_QC:
1202 switch (CC) {
1203 default:
1204 llvm_unreachable("Unexpected condition code!");
1205 case RISCVCC::COND_LTU:
1206 return RISCV::QC_BLTUI;
1207 case RISCVCC::COND_GEU:
1208 return RISCV::QC_BGEUI;
1209 }
1210 break;
1211 case RISCV::Select_GPRNoX0_Using_CC_SImm16NonZero_QC:
1212 switch (CC) {
1213 default:
1214 llvm_unreachable("Unexpected condition code!");
1215 case RISCVCC::COND_EQ:
1216 return RISCV::QC_E_BEQI;
1217 case RISCVCC::COND_NE:
1218 return RISCV::QC_E_BNEI;
1219 case RISCVCC::COND_LT:
1220 return RISCV::QC_E_BLTI;
1221 case RISCVCC::COND_GE:
1222 return RISCV::QC_E_BGEI;
1223 }
1224 break;
1225 case RISCV::Select_GPRNoX0_Using_CC_UImm16NonZero_QC:
1226 switch (CC) {
1227 default:
1228 llvm_unreachable("Unexpected condition code!");
1229 case RISCVCC::COND_LTU:
1230 return RISCV::QC_E_BLTUI;
1231 case RISCVCC::COND_GEU:
1232 return RISCV::QC_E_BGEUI;
1233 }
1234 break;
1235 case RISCV::Select_GPR_Using_CC_UImmLog2XLen_NDS:
1236 switch (CC) {
1237 default:
1238 llvm_unreachable("Unexpected condition code!");
1239 case RISCVCC::COND_EQ:
1240 return RISCV::NDS_BBC;
1241 case RISCVCC::COND_NE:
1242 return RISCV::NDS_BBS;
1243 }
1244 break;
1245 case RISCV::Select_GPR_Using_CC_UImm7_NDS:
1246 switch (CC) {
1247 default:
1248 llvm_unreachable("Unexpected condition code!");
1249 case RISCVCC::COND_EQ:
1250 return RISCV::NDS_BEQC;
1251 case RISCVCC::COND_NE:
1252 return RISCV::NDS_BNEC;
1253 }
1254 break;
1255 }
1256}
1257
1259 switch (CC) {
1260 default:
1261 llvm_unreachable("Unrecognized conditional branch");
1262 case RISCVCC::COND_EQ:
1263 return RISCVCC::COND_NE;
1264 case RISCVCC::COND_NE:
1265 return RISCVCC::COND_EQ;
1266 case RISCVCC::COND_LT:
1267 return RISCVCC::COND_GE;
1268 case RISCVCC::COND_GE:
1269 return RISCVCC::COND_LT;
1270 case RISCVCC::COND_LTU:
1271 return RISCVCC::COND_GEU;
1272 case RISCVCC::COND_GEU:
1273 return RISCVCC::COND_LTU;
1274 }
1275}
1276
1279 MachineBasicBlock *&FBB,
1281 bool AllowModify) const {
1282 TBB = FBB = nullptr;
1283 Cond.clear();
1284
1285 // If the block has no terminators, it just falls into the block after it.
1286 MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
1287 if (I == MBB.end() || !isUnpredicatedTerminator(*I))
1288 return false;
1289
1290 // Count the number of terminators and find the first unconditional or
1291 // indirect branch.
1292 MachineBasicBlock::iterator FirstUncondOrIndirectBr = MBB.end();
1293 int NumTerminators = 0;
1294 for (auto J = I.getReverse(); J != MBB.rend() && isUnpredicatedTerminator(*J);
1295 J++) {
1296 NumTerminators++;
1297 if (J->getDesc().isUnconditionalBranch() ||
1298 J->getDesc().isIndirectBranch()) {
1299 FirstUncondOrIndirectBr = J.getReverse();
1300 }
1301 }
1302
1303 // If AllowModify is true, we can erase any terminators after
1304 // FirstUncondOrIndirectBR.
1305 if (AllowModify && FirstUncondOrIndirectBr != MBB.end()) {
1306 while (std::next(FirstUncondOrIndirectBr) != MBB.end()) {
1307 std::next(FirstUncondOrIndirectBr)->eraseFromParent();
1308 NumTerminators--;
1309 }
1310 I = FirstUncondOrIndirectBr;
1311 }
1312
1313 // We can't handle blocks that end in an indirect branch.
1314 if (I->getDesc().isIndirectBranch())
1315 return true;
1316
1317 // We can't handle Generic branch opcodes from Global ISel.
1318 if (I->isPreISelOpcode())
1319 return true;
1320
1321 // We can't handle blocks with more than 2 terminators.
1322 if (NumTerminators > 2)
1323 return true;
1324
1325 // Handle a single unconditional branch.
1326 if (NumTerminators == 1 && I->getDesc().isUnconditionalBranch()) {
1328 return false;
1329 }
1330
1331 // Handle a single conditional branch.
1332 if (NumTerminators == 1 && I->getDesc().isConditionalBranch()) {
1334 return false;
1335 }
1336
1337 // Handle a conditional branch followed by an unconditional branch.
1338 if (NumTerminators == 2 && std::prev(I)->getDesc().isConditionalBranch() &&
1339 I->getDesc().isUnconditionalBranch()) {
1340 parseCondBranch(*std::prev(I), TBB, Cond);
1341 FBB = getBranchDestBlock(*I);
1342 return false;
1343 }
1344
1345 // Otherwise, we can't handle this.
1346 return true;
1347}
1348
1350 int *BytesRemoved) const {
1351 if (BytesRemoved)
1352 *BytesRemoved = 0;
1353 MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
1354 if (I == MBB.end())
1355 return 0;
1356
1357 if (!I->getDesc().isUnconditionalBranch() &&
1358 !I->getDesc().isConditionalBranch())
1359 return 0;
1360
1361 // Remove the branch.
1362 if (BytesRemoved)
1363 *BytesRemoved += getInstSizeInBytes(*I);
1364 I->eraseFromParent();
1365
1366 I = MBB.end();
1367
1368 if (I == MBB.begin())
1369 return 1;
1370 --I;
1371 if (!I->getDesc().isConditionalBranch())
1372 return 1;
1373
1374 // Remove the branch.
1375 if (BytesRemoved)
1376 *BytesRemoved += getInstSizeInBytes(*I);
1377 I->eraseFromParent();
1378 return 2;
1379}
1380
1381// Inserts a branch into the end of the specific MachineBasicBlock, returning
1382// the number of instructions inserted.
1385 ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const {
1386 if (BytesAdded)
1387 *BytesAdded = 0;
1388
1389 // Shouldn't be a fall through.
1390 assert(TBB && "insertBranch must not be told to insert a fallthrough");
1391 assert((Cond.size() == 3 || Cond.size() == 0) &&
1392 "RISC-V branch conditions have two components!");
1393
1394 // Unconditional branch.
1395 if (Cond.empty()) {
1396 MachineInstr &MI = *BuildMI(&MBB, DL, get(RISCV::PseudoBR)).addMBB(TBB);
1397 if (BytesAdded)
1398 *BytesAdded += getInstSizeInBytes(MI);
1399 return 1;
1400 }
1401
1402 // Either a one or two-way conditional branch.
1403 MachineInstr &CondMI = *BuildMI(&MBB, DL, get(Cond[0].getImm()))
1404 .add(Cond[1])
1405 .add(Cond[2])
1406 .addMBB(TBB);
1407 if (BytesAdded)
1408 *BytesAdded += getInstSizeInBytes(CondMI);
1409
1410 // One-way conditional branch.
1411 if (!FBB)
1412 return 1;
1413
1414 // Two-way conditional branch.
1415 MachineInstr &MI = *BuildMI(&MBB, DL, get(RISCV::PseudoBR)).addMBB(FBB);
1416 if (BytesAdded)
1417 *BytesAdded += getInstSizeInBytes(MI);
1418 return 2;
1419}
1420
1422 MachineBasicBlock &DestBB,
1423 MachineBasicBlock &RestoreBB,
1424 const DebugLoc &DL, int64_t BrOffset,
1425 RegScavenger *RS) const {
1426 assert(RS && "RegScavenger required for long branching");
1427 assert(MBB.empty() &&
1428 "new block should be inserted for expanding unconditional branch");
1429 assert(MBB.pred_size() == 1);
1430 assert(RestoreBB.empty() &&
1431 "restore block should be inserted for restoring clobbered registers");
1432
1433 MachineFunction *MF = MBB.getParent();
1437
1438 if (!isInt<32>(BrOffset))
1440 "Branch offsets outside of the signed 32-bit range not supported");
1441
1442 // FIXME: A virtual register must be used initially, as the register
1443 // scavenger won't work with empty blocks (SIInstrInfo::insertIndirectBranch
1444 // uses the same workaround).
1445 Register ScratchReg = MRI.createVirtualRegister(&RISCV::GPRJALRRegClass);
1446 auto II = MBB.end();
1447 // We may also update the jump target to RestoreBB later.
1448 MachineInstr &MI = *BuildMI(MBB, II, DL, get(RISCV::PseudoJump))
1449 .addReg(ScratchReg, RegState::Define | RegState::Dead)
1450 .addMBB(&DestBB, RISCVII::MO_CALL);
1451
1452 RS->enterBasicBlockEnd(MBB);
1453 const TargetRegisterClass *RC = &RISCV::GPRRegClass;
1454 if (STI.hasStdExtZicfilp())
1455 RC = &RISCV::GPRX7RegClass;
1456 Register TmpGPR =
1457 RS->scavengeRegisterBackwards(*RC, MI.getIterator(),
1458 /*RestoreAfter=*/false, /*SpAdj=*/0,
1459 /*AllowSpill=*/false);
1460 if (TmpGPR.isValid())
1461 RS->setRegUsed(TmpGPR);
1462 else {
1463 // The case when there is no scavenged register needs special handling.
1464
1465 // Pick s11(or s1 for rve) because it doesn't make a difference.
1466 TmpGPR = STI.hasStdExtE() ? RISCV::X9 : RISCV::X27;
1467 // Force t2 if Zicfilp is on
1468 if (STI.hasStdExtZicfilp())
1469 TmpGPR = RISCV::X7;
1470
1471 int FrameIndex = RVFI->getBranchRelaxationScratchFrameIndex();
1472 if (FrameIndex == -1)
1473 report_fatal_error("underestimated function size");
1474
1475 storeRegToStackSlot(MBB, MI, TmpGPR, /*IsKill=*/true, FrameIndex,
1476 &RISCV::GPRRegClass, Register());
1477 TRI->eliminateFrameIndex(std::prev(MI.getIterator()),
1478 /*SpAdj=*/0, /*FIOperandNum=*/1);
1479
1480 MI.getOperand(1).setMBB(&RestoreBB);
1481
1482 loadRegFromStackSlot(RestoreBB, RestoreBB.end(), TmpGPR, FrameIndex,
1483 &RISCV::GPRRegClass, Register());
1484 TRI->eliminateFrameIndex(RestoreBB.back(),
1485 /*SpAdj=*/0, /*FIOperandNum=*/1);
1486 }
1487
1488 MRI.replaceRegWith(ScratchReg, TmpGPR);
1489 MRI.clearVirtRegs();
1490}
1491
1494 assert((Cond.size() == 3) && "Invalid branch condition!");
1495 switch (Cond[0].getImm()) {
1496 default:
1497 llvm_unreachable("Unknown conditional branch!");
1498 case RISCV::BEQ:
1499 Cond[0].setImm(RISCV::BNE);
1500 break;
1501 case RISCV::BEQI:
1502 Cond[0].setImm(RISCV::BNEI);
1503 break;
1504 case RISCV::BNE:
1505 Cond[0].setImm(RISCV::BEQ);
1506 break;
1507 case RISCV::BNEI:
1508 Cond[0].setImm(RISCV::BEQI);
1509 break;
1510 case RISCV::BLT:
1511 Cond[0].setImm(RISCV::BGE);
1512 break;
1513 case RISCV::BGE:
1514 Cond[0].setImm(RISCV::BLT);
1515 break;
1516 case RISCV::BLTU:
1517 Cond[0].setImm(RISCV::BGEU);
1518 break;
1519 case RISCV::BGEU:
1520 Cond[0].setImm(RISCV::BLTU);
1521 break;
1522 case RISCV::CV_BEQIMM:
1523 Cond[0].setImm(RISCV::CV_BNEIMM);
1524 break;
1525 case RISCV::CV_BNEIMM:
1526 Cond[0].setImm(RISCV::CV_BEQIMM);
1527 break;
1528 case RISCV::QC_BEQI:
1529 Cond[0].setImm(RISCV::QC_BNEI);
1530 break;
1531 case RISCV::QC_BNEI:
1532 Cond[0].setImm(RISCV::QC_BEQI);
1533 break;
1534 case RISCV::QC_BGEI:
1535 Cond[0].setImm(RISCV::QC_BLTI);
1536 break;
1537 case RISCV::QC_BLTI:
1538 Cond[0].setImm(RISCV::QC_BGEI);
1539 break;
1540 case RISCV::QC_BGEUI:
1541 Cond[0].setImm(RISCV::QC_BLTUI);
1542 break;
1543 case RISCV::QC_BLTUI:
1544 Cond[0].setImm(RISCV::QC_BGEUI);
1545 break;
1546 case RISCV::QC_E_BEQI:
1547 Cond[0].setImm(RISCV::QC_E_BNEI);
1548 break;
1549 case RISCV::QC_E_BNEI:
1550 Cond[0].setImm(RISCV::QC_E_BEQI);
1551 break;
1552 case RISCV::QC_E_BGEI:
1553 Cond[0].setImm(RISCV::QC_E_BLTI);
1554 break;
1555 case RISCV::QC_E_BLTI:
1556 Cond[0].setImm(RISCV::QC_E_BGEI);
1557 break;
1558 case RISCV::QC_E_BGEUI:
1559 Cond[0].setImm(RISCV::QC_E_BLTUI);
1560 break;
1561 case RISCV::QC_E_BLTUI:
1562 Cond[0].setImm(RISCV::QC_E_BGEUI);
1563 break;
1564 case RISCV::NDS_BBC:
1565 Cond[0].setImm(RISCV::NDS_BBS);
1566 break;
1567 case RISCV::NDS_BBS:
1568 Cond[0].setImm(RISCV::NDS_BBC);
1569 break;
1570 case RISCV::NDS_BEQC:
1571 Cond[0].setImm(RISCV::NDS_BNEC);
1572 break;
1573 case RISCV::NDS_BNEC:
1574 Cond[0].setImm(RISCV::NDS_BEQC);
1575 break;
1576 }
1577
1578 return false;
1579}
1580
1581// Return true if the instruction is a load immediate instruction (i.e.
1582// ADDI x0, imm).
1583static bool isLoadImm(const MachineInstr *MI, int64_t &Imm) {
1584 if (MI->getOpcode() == RISCV::ADDI && MI->getOperand(1).isReg() &&
1585 MI->getOperand(1).getReg() == RISCV::X0) {
1586 Imm = MI->getOperand(2).getImm();
1587 return true;
1588 }
1589 return false;
1590}
1591
1593 const MachineOperand &Op, int64_t &Imm) {
1594 // Either a load from immediate instruction or X0.
1595 if (!Op.isReg())
1596 return false;
1597
1598 Register Reg = Op.getReg();
1599 if (Reg == RISCV::X0) {
1600 Imm = 0;
1601 return true;
1602 }
1603 return Reg.isVirtual() && isLoadImm(MRI.getVRegDef(Reg), Imm);
1604}
1605
1607 bool IsSigned = false;
1608 bool IsEquality = false;
1609 switch (MI.getOpcode()) {
1610 default:
1611 return false;
1612 case RISCV::BEQ:
1613 case RISCV::BNE:
1614 IsEquality = true;
1615 break;
1616 case RISCV::BGE:
1617 case RISCV::BLT:
1618 IsSigned = true;
1619 break;
1620 case RISCV::BGEU:
1621 case RISCV::BLTU:
1622 break;
1623 }
1624
1625 MachineBasicBlock *MBB = MI.getParent();
1626 MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
1627
1628 const MachineOperand &LHS = MI.getOperand(0);
1629 const MachineOperand &RHS = MI.getOperand(1);
1630 MachineBasicBlock *TBB = MI.getOperand(2).getMBB();
1631
1632 RISCVCC::CondCode CC = getCondFromBranchOpc(MI.getOpcode());
1634
1635 // Canonicalize conditional branches which can be constant folded into
1636 // beqz or bnez. We can't modify the CFG here.
1637 int64_t C0, C1;
1638 if (isFromLoadImm(MRI, LHS, C0) && isFromLoadImm(MRI, RHS, C1)) {
1639 unsigned NewOpc = evaluateCondBranch(CC, C0, C1) ? RISCV::BEQ : RISCV::BNE;
1640 // Build the new branch and remove the old one.
1641 BuildMI(*MBB, MI, MI.getDebugLoc(), get(NewOpc))
1642 .addReg(RISCV::X0)
1643 .addReg(RISCV::X0)
1644 .addMBB(TBB);
1645 MI.eraseFromParent();
1646 return true;
1647 }
1648
1649 if (IsEquality)
1650 return false;
1651
1652 // For two constants C0 and C1 from
1653 // ```
1654 // li Y, C0
1655 // li Z, C1
1656 // ```
1657 // 1. if C1 = C0 + 1
1658 // we can turn:
1659 // (a) blt Y, X -> bge X, Z
1660 // (b) bge Y, X -> blt X, Z
1661 //
1662 // 2. if C1 = C0 - 1
1663 // we can turn:
1664 // (a) blt X, Y -> bge Z, X
1665 // (b) bge X, Y -> blt Z, X
1666 //
1667 // To make sure this optimization is really beneficial, we only
1668 // optimize for cases where Y had only one use (i.e. only used by the branch).
1669 // Try to find the register for constant Z; return
1670 // invalid register otherwise.
1671 auto searchConst = [&](int64_t C1) -> Register {
1673 auto DefC1 = std::find_if(++II, E, [&](const MachineInstr &I) -> bool {
1674 int64_t Imm;
1675 return isLoadImm(&I, Imm) && Imm == C1 &&
1676 I.getOperand(0).getReg().isVirtual();
1677 });
1678 if (DefC1 != E)
1679 return DefC1->getOperand(0).getReg();
1680
1681 return Register();
1682 };
1683
1684 unsigned NewOpc = RISCVCC::getBrCond(getInverseBranchCondition(CC));
1685
1686 // Might be case 1.
1687 // Don't change 0 to 1 since we can use x0.
1688 // For unsigned cases changing -1U to 0 would be incorrect.
1689 // The incorrect case for signed would be INT_MAX, but isFromLoadImm can't
1690 // return that.
1691 if (isFromLoadImm(MRI, LHS, C0) && C0 != 0 && LHS.getReg().isVirtual() &&
1692 MRI.hasOneUse(LHS.getReg()) && (IsSigned || C0 != -1)) {
1693 assert(isInt<12>(C0) && "Unexpected immediate");
1694 if (Register RegZ = searchConst(C0 + 1)) {
1695 BuildMI(*MBB, MI, MI.getDebugLoc(), get(NewOpc))
1696 .add(RHS)
1697 .addReg(RegZ)
1698 .addMBB(TBB);
1699 // We might extend the live range of Z, clear its kill flag to
1700 // account for this.
1701 MRI.clearKillFlags(RegZ);
1702 MI.eraseFromParent();
1703 return true;
1704 }
1705 }
1706
1707 // Might be case 2.
1708 // For signed cases we don't want to change 0 since we can use x0.
1709 // For unsigned cases changing 0 to -1U would be incorrect.
1710 // The incorrect case for signed would be INT_MIN, but isFromLoadImm can't
1711 // return that.
1712 if (isFromLoadImm(MRI, RHS, C0) && C0 != 0 && RHS.getReg().isVirtual() &&
1713 MRI.hasOneUse(RHS.getReg())) {
1714 assert(isInt<12>(C0) && "Unexpected immediate");
1715 if (Register RegZ = searchConst(C0 - 1)) {
1716 BuildMI(*MBB, MI, MI.getDebugLoc(), get(NewOpc))
1717 .addReg(RegZ)
1718 .add(LHS)
1719 .addMBB(TBB);
1720 // We might extend the live range of Z, clear its kill flag to
1721 // account for this.
1722 MRI.clearKillFlags(RegZ);
1723 MI.eraseFromParent();
1724 return true;
1725 }
1726 }
1727
1728 return false;
1729}
1730
1733 assert(MI.getDesc().isBranch() && "Unexpected opcode!");
1734 // The branch target is always the last operand.
1735 int NumOp = MI.getNumExplicitOperands();
1736 return MI.getOperand(NumOp - 1).getMBB();
1737}
1738
1740 int64_t BrOffset) const {
1741 unsigned XLen = STI.getXLen();
1742 // Ideally we could determine the supported branch offset from the
1743 // RISCVII::FormMask, but this can't be used for Pseudo instructions like
1744 // PseudoBR.
1745 switch (BranchOp) {
1746 default:
1747 llvm_unreachable("Unexpected opcode!");
1748 case RISCV::NDS_BBC:
1749 case RISCV::NDS_BBS:
1750 case RISCV::NDS_BEQC:
1751 case RISCV::NDS_BNEC:
1752 return isInt<11>(BrOffset);
1753 case RISCV::BEQ:
1754 case RISCV::BNE:
1755 case RISCV::BLT:
1756 case RISCV::BGE:
1757 case RISCV::BLTU:
1758 case RISCV::BGEU:
1759 case RISCV::BEQI:
1760 case RISCV::BNEI:
1761 case RISCV::CV_BEQIMM:
1762 case RISCV::CV_BNEIMM:
1763 case RISCV::QC_BEQI:
1764 case RISCV::QC_BNEI:
1765 case RISCV::QC_BGEI:
1766 case RISCV::QC_BLTI:
1767 case RISCV::QC_BLTUI:
1768 case RISCV::QC_BGEUI:
1769 case RISCV::QC_E_BEQI:
1770 case RISCV::QC_E_BNEI:
1771 case RISCV::QC_E_BGEI:
1772 case RISCV::QC_E_BLTI:
1773 case RISCV::QC_E_BLTUI:
1774 case RISCV::QC_E_BGEUI:
1775 return isInt<13>(BrOffset);
1776 case RISCV::JAL:
1777 case RISCV::PseudoBR:
1778 return isInt<21>(BrOffset);
1779 case RISCV::PseudoJump:
1780 return isInt<32>(SignExtend64(BrOffset + 0x800, XLen));
1781 }
1782}
1783
1784// If the operation has a predicated pseudo instruction, return the pseudo
1785// instruction opcode. Otherwise, return RISCV::INSTRUCTION_LIST_END.
1786// TODO: Support more operations.
1787unsigned getPredicatedOpcode(unsigned Opcode) {
1788 // clang-format off
1789 switch (Opcode) {
1790 case RISCV::ADD: return RISCV::PseudoCCADD;
1791 case RISCV::SUB: return RISCV::PseudoCCSUB;
1792 case RISCV::SLL: return RISCV::PseudoCCSLL;
1793 case RISCV::SRL: return RISCV::PseudoCCSRL;
1794 case RISCV::SRA: return RISCV::PseudoCCSRA;
1795 case RISCV::AND: return RISCV::PseudoCCAND;
1796 case RISCV::OR: return RISCV::PseudoCCOR;
1797 case RISCV::XOR: return RISCV::PseudoCCXOR;
1798 case RISCV::MAX: return RISCV::PseudoCCMAX;
1799 case RISCV::MAXU: return RISCV::PseudoCCMAXU;
1800 case RISCV::MIN: return RISCV::PseudoCCMIN;
1801 case RISCV::MINU: return RISCV::PseudoCCMINU;
1802 case RISCV::MUL: return RISCV::PseudoCCMUL;
1803 case RISCV::LUI: return RISCV::PseudoCCLUI;
1804 case RISCV::QC_LI: return RISCV::PseudoCCQC_LI;
1805 case RISCV::QC_E_LI: return RISCV::PseudoCCQC_E_LI;
1806
1807 case RISCV::ADDI: return RISCV::PseudoCCADDI;
1808 case RISCV::SLLI: return RISCV::PseudoCCSLLI;
1809 case RISCV::SRLI: return RISCV::PseudoCCSRLI;
1810 case RISCV::SRAI: return RISCV::PseudoCCSRAI;
1811 case RISCV::ANDI: return RISCV::PseudoCCANDI;
1812 case RISCV::ORI: return RISCV::PseudoCCORI;
1813 case RISCV::XORI: return RISCV::PseudoCCXORI;
1814
1815 case RISCV::ADDW: return RISCV::PseudoCCADDW;
1816 case RISCV::SUBW: return RISCV::PseudoCCSUBW;
1817 case RISCV::SLLW: return RISCV::PseudoCCSLLW;
1818 case RISCV::SRLW: return RISCV::PseudoCCSRLW;
1819 case RISCV::SRAW: return RISCV::PseudoCCSRAW;
1820
1821 case RISCV::ADDIW: return RISCV::PseudoCCADDIW;
1822 case RISCV::SLLIW: return RISCV::PseudoCCSLLIW;
1823 case RISCV::SRLIW: return RISCV::PseudoCCSRLIW;
1824 case RISCV::SRAIW: return RISCV::PseudoCCSRAIW;
1825
1826 case RISCV::ANDN: return RISCV::PseudoCCANDN;
1827 case RISCV::ORN: return RISCV::PseudoCCORN;
1828 case RISCV::XNOR: return RISCV::PseudoCCXNOR;
1829
1830 case RISCV::NDS_BFOS: return RISCV::PseudoCCNDS_BFOS;
1831 case RISCV::NDS_BFOZ: return RISCV::PseudoCCNDS_BFOZ;
1832 }
1833 // clang-format on
1834
1835 return RISCV::INSTRUCTION_LIST_END;
1836}
1837
1838/// Identify instructions that can be folded into a CCMOV instruction, and
1839/// return the defining instruction.
1841 const MachineRegisterInfo &MRI,
1842 const TargetInstrInfo *TII,
1843 const RISCVSubtarget &STI) {
1844 if (!Reg.isVirtual())
1845 return nullptr;
1846 if (!MRI.hasOneNonDBGUse(Reg))
1847 return nullptr;
1848 MachineInstr *MI = MRI.getVRegDef(Reg);
1849 if (!MI)
1850 return nullptr;
1851
1852 if (!STI.hasShortForwardBranchIMinMax() &&
1853 (MI->getOpcode() == RISCV::MAX || MI->getOpcode() == RISCV::MIN ||
1854 MI->getOpcode() == RISCV::MINU || MI->getOpcode() == RISCV::MAXU))
1855 return nullptr;
1856
1857 if (!STI.hasShortForwardBranchIMul() && MI->getOpcode() == RISCV::MUL)
1858 return nullptr;
1859
1860 // Check if MI can be predicated and folded into the CCMOV.
1861 if (getPredicatedOpcode(MI->getOpcode()) == RISCV::INSTRUCTION_LIST_END)
1862 return nullptr;
1863 // Don't predicate li idiom.
1864 if (MI->getOpcode() == RISCV::ADDI && MI->getOperand(1).isReg() &&
1865 MI->getOperand(1).getReg() == RISCV::X0)
1866 return nullptr;
1867 // Check if MI has any other defs or physreg uses.
1868 for (const MachineOperand &MO : llvm::drop_begin(MI->operands())) {
1869 // Reject frame index operands, PEI can't handle the predicated pseudos.
1870 if (MO.isFI() || MO.isCPI() || MO.isJTI())
1871 return nullptr;
1872 if (!MO.isReg())
1873 continue;
1874 // MI can't have any tied operands, that would conflict with predication.
1875 if (MO.isTied())
1876 return nullptr;
1877 if (MO.isDef())
1878 return nullptr;
1879 // Allow constant physregs.
1880 if (MO.getReg().isPhysical() && !MRI.isConstantPhysReg(MO.getReg()))
1881 return nullptr;
1882 }
1883 bool DontMoveAcrossStores = true;
1884 if (!MI->isSafeToMove(DontMoveAcrossStores))
1885 return nullptr;
1886 return MI;
1887}
1888
1891 unsigned &TrueOp, unsigned &FalseOp,
1892 bool &Optimizable) const {
1893 assert(MI.getOpcode() == RISCV::PseudoCCMOVGPR &&
1894 "Unknown select instruction");
1895 // CCMOV operands:
1896 // 0: Def.
1897 // 1: LHS of compare.
1898 // 2: RHS of compare.
1899 // 3: Condition code.
1900 // 4: False use.
1901 // 5: True use.
1902 TrueOp = 5;
1903 FalseOp = 4;
1904 Cond.push_back(MI.getOperand(1));
1905 Cond.push_back(MI.getOperand(2));
1906 Cond.push_back(MI.getOperand(3));
1907 // We can only fold when we support short forward branch opt.
1908 Optimizable = STI.hasShortForwardBranchIALU();
1909 return false;
1910}
1911
1915 bool PreferFalse) const {
1916 assert(MI.getOpcode() == RISCV::PseudoCCMOVGPR &&
1917 "Unknown select instruction");
1918 if (!STI.hasShortForwardBranchIALU())
1919 return nullptr;
1920
1921 MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
1923 canFoldAsPredicatedOp(MI.getOperand(5).getReg(), MRI, this, STI);
1924 bool Invert = !DefMI;
1925 if (!DefMI)
1926 DefMI = canFoldAsPredicatedOp(MI.getOperand(4).getReg(), MRI, this, STI);
1927 if (!DefMI)
1928 return nullptr;
1929
1930 // Find new register class to use.
1931 MachineOperand FalseReg = MI.getOperand(Invert ? 5 : 4);
1932 Register DestReg = MI.getOperand(0).getReg();
1933 const TargetRegisterClass *PreviousClass = MRI.getRegClass(FalseReg.getReg());
1934 if (!MRI.constrainRegClass(DestReg, PreviousClass))
1935 return nullptr;
1936
1937 unsigned PredOpc = getPredicatedOpcode(DefMI->getOpcode());
1938 assert(PredOpc != RISCV::INSTRUCTION_LIST_END && "Unexpected opcode!");
1939
1940 // Create a new predicated version of DefMI.
1941 MachineInstrBuilder NewMI =
1942 BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), get(PredOpc), DestReg);
1943
1944 // Copy the condition portion.
1945 NewMI.add(MI.getOperand(1));
1946 NewMI.add(MI.getOperand(2));
1947
1948 // Add condition code, inverting if necessary.
1949 auto CC = static_cast<RISCVCC::CondCode>(MI.getOperand(3).getImm());
1950 if (Invert)
1952 NewMI.addImm(CC);
1953
1954 // Copy the false register.
1955 NewMI.add(FalseReg);
1956
1957 // Copy all the DefMI operands.
1958 const MCInstrDesc &DefDesc = DefMI->getDesc();
1959 for (unsigned i = 1, e = DefDesc.getNumOperands(); i != e; ++i)
1960 NewMI.add(DefMI->getOperand(i));
1961
1962 // Update SeenMIs set: register newly created MI and erase removed DefMI.
1963 SeenMIs.insert(NewMI);
1964 SeenMIs.erase(DefMI);
1965
1966 // If MI is inside a loop, and DefMI is outside the loop, then kill flags on
1967 // DefMI would be invalid when transferred inside the loop. Checking for a
1968 // loop is expensive, but at least remove kill flags if they are in different
1969 // BBs.
1970 if (DefMI->getParent() != MI.getParent())
1971 NewMI->clearKillInfo();
1972
1973 // The caller will erase MI, but not DefMI.
1974 DefMI->eraseFromParent();
1975 return NewMI;
1976}
1977
1979 if (MI.isMetaInstruction())
1980 return 0;
1981
1982 unsigned Opcode = MI.getOpcode();
1983
1984 if (Opcode == TargetOpcode::INLINEASM ||
1985 Opcode == TargetOpcode::INLINEASM_BR) {
1986 const MachineFunction &MF = *MI.getParent()->getParent();
1987 return getInlineAsmLength(MI.getOperand(0).getSymbolName(),
1988 *MF.getTarget().getMCAsmInfo());
1989 }
1990
1991 if (!MI.memoperands_empty()) {
1992 MachineMemOperand *MMO = *(MI.memoperands_begin());
1993 if (STI.hasStdExtZihintntl() && MMO->isNonTemporal()) {
1994 if (STI.hasStdExtZca()) {
1995 if (isCompressibleInst(MI, STI))
1996 return 4; // c.ntl.all + c.load/c.store
1997 return 6; // c.ntl.all + load/store
1998 }
1999 return 8; // ntl.all + load/store
2000 }
2001 }
2002
2003 if (Opcode == TargetOpcode::BUNDLE)
2004 return getInstBundleLength(MI);
2005
2006 if (MI.getParent() && MI.getParent()->getParent()) {
2007 if (isCompressibleInst(MI, STI))
2008 return 2;
2009 }
2010
2011 switch (Opcode) {
2012 case RISCV::PseudoMV_FPR16INX:
2013 case RISCV::PseudoMV_FPR32INX:
2014 // MV is always compressible to either c.mv or c.li rd, 0.
2015 return STI.hasStdExtZca() ? 2 : 4;
2016 case TargetOpcode::STACKMAP:
2017 // The upper bound for a stackmap intrinsic is the full length of its shadow
2019 case TargetOpcode::PATCHPOINT:
2020 // The size of the patchpoint intrinsic is the number of bytes requested
2022 case TargetOpcode::STATEPOINT: {
2023 // The size of the statepoint intrinsic is the number of bytes requested
2024 unsigned NumBytes = StatepointOpers(&MI).getNumPatchBytes();
2025 // No patch bytes means at most a PseudoCall is emitted
2026 return std::max(NumBytes, 8U);
2027 }
2028 case TargetOpcode::PATCHABLE_FUNCTION_ENTER:
2029 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
2030 case TargetOpcode::PATCHABLE_TAIL_CALL: {
2031 const MachineFunction &MF = *MI.getParent()->getParent();
2032 const Function &F = MF.getFunction();
2033 if (Opcode == TargetOpcode::PATCHABLE_FUNCTION_ENTER &&
2034 F.hasFnAttribute("patchable-function-entry")) {
2035 unsigned Num;
2036 if (F.getFnAttribute("patchable-function-entry")
2037 .getValueAsString()
2038 .getAsInteger(10, Num))
2039 return get(Opcode).getSize();
2040
2041 // Number of C.NOP or NOP
2042 return (STI.hasStdExtZca() ? 2 : 4) * Num;
2043 }
2044 // XRay uses C.JAL + 21 or 33 C.NOP for each sled in RV32 and RV64,
2045 // respectively.
2046 return STI.is64Bit() ? 68 : 44;
2047 }
2048 default:
2049 return get(Opcode).getSize();
2050 }
2051}
2052
2053unsigned RISCVInstrInfo::getInstBundleLength(const MachineInstr &MI) const {
2054 unsigned Size = 0;
2056 MachineBasicBlock::const_instr_iterator E = MI.getParent()->instr_end();
2057 while (++I != E && I->isInsideBundle()) {
2058 assert(!I->isBundle() && "No nested bundle!");
2060 }
2061 return Size;
2062}
2063
2065 const unsigned Opcode = MI.getOpcode();
2066 switch (Opcode) {
2067 default:
2068 break;
2069 case RISCV::FSGNJ_D:
2070 case RISCV::FSGNJ_S:
2071 case RISCV::FSGNJ_H:
2072 case RISCV::FSGNJ_D_INX:
2073 case RISCV::FSGNJ_D_IN32X:
2074 case RISCV::FSGNJ_S_INX:
2075 case RISCV::FSGNJ_H_INX:
2076 // The canonical floating-point move is fsgnj rd, rs, rs.
2077 return MI.getOperand(1).isReg() && MI.getOperand(2).isReg() &&
2078 MI.getOperand(1).getReg() == MI.getOperand(2).getReg();
2079 case RISCV::ADDI:
2080 case RISCV::ORI:
2081 case RISCV::XORI:
2082 return (MI.getOperand(1).isReg() &&
2083 MI.getOperand(1).getReg() == RISCV::X0) ||
2084 (MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0);
2085 }
2086 return MI.isAsCheapAsAMove();
2087}
2088
2089std::optional<DestSourcePair>
2091 if (MI.isMoveReg())
2092 return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
2093 switch (MI.getOpcode()) {
2094 default:
2095 break;
2096 case RISCV::ADD:
2097 case RISCV::OR:
2098 case RISCV::XOR:
2099 if (MI.getOperand(1).isReg() && MI.getOperand(1).getReg() == RISCV::X0 &&
2100 MI.getOperand(2).isReg())
2101 return DestSourcePair{MI.getOperand(0), MI.getOperand(2)};
2102 if (MI.getOperand(2).isReg() && MI.getOperand(2).getReg() == RISCV::X0 &&
2103 MI.getOperand(1).isReg())
2104 return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
2105 break;
2106 case RISCV::ADDI:
2107 // Operand 1 can be a frameindex but callers expect registers
2108 if (MI.getOperand(1).isReg() && MI.getOperand(2).isImm() &&
2109 MI.getOperand(2).getImm() == 0)
2110 return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
2111 break;
2112 case RISCV::SUB:
2113 if (MI.getOperand(2).isReg() && MI.getOperand(2).getReg() == RISCV::X0 &&
2114 MI.getOperand(1).isReg())
2115 return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
2116 break;
2117 case RISCV::SH1ADD:
2118 case RISCV::SH1ADD_UW:
2119 case RISCV::SH2ADD:
2120 case RISCV::SH2ADD_UW:
2121 case RISCV::SH3ADD:
2122 case RISCV::SH3ADD_UW:
2123 if (MI.getOperand(1).isReg() && MI.getOperand(1).getReg() == RISCV::X0 &&
2124 MI.getOperand(2).isReg())
2125 return DestSourcePair{MI.getOperand(0), MI.getOperand(2)};
2126 break;
2127 case RISCV::FSGNJ_D:
2128 case RISCV::FSGNJ_S:
2129 case RISCV::FSGNJ_H:
2130 case RISCV::FSGNJ_D_INX:
2131 case RISCV::FSGNJ_D_IN32X:
2132 case RISCV::FSGNJ_S_INX:
2133 case RISCV::FSGNJ_H_INX:
2134 // The canonical floating-point move is fsgnj rd, rs, rs.
2135 if (MI.getOperand(1).isReg() && MI.getOperand(2).isReg() &&
2136 MI.getOperand(1).getReg() == MI.getOperand(2).getReg())
2137 return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
2138 break;
2139 }
2140 return std::nullopt;
2141}
2142
2144 if (ForceMachineCombinerStrategy.getNumOccurrences() == 0) {
2145 // The option is unused. Choose Local strategy only for in-order cores. When
2146 // scheduling model is unspecified, use MinInstrCount strategy as more
2147 // generic one.
2148 const auto &SchedModel = STI.getSchedModel();
2149 return (!SchedModel.hasInstrSchedModel() || SchedModel.isOutOfOrder())
2152 }
2153 // The strategy was forced by the option.
2155}
2156
2158 MachineInstr &Root, unsigned &Pattern,
2159 SmallVectorImpl<MachineInstr *> &InsInstrs) const {
2160 int16_t FrmOpIdx =
2161 RISCV::getNamedOperandIdx(Root.getOpcode(), RISCV::OpName::frm);
2162 if (FrmOpIdx < 0) {
2163 assert(all_of(InsInstrs,
2164 [](MachineInstr *MI) {
2165 return RISCV::getNamedOperandIdx(MI->getOpcode(),
2166 RISCV::OpName::frm) < 0;
2167 }) &&
2168 "New instructions require FRM whereas the old one does not have it");
2169 return;
2170 }
2171
2172 const MachineOperand &FRM = Root.getOperand(FrmOpIdx);
2173 MachineFunction &MF = *Root.getMF();
2174
2175 for (auto *NewMI : InsInstrs) {
2176 // We'd already added the FRM operand.
2177 if (static_cast<unsigned>(RISCV::getNamedOperandIdx(
2178 NewMI->getOpcode(), RISCV::OpName::frm)) != NewMI->getNumOperands())
2179 continue;
2180 MachineInstrBuilder MIB(MF, NewMI);
2181 MIB.add(FRM);
2182 if (FRM.getImm() == RISCVFPRndMode::DYN)
2183 MIB.addUse(RISCV::FRM, RegState::Implicit);
2184 }
2185}
2186
2187static bool isFADD(unsigned Opc) {
2188 switch (Opc) {
2189 default:
2190 return false;
2191 case RISCV::FADD_H:
2192 case RISCV::FADD_S:
2193 case RISCV::FADD_D:
2194 return true;
2195 }
2196}
2197
2198static bool isFSUB(unsigned Opc) {
2199 switch (Opc) {
2200 default:
2201 return false;
2202 case RISCV::FSUB_H:
2203 case RISCV::FSUB_S:
2204 case RISCV::FSUB_D:
2205 return true;
2206 }
2207}
2208
2209static bool isFMUL(unsigned Opc) {
2210 switch (Opc) {
2211 default:
2212 return false;
2213 case RISCV::FMUL_H:
2214 case RISCV::FMUL_S:
2215 case RISCV::FMUL_D:
2216 return true;
2217 }
2218}
2219
2220bool RISCVInstrInfo::isVectorAssociativeAndCommutative(const MachineInstr &Inst,
2221 bool Invert) const {
2222#define OPCODE_LMUL_CASE(OPC) \
2223 case RISCV::OPC##_M1: \
2224 case RISCV::OPC##_M2: \
2225 case RISCV::OPC##_M4: \
2226 case RISCV::OPC##_M8: \
2227 case RISCV::OPC##_MF2: \
2228 case RISCV::OPC##_MF4: \
2229 case RISCV::OPC##_MF8
2230
2231#define OPCODE_LMUL_MASK_CASE(OPC) \
2232 case RISCV::OPC##_M1_MASK: \
2233 case RISCV::OPC##_M2_MASK: \
2234 case RISCV::OPC##_M4_MASK: \
2235 case RISCV::OPC##_M8_MASK: \
2236 case RISCV::OPC##_MF2_MASK: \
2237 case RISCV::OPC##_MF4_MASK: \
2238 case RISCV::OPC##_MF8_MASK
2239
2240 unsigned Opcode = Inst.getOpcode();
2241 if (Invert) {
2242 if (auto InvOpcode = getInverseOpcode(Opcode))
2243 Opcode = *InvOpcode;
2244 else
2245 return false;
2246 }
2247
2248 // clang-format off
2249 switch (Opcode) {
2250 default:
2251 return false;
2252 OPCODE_LMUL_CASE(PseudoVADD_VV):
2253 OPCODE_LMUL_MASK_CASE(PseudoVADD_VV):
2254 OPCODE_LMUL_CASE(PseudoVMUL_VV):
2255 OPCODE_LMUL_MASK_CASE(PseudoVMUL_VV):
2256 return true;
2257 }
2258 // clang-format on
2259
2260#undef OPCODE_LMUL_MASK_CASE
2261#undef OPCODE_LMUL_CASE
2262}
2263
2264bool RISCVInstrInfo::areRVVInstsReassociable(const MachineInstr &Root,
2265 const MachineInstr &Prev) const {
2266 if (!areOpcodesEqualOrInverse(Root.getOpcode(), Prev.getOpcode()))
2267 return false;
2268
2269 assert(Root.getMF() == Prev.getMF());
2270 const MachineRegisterInfo *MRI = &Root.getMF()->getRegInfo();
2271 const TargetRegisterInfo *TRI = MRI->getTargetRegisterInfo();
2272
2273 // Make sure vtype operands are also the same.
2274 const MCInstrDesc &Desc = get(Root.getOpcode());
2275 const uint64_t TSFlags = Desc.TSFlags;
2276
2277 auto checkImmOperand = [&](unsigned OpIdx) {
2278 return Root.getOperand(OpIdx).getImm() == Prev.getOperand(OpIdx).getImm();
2279 };
2280
2281 auto checkRegOperand = [&](unsigned OpIdx) {
2282 return Root.getOperand(OpIdx).getReg() == Prev.getOperand(OpIdx).getReg();
2283 };
2284
2285 // PassThru
2286 // TODO: Potentially we can loosen the condition to consider Root to be
2287 // associable with Prev if Root has NoReg as passthru. In which case we
2288 // also need to loosen the condition on vector policies between these.
2289 if (!checkRegOperand(1))
2290 return false;
2291
2292 // SEW
2293 if (RISCVII::hasSEWOp(TSFlags) &&
2294 !checkImmOperand(RISCVII::getSEWOpNum(Desc)))
2295 return false;
2296
2297 // Mask
2298 if (RISCVII::usesMaskPolicy(TSFlags)) {
2299 const MachineBasicBlock *MBB = Root.getParent();
2302 Register MI1VReg;
2303
2304 bool SeenMI2 = false;
2305 for (auto End = MBB->rend(), It = It1; It != End; ++It) {
2306 if (It == It2) {
2307 SeenMI2 = true;
2308 if (!MI1VReg.isValid())
2309 // There is no V0 def between Root and Prev; they're sharing the
2310 // same V0.
2311 break;
2312 }
2313
2314 if (It->modifiesRegister(RISCV::V0, TRI)) {
2315 Register SrcReg = It->getOperand(1).getReg();
2316 // If it's not VReg it'll be more difficult to track its defs, so
2317 // bailing out here just to be safe.
2318 if (!SrcReg.isVirtual())
2319 return false;
2320
2321 if (!MI1VReg.isValid()) {
2322 // This is the V0 def for Root.
2323 MI1VReg = SrcReg;
2324 continue;
2325 }
2326
2327 // Some random mask updates.
2328 if (!SeenMI2)
2329 continue;
2330
2331 // This is the V0 def for Prev; check if it's the same as that of
2332 // Root.
2333 if (MI1VReg != SrcReg)
2334 return false;
2335 else
2336 break;
2337 }
2338 }
2339
2340 // If we haven't encountered Prev, it's likely that this function was
2341 // called in a wrong way (e.g. Root is before Prev).
2342 assert(SeenMI2 && "Prev is expected to appear before Root");
2343 }
2344
2345 // Tail / Mask policies
2346 if (RISCVII::hasVecPolicyOp(TSFlags) &&
2347 !checkImmOperand(RISCVII::getVecPolicyOpNum(Desc)))
2348 return false;
2349
2350 // VL
2351 if (RISCVII::hasVLOp(TSFlags)) {
2352 unsigned OpIdx = RISCVII::getVLOpNum(Desc);
2353 const MachineOperand &Op1 = Root.getOperand(OpIdx);
2354 const MachineOperand &Op2 = Prev.getOperand(OpIdx);
2355 if (Op1.getType() != Op2.getType())
2356 return false;
2357 switch (Op1.getType()) {
2359 if (Op1.getReg() != Op2.getReg())
2360 return false;
2361 break;
2363 if (Op1.getImm() != Op2.getImm())
2364 return false;
2365 break;
2366 default:
2367 llvm_unreachable("Unrecognized VL operand type");
2368 }
2369 }
2370
2371 // Rounding modes
2372 if (RISCVII::hasRoundModeOp(TSFlags) &&
2373 !checkImmOperand(RISCVII::getVLOpNum(Desc) - 1))
2374 return false;
2375
2376 return true;
2377}
2378
2379// Most of our RVV pseudos have passthru operand, so the real operands
2380// start from index = 2.
2381bool RISCVInstrInfo::hasReassociableVectorSibling(const MachineInstr &Inst,
2382 bool &Commuted) const {
2383 const MachineBasicBlock *MBB = Inst.getParent();
2384 const MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
2386 "Expect the present of passthrough operand.");
2387 MachineInstr *MI1 = MRI.getUniqueVRegDef(Inst.getOperand(2).getReg());
2388 MachineInstr *MI2 = MRI.getUniqueVRegDef(Inst.getOperand(3).getReg());
2389
2390 // If only one operand has the same or inverse opcode and it's the second
2391 // source operand, the operands must be commuted.
2392 Commuted = !areRVVInstsReassociable(Inst, *MI1) &&
2393 areRVVInstsReassociable(Inst, *MI2);
2394 if (Commuted)
2395 std::swap(MI1, MI2);
2396
2397 return areRVVInstsReassociable(Inst, *MI1) &&
2398 (isVectorAssociativeAndCommutative(*MI1) ||
2399 isVectorAssociativeAndCommutative(*MI1, /* Invert */ true)) &&
2401 MRI.hasOneNonDBGUse(MI1->getOperand(0).getReg());
2402}
2403
2405 const MachineInstr &Inst, const MachineBasicBlock *MBB) const {
2406 if (!isVectorAssociativeAndCommutative(Inst) &&
2407 !isVectorAssociativeAndCommutative(Inst, /*Invert=*/true))
2409
2410 const MachineOperand &Op1 = Inst.getOperand(2);
2411 const MachineOperand &Op2 = Inst.getOperand(3);
2412 const MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
2413
2414 // We need virtual register definitions for the operands that we will
2415 // reassociate.
2416 MachineInstr *MI1 = nullptr;
2417 MachineInstr *MI2 = nullptr;
2418 if (Op1.isReg() && Op1.getReg().isVirtual())
2419 MI1 = MRI.getUniqueVRegDef(Op1.getReg());
2420 if (Op2.isReg() && Op2.getReg().isVirtual())
2421 MI2 = MRI.getUniqueVRegDef(Op2.getReg());
2422
2423 // And at least one operand must be defined in MBB.
2424 return MI1 && MI2 && (MI1->getParent() == MBB || MI2->getParent() == MBB);
2425}
2426
2428 const MachineInstr &Root, unsigned Pattern,
2429 std::array<unsigned, 5> &OperandIndices) const {
2431 if (RISCV::getRVVMCOpcode(Root.getOpcode())) {
2432 // Skip the passthrough operand, so increment all indices by one.
2433 for (unsigned I = 0; I < 5; ++I)
2434 ++OperandIndices[I];
2435 }
2436}
2437
2439 bool &Commuted) const {
2440 if (isVectorAssociativeAndCommutative(Inst) ||
2441 isVectorAssociativeAndCommutative(Inst, /*Invert=*/true))
2442 return hasReassociableVectorSibling(Inst, Commuted);
2443
2444 if (!TargetInstrInfo::hasReassociableSibling(Inst, Commuted))
2445 return false;
2446
2447 const MachineRegisterInfo &MRI = Inst.getMF()->getRegInfo();
2448 unsigned OperandIdx = Commuted ? 2 : 1;
2449 const MachineInstr &Sibling =
2450 *MRI.getVRegDef(Inst.getOperand(OperandIdx).getReg());
2451
2452 int16_t InstFrmOpIdx =
2453 RISCV::getNamedOperandIdx(Inst.getOpcode(), RISCV::OpName::frm);
2454 int16_t SiblingFrmOpIdx =
2455 RISCV::getNamedOperandIdx(Sibling.getOpcode(), RISCV::OpName::frm);
2456
2457 return (InstFrmOpIdx < 0 && SiblingFrmOpIdx < 0) ||
2458 RISCV::hasEqualFRM(Inst, Sibling);
2459}
2460
2462 bool Invert) const {
2463 if (isVectorAssociativeAndCommutative(Inst, Invert))
2464 return true;
2465
2466 unsigned Opc = Inst.getOpcode();
2467 if (Invert) {
2468 auto InverseOpcode = getInverseOpcode(Opc);
2469 if (!InverseOpcode)
2470 return false;
2471 Opc = *InverseOpcode;
2472 }
2473
2474 if (isFADD(Opc) || isFMUL(Opc))
2477
2478 switch (Opc) {
2479 default:
2480 return false;
2481 case RISCV::ADD:
2482 case RISCV::ADDW:
2483 case RISCV::AND:
2484 case RISCV::OR:
2485 case RISCV::XOR:
2486 // From RISC-V ISA spec, if both the high and low bits of the same product
2487 // are required, then the recommended code sequence is:
2488 //
2489 // MULH[[S]U] rdh, rs1, rs2
2490 // MUL rdl, rs1, rs2
2491 // (source register specifiers must be in same order and rdh cannot be the
2492 // same as rs1 or rs2)
2493 //
2494 // Microarchitectures can then fuse these into a single multiply operation
2495 // instead of performing two separate multiplies.
2496 // MachineCombiner may reassociate MUL operands and lose the fusion
2497 // opportunity.
2498 case RISCV::MUL:
2499 case RISCV::MULW:
2500 case RISCV::MIN:
2501 case RISCV::MINU:
2502 case RISCV::MAX:
2503 case RISCV::MAXU:
2504 case RISCV::FMIN_H:
2505 case RISCV::FMIN_S:
2506 case RISCV::FMIN_D:
2507 case RISCV::FMAX_H:
2508 case RISCV::FMAX_S:
2509 case RISCV::FMAX_D:
2510 return true;
2511 }
2512
2513 return false;
2514}
2515
2516std::optional<unsigned>
2517RISCVInstrInfo::getInverseOpcode(unsigned Opcode) const {
2518#define RVV_OPC_LMUL_CASE(OPC, INV) \
2519 case RISCV::OPC##_M1: \
2520 return RISCV::INV##_M1; \
2521 case RISCV::OPC##_M2: \
2522 return RISCV::INV##_M2; \
2523 case RISCV::OPC##_M4: \
2524 return RISCV::INV##_M4; \
2525 case RISCV::OPC##_M8: \
2526 return RISCV::INV##_M8; \
2527 case RISCV::OPC##_MF2: \
2528 return RISCV::INV##_MF2; \
2529 case RISCV::OPC##_MF4: \
2530 return RISCV::INV##_MF4; \
2531 case RISCV::OPC##_MF8: \
2532 return RISCV::INV##_MF8
2533
2534#define RVV_OPC_LMUL_MASK_CASE(OPC, INV) \
2535 case RISCV::OPC##_M1_MASK: \
2536 return RISCV::INV##_M1_MASK; \
2537 case RISCV::OPC##_M2_MASK: \
2538 return RISCV::INV##_M2_MASK; \
2539 case RISCV::OPC##_M4_MASK: \
2540 return RISCV::INV##_M4_MASK; \
2541 case RISCV::OPC##_M8_MASK: \
2542 return RISCV::INV##_M8_MASK; \
2543 case RISCV::OPC##_MF2_MASK: \
2544 return RISCV::INV##_MF2_MASK; \
2545 case RISCV::OPC##_MF4_MASK: \
2546 return RISCV::INV##_MF4_MASK; \
2547 case RISCV::OPC##_MF8_MASK: \
2548 return RISCV::INV##_MF8_MASK
2549
2550 switch (Opcode) {
2551 default:
2552 return std::nullopt;
2553 case RISCV::FADD_H:
2554 return RISCV::FSUB_H;
2555 case RISCV::FADD_S:
2556 return RISCV::FSUB_S;
2557 case RISCV::FADD_D:
2558 return RISCV::FSUB_D;
2559 case RISCV::FSUB_H:
2560 return RISCV::FADD_H;
2561 case RISCV::FSUB_S:
2562 return RISCV::FADD_S;
2563 case RISCV::FSUB_D:
2564 return RISCV::FADD_D;
2565 case RISCV::ADD:
2566 return RISCV::SUB;
2567 case RISCV::SUB:
2568 return RISCV::ADD;
2569 case RISCV::ADDW:
2570 return RISCV::SUBW;
2571 case RISCV::SUBW:
2572 return RISCV::ADDW;
2573 // clang-format off
2574 RVV_OPC_LMUL_CASE(PseudoVADD_VV, PseudoVSUB_VV);
2575 RVV_OPC_LMUL_MASK_CASE(PseudoVADD_VV, PseudoVSUB_VV);
2576 RVV_OPC_LMUL_CASE(PseudoVSUB_VV, PseudoVADD_VV);
2577 RVV_OPC_LMUL_MASK_CASE(PseudoVSUB_VV, PseudoVADD_VV);
2578 // clang-format on
2579 }
2580
2581#undef RVV_OPC_LMUL_MASK_CASE
2582#undef RVV_OPC_LMUL_CASE
2583}
2584
2586 const MachineOperand &MO,
2587 bool DoRegPressureReduce) {
2588 if (!MO.isReg() || !MO.getReg().isVirtual())
2589 return false;
2590 const MachineRegisterInfo &MRI = Root.getMF()->getRegInfo();
2591 MachineInstr *MI = MRI.getVRegDef(MO.getReg());
2592 if (!MI || !isFMUL(MI->getOpcode()))
2593 return false;
2594
2597 return false;
2598
2599 // Try combining even if fmul has more than one use as it eliminates
2600 // dependency between fadd(fsub) and fmul. However, it can extend liveranges
2601 // for fmul operands, so reject the transformation in register pressure
2602 // reduction mode.
2603 if (DoRegPressureReduce && !MRI.hasOneNonDBGUse(MI->getOperand(0).getReg()))
2604 return false;
2605
2606 // Do not combine instructions from different basic blocks.
2607 if (Root.getParent() != MI->getParent())
2608 return false;
2609 return RISCV::hasEqualFRM(Root, *MI);
2610}
2611
2613 SmallVectorImpl<unsigned> &Patterns,
2614 bool DoRegPressureReduce) {
2615 unsigned Opc = Root.getOpcode();
2616 bool IsFAdd = isFADD(Opc);
2617 if (!IsFAdd && !isFSUB(Opc))
2618 return false;
2619 bool Added = false;
2620 if (canCombineFPFusedMultiply(Root, Root.getOperand(1),
2621 DoRegPressureReduce)) {
2624 Added = true;
2625 }
2626 if (canCombineFPFusedMultiply(Root, Root.getOperand(2),
2627 DoRegPressureReduce)) {
2630 Added = true;
2631 }
2632 return Added;
2633}
2634
2635static bool getFPPatterns(MachineInstr &Root,
2636 SmallVectorImpl<unsigned> &Patterns,
2637 bool DoRegPressureReduce) {
2638 return getFPFusedMultiplyPatterns(Root, Patterns, DoRegPressureReduce);
2639}
2640
2641/// Utility routine that checks if \param MO is defined by an
2642/// \param CombineOpc instruction in the basic block \param MBB
2644 const MachineOperand &MO,
2645 unsigned CombineOpc) {
2646 const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
2647 const MachineInstr *MI = nullptr;
2648
2649 if (MO.isReg() && MO.getReg().isVirtual())
2650 MI = MRI.getUniqueVRegDef(MO.getReg());
2651 // And it needs to be in the trace (otherwise, it won't have a depth).
2652 if (!MI || MI->getParent() != &MBB || MI->getOpcode() != CombineOpc)
2653 return nullptr;
2654 // Must only used by the user we combine with.
2655 if (!MRI.hasOneNonDBGUse(MI->getOperand(0).getReg()))
2656 return nullptr;
2657
2658 return MI;
2659}
2660
2661/// Utility routine that checks if \param MO is defined by a SLLI in \param
2662/// MBB that can be combined by splitting across 2 SHXADD instructions. The
2663/// first SHXADD shift amount is given by \param OuterShiftAmt.
2665 const MachineOperand &MO,
2666 unsigned OuterShiftAmt) {
2667 const MachineInstr *ShiftMI = canCombine(MBB, MO, RISCV::SLLI);
2668 if (!ShiftMI)
2669 return false;
2670
2671 unsigned InnerShiftAmt = ShiftMI->getOperand(2).getImm();
2672 if (InnerShiftAmt < OuterShiftAmt || (InnerShiftAmt - OuterShiftAmt) > 3)
2673 return false;
2674
2675 return true;
2676}
2677
2678// Returns the shift amount from a SHXADD instruction. Returns 0 if the
2679// instruction is not a SHXADD.
2680static unsigned getSHXADDShiftAmount(unsigned Opc) {
2681 switch (Opc) {
2682 default:
2683 return 0;
2684 case RISCV::SH1ADD:
2685 return 1;
2686 case RISCV::SH2ADD:
2687 return 2;
2688 case RISCV::SH3ADD:
2689 return 3;
2690 }
2691}
2692
2693// Returns the shift amount from a SHXADD.UW instruction. Returns 0 if the
2694// instruction is not a SHXADD.UW.
2695static unsigned getSHXADDUWShiftAmount(unsigned Opc) {
2696 switch (Opc) {
2697 default:
2698 return 0;
2699 case RISCV::SH1ADD_UW:
2700 return 1;
2701 case RISCV::SH2ADD_UW:
2702 return 2;
2703 case RISCV::SH3ADD_UW:
2704 return 3;
2705 }
2706}
2707
2708// Look for opportunities to combine (sh3add Z, (add X, (slli Y, 5))) into
2709// (sh3add (sh2add Y, Z), X).
2710static bool getSHXADDPatterns(const MachineInstr &Root,
2711 SmallVectorImpl<unsigned> &Patterns) {
2712 unsigned ShiftAmt = getSHXADDShiftAmount(Root.getOpcode());
2713 if (!ShiftAmt)
2714 return false;
2715
2716 const MachineBasicBlock &MBB = *Root.getParent();
2717
2718 const MachineInstr *AddMI = canCombine(MBB, Root.getOperand(2), RISCV::ADD);
2719 if (!AddMI)
2720 return false;
2721
2722 bool Found = false;
2723 if (canCombineShiftIntoShXAdd(MBB, AddMI->getOperand(1), ShiftAmt)) {
2725 Found = true;
2726 }
2727 if (canCombineShiftIntoShXAdd(MBB, AddMI->getOperand(2), ShiftAmt)) {
2729 Found = true;
2730 }
2731
2732 return Found;
2733}
2734
2746
2748 MachineInstr &Root, SmallVectorImpl<unsigned> &Patterns,
2749 bool DoRegPressureReduce) const {
2750
2751 if (getFPPatterns(Root, Patterns, DoRegPressureReduce))
2752 return true;
2753
2754 if (getSHXADDPatterns(Root, Patterns))
2755 return true;
2756
2757 return TargetInstrInfo::getMachineCombinerPatterns(Root, Patterns,
2758 DoRegPressureReduce);
2759}
2760
2761static unsigned getFPFusedMultiplyOpcode(unsigned RootOpc, unsigned Pattern) {
2762 switch (RootOpc) {
2763 default:
2764 llvm_unreachable("Unexpected opcode");
2765 case RISCV::FADD_H:
2766 return RISCV::FMADD_H;
2767 case RISCV::FADD_S:
2768 return RISCV::FMADD_S;
2769 case RISCV::FADD_D:
2770 return RISCV::FMADD_D;
2771 case RISCV::FSUB_H:
2772 return Pattern == RISCVMachineCombinerPattern::FMSUB ? RISCV::FMSUB_H
2773 : RISCV::FNMSUB_H;
2774 case RISCV::FSUB_S:
2775 return Pattern == RISCVMachineCombinerPattern::FMSUB ? RISCV::FMSUB_S
2776 : RISCV::FNMSUB_S;
2777 case RISCV::FSUB_D:
2778 return Pattern == RISCVMachineCombinerPattern::FMSUB ? RISCV::FMSUB_D
2779 : RISCV::FNMSUB_D;
2780 }
2781}
2782
2783static unsigned getAddendOperandIdx(unsigned Pattern) {
2784 switch (Pattern) {
2785 default:
2786 llvm_unreachable("Unexpected pattern");
2789 return 2;
2792 return 1;
2793 }
2794}
2795
2797 unsigned Pattern,
2800 MachineFunction *MF = Root.getMF();
2803
2804 MachineOperand &Mul1 = Prev.getOperand(1);
2805 MachineOperand &Mul2 = Prev.getOperand(2);
2806 MachineOperand &Dst = Root.getOperand(0);
2808
2809 Register DstReg = Dst.getReg();
2810 unsigned FusedOpc = getFPFusedMultiplyOpcode(Root.getOpcode(), Pattern);
2811 uint32_t IntersectedFlags = Root.getFlags() & Prev.getFlags();
2812 DebugLoc MergedLoc =
2814
2815 bool Mul1IsKill = Mul1.isKill();
2816 bool Mul2IsKill = Mul2.isKill();
2817 bool AddendIsKill = Addend.isKill();
2818
2819 // We need to clear kill flags since we may be extending the live range past
2820 // a kill. If the mul had kill flags, we can preserve those since we know
2821 // where the previous range stopped.
2822 MRI.clearKillFlags(Mul1.getReg());
2823 MRI.clearKillFlags(Mul2.getReg());
2824
2826 BuildMI(*MF, MergedLoc, TII->get(FusedOpc), DstReg)
2827 .addReg(Mul1.getReg(), getKillRegState(Mul1IsKill))
2828 .addReg(Mul2.getReg(), getKillRegState(Mul2IsKill))
2829 .addReg(Addend.getReg(), getKillRegState(AddendIsKill))
2830 .setMIFlags(IntersectedFlags);
2831
2832 InsInstrs.push_back(MIB);
2833 if (MRI.hasOneNonDBGUse(Prev.getOperand(0).getReg()))
2834 DelInstrs.push_back(&Prev);
2835 DelInstrs.push_back(&Root);
2836}
2837
2838// Combine patterns like (sh3add Z, (add X, (slli Y, 5))) to
2839// (sh3add (sh2add Y, Z), X) if the shift amount can be split across two
2840// shXadd instructions. The outer shXadd keeps its original opcode.
2841static void
2842genShXAddAddShift(MachineInstr &Root, unsigned AddOpIdx,
2845 DenseMap<Register, unsigned> &InstrIdxForVirtReg) {
2846 MachineFunction *MF = Root.getMF();
2849
2850 unsigned OuterShiftAmt = getSHXADDShiftAmount(Root.getOpcode());
2851 assert(OuterShiftAmt != 0 && "Unexpected opcode");
2852
2853 MachineInstr *AddMI = MRI.getUniqueVRegDef(Root.getOperand(2).getReg());
2854 MachineInstr *ShiftMI =
2855 MRI.getUniqueVRegDef(AddMI->getOperand(AddOpIdx).getReg());
2856
2857 unsigned InnerShiftAmt = ShiftMI->getOperand(2).getImm();
2858 assert(InnerShiftAmt >= OuterShiftAmt && "Unexpected shift amount");
2859
2860 unsigned InnerOpc;
2861 switch (InnerShiftAmt - OuterShiftAmt) {
2862 default:
2863 llvm_unreachable("Unexpected shift amount");
2864 case 0:
2865 InnerOpc = RISCV::ADD;
2866 break;
2867 case 1:
2868 InnerOpc = RISCV::SH1ADD;
2869 break;
2870 case 2:
2871 InnerOpc = RISCV::SH2ADD;
2872 break;
2873 case 3:
2874 InnerOpc = RISCV::SH3ADD;
2875 break;
2876 }
2877
2878 const MachineOperand &X = AddMI->getOperand(3 - AddOpIdx);
2879 const MachineOperand &Y = ShiftMI->getOperand(1);
2880 const MachineOperand &Z = Root.getOperand(1);
2881
2882 Register NewVR = MRI.createVirtualRegister(&RISCV::GPRRegClass);
2883
2884 auto MIB1 = BuildMI(*MF, MIMetadata(Root), TII->get(InnerOpc), NewVR)
2885 .addReg(Y.getReg(), getKillRegState(Y.isKill()))
2886 .addReg(Z.getReg(), getKillRegState(Z.isKill()));
2887 auto MIB2 = BuildMI(*MF, MIMetadata(Root), TII->get(Root.getOpcode()),
2888 Root.getOperand(0).getReg())
2889 .addReg(NewVR, RegState::Kill)
2890 .addReg(X.getReg(), getKillRegState(X.isKill()));
2891
2892 InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0));
2893 InsInstrs.push_back(MIB1);
2894 InsInstrs.push_back(MIB2);
2895 DelInstrs.push_back(ShiftMI);
2896 DelInstrs.push_back(AddMI);
2897 DelInstrs.push_back(&Root);
2898}
2899
2901 MachineInstr &Root, unsigned Pattern,
2904 DenseMap<Register, unsigned> &InstrIdxForVirtReg) const {
2906 switch (Pattern) {
2907 default:
2909 DelInstrs, InstrIdxForVirtReg);
2910 return;
2913 MachineInstr &Prev = *MRI.getVRegDef(Root.getOperand(1).getReg());
2914 combineFPFusedMultiply(Root, Prev, Pattern, InsInstrs, DelInstrs);
2915 return;
2916 }
2919 MachineInstr &Prev = *MRI.getVRegDef(Root.getOperand(2).getReg());
2920 combineFPFusedMultiply(Root, Prev, Pattern, InsInstrs, DelInstrs);
2921 return;
2922 }
2924 genShXAddAddShift(Root, 1, InsInstrs, DelInstrs, InstrIdxForVirtReg);
2925 return;
2927 genShXAddAddShift(Root, 2, InsInstrs, DelInstrs, InstrIdxForVirtReg);
2928 return;
2929 }
2930}
2931
2933 StringRef &ErrInfo) const {
2934 MCInstrDesc const &Desc = MI.getDesc();
2935
2936 for (const auto &[Index, Operand] : enumerate(Desc.operands())) {
2937 const MachineOperand &MO = MI.getOperand(Index);
2938 unsigned OpType = Operand.OperandType;
2939 switch (OpType) {
2940 default:
2941 if (OpType >= RISCVOp::OPERAND_FIRST_RISCV_IMM &&
2943 if (!MO.isImm()) {
2944 ErrInfo = "Expected an immediate operand.";
2945 return false;
2946 }
2947 int64_t Imm = MO.getImm();
2948 bool Ok;
2949 switch (OpType) {
2950 default:
2951 llvm_unreachable("Unexpected operand type");
2952
2953 // clang-format off
2954#define CASE_OPERAND_UIMM(NUM) \
2955 case RISCVOp::OPERAND_UIMM##NUM: \
2956 Ok = isUInt<NUM>(Imm); \
2957 break;
2958#define CASE_OPERAND_SIMM(NUM) \
2959 case RISCVOp::OPERAND_SIMM##NUM: \
2960 Ok = isInt<NUM>(Imm); \
2961 break;
2977 // clang-format on
2979 Ok = isShiftedUInt<1, 1>(Imm);
2980 break;
2982 Ok = isShiftedUInt<4, 1>(Imm);
2983 break;
2985 Ok = isUInt<5>(Imm) && (Imm != 0);
2986 break;
2988 Ok = isUInt<5>(Imm) && (Imm > 3);
2989 break;
2991 Ok = Imm >= 1 && Imm <= 32;
2992 break;
2994 Ok = isShiftedUInt<5, 1>(Imm);
2995 break;
2997 Ok = isShiftedUInt<5, 2>(Imm);
2998 break;
3000 Ok = isShiftedUInt<4, 3>(Imm);
3001 break;
3003 Ok = isShiftedUInt<6, 2>(Imm);
3004 break;
3006 Ok = isShiftedUInt<5, 3>(Imm);
3007 break;
3009 Ok = isUInt<8>(Imm) && Imm >= 32;
3010 break;
3012 Ok = isShiftedUInt<6, 3>(Imm);
3013 break;
3015 Ok = isInt<8>(Imm);
3016 break;
3018 Ok = isShiftedInt<6, 4>(Imm) && (Imm != 0);
3019 break;
3021 Ok = isShiftedUInt<8, 2>(Imm) && (Imm != 0);
3022 break;
3024 Ok = isUInt<16>(Imm) && (Imm != 0);
3025 break;
3027 Ok = Imm == 3;
3028 break;
3030 Ok = Imm == 4;
3031 break;
3033 Ok = (isUInt<5>(Imm) && Imm != 0) || Imm == -1;
3034 break;
3035 // clang-format off
3041 // clang-format on
3043 Ok = Imm >= -15 && Imm <= 16;
3044 break;
3046 Ok = isInt<5>(Imm) && (Imm != 0);
3047 break;
3049 Ok = Imm != 0 && isInt<6>(Imm);
3050 break;
3052 Ok = isUInt<10>(Imm);
3053 break;
3055 Ok = isUInt<11>(Imm);
3056 break;
3058 Ok = isShiftedInt<7, 5>(Imm);
3059 break;
3061 Ok = isInt<16>(Imm) && (Imm != 0);
3062 break;
3064 Ok = isInt<20>(Imm);
3065 break;
3067 Ok = STI.is64Bit() ? isUInt<6>(Imm) : isUInt<5>(Imm);
3068 break;
3070 Ok = STI.is64Bit() ? isUInt<6>(Imm) : isUInt<5>(Imm);
3071 Ok = Ok && Imm != 0;
3072 break;
3074 Ok = (isUInt<5>(Imm) && Imm != 0) || (Imm >= 0xfffe0 && Imm <= 0xfffff);
3075 break;
3077 Ok = Imm >= 0 && Imm <= 10;
3078 break;
3080 Ok = Imm >= 0 && Imm <= 7;
3081 break;
3083 Ok = Imm >= 1 && Imm <= 10;
3084 break;
3086 Ok = Imm >= 2 && Imm <= 14;
3087 break;
3089 Ok = Imm >= RISCVZC::RA && Imm <= RISCVZC::RA_S0_S11;
3090 break;
3092 Ok = Imm >= RISCVZC::RA_S0 && Imm <= RISCVZC::RA_S0_S11;
3093 break;
3095 Ok = Imm >= 0 && Imm <= 48 && Imm % 16 == 0;
3096 break;
3099 break;
3101 Ok = Imm == RISCVFPRndMode::RTZ;
3102 break;
3104 Ok = Imm >= 0 && Imm < RISCVCC::COND_INVALID;
3105 break;
3107 Ok = isValidAtomicOrdering(Imm);
3108 break;
3111 Imm;
3112 break;
3114 Ok = (isUInt<5>(Imm) && RISCVVType::isValidSEW(1 << Imm));
3115 break;
3117 Ok = Imm == 0;
3118 break;
3121 if (RISCVII::usesVXRM(Desc.TSFlags))
3122 Ok = isUInt<2>(Imm);
3123 else
3125 break;
3128 break;
3130 Ok = Imm == 1 || Imm == 2 || Imm == 4;
3131 break;
3132 }
3133 if (!Ok) {
3134 ErrInfo = "Invalid immediate";
3135 return false;
3136 }
3137 }
3138 break;
3140 // TODO: We could be stricter about what non-register operands are
3141 // allowed.
3142 if (MO.isReg()) {
3143 ErrInfo = "Expected a non-register operand.";
3144 return false;
3145 }
3146 if (MO.isImm() && !isInt<12>(MO.getImm())) {
3147 ErrInfo = "Invalid immediate";
3148 return false;
3149 }
3150 break;
3153 // TODO: We could be stricter about what non-register operands are
3154 // allowed.
3155 if (MO.isReg()) {
3156 ErrInfo = "Expected a non-register operand.";
3157 return false;
3158 }
3159 if (MO.isImm() && !isUInt<20>(MO.getImm())) {
3160 ErrInfo = "Invalid immediate";
3161 return false;
3162 }
3163 break;
3165 // TODO: We could be stricter about what non-register operands are
3166 // allowed.
3167 if (MO.isReg()) {
3168 ErrInfo = "Expected a non-register operand.";
3169 return false;
3170 }
3171 if (MO.isImm() && !isInt<32>(MO.getImm())) {
3172 ErrInfo = "Invalid immediate";
3173 return false;
3174 }
3175 break;
3177 if (MO.isImm()) {
3178 int64_t Imm = MO.getImm();
3179 // VLMAX is represented as -1.
3180 if (!isUInt<5>(Imm) && Imm != -1) {
3181 ErrInfo = "Invalid immediate";
3182 return false;
3183 }
3184 } else if (!MO.isReg()) {
3185 ErrInfo = "Expected a register or immediate operand.";
3186 return false;
3187 }
3188 break;
3189 }
3190 }
3191
3192 const uint64_t TSFlags = Desc.TSFlags;
3193 if (RISCVII::hasVLOp(TSFlags)) {
3194 const MachineOperand &Op = MI.getOperand(RISCVII::getVLOpNum(Desc));
3195 if (!Op.isImm() && !Op.isReg()) {
3196 ErrInfo = "Invalid operand type for VL operand";
3197 return false;
3198 }
3199 if (Op.isReg() && Op.getReg().isValid()) {
3200 const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
3201 auto *RC = MRI.getRegClass(Op.getReg());
3202 if (!RISCV::GPRNoX0RegClass.hasSubClassEq(RC)) {
3203 ErrInfo = "Invalid register class for VL operand";
3204 return false;
3205 }
3206 }
3207 if (!RISCVII::hasSEWOp(TSFlags)) {
3208 ErrInfo = "VL operand w/o SEW operand?";
3209 return false;
3210 }
3211 }
3212 if (RISCVII::hasSEWOp(TSFlags)) {
3213 unsigned OpIdx = RISCVII::getSEWOpNum(Desc);
3214 if (!MI.getOperand(OpIdx).isImm()) {
3215 ErrInfo = "SEW value expected to be an immediate";
3216 return false;
3217 }
3218 uint64_t Log2SEW = MI.getOperand(OpIdx).getImm();
3219 if (Log2SEW > 31) {
3220 ErrInfo = "Unexpected SEW value";
3221 return false;
3222 }
3223 unsigned SEW = Log2SEW ? 1 << Log2SEW : 8;
3224 if (!RISCVVType::isValidSEW(SEW)) {
3225 ErrInfo = "Unexpected SEW value";
3226 return false;
3227 }
3228 }
3229 if (RISCVII::hasVecPolicyOp(TSFlags)) {
3231 if (!MI.getOperand(OpIdx).isImm()) {
3232 ErrInfo = "Policy operand expected to be an immediate";
3233 return false;
3234 }
3235 uint64_t Policy = MI.getOperand(OpIdx).getImm();
3237 ErrInfo = "Invalid Policy Value";
3238 return false;
3239 }
3240 if (!RISCVII::hasVLOp(TSFlags)) {
3241 ErrInfo = "policy operand w/o VL operand?";
3242 return false;
3243 }
3244
3245 // VecPolicy operands can only exist on instructions with passthru/merge
3246 // arguments. Note that not all arguments with passthru have vec policy
3247 // operands- some instructions have implicit policies.
3248 unsigned UseOpIdx;
3249 if (!MI.isRegTiedToUseOperand(0, &UseOpIdx)) {
3250 ErrInfo = "policy operand w/o tied operand?";
3251 return false;
3252 }
3253 }
3254
3255 if (int Idx = RISCVII::getFRMOpNum(Desc);
3256 Idx >= 0 && MI.getOperand(Idx).getImm() == RISCVFPRndMode::DYN &&
3257 !MI.readsRegister(RISCV::FRM, /*TRI=*/nullptr)) {
3258 ErrInfo = "dynamic rounding mode should read FRM";
3259 return false;
3260 }
3261
3262 return true;
3263}
3264
3266 const MachineInstr &AddrI,
3267 ExtAddrMode &AM) const {
3268 switch (MemI.getOpcode()) {
3269 default:
3270 return false;
3271 case RISCV::LB:
3272 case RISCV::LBU:
3273 case RISCV::LH:
3274 case RISCV::LH_INX:
3275 case RISCV::LHU:
3276 case RISCV::LW:
3277 case RISCV::LW_INX:
3278 case RISCV::LWU:
3279 case RISCV::LD:
3280 case RISCV::LD_RV32:
3281 case RISCV::FLH:
3282 case RISCV::FLW:
3283 case RISCV::FLD:
3284 case RISCV::SB:
3285 case RISCV::SH:
3286 case RISCV::SH_INX:
3287 case RISCV::SW:
3288 case RISCV::SW_INX:
3289 case RISCV::SD:
3290 case RISCV::SD_RV32:
3291 case RISCV::FSH:
3292 case RISCV::FSW:
3293 case RISCV::FSD:
3294 break;
3295 }
3296
3297 if (MemI.getOperand(0).getReg() == Reg)
3298 return false;
3299
3300 if (AddrI.getOpcode() != RISCV::ADDI || !AddrI.getOperand(1).isReg() ||
3301 !AddrI.getOperand(2).isImm())
3302 return false;
3303
3304 int64_t OldOffset = MemI.getOperand(2).getImm();
3305 int64_t Disp = AddrI.getOperand(2).getImm();
3306 int64_t NewOffset = OldOffset + Disp;
3307 if (!STI.is64Bit())
3308 NewOffset = SignExtend64<32>(NewOffset);
3309
3310 if (!isInt<12>(NewOffset))
3311 return false;
3312
3313 AM.BaseReg = AddrI.getOperand(1).getReg();
3314 AM.ScaledReg = 0;
3315 AM.Scale = 0;
3316 AM.Displacement = NewOffset;
3318 return true;
3319}
3320
3322 const ExtAddrMode &AM) const {
3323
3324 const DebugLoc &DL = MemI.getDebugLoc();
3325 MachineBasicBlock &MBB = *MemI.getParent();
3326
3327 assert(AM.ScaledReg == 0 && AM.Scale == 0 &&
3328 "Addressing mode not supported for folding");
3329
3330 return BuildMI(MBB, MemI, DL, get(MemI.getOpcode()))
3331 .addReg(MemI.getOperand(0).getReg(),
3332 MemI.mayLoad() ? RegState::Define : 0)
3333 .addReg(AM.BaseReg)
3334 .addImm(AM.Displacement)
3335 .setMemRefs(MemI.memoperands())
3336 .setMIFlags(MemI.getFlags());
3337}
3338
3339// TODO: At the moment, MIPS introduced paring of instructions operating with
3340// word or double word. This should be extended with more instructions when more
3341// vendors support load/store pairing.
3343 switch (Opc) {
3344 default:
3345 return false;
3346 case RISCV::SW:
3347 case RISCV::SD:
3348 case RISCV::LD:
3349 case RISCV::LW:
3350 return true;
3351 }
3352}
3353
3355 const TargetRegisterInfo *TRI) {
3356 // If this is a volatile load/store, don't mess with it.
3357 if (LdSt.hasOrderedMemoryRef() || LdSt.getNumExplicitOperands() != 3)
3358 return false;
3359
3360 if (LdSt.getOperand(1).isFI())
3361 return true;
3362
3363 assert(LdSt.getOperand(1).isReg() && "Expected a reg operand.");
3364 // Can't cluster if the instruction modifies the base register
3365 // or it is update form. e.g. ld x5,8(x5)
3366 if (LdSt.modifiesRegister(LdSt.getOperand(1).getReg(), TRI))
3367 return false;
3368
3369 if (!LdSt.getOperand(2).isImm())
3370 return false;
3371
3372 return true;
3373}
3374
3377 int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width,
3378 const TargetRegisterInfo *TRI) const {
3379 if (!LdSt.mayLoadOrStore())
3380 return false;
3381
3382 // Conservatively, only handle scalar loads/stores for now.
3383 switch (LdSt.getOpcode()) {
3384 case RISCV::LB:
3385 case RISCV::LBU:
3386 case RISCV::SB:
3387 case RISCV::LH:
3388 case RISCV::LH_INX:
3389 case RISCV::LHU:
3390 case RISCV::FLH:
3391 case RISCV::SH:
3392 case RISCV::SH_INX:
3393 case RISCV::FSH:
3394 case RISCV::LW:
3395 case RISCV::LW_INX:
3396 case RISCV::LWU:
3397 case RISCV::FLW:
3398 case RISCV::SW:
3399 case RISCV::SW_INX:
3400 case RISCV::FSW:
3401 case RISCV::LD:
3402 case RISCV::LD_RV32:
3403 case RISCV::FLD:
3404 case RISCV::SD:
3405 case RISCV::SD_RV32:
3406 case RISCV::FSD:
3407 break;
3408 default:
3409 return false;
3410 }
3411 const MachineOperand *BaseOp;
3412 OffsetIsScalable = false;
3413 if (!getMemOperandWithOffsetWidth(LdSt, BaseOp, Offset, Width, TRI))
3414 return false;
3415 BaseOps.push_back(BaseOp);
3416 return true;
3417}
3418
3419// TODO: This was copied from SIInstrInfo. Could it be lifted to a common
3420// helper?
3423 const MachineInstr &MI2,
3425 // Only examine the first "base" operand of each instruction, on the
3426 // assumption that it represents the real base address of the memory access.
3427 // Other operands are typically offsets or indices from this base address.
3428 if (BaseOps1.front()->isIdenticalTo(*BaseOps2.front()))
3429 return true;
3430
3431 if (!MI1.hasOneMemOperand() || !MI2.hasOneMemOperand())
3432 return false;
3433
3434 auto MO1 = *MI1.memoperands_begin();
3435 auto MO2 = *MI2.memoperands_begin();
3436 if (MO1->getAddrSpace() != MO2->getAddrSpace())
3437 return false;
3438
3439 auto Base1 = MO1->getValue();
3440 auto Base2 = MO2->getValue();
3441 if (!Base1 || !Base2)
3442 return false;
3443 Base1 = getUnderlyingObject(Base1);
3444 Base2 = getUnderlyingObject(Base2);
3445
3446 if (isa<UndefValue>(Base1) || isa<UndefValue>(Base2))
3447 return false;
3448
3449 return Base1 == Base2;
3450}
3451
3453 ArrayRef<const MachineOperand *> BaseOps1, int64_t Offset1,
3454 bool OffsetIsScalable1, ArrayRef<const MachineOperand *> BaseOps2,
3455 int64_t Offset2, bool OffsetIsScalable2, unsigned ClusterSize,
3456 unsigned NumBytes) const {
3457 // If the mem ops (to be clustered) do not have the same base ptr, then they
3458 // should not be clustered
3459 if (!BaseOps1.empty() && !BaseOps2.empty()) {
3460 const MachineInstr &FirstLdSt = *BaseOps1.front()->getParent();
3461 const MachineInstr &SecondLdSt = *BaseOps2.front()->getParent();
3462 if (!memOpsHaveSameBasePtr(FirstLdSt, BaseOps1, SecondLdSt, BaseOps2))
3463 return false;
3464 } else if (!BaseOps1.empty() || !BaseOps2.empty()) {
3465 // If only one base op is empty, they do not have the same base ptr
3466 return false;
3467 }
3468
3469 unsigned CacheLineSize =
3470 BaseOps1.front()->getParent()->getMF()->getSubtarget().getCacheLineSize();
3471 // Assume a cache line size of 64 bytes if no size is set in RISCVSubtarget.
3473 // Cluster if the memory operations are on the same or a neighbouring cache
3474 // line, but limit the maximum ClusterSize to avoid creating too much
3475 // additional register pressure.
3476 return ClusterSize <= 4 && std::abs(Offset1 - Offset2) < CacheLineSize;
3477}
3478
3479// Set BaseReg (the base register operand), Offset (the byte offset being
3480// accessed) and the access Width of the passed instruction that reads/writes
3481// memory. Returns false if the instruction does not read/write memory or the
3482// BaseReg/Offset/Width can't be determined. Is not guaranteed to always
3483// recognise base operands and offsets in all cases.
3484// TODO: Add an IsScalable bool ref argument (like the equivalent AArch64
3485// function) and set it as appropriate.
3487 const MachineInstr &LdSt, const MachineOperand *&BaseReg, int64_t &Offset,
3488 LocationSize &Width, const TargetRegisterInfo *TRI) const {
3489 if (!LdSt.mayLoadOrStore())
3490 return false;
3491
3492 // Here we assume the standard RISC-V ISA, which uses a base+offset
3493 // addressing mode. You'll need to relax these conditions to support custom
3494 // load/store instructions.
3495 if (LdSt.getNumExplicitOperands() != 3)
3496 return false;
3497 if ((!LdSt.getOperand(1).isReg() && !LdSt.getOperand(1).isFI()) ||
3498 !LdSt.getOperand(2).isImm())
3499 return false;
3500
3501 if (!LdSt.hasOneMemOperand())
3502 return false;
3503
3504 Width = (*LdSt.memoperands_begin())->getSize();
3505 BaseReg = &LdSt.getOperand(1);
3506 Offset = LdSt.getOperand(2).getImm();
3507 return true;
3508}
3509
3511 const MachineInstr &MIa, const MachineInstr &MIb) const {
3512 assert(MIa.mayLoadOrStore() && "MIa must be a load or store.");
3513 assert(MIb.mayLoadOrStore() && "MIb must be a load or store.");
3514
3517 return false;
3518
3519 // Retrieve the base register, offset from the base register and width. Width
3520 // is the size of memory that is being loaded/stored (e.g. 1, 2, 4). If
3521 // base registers are identical, and the offset of a lower memory access +
3522 // the width doesn't overlap the offset of a higher memory access,
3523 // then the memory accesses are different.
3524 const TargetRegisterInfo *TRI = STI.getRegisterInfo();
3525 const MachineOperand *BaseOpA = nullptr, *BaseOpB = nullptr;
3526 int64_t OffsetA = 0, OffsetB = 0;
3528 WidthB = LocationSize::precise(0);
3529 if (getMemOperandWithOffsetWidth(MIa, BaseOpA, OffsetA, WidthA, TRI) &&
3530 getMemOperandWithOffsetWidth(MIb, BaseOpB, OffsetB, WidthB, TRI)) {
3531 if (BaseOpA->isIdenticalTo(*BaseOpB)) {
3532 int LowOffset = std::min(OffsetA, OffsetB);
3533 int HighOffset = std::max(OffsetA, OffsetB);
3534 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
3535 if (LowWidth.hasValue() &&
3536 LowOffset + (int)LowWidth.getValue() <= HighOffset)
3537 return true;
3538 }
3539 }
3540 return false;
3541}
3542
3543std::pair<unsigned, unsigned>
3545 const unsigned Mask = RISCVII::MO_DIRECT_FLAG_MASK;
3546 return std::make_pair(TF & Mask, TF & ~Mask);
3547}
3548
3551 using namespace RISCVII;
3552 static const std::pair<unsigned, const char *> TargetFlags[] = {
3553 {MO_CALL, "riscv-call"},
3554 {MO_LO, "riscv-lo"},
3555 {MO_HI, "riscv-hi"},
3556 {MO_PCREL_LO, "riscv-pcrel-lo"},
3557 {MO_PCREL_HI, "riscv-pcrel-hi"},
3558 {MO_GOT_HI, "riscv-got-hi"},
3559 {MO_TPREL_LO, "riscv-tprel-lo"},
3560 {MO_TPREL_HI, "riscv-tprel-hi"},
3561 {MO_TPREL_ADD, "riscv-tprel-add"},
3562 {MO_TLS_GOT_HI, "riscv-tls-got-hi"},
3563 {MO_TLS_GD_HI, "riscv-tls-gd-hi"},
3564 {MO_TLSDESC_HI, "riscv-tlsdesc-hi"},
3565 {MO_TLSDESC_LOAD_LO, "riscv-tlsdesc-load-lo"},
3566 {MO_TLSDESC_ADD_LO, "riscv-tlsdesc-add-lo"},
3567 {MO_TLSDESC_CALL, "riscv-tlsdesc-call"}};
3568 return ArrayRef(TargetFlags);
3569}
3571 MachineFunction &MF, bool OutlineFromLinkOnceODRs) const {
3572 const Function &F = MF.getFunction();
3573
3574 // Can F be deduplicated by the linker? If it can, don't outline from it.
3575 if (!OutlineFromLinkOnceODRs && F.hasLinkOnceODRLinkage())
3576 return false;
3577
3578 // Don't outline from functions with section markings; the program could
3579 // expect that all the code is in the named section.
3580 if (F.hasSection())
3581 return false;
3582
3583 // It's safe to outline from MF.
3584 return true;
3585}
3586
3588 unsigned &Flags) const {
3589 // More accurate safety checking is done in getOutliningCandidateInfo.
3591}
3592
3593// Enum values indicating how an outlined call should be constructed.
3598
3603
3605 const MachineFunction *MF = MBB.getParent();
3606 const Function &F = MF->getFunction();
3607 return F.getFnAttribute("fentry-call").getValueAsBool() ||
3608 F.hasFnAttribute("patchable-function-entry");
3609}
3610
3612 MCRegister RegNo) {
3613 return MI.readsRegister(RegNo, TRI) ||
3614 MI.getDesc().hasImplicitUseOfPhysReg(RegNo);
3615}
3616
3618 const TargetRegisterInfo *TRI, MCRegister RegNo) {
3619 return MI.modifiesRegister(RegNo, TRI) ||
3620 MI.getDesc().hasImplicitDefOfPhysReg(RegNo);
3621}
3622
3624 if (!MBB.back().isReturn())
3625 return true;
3627 return true;
3628
3629 // If the candidate reads the pre-set register
3630 // that can be used for expanding PseudoTAIL instruction,
3631 // then we cannot insert tail call.
3632 const TargetSubtargetInfo &STI = MBB.getParent()->getSubtarget();
3633 MCRegister TailExpandUseRegNo =
3635 for (const MachineInstr &MI : MBB) {
3636 if (isMIReadsReg(MI, STI.getRegisterInfo(), TailExpandUseRegNo))
3637 return true;
3638 if (isMIModifiesReg(MI, STI.getRegisterInfo(), TailExpandUseRegNo))
3639 break;
3640 }
3641 return false;
3642}
3643
3645 // If last instruction is return then we can rely on
3646 // the verification already performed in the getOutliningTypeImpl.
3647 if (C.back().isReturn()) {
3648 assert(!cannotInsertTailCall(*C.getMBB()) &&
3649 "The candidate who uses return instruction must be outlined "
3650 "using tail call");
3651 return false;
3652 }
3653
3654 // Filter out candidates where the X5 register (t0) can't be used to setup
3655 // the function call.
3656 const TargetRegisterInfo *TRI = C.getMF()->getSubtarget().getRegisterInfo();
3657 if (llvm::any_of(C, [TRI](const MachineInstr &MI) {
3658 return isMIModifiesReg(MI, TRI, RISCV::X5);
3659 }))
3660 return true;
3661
3662 return !C.isAvailableAcrossAndOutOfSeq(RISCV::X5, *TRI);
3663}
3664
3665std::optional<std::unique_ptr<outliner::OutlinedFunction>>
3667 const MachineModuleInfo &MMI,
3668 std::vector<outliner::Candidate> &RepeatedSequenceLocs,
3669 unsigned MinRepeats) const {
3670
3671 // Analyze each candidate and erase the ones that are not viable.
3672 llvm::erase_if(RepeatedSequenceLocs, analyzeCandidate);
3673
3674 // If the sequence doesn't have enough candidates left, then we're done.
3675 if (RepeatedSequenceLocs.size() < MinRepeats)
3676 return std::nullopt;
3677
3678 // Each RepeatedSequenceLoc is identical.
3679 outliner::Candidate &Candidate = RepeatedSequenceLocs[0];
3680 unsigned InstrSizeCExt =
3681 Candidate.getMF()->getSubtarget<RISCVSubtarget>().hasStdExtZca() ? 2 : 4;
3682 unsigned CallOverhead = 0, FrameOverhead = 0;
3683
3684 // Count the number of CFI instructions in the candidate, if present.
3685 unsigned CFICount = 0;
3686 for (auto &I : Candidate) {
3687 if (I.isCFIInstruction())
3688 CFICount++;
3689 }
3690
3691 // Ensure CFI coverage matches: comparing the number of CFIs in the candidate
3692 // with the total number of CFIs in the parent function for each candidate.
3693 // Outlining only a subset of a function’s CFIs would split the unwind state
3694 // across two code regions and lead to incorrect address offsets between the
3695 // outlined body and the remaining code. To preserve correct unwind info, we
3696 // only outline when all CFIs in the function can be outlined together.
3697 for (outliner::Candidate &C : RepeatedSequenceLocs) {
3698 std::vector<MCCFIInstruction> CFIInstructions =
3699 C.getMF()->getFrameInstructions();
3700
3701 if (CFICount > 0 && CFICount != CFIInstructions.size())
3702 return std::nullopt;
3703 }
3704
3706 if (Candidate.back().isReturn()) {
3708 // tail call = auipc + jalr in the worst case without linker relaxation.
3709 // FIXME: This code suggests the JALR can be compressed - how?
3710 CallOverhead = 4 + InstrSizeCExt;
3711 // Using tail call we move ret instruction from caller to callee.
3712 FrameOverhead = 0;
3713 } else {
3714 // call t0, function = 8 bytes.
3715 CallOverhead = 8;
3716 // jr t0 = 4 bytes, 2 bytes if compressed instructions are enabled.
3717 FrameOverhead = InstrSizeCExt;
3718 }
3719
3720 // If we have CFI instructions, we can only outline if the outlined section
3721 // can be a tail call.
3722 if (MOCI != MachineOutlinerTailCall && CFICount > 0)
3723 return std::nullopt;
3724
3725 for (auto &C : RepeatedSequenceLocs)
3726 C.setCallInfo(MOCI, CallOverhead);
3727
3728 unsigned SequenceSize = 0;
3729 for (auto &MI : Candidate)
3730 SequenceSize += getInstSizeInBytes(MI);
3731
3732 return std::make_unique<outliner::OutlinedFunction>(
3733 RepeatedSequenceLocs, SequenceSize, FrameOverhead, MOCI);
3734}
3735
3739 unsigned Flags) const {
3740 MachineInstr &MI = *MBBI;
3741 MachineBasicBlock *MBB = MI.getParent();
3742 const TargetRegisterInfo *TRI =
3743 MBB->getParent()->getSubtarget().getRegisterInfo();
3744 const auto &F = MI.getMF()->getFunction();
3745
3746 // We can only outline CFI instructions if we will tail call the outlined
3747 // function, or fix up the CFI offsets. Currently, CFI instructions are
3748 // outlined only if in a tail call.
3749 if (MI.isCFIInstruction())
3751
3752 if (cannotInsertTailCall(*MBB) &&
3753 (MI.isReturn() || isMIModifiesReg(MI, TRI, RISCV::X5)))
3755
3756 // Make sure the operands don't reference something unsafe.
3757 for (const auto &MO : MI.operands()) {
3758
3759 // pcrel-hi and pcrel-lo can't put in separate sections, filter that out
3760 // if any possible.
3761 if (MO.getTargetFlags() == RISCVII::MO_PCREL_LO &&
3762 (MI.getMF()->getTarget().getFunctionSections() || F.hasComdat() ||
3763 F.hasSection() || F.getSectionPrefix()))
3765 }
3766
3767 if (isLPAD(MI))
3769
3771}
3772
3775 const outliner::OutlinedFunction &OF) const {
3776
3777 if (OF.FrameConstructionID == MachineOutlinerTailCall)
3778 return;
3779
3780 MBB.addLiveIn(RISCV::X5);
3781
3782 // Add in a return instruction to the end of the outlined frame.
3783 MBB.insert(MBB.end(), BuildMI(MF, DebugLoc(), get(RISCV::JALR))
3784 .addReg(RISCV::X0, RegState::Define)
3785 .addReg(RISCV::X5)
3786 .addImm(0));
3787}
3788
3792
3793 if (C.CallConstructionID == MachineOutlinerTailCall) {
3794 It = MBB.insert(It, BuildMI(MF, DebugLoc(), get(RISCV::PseudoTAIL))
3795 .addGlobalAddress(M.getNamedValue(MF.getName()),
3796 /*Offset=*/0, RISCVII::MO_CALL));
3797 return It;
3798 }
3799
3800 // Add in a call instruction to the outlined function at the given location.
3801 It = MBB.insert(It,
3802 BuildMI(MF, DebugLoc(), get(RISCV::PseudoCALLReg), RISCV::X5)
3803 .addGlobalAddress(M.getNamedValue(MF.getName()), 0,
3805 return It;
3806}
3807
3808std::optional<RegImmPair> RISCVInstrInfo::isAddImmediate(const MachineInstr &MI,
3809 Register Reg) const {
3810 // TODO: Handle cases where Reg is a super- or sub-register of the
3811 // destination register.
3812 const MachineOperand &Op0 = MI.getOperand(0);
3813 if (!Op0.isReg() || Reg != Op0.getReg())
3814 return std::nullopt;
3815
3816 // Don't consider ADDIW as a candidate because the caller may not be aware
3817 // of its sign extension behaviour.
3818 if (MI.getOpcode() == RISCV::ADDI && MI.getOperand(1).isReg() &&
3819 MI.getOperand(2).isImm())
3820 return RegImmPair{MI.getOperand(1).getReg(), MI.getOperand(2).getImm()};
3821
3822 return std::nullopt;
3823}
3824
3825// MIR printer helper function to annotate Operands with a comment.
3827 const MachineInstr &MI, const MachineOperand &Op, unsigned OpIdx,
3828 const TargetRegisterInfo *TRI) const {
3829 // Print a generic comment for this operand if there is one.
3830 std::string GenericComment =
3832 if (!GenericComment.empty())
3833 return GenericComment;
3834
3835 // If not, we must have an immediate operand.
3836 if (!Op.isImm())
3837 return std::string();
3838
3839 const MCInstrDesc &Desc = MI.getDesc();
3840 if (OpIdx >= Desc.getNumOperands())
3841 return std::string();
3842
3843 std::string Comment;
3844 raw_string_ostream OS(Comment);
3845
3846 const MCOperandInfo &OpInfo = Desc.operands()[OpIdx];
3847
3848 // Print the full VType operand of vsetvli/vsetivli instructions, and the SEW
3849 // operand of vector codegen pseudos.
3850 switch (OpInfo.OperandType) {
3853 unsigned Imm = Op.getImm();
3854 RISCVVType::printVType(Imm, OS);
3855 break;
3856 }
3858 unsigned Imm = Op.getImm();
3860 break;
3861 }
3863 unsigned Imm = Op.getImm();
3864 OS << "w" << Imm;
3865 break;
3866 }
3869 unsigned Log2SEW = Op.getImm();
3870 unsigned SEW = Log2SEW ? 1 << Log2SEW : 8;
3871 assert(RISCVVType::isValidSEW(SEW) && "Unexpected SEW");
3872 OS << "e" << SEW;
3873 break;
3874 }
3876 unsigned Policy = Op.getImm();
3878 "Invalid Policy Value");
3879 OS << (Policy & RISCVVType::TAIL_AGNOSTIC ? "ta" : "tu") << ", "
3880 << (Policy & RISCVVType::MASK_AGNOSTIC ? "ma" : "mu");
3881 break;
3882 }
3883
3884 return Comment;
3885}
3886
3887// clang-format off
3888#define CASE_RVV_OPCODE_UNMASK_LMUL(OP, LMUL) \
3889 RISCV::Pseudo##OP##_##LMUL
3890
3891#define CASE_RVV_OPCODE_MASK_LMUL(OP, LMUL) \
3892 RISCV::Pseudo##OP##_##LMUL##_MASK
3893
3894#define CASE_RVV_OPCODE_LMUL(OP, LMUL) \
3895 CASE_RVV_OPCODE_UNMASK_LMUL(OP, LMUL): \
3896 case CASE_RVV_OPCODE_MASK_LMUL(OP, LMUL)
3897
3898#define CASE_RVV_OPCODE_UNMASK_WIDEN(OP) \
3899 CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF8): \
3900 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF4): \
3901 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF2): \
3902 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M1): \
3903 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M2): \
3904 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M4)
3905
3906#define CASE_RVV_OPCODE_UNMASK(OP) \
3907 CASE_RVV_OPCODE_UNMASK_WIDEN(OP): \
3908 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M8)
3909
3910#define CASE_RVV_OPCODE_MASK_WIDEN(OP) \
3911 CASE_RVV_OPCODE_MASK_LMUL(OP, MF8): \
3912 case CASE_RVV_OPCODE_MASK_LMUL(OP, MF4): \
3913 case CASE_RVV_OPCODE_MASK_LMUL(OP, MF2): \
3914 case CASE_RVV_OPCODE_MASK_LMUL(OP, M1): \
3915 case CASE_RVV_OPCODE_MASK_LMUL(OP, M2): \
3916 case CASE_RVV_OPCODE_MASK_LMUL(OP, M4)
3917
3918#define CASE_RVV_OPCODE_MASK(OP) \
3919 CASE_RVV_OPCODE_MASK_WIDEN(OP): \
3920 case CASE_RVV_OPCODE_MASK_LMUL(OP, M8)
3921
3922#define CASE_RVV_OPCODE_WIDEN(OP) \
3923 CASE_RVV_OPCODE_UNMASK_WIDEN(OP): \
3924 case CASE_RVV_OPCODE_MASK_WIDEN(OP)
3925
3926#define CASE_RVV_OPCODE(OP) \
3927 CASE_RVV_OPCODE_UNMASK(OP): \
3928 case CASE_RVV_OPCODE_MASK(OP)
3929// clang-format on
3930
3931// clang-format off
3932#define CASE_VMA_OPCODE_COMMON(OP, TYPE, LMUL) \
3933 RISCV::PseudoV##OP##_##TYPE##_##LMUL
3934
3935#define CASE_VMA_OPCODE_LMULS(OP, TYPE) \
3936 CASE_VMA_OPCODE_COMMON(OP, TYPE, MF8): \
3937 case CASE_VMA_OPCODE_COMMON(OP, TYPE, MF4): \
3938 case CASE_VMA_OPCODE_COMMON(OP, TYPE, MF2): \
3939 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M1): \
3940 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M2): \
3941 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M4): \
3942 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M8)
3943
3944// VFMA instructions are SEW specific.
3945#define CASE_VFMA_OPCODE_COMMON(OP, TYPE, LMUL, SEW) \
3946 RISCV::PseudoV##OP##_##TYPE##_##LMUL##_##SEW
3947
3948#define CASE_VFMA_OPCODE_LMULS_M1(OP, TYPE, SEW) \
3949 CASE_VFMA_OPCODE_COMMON(OP, TYPE, M1, SEW): \
3950 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M2, SEW): \
3951 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M4, SEW): \
3952 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M8, SEW)
3953
3954#define CASE_VFMA_OPCODE_LMULS_MF2(OP, TYPE, SEW) \
3955 CASE_VFMA_OPCODE_COMMON(OP, TYPE, MF2, SEW): \
3956 case CASE_VFMA_OPCODE_LMULS_M1(OP, TYPE, SEW)
3957
3958#define CASE_VFMA_OPCODE_LMULS_MF4(OP, TYPE, SEW) \
3959 CASE_VFMA_OPCODE_COMMON(OP, TYPE, MF4, SEW): \
3960 case CASE_VFMA_OPCODE_LMULS_MF2(OP, TYPE, SEW)
3961
3962#define CASE_VFMA_OPCODE_VV(OP) \
3963 CASE_VFMA_OPCODE_LMULS_MF4(OP, VV, E16): \
3964 case CASE_VFMA_OPCODE_LMULS_MF4(OP##_ALT, VV, E16): \
3965 case CASE_VFMA_OPCODE_LMULS_MF2(OP, VV, E32): \
3966 case CASE_VFMA_OPCODE_LMULS_M1(OP, VV, E64)
3967
3968#define CASE_VFMA_SPLATS(OP) \
3969 CASE_VFMA_OPCODE_LMULS_MF4(OP, VFPR16, E16): \
3970 case CASE_VFMA_OPCODE_LMULS_MF4(OP##_ALT, VFPR16, E16): \
3971 case CASE_VFMA_OPCODE_LMULS_MF2(OP, VFPR32, E32): \
3972 case CASE_VFMA_OPCODE_LMULS_M1(OP, VFPR64, E64)
3973// clang-format on
3974
3976 unsigned &SrcOpIdx1,
3977 unsigned &SrcOpIdx2) const {
3978 const MCInstrDesc &Desc = MI.getDesc();
3979 if (!Desc.isCommutable())
3980 return false;
3981
3982 switch (MI.getOpcode()) {
3983 case RISCV::TH_MVEQZ:
3984 case RISCV::TH_MVNEZ:
3985 // We can't commute operands if operand 2 (i.e., rs1 in
3986 // mveqz/mvnez rd,rs1,rs2) is the zero-register (as it is
3987 // not valid as the in/out-operand 1).
3988 if (MI.getOperand(2).getReg() == RISCV::X0)
3989 return false;
3990 // Operands 1 and 2 are commutable, if we switch the opcode.
3991 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 2);
3992 case RISCV::QC_SELECTIEQ:
3993 case RISCV::QC_SELECTINE:
3994 case RISCV::QC_SELECTIIEQ:
3995 case RISCV::QC_SELECTIINE:
3996 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 2);
3997 case RISCV::QC_MVEQ:
3998 case RISCV::QC_MVNE:
3999 case RISCV::QC_MVLT:
4000 case RISCV::QC_MVGE:
4001 case RISCV::QC_MVLTU:
4002 case RISCV::QC_MVGEU:
4003 case RISCV::QC_MVEQI:
4004 case RISCV::QC_MVNEI:
4005 case RISCV::QC_MVLTI:
4006 case RISCV::QC_MVGEI:
4007 case RISCV::QC_MVLTUI:
4008 case RISCV::QC_MVGEUI:
4009 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 4);
4010 case RISCV::TH_MULA:
4011 case RISCV::TH_MULAW:
4012 case RISCV::TH_MULAH:
4013 case RISCV::TH_MULS:
4014 case RISCV::TH_MULSW:
4015 case RISCV::TH_MULSH:
4016 // Operands 2 and 3 are commutable.
4017 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
4018 case RISCV::PseudoCCMOVGPRNoX0:
4019 case RISCV::PseudoCCMOVGPR:
4020 // Operands 4 and 5 are commutable.
4021 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 4, 5);
4022 case CASE_RVV_OPCODE(VADD_VV):
4023 case CASE_RVV_OPCODE(VAND_VV):
4024 case CASE_RVV_OPCODE(VOR_VV):
4025 case CASE_RVV_OPCODE(VXOR_VV):
4026 case CASE_RVV_OPCODE_MASK(VMSEQ_VV):
4027 case CASE_RVV_OPCODE_MASK(VMSNE_VV):
4028 case CASE_RVV_OPCODE(VMIN_VV):
4029 case CASE_RVV_OPCODE(VMINU_VV):
4030 case CASE_RVV_OPCODE(VMAX_VV):
4031 case CASE_RVV_OPCODE(VMAXU_VV):
4032 case CASE_RVV_OPCODE(VMUL_VV):
4033 case CASE_RVV_OPCODE(VMULH_VV):
4034 case CASE_RVV_OPCODE(VMULHU_VV):
4035 case CASE_RVV_OPCODE_WIDEN(VWADD_VV):
4036 case CASE_RVV_OPCODE_WIDEN(VWADDU_VV):
4037 case CASE_RVV_OPCODE_WIDEN(VWMUL_VV):
4038 case CASE_RVV_OPCODE_WIDEN(VWMULU_VV):
4039 case CASE_RVV_OPCODE_WIDEN(VWMACC_VV):
4040 case CASE_RVV_OPCODE_WIDEN(VWMACCU_VV):
4041 case CASE_RVV_OPCODE_UNMASK(VADC_VVM):
4042 case CASE_RVV_OPCODE(VSADD_VV):
4043 case CASE_RVV_OPCODE(VSADDU_VV):
4044 case CASE_RVV_OPCODE(VAADD_VV):
4045 case CASE_RVV_OPCODE(VAADDU_VV):
4046 case CASE_RVV_OPCODE(VSMUL_VV):
4047 // Operands 2 and 3 are commutable.
4048 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
4049 case CASE_VFMA_SPLATS(FMADD):
4050 case CASE_VFMA_SPLATS(FMSUB):
4051 case CASE_VFMA_SPLATS(FMACC):
4052 case CASE_VFMA_SPLATS(FMSAC):
4055 case CASE_VFMA_SPLATS(FNMACC):
4056 case CASE_VFMA_SPLATS(FNMSAC):
4057 case CASE_VFMA_OPCODE_VV(FMACC):
4058 case CASE_VFMA_OPCODE_VV(FMSAC):
4059 case CASE_VFMA_OPCODE_VV(FNMACC):
4060 case CASE_VFMA_OPCODE_VV(FNMSAC):
4061 case CASE_VMA_OPCODE_LMULS(MADD, VX):
4062 case CASE_VMA_OPCODE_LMULS(NMSUB, VX):
4063 case CASE_VMA_OPCODE_LMULS(MACC, VX):
4064 case CASE_VMA_OPCODE_LMULS(NMSAC, VX):
4065 case CASE_VMA_OPCODE_LMULS(MACC, VV):
4066 case CASE_VMA_OPCODE_LMULS(NMSAC, VV): {
4067 // If the tail policy is undisturbed we can't commute.
4068 assert(RISCVII::hasVecPolicyOp(MI.getDesc().TSFlags));
4069 if ((MI.getOperand(RISCVII::getVecPolicyOpNum(MI.getDesc())).getImm() &
4070 1) == 0)
4071 return false;
4072
4073 // For these instructions we can only swap operand 1 and operand 3 by
4074 // changing the opcode.
4075 unsigned CommutableOpIdx1 = 1;
4076 unsigned CommutableOpIdx2 = 3;
4077 if (!fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, CommutableOpIdx1,
4078 CommutableOpIdx2))
4079 return false;
4080 return true;
4081 }
4082 case CASE_VFMA_OPCODE_VV(FMADD):
4086 case CASE_VMA_OPCODE_LMULS(MADD, VV):
4087 case CASE_VMA_OPCODE_LMULS(NMSUB, VV): {
4088 // If the tail policy is undisturbed we can't commute.
4089 assert(RISCVII::hasVecPolicyOp(MI.getDesc().TSFlags));
4090 if ((MI.getOperand(RISCVII::getVecPolicyOpNum(MI.getDesc())).getImm() &
4091 1) == 0)
4092 return false;
4093
4094 // For these instructions we have more freedom. We can commute with the
4095 // other multiplicand or with the addend/subtrahend/minuend.
4096
4097 // Any fixed operand must be from source 1, 2 or 3.
4098 if (SrcOpIdx1 != CommuteAnyOperandIndex && SrcOpIdx1 > 3)
4099 return false;
4100 if (SrcOpIdx2 != CommuteAnyOperandIndex && SrcOpIdx2 > 3)
4101 return false;
4102
4103 // It both ops are fixed one must be the tied source.
4104 if (SrcOpIdx1 != CommuteAnyOperandIndex &&
4105 SrcOpIdx2 != CommuteAnyOperandIndex && SrcOpIdx1 != 1 && SrcOpIdx2 != 1)
4106 return false;
4107
4108 // Look for two different register operands assumed to be commutable
4109 // regardless of the FMA opcode. The FMA opcode is adjusted later if
4110 // needed.
4111 if (SrcOpIdx1 == CommuteAnyOperandIndex ||
4112 SrcOpIdx2 == CommuteAnyOperandIndex) {
4113 // At least one of operands to be commuted is not specified and
4114 // this method is free to choose appropriate commutable operands.
4115 unsigned CommutableOpIdx1 = SrcOpIdx1;
4116 if (SrcOpIdx1 == SrcOpIdx2) {
4117 // Both of operands are not fixed. Set one of commutable
4118 // operands to the tied source.
4119 CommutableOpIdx1 = 1;
4120 } else if (SrcOpIdx1 == CommuteAnyOperandIndex) {
4121 // Only one of the operands is not fixed.
4122 CommutableOpIdx1 = SrcOpIdx2;
4123 }
4124
4125 // CommutableOpIdx1 is well defined now. Let's choose another commutable
4126 // operand and assign its index to CommutableOpIdx2.
4127 unsigned CommutableOpIdx2;
4128 if (CommutableOpIdx1 != 1) {
4129 // If we haven't already used the tied source, we must use it now.
4130 CommutableOpIdx2 = 1;
4131 } else {
4132 Register Op1Reg = MI.getOperand(CommutableOpIdx1).getReg();
4133
4134 // The commuted operands should have different registers.
4135 // Otherwise, the commute transformation does not change anything and
4136 // is useless. We use this as a hint to make our decision.
4137 if (Op1Reg != MI.getOperand(2).getReg())
4138 CommutableOpIdx2 = 2;
4139 else
4140 CommutableOpIdx2 = 3;
4141 }
4142
4143 // Assign the found pair of commutable indices to SrcOpIdx1 and
4144 // SrcOpIdx2 to return those values.
4145 if (!fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, CommutableOpIdx1,
4146 CommutableOpIdx2))
4147 return false;
4148 }
4149
4150 return true;
4151 }
4152 }
4153
4154 return TargetInstrInfo::findCommutedOpIndices(MI, SrcOpIdx1, SrcOpIdx2);
4155}
4156
4157// clang-format off
4158#define CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, LMUL) \
4159 case RISCV::PseudoV##OLDOP##_##TYPE##_##LMUL: \
4160 Opc = RISCV::PseudoV##NEWOP##_##TYPE##_##LMUL; \
4161 break;
4162
4163#define CASE_VMA_CHANGE_OPCODE_LMULS(OLDOP, NEWOP, TYPE) \
4164 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF8) \
4165 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF4) \
4166 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF2) \
4167 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M1) \
4168 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M2) \
4169 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M4) \
4170 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M8)
4171
4172// VFMA depends on SEW.
4173#define CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, LMUL, SEW) \
4174 case RISCV::PseudoV##OLDOP##_##TYPE##_##LMUL##_##SEW: \
4175 Opc = RISCV::PseudoV##NEWOP##_##TYPE##_##LMUL##_##SEW; \
4176 break;
4177
4178#define CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, TYPE, SEW) \
4179 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M1, SEW) \
4180 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M2, SEW) \
4181 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M4, SEW) \
4182 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M8, SEW)
4183
4184#define CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, TYPE, SEW) \
4185 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF2, SEW) \
4186 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, TYPE, SEW)
4187
4188#define CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, TYPE, SEW) \
4189 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF4, SEW) \
4190 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, TYPE, SEW)
4191
4192#define CASE_VFMA_CHANGE_OPCODE_VV(OLDOP, NEWOP) \
4193 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, VV, E16) \
4194 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP##_ALT, NEWOP##_ALT, VV, E16) \
4195 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, VV, E32) \
4196 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, VV, E64)
4197
4198#define CASE_VFMA_CHANGE_OPCODE_SPLATS(OLDOP, NEWOP) \
4199 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, VFPR16, E16) \
4200 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP##_ALT, NEWOP##_ALT, VFPR16, E16) \
4201 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, VFPR32, E32) \
4202 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, VFPR64, E64)
4203// clang-format on
4204
4206 bool NewMI,
4207 unsigned OpIdx1,
4208 unsigned OpIdx2) const {
4209 auto cloneIfNew = [NewMI](MachineInstr &MI) -> MachineInstr & {
4210 if (NewMI)
4211 return *MI.getParent()->getParent()->CloneMachineInstr(&MI);
4212 return MI;
4213 };
4214
4215 switch (MI.getOpcode()) {
4216 case RISCV::TH_MVEQZ:
4217 case RISCV::TH_MVNEZ: {
4218 auto &WorkingMI = cloneIfNew(MI);
4219 WorkingMI.setDesc(get(MI.getOpcode() == RISCV::TH_MVEQZ ? RISCV::TH_MVNEZ
4220 : RISCV::TH_MVEQZ));
4221 return TargetInstrInfo::commuteInstructionImpl(WorkingMI, false, OpIdx1,
4222 OpIdx2);
4223 }
4224 case RISCV::QC_SELECTIEQ:
4225 case RISCV::QC_SELECTINE:
4226 case RISCV::QC_SELECTIIEQ:
4227 case RISCV::QC_SELECTIINE:
4228 return TargetInstrInfo::commuteInstructionImpl(MI, NewMI, OpIdx1, OpIdx2);
4229 case RISCV::QC_MVEQ:
4230 case RISCV::QC_MVNE:
4231 case RISCV::QC_MVLT:
4232 case RISCV::QC_MVGE:
4233 case RISCV::QC_MVLTU:
4234 case RISCV::QC_MVGEU:
4235 case RISCV::QC_MVEQI:
4236 case RISCV::QC_MVNEI:
4237 case RISCV::QC_MVLTI:
4238 case RISCV::QC_MVGEI:
4239 case RISCV::QC_MVLTUI:
4240 case RISCV::QC_MVGEUI: {
4241 auto &WorkingMI = cloneIfNew(MI);
4242 WorkingMI.setDesc(get(getInverseXqcicmOpcode(MI.getOpcode())));
4243 return TargetInstrInfo::commuteInstructionImpl(WorkingMI, false, OpIdx1,
4244 OpIdx2);
4245 }
4246 case RISCV::PseudoCCMOVGPRNoX0:
4247 case RISCV::PseudoCCMOVGPR: {
4248 // CCMOV can be commuted by inverting the condition.
4249 auto CC = static_cast<RISCVCC::CondCode>(MI.getOperand(3).getImm());
4251 auto &WorkingMI = cloneIfNew(MI);
4252 WorkingMI.getOperand(3).setImm(CC);
4253 return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI*/ false,
4254 OpIdx1, OpIdx2);
4255 }
4256 case CASE_VFMA_SPLATS(FMACC):
4257 case CASE_VFMA_SPLATS(FMADD):
4258 case CASE_VFMA_SPLATS(FMSAC):
4259 case CASE_VFMA_SPLATS(FMSUB):
4260 case CASE_VFMA_SPLATS(FNMACC):
4262 case CASE_VFMA_SPLATS(FNMSAC):
4264 case CASE_VFMA_OPCODE_VV(FMACC):
4265 case CASE_VFMA_OPCODE_VV(FMSAC):
4266 case CASE_VFMA_OPCODE_VV(FNMACC):
4267 case CASE_VFMA_OPCODE_VV(FNMSAC):
4268 case CASE_VMA_OPCODE_LMULS(MADD, VX):
4269 case CASE_VMA_OPCODE_LMULS(NMSUB, VX):
4270 case CASE_VMA_OPCODE_LMULS(MACC, VX):
4271 case CASE_VMA_OPCODE_LMULS(NMSAC, VX):
4272 case CASE_VMA_OPCODE_LMULS(MACC, VV):
4273 case CASE_VMA_OPCODE_LMULS(NMSAC, VV): {
4274 // It only make sense to toggle these between clobbering the
4275 // addend/subtrahend/minuend one of the multiplicands.
4276 assert((OpIdx1 == 1 || OpIdx2 == 1) && "Unexpected opcode index");
4277 assert((OpIdx1 == 3 || OpIdx2 == 3) && "Unexpected opcode index");
4278 unsigned Opc;
4279 switch (MI.getOpcode()) {
4280 default:
4281 llvm_unreachable("Unexpected opcode");
4282 CASE_VFMA_CHANGE_OPCODE_SPLATS(FMACC, FMADD)
4283 CASE_VFMA_CHANGE_OPCODE_SPLATS(FMADD, FMACC)
4290 CASE_VFMA_CHANGE_OPCODE_VV(FMACC, FMADD)
4294 CASE_VMA_CHANGE_OPCODE_LMULS(MACC, MADD, VX)
4295 CASE_VMA_CHANGE_OPCODE_LMULS(MADD, MACC, VX)
4296 CASE_VMA_CHANGE_OPCODE_LMULS(NMSAC, NMSUB, VX)
4297 CASE_VMA_CHANGE_OPCODE_LMULS(NMSUB, NMSAC, VX)
4298 CASE_VMA_CHANGE_OPCODE_LMULS(MACC, MADD, VV)
4299 CASE_VMA_CHANGE_OPCODE_LMULS(NMSAC, NMSUB, VV)
4300 }
4301
4302 auto &WorkingMI = cloneIfNew(MI);
4303 WorkingMI.setDesc(get(Opc));
4304 return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI=*/false,
4305 OpIdx1, OpIdx2);
4306 }
4307 case CASE_VFMA_OPCODE_VV(FMADD):
4311 case CASE_VMA_OPCODE_LMULS(MADD, VV):
4312 case CASE_VMA_OPCODE_LMULS(NMSUB, VV): {
4313 assert((OpIdx1 == 1 || OpIdx2 == 1) && "Unexpected opcode index");
4314 // If one of the operands, is the addend we need to change opcode.
4315 // Otherwise we're just swapping 2 of the multiplicands.
4316 if (OpIdx1 == 3 || OpIdx2 == 3) {
4317 unsigned Opc;
4318 switch (MI.getOpcode()) {
4319 default:
4320 llvm_unreachable("Unexpected opcode");
4321 CASE_VFMA_CHANGE_OPCODE_VV(FMADD, FMACC)
4325 CASE_VMA_CHANGE_OPCODE_LMULS(MADD, MACC, VV)
4326 CASE_VMA_CHANGE_OPCODE_LMULS(NMSUB, NMSAC, VV)
4327 }
4328
4329 auto &WorkingMI = cloneIfNew(MI);
4330 WorkingMI.setDesc(get(Opc));
4331 return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI=*/false,
4332 OpIdx1, OpIdx2);
4333 }
4334 // Let the default code handle it.
4335 break;
4336 }
4337 }
4338
4339 return TargetInstrInfo::commuteInstructionImpl(MI, NewMI, OpIdx1, OpIdx2);
4340}
4341
4342#undef CASE_VMA_CHANGE_OPCODE_COMMON
4343#undef CASE_VMA_CHANGE_OPCODE_LMULS
4344#undef CASE_VFMA_CHANGE_OPCODE_COMMON
4345#undef CASE_VFMA_CHANGE_OPCODE_LMULS_M1
4346#undef CASE_VFMA_CHANGE_OPCODE_LMULS_MF2
4347#undef CASE_VFMA_CHANGE_OPCODE_LMULS_MF4
4348#undef CASE_VFMA_CHANGE_OPCODE_VV
4349#undef CASE_VFMA_CHANGE_OPCODE_SPLATS
4350
4351#undef CASE_RVV_OPCODE_UNMASK_LMUL
4352#undef CASE_RVV_OPCODE_MASK_LMUL
4353#undef CASE_RVV_OPCODE_LMUL
4354#undef CASE_RVV_OPCODE_UNMASK_WIDEN
4355#undef CASE_RVV_OPCODE_UNMASK
4356#undef CASE_RVV_OPCODE_MASK_WIDEN
4357#undef CASE_RVV_OPCODE_MASK
4358#undef CASE_RVV_OPCODE_WIDEN
4359#undef CASE_RVV_OPCODE
4360
4361#undef CASE_VMA_OPCODE_COMMON
4362#undef CASE_VMA_OPCODE_LMULS
4363#undef CASE_VFMA_OPCODE_COMMON
4364#undef CASE_VFMA_OPCODE_LMULS_M1
4365#undef CASE_VFMA_OPCODE_LMULS_MF2
4366#undef CASE_VFMA_OPCODE_LMULS_MF4
4367#undef CASE_VFMA_OPCODE_VV
4368#undef CASE_VFMA_SPLATS
4369
4371 switch (MI.getOpcode()) {
4372 default:
4373 break;
4374 case RISCV::ADD:
4375 case RISCV::OR:
4376 case RISCV::XOR:
4377 // Normalize (so we hit the next if clause).
4378 // add/[x]or rd, zero, rs => add/[x]or rd, rs, zero
4379 if (MI.getOperand(1).getReg() == RISCV::X0)
4380 commuteInstruction(MI);
4381 // add/[x]or rd, rs, zero => addi rd, rs, 0
4382 if (MI.getOperand(2).getReg() == RISCV::X0) {
4383 MI.getOperand(2).ChangeToImmediate(0);
4384 MI.setDesc(get(RISCV::ADDI));
4385 return true;
4386 }
4387 // xor rd, rs, rs => addi rd, zero, 0
4388 if (MI.getOpcode() == RISCV::XOR &&
4389 MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) {
4390 MI.getOperand(1).setReg(RISCV::X0);
4391 MI.getOperand(2).ChangeToImmediate(0);
4392 MI.setDesc(get(RISCV::ADDI));
4393 return true;
4394 }
4395 break;
4396 case RISCV::ORI:
4397 case RISCV::XORI:
4398 // [x]ori rd, zero, N => addi rd, zero, N
4399 if (MI.getOperand(1).getReg() == RISCV::X0) {
4400 MI.setDesc(get(RISCV::ADDI));
4401 return true;
4402 }
4403 break;
4404 case RISCV::SUB:
4405 // sub rd, rs, zero => addi rd, rs, 0
4406 if (MI.getOperand(2).getReg() == RISCV::X0) {
4407 MI.getOperand(2).ChangeToImmediate(0);
4408 MI.setDesc(get(RISCV::ADDI));
4409 return true;
4410 }
4411 break;
4412 case RISCV::SUBW:
4413 // subw rd, rs, zero => addiw rd, rs, 0
4414 if (MI.getOperand(2).getReg() == RISCV::X0) {
4415 MI.getOperand(2).ChangeToImmediate(0);
4416 MI.setDesc(get(RISCV::ADDIW));
4417 return true;
4418 }
4419 break;
4420 case RISCV::ADDW:
4421 // Normalize (so we hit the next if clause).
4422 // addw rd, zero, rs => addw rd, rs, zero
4423 if (MI.getOperand(1).getReg() == RISCV::X0)
4424 commuteInstruction(MI);
4425 // addw rd, rs, zero => addiw rd, rs, 0
4426 if (MI.getOperand(2).getReg() == RISCV::X0) {
4427 MI.getOperand(2).ChangeToImmediate(0);
4428 MI.setDesc(get(RISCV::ADDIW));
4429 return true;
4430 }
4431 break;
4432 case RISCV::SH1ADD:
4433 case RISCV::SH1ADD_UW:
4434 case RISCV::SH2ADD:
4435 case RISCV::SH2ADD_UW:
4436 case RISCV::SH3ADD:
4437 case RISCV::SH3ADD_UW:
4438 // shNadd[.uw] rd, zero, rs => addi rd, rs, 0
4439 if (MI.getOperand(1).getReg() == RISCV::X0) {
4440 MI.removeOperand(1);
4441 MI.addOperand(MachineOperand::CreateImm(0));
4442 MI.setDesc(get(RISCV::ADDI));
4443 return true;
4444 }
4445 // shNadd[.uw] rd, rs, zero => slli[.uw] rd, rs, N
4446 if (MI.getOperand(2).getReg() == RISCV::X0) {
4447 MI.removeOperand(2);
4448 unsigned Opc = MI.getOpcode();
4449 if (Opc == RISCV::SH1ADD_UW || Opc == RISCV::SH2ADD_UW ||
4450 Opc == RISCV::SH3ADD_UW) {
4452 MI.setDesc(get(RISCV::SLLI_UW));
4453 return true;
4454 }
4456 MI.setDesc(get(RISCV::SLLI));
4457 return true;
4458 }
4459 break;
4460 case RISCV::AND:
4461 case RISCV::MUL:
4462 case RISCV::MULH:
4463 case RISCV::MULHSU:
4464 case RISCV::MULHU:
4465 case RISCV::MULW:
4466 // and rd, zero, rs => addi rd, zero, 0
4467 // mul* rd, zero, rs => addi rd, zero, 0
4468 // and rd, rs, zero => addi rd, zero, 0
4469 // mul* rd, rs, zero => addi rd, zero, 0
4470 if (MI.getOperand(1).getReg() == RISCV::X0 ||
4471 MI.getOperand(2).getReg() == RISCV::X0) {
4472 MI.getOperand(1).setReg(RISCV::X0);
4473 MI.getOperand(2).ChangeToImmediate(0);
4474 MI.setDesc(get(RISCV::ADDI));
4475 return true;
4476 }
4477 break;
4478 case RISCV::ANDI:
4479 // andi rd, zero, C => addi rd, zero, 0
4480 if (MI.getOperand(1).getReg() == RISCV::X0) {
4481 MI.getOperand(2).setImm(0);
4482 MI.setDesc(get(RISCV::ADDI));
4483 return true;
4484 }
4485 break;
4486 case RISCV::SLL:
4487 case RISCV::SRL:
4488 case RISCV::SRA:
4489 // shift rd, zero, rs => addi rd, zero, 0
4490 if (MI.getOperand(1).getReg() == RISCV::X0) {
4491 MI.getOperand(2).ChangeToImmediate(0);
4492 MI.setDesc(get(RISCV::ADDI));
4493 return true;
4494 }
4495 // shift rd, rs, zero => addi rd, rs, 0
4496 if (MI.getOperand(2).getReg() == RISCV::X0) {
4497 MI.getOperand(2).ChangeToImmediate(0);
4498 MI.setDesc(get(RISCV::ADDI));
4499 return true;
4500 }
4501 break;
4502 case RISCV::SLLW:
4503 case RISCV::SRLW:
4504 case RISCV::SRAW:
4505 // shiftw rd, zero, rs => addi rd, zero, 0
4506 if (MI.getOperand(1).getReg() == RISCV::X0) {
4507 MI.getOperand(2).ChangeToImmediate(0);
4508 MI.setDesc(get(RISCV::ADDI));
4509 return true;
4510 }
4511 break;
4512 case RISCV::SLLI:
4513 case RISCV::SRLI:
4514 case RISCV::SRAI:
4515 case RISCV::SLLIW:
4516 case RISCV::SRLIW:
4517 case RISCV::SRAIW:
4518 case RISCV::SLLI_UW:
4519 // shiftimm rd, zero, N => addi rd, zero, 0
4520 if (MI.getOperand(1).getReg() == RISCV::X0) {
4521 MI.getOperand(2).setImm(0);
4522 MI.setDesc(get(RISCV::ADDI));
4523 return true;
4524 }
4525 break;
4526 case RISCV::SLTU:
4527 case RISCV::ADD_UW:
4528 // sltu rd, zero, zero => addi rd, zero, 0
4529 // add.uw rd, zero, zero => addi rd, zero, 0
4530 if (MI.getOperand(1).getReg() == RISCV::X0 &&
4531 MI.getOperand(2).getReg() == RISCV::X0) {
4532 MI.getOperand(2).ChangeToImmediate(0);
4533 MI.setDesc(get(RISCV::ADDI));
4534 return true;
4535 }
4536 // add.uw rd, zero, rs => addi rd, rs, 0
4537 if (MI.getOpcode() == RISCV::ADD_UW &&
4538 MI.getOperand(1).getReg() == RISCV::X0) {
4539 MI.removeOperand(1);
4540 MI.addOperand(MachineOperand::CreateImm(0));
4541 MI.setDesc(get(RISCV::ADDI));
4542 }
4543 break;
4544 case RISCV::SLTIU:
4545 // sltiu rd, zero, NZC => addi rd, zero, 1
4546 // sltiu rd, zero, 0 => addi rd, zero, 0
4547 if (MI.getOperand(1).getReg() == RISCV::X0) {
4548 MI.getOperand(2).setImm(MI.getOperand(2).getImm() != 0);
4549 MI.setDesc(get(RISCV::ADDI));
4550 return true;
4551 }
4552 break;
4553 case RISCV::SEXT_H:
4554 case RISCV::SEXT_B:
4555 case RISCV::ZEXT_H_RV32:
4556 case RISCV::ZEXT_H_RV64:
4557 // sext.[hb] rd, zero => addi rd, zero, 0
4558 // zext.h rd, zero => addi rd, zero, 0
4559 if (MI.getOperand(1).getReg() == RISCV::X0) {
4560 MI.addOperand(MachineOperand::CreateImm(0));
4561 MI.setDesc(get(RISCV::ADDI));
4562 return true;
4563 }
4564 break;
4565 case RISCV::MIN:
4566 case RISCV::MINU:
4567 case RISCV::MAX:
4568 case RISCV::MAXU:
4569 // min|max rd, rs, rs => addi rd, rs, 0
4570 if (MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) {
4571 MI.getOperand(2).ChangeToImmediate(0);
4572 MI.setDesc(get(RISCV::ADDI));
4573 return true;
4574 }
4575 break;
4576 case RISCV::BEQ:
4577 case RISCV::BNE:
4578 // b{eq,ne} zero, rs, imm => b{eq,ne} rs, zero, imm
4579 if (MI.getOperand(0).getReg() == RISCV::X0) {
4580 MachineOperand MO0 = MI.getOperand(0);
4581 MI.removeOperand(0);
4582 MI.insert(MI.operands_begin() + 1, {MO0});
4583 }
4584 break;
4585 case RISCV::BLTU:
4586 // bltu zero, rs, imm => bne rs, zero, imm
4587 if (MI.getOperand(0).getReg() == RISCV::X0) {
4588 MachineOperand MO0 = MI.getOperand(0);
4589 MI.removeOperand(0);
4590 MI.insert(MI.operands_begin() + 1, {MO0});
4591 MI.setDesc(get(RISCV::BNE));
4592 }
4593 break;
4594 case RISCV::BGEU:
4595 // bgeu zero, rs, imm => beq rs, zero, imm
4596 if (MI.getOperand(0).getReg() == RISCV::X0) {
4597 MachineOperand MO0 = MI.getOperand(0);
4598 MI.removeOperand(0);
4599 MI.insert(MI.operands_begin() + 1, {MO0});
4600 MI.setDesc(get(RISCV::BEQ));
4601 }
4602 break;
4603 }
4604 return false;
4605}
4606
4607// clang-format off
4608#define CASE_WIDEOP_OPCODE_COMMON(OP, LMUL) \
4609 RISCV::PseudoV##OP##_##LMUL##_TIED
4610
4611#define CASE_WIDEOP_OPCODE_LMULS(OP) \
4612 CASE_WIDEOP_OPCODE_COMMON(OP, MF8): \
4613 case CASE_WIDEOP_OPCODE_COMMON(OP, MF4): \
4614 case CASE_WIDEOP_OPCODE_COMMON(OP, MF2): \
4615 case CASE_WIDEOP_OPCODE_COMMON(OP, M1): \
4616 case CASE_WIDEOP_OPCODE_COMMON(OP, M2): \
4617 case CASE_WIDEOP_OPCODE_COMMON(OP, M4)
4618
4619#define CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, LMUL) \
4620 case RISCV::PseudoV##OP##_##LMUL##_TIED: \
4621 NewOpc = RISCV::PseudoV##OP##_##LMUL; \
4622 break;
4623
4624#define CASE_WIDEOP_CHANGE_OPCODE_LMULS(OP) \
4625 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF8) \
4626 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF4) \
4627 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2) \
4628 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1) \
4629 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2) \
4630 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4)
4631
4632// FP Widening Ops may by SEW aware. Create SEW aware cases for these cases.
4633#define CASE_FP_WIDEOP_OPCODE_COMMON(OP, LMUL, SEW) \
4634 RISCV::PseudoV##OP##_##LMUL##_##SEW##_TIED
4635
4636#define CASE_FP_WIDEOP_OPCODE_LMULS(OP) \
4637 CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF4, E16): \
4638 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF2, E16): \
4639 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF2, E32): \
4640 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M1, E16): \
4641 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M1, E32): \
4642 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M2, E16): \
4643 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M2, E32): \
4644 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M4, E16): \
4645 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M4, E32) \
4646
4647#define CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, LMUL, SEW) \
4648 case RISCV::PseudoV##OP##_##LMUL##_##SEW##_TIED: \
4649 NewOpc = RISCV::PseudoV##OP##_##LMUL##_##SEW; \
4650 break;
4651
4652#define CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS(OP) \
4653 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF4, E16) \
4654 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2, E16) \
4655 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2, E32) \
4656 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1, E16) \
4657 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1, E32) \
4658 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2, E16) \
4659 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2, E32) \
4660 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4, E16) \
4661 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4, E32) \
4662
4663#define CASE_FP_WIDEOP_OPCODE_LMULS_ALT(OP) \
4664 CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF4, E16): \
4665 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF2, E16): \
4666 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M1, E16): \
4667 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M2, E16): \
4668 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M4, E16)
4669
4670#define CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS_ALT(OP) \
4671 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF4, E16) \
4672 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2, E16) \
4673 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1, E16) \
4674 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2, E16) \
4675 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4, E16)
4676// clang-format on
4677
4679 LiveVariables *LV,
4680 LiveIntervals *LIS) const {
4682 switch (MI.getOpcode()) {
4683 default:
4684 return nullptr;
4685 case CASE_FP_WIDEOP_OPCODE_LMULS_ALT(FWADD_ALT_WV):
4686 case CASE_FP_WIDEOP_OPCODE_LMULS_ALT(FWSUB_ALT_WV):
4687 case CASE_FP_WIDEOP_OPCODE_LMULS(FWADD_WV):
4688 case CASE_FP_WIDEOP_OPCODE_LMULS(FWSUB_WV): {
4689 assert(RISCVII::hasVecPolicyOp(MI.getDesc().TSFlags) &&
4690 MI.getNumExplicitOperands() == 7 &&
4691 "Expect 7 explicit operands rd, rs2, rs1, rm, vl, sew, policy");
4692 // If the tail policy is undisturbed we can't convert.
4693 if ((MI.getOperand(RISCVII::getVecPolicyOpNum(MI.getDesc())).getImm() &
4694 1) == 0)
4695 return nullptr;
4696 // clang-format off
4697 unsigned NewOpc;
4698 switch (MI.getOpcode()) {
4699 default:
4700 llvm_unreachable("Unexpected opcode");
4705 }
4706 // clang-format on
4707
4708 MachineBasicBlock &MBB = *MI.getParent();
4709 MIB = BuildMI(MBB, MI, MI.getDebugLoc(), get(NewOpc))
4710 .add(MI.getOperand(0))
4711 .addReg(MI.getOperand(0).getReg(), RegState::Undef)
4712 .add(MI.getOperand(1))
4713 .add(MI.getOperand(2))
4714 .add(MI.getOperand(3))
4715 .add(MI.getOperand(4))
4716 .add(MI.getOperand(5))
4717 .add(MI.getOperand(6));
4718 break;
4719 }
4720 case CASE_WIDEOP_OPCODE_LMULS(WADD_WV):
4721 case CASE_WIDEOP_OPCODE_LMULS(WADDU_WV):
4722 case CASE_WIDEOP_OPCODE_LMULS(WSUB_WV):
4723 case CASE_WIDEOP_OPCODE_LMULS(WSUBU_WV): {
4724 // If the tail policy is undisturbed we can't convert.
4725 assert(RISCVII::hasVecPolicyOp(MI.getDesc().TSFlags) &&
4726 MI.getNumExplicitOperands() == 6);
4727 if ((MI.getOperand(RISCVII::getVecPolicyOpNum(MI.getDesc())).getImm() &
4728 1) == 0)
4729 return nullptr;
4730
4731 // clang-format off
4732 unsigned NewOpc;
4733 switch (MI.getOpcode()) {
4734 default:
4735 llvm_unreachable("Unexpected opcode");
4740 }
4741 // clang-format on
4742
4743 MachineBasicBlock &MBB = *MI.getParent();
4744 MIB = BuildMI(MBB, MI, MI.getDebugLoc(), get(NewOpc))
4745 .add(MI.getOperand(0))
4746 .addReg(MI.getOperand(0).getReg(), RegState::Undef)
4747 .add(MI.getOperand(1))
4748 .add(MI.getOperand(2))
4749 .add(MI.getOperand(3))
4750 .add(MI.getOperand(4))
4751 .add(MI.getOperand(5));
4752 break;
4753 }
4754 }
4755 MIB.copyImplicitOps(MI);
4756
4757 if (LV) {
4758 unsigned NumOps = MI.getNumOperands();
4759 for (unsigned I = 1; I < NumOps; ++I) {
4760 MachineOperand &Op = MI.getOperand(I);
4761 if (Op.isReg() && Op.isKill())
4762 LV->replaceKillInstruction(Op.getReg(), MI, *MIB);
4763 }
4764 }
4765
4766 if (LIS) {
4767 SlotIndex Idx = LIS->ReplaceMachineInstrInMaps(MI, *MIB);
4768
4769 if (MI.getOperand(0).isEarlyClobber()) {
4770 // Use operand 1 was tied to early-clobber def operand 0, so its live
4771 // interval could have ended at an early-clobber slot. Now they are not
4772 // tied we need to update it to the normal register slot.
4773 LiveInterval &LI = LIS->getInterval(MI.getOperand(1).getReg());
4775 if (S->end == Idx.getRegSlot(true))
4776 S->end = Idx.getRegSlot();
4777 }
4778 }
4779
4780 return MIB;
4781}
4782
4783#undef CASE_WIDEOP_OPCODE_COMMON
4784#undef CASE_WIDEOP_OPCODE_LMULS
4785#undef CASE_WIDEOP_CHANGE_OPCODE_COMMON
4786#undef CASE_WIDEOP_CHANGE_OPCODE_LMULS
4787#undef CASE_FP_WIDEOP_OPCODE_COMMON
4788#undef CASE_FP_WIDEOP_OPCODE_LMULS
4789#undef CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON
4790#undef CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS
4791
4794 Register DestReg, uint32_t Amount,
4795 MachineInstr::MIFlag Flag) const {
4797 if (llvm::has_single_bit<uint32_t>(Amount)) {
4798 uint32_t ShiftAmount = Log2_32(Amount);
4799 if (ShiftAmount == 0)
4800 return;
4801 BuildMI(MBB, II, DL, get(RISCV::SLLI), DestReg)
4802 .addReg(DestReg, RegState::Kill)
4803 .addImm(ShiftAmount)
4804 .setMIFlag(Flag);
4805 } else if (int ShXAmount, ShiftAmount;
4806 STI.hasShlAdd(3) &&
4807 (ShXAmount = isShifted359(Amount, ShiftAmount)) != 0) {
4808 // We can use Zba SHXADD+SLLI instructions for multiply in some cases.
4809 unsigned Opc;
4810 switch (ShXAmount) {
4811 case 1:
4812 Opc = RISCV::SH1ADD;
4813 break;
4814 case 2:
4815 Opc = RISCV::SH2ADD;
4816 break;
4817 case 3:
4818 Opc = RISCV::SH3ADD;
4819 break;
4820 default:
4821 llvm_unreachable("unexpected result of isShifted359");
4822 }
4823 if (ShiftAmount)
4824 BuildMI(MBB, II, DL, get(RISCV::SLLI), DestReg)
4825 .addReg(DestReg, RegState::Kill)
4826 .addImm(ShiftAmount)
4827 .setMIFlag(Flag);
4828 BuildMI(MBB, II, DL, get(Opc), DestReg)
4829 .addReg(DestReg, RegState::Kill)
4830 .addReg(DestReg)
4831 .setMIFlag(Flag);
4832 } else if (llvm::has_single_bit<uint32_t>(Amount - 1)) {
4833 Register ScaledRegister = MRI.createVirtualRegister(&RISCV::GPRRegClass);
4834 uint32_t ShiftAmount = Log2_32(Amount - 1);
4835 BuildMI(MBB, II, DL, get(RISCV::SLLI), ScaledRegister)
4836 .addReg(DestReg)
4837 .addImm(ShiftAmount)
4838 .setMIFlag(Flag);
4839 BuildMI(MBB, II, DL, get(RISCV::ADD), DestReg)
4840 .addReg(ScaledRegister, RegState::Kill)
4841 .addReg(DestReg, RegState::Kill)
4842 .setMIFlag(Flag);
4843 } else if (llvm::has_single_bit<uint32_t>(Amount + 1)) {
4844 Register ScaledRegister = MRI.createVirtualRegister(&RISCV::GPRRegClass);
4845 uint32_t ShiftAmount = Log2_32(Amount + 1);
4846 BuildMI(MBB, II, DL, get(RISCV::SLLI), ScaledRegister)
4847 .addReg(DestReg)
4848 .addImm(ShiftAmount)
4849 .setMIFlag(Flag);
4850 BuildMI(MBB, II, DL, get(RISCV::SUB), DestReg)
4851 .addReg(ScaledRegister, RegState::Kill)
4852 .addReg(DestReg, RegState::Kill)
4853 .setMIFlag(Flag);
4854 } else if (STI.hasStdExtZmmul()) {
4855 Register N = MRI.createVirtualRegister(&RISCV::GPRRegClass);
4856 movImm(MBB, II, DL, N, Amount, Flag);
4857 BuildMI(MBB, II, DL, get(RISCV::MUL), DestReg)
4858 .addReg(DestReg, RegState::Kill)
4860 .setMIFlag(Flag);
4861 } else {
4862 Register Acc;
4863 uint32_t PrevShiftAmount = 0;
4864 for (uint32_t ShiftAmount = 0; Amount >> ShiftAmount; ShiftAmount++) {
4865 if (Amount & (1U << ShiftAmount)) {
4866 if (ShiftAmount)
4867 BuildMI(MBB, II, DL, get(RISCV::SLLI), DestReg)
4868 .addReg(DestReg, RegState::Kill)
4869 .addImm(ShiftAmount - PrevShiftAmount)
4870 .setMIFlag(Flag);
4871 if (Amount >> (ShiftAmount + 1)) {
4872 // If we don't have an accmulator yet, create it and copy DestReg.
4873 if (!Acc) {
4874 Acc = MRI.createVirtualRegister(&RISCV::GPRRegClass);
4875 BuildMI(MBB, II, DL, get(TargetOpcode::COPY), Acc)
4876 .addReg(DestReg)
4877 .setMIFlag(Flag);
4878 } else {
4879 BuildMI(MBB, II, DL, get(RISCV::ADD), Acc)
4880 .addReg(Acc, RegState::Kill)
4881 .addReg(DestReg)
4882 .setMIFlag(Flag);
4883 }
4884 }
4885 PrevShiftAmount = ShiftAmount;
4886 }
4887 }
4888 assert(Acc && "Expected valid accumulator");
4889 BuildMI(MBB, II, DL, get(RISCV::ADD), DestReg)
4890 .addReg(DestReg, RegState::Kill)
4891 .addReg(Acc, RegState::Kill)
4892 .setMIFlag(Flag);
4893 }
4894}
4895
4898 static const std::pair<MachineMemOperand::Flags, const char *> TargetFlags[] =
4899 {{MONontemporalBit0, "riscv-nontemporal-domain-bit-0"},
4900 {MONontemporalBit1, "riscv-nontemporal-domain-bit-1"}};
4901 return ArrayRef(TargetFlags);
4902}
4903
4905 return OptLevel >= CodeGenOptLevel::Aggressive
4906 ? STI.getTailDupAggressiveThreshold()
4907 : 2;
4908}
4909
4911 // RVV lacks any support for immediate addressing for stack addresses, so be
4912 // conservative.
4913 unsigned Opcode = MI.getOpcode();
4914 if (!RISCVVPseudosTable::getPseudoInfo(Opcode) &&
4916 return false;
4917 return true;
4918}
4919
4920std::optional<std::pair<unsigned, unsigned>>
4922 switch (Opcode) {
4923 default:
4924 return std::nullopt;
4925 case RISCV::PseudoVSPILL2_M1:
4926 case RISCV::PseudoVRELOAD2_M1:
4927 return std::make_pair(2u, 1u);
4928 case RISCV::PseudoVSPILL2_M2:
4929 case RISCV::PseudoVRELOAD2_M2:
4930 return std::make_pair(2u, 2u);
4931 case RISCV::PseudoVSPILL2_M4:
4932 case RISCV::PseudoVRELOAD2_M4:
4933 return std::make_pair(2u, 4u);
4934 case RISCV::PseudoVSPILL3_M1:
4935 case RISCV::PseudoVRELOAD3_M1:
4936 return std::make_pair(3u, 1u);
4937 case RISCV::PseudoVSPILL3_M2:
4938 case RISCV::PseudoVRELOAD3_M2:
4939 return std::make_pair(3u, 2u);
4940 case RISCV::PseudoVSPILL4_M1:
4941 case RISCV::PseudoVRELOAD4_M1:
4942 return std::make_pair(4u, 1u);
4943 case RISCV::PseudoVSPILL4_M2:
4944 case RISCV::PseudoVRELOAD4_M2:
4945 return std::make_pair(4u, 2u);
4946 case RISCV::PseudoVSPILL5_M1:
4947 case RISCV::PseudoVRELOAD5_M1:
4948 return std::make_pair(5u, 1u);
4949 case RISCV::PseudoVSPILL6_M1:
4950 case RISCV::PseudoVRELOAD6_M1:
4951 return std::make_pair(6u, 1u);
4952 case RISCV::PseudoVSPILL7_M1:
4953 case RISCV::PseudoVRELOAD7_M1:
4954 return std::make_pair(7u, 1u);
4955 case RISCV::PseudoVSPILL8_M1:
4956 case RISCV::PseudoVRELOAD8_M1:
4957 return std::make_pair(8u, 1u);
4958 }
4959}
4960
4961bool RISCV::hasEqualFRM(const MachineInstr &MI1, const MachineInstr &MI2) {
4962 int16_t MI1FrmOpIdx =
4963 RISCV::getNamedOperandIdx(MI1.getOpcode(), RISCV::OpName::frm);
4964 int16_t MI2FrmOpIdx =
4965 RISCV::getNamedOperandIdx(MI2.getOpcode(), RISCV::OpName::frm);
4966 if (MI1FrmOpIdx < 0 || MI2FrmOpIdx < 0)
4967 return false;
4968 MachineOperand FrmOp1 = MI1.getOperand(MI1FrmOpIdx);
4969 MachineOperand FrmOp2 = MI2.getOperand(MI2FrmOpIdx);
4970 return FrmOp1.getImm() == FrmOp2.getImm();
4971}
4972
4973std::optional<unsigned>
4974RISCV::getVectorLowDemandedScalarBits(unsigned Opcode, unsigned Log2SEW) {
4975 switch (Opcode) {
4976 default:
4977 return std::nullopt;
4978
4979 // 11.6. Vector Single-Width Shift Instructions
4980 case RISCV::VSLL_VX:
4981 case RISCV::VSRL_VX:
4982 case RISCV::VSRA_VX:
4983 // 12.4. Vector Single-Width Scaling Shift Instructions
4984 case RISCV::VSSRL_VX:
4985 case RISCV::VSSRA_VX:
4986 // Zvbb
4987 case RISCV::VROL_VX:
4988 case RISCV::VROR_VX:
4989 // Only the low lg2(SEW) bits of the shift-amount value are used.
4990 return Log2SEW;
4991
4992 // 11.7 Vector Narrowing Integer Right Shift Instructions
4993 case RISCV::VNSRL_WX:
4994 case RISCV::VNSRA_WX:
4995 // 12.5. Vector Narrowing Fixed-Point Clip Instructions
4996 case RISCV::VNCLIPU_WX:
4997 case RISCV::VNCLIP_WX:
4998 // Zvbb
4999 case RISCV::VWSLL_VX:
5000 // Only the low lg2(2*SEW) bits of the shift-amount value are used.
5001 return Log2SEW + 1;
5002
5003 // 11.1. Vector Single-Width Integer Add and Subtract
5004 case RISCV::VADD_VX:
5005 case RISCV::VSUB_VX:
5006 case RISCV::VRSUB_VX:
5007 // 11.2. Vector Widening Integer Add/Subtract
5008 case RISCV::VWADDU_VX:
5009 case RISCV::VWSUBU_VX:
5010 case RISCV::VWADD_VX:
5011 case RISCV::VWSUB_VX:
5012 case RISCV::VWADDU_WX:
5013 case RISCV::VWSUBU_WX:
5014 case RISCV::VWADD_WX:
5015 case RISCV::VWSUB_WX:
5016 // 11.4. Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions
5017 case RISCV::VADC_VXM:
5018 case RISCV::VADC_VIM:
5019 case RISCV::VMADC_VXM:
5020 case RISCV::VMADC_VIM:
5021 case RISCV::VMADC_VX:
5022 case RISCV::VSBC_VXM:
5023 case RISCV::VMSBC_VXM:
5024 case RISCV::VMSBC_VX:
5025 // 11.5 Vector Bitwise Logical Instructions
5026 case RISCV::VAND_VX:
5027 case RISCV::VOR_VX:
5028 case RISCV::VXOR_VX:
5029 // 11.8. Vector Integer Compare Instructions
5030 case RISCV::VMSEQ_VX:
5031 case RISCV::VMSNE_VX:
5032 case RISCV::VMSLTU_VX:
5033 case RISCV::VMSLT_VX:
5034 case RISCV::VMSLEU_VX:
5035 case RISCV::VMSLE_VX:
5036 case RISCV::VMSGTU_VX:
5037 case RISCV::VMSGT_VX:
5038 // 11.9. Vector Integer Min/Max Instructions
5039 case RISCV::VMINU_VX:
5040 case RISCV::VMIN_VX:
5041 case RISCV::VMAXU_VX:
5042 case RISCV::VMAX_VX:
5043 // 11.10. Vector Single-Width Integer Multiply Instructions
5044 case RISCV::VMUL_VX:
5045 case RISCV::VMULH_VX:
5046 case RISCV::VMULHU_VX:
5047 case RISCV::VMULHSU_VX:
5048 // 11.11. Vector Integer Divide Instructions
5049 case RISCV::VDIVU_VX:
5050 case RISCV::VDIV_VX:
5051 case RISCV::VREMU_VX:
5052 case RISCV::VREM_VX:
5053 // 11.12. Vector Widening Integer Multiply Instructions
5054 case RISCV::VWMUL_VX:
5055 case RISCV::VWMULU_VX:
5056 case RISCV::VWMULSU_VX:
5057 // 11.13. Vector Single-Width Integer Multiply-Add Instructions
5058 case RISCV::VMACC_VX:
5059 case RISCV::VNMSAC_VX:
5060 case RISCV::VMADD_VX:
5061 case RISCV::VNMSUB_VX:
5062 // 11.14. Vector Widening Integer Multiply-Add Instructions
5063 case RISCV::VWMACCU_VX:
5064 case RISCV::VWMACC_VX:
5065 case RISCV::VWMACCSU_VX:
5066 case RISCV::VWMACCUS_VX:
5067 // 11.15. Vector Integer Merge Instructions
5068 case RISCV::VMERGE_VXM:
5069 // 11.16. Vector Integer Move Instructions
5070 case RISCV::VMV_V_X:
5071 // 12.1. Vector Single-Width Saturating Add and Subtract
5072 case RISCV::VSADDU_VX:
5073 case RISCV::VSADD_VX:
5074 case RISCV::VSSUBU_VX:
5075 case RISCV::VSSUB_VX:
5076 // 12.2. Vector Single-Width Averaging Add and Subtract
5077 case RISCV::VAADDU_VX:
5078 case RISCV::VAADD_VX:
5079 case RISCV::VASUBU_VX:
5080 case RISCV::VASUB_VX:
5081 // 12.3. Vector Single-Width Fractional Multiply with Rounding and Saturation
5082 case RISCV::VSMUL_VX:
5083 // 16.1. Integer Scalar Move Instructions
5084 case RISCV::VMV_S_X:
5085 // Zvbb
5086 case RISCV::VANDN_VX:
5087 return 1U << Log2SEW;
5088 }
5089}
5090
5091unsigned RISCV::getRVVMCOpcode(unsigned RVVPseudoOpcode) {
5093 RISCVVPseudosTable::getPseudoInfo(RVVPseudoOpcode);
5094 if (!RVV)
5095 return 0;
5096 return RVV->BaseInstr;
5097}
5098
5099unsigned RISCV::getDestLog2EEW(const MCInstrDesc &Desc, unsigned Log2SEW) {
5100 unsigned DestEEW =
5102 // EEW = 1
5103 if (DestEEW == 0)
5104 return 0;
5105 // EEW = SEW * n
5106 unsigned Scaled = Log2SEW + (DestEEW - 1);
5107 assert(Scaled >= 3 && Scaled <= 6);
5108 return Scaled;
5109}
5110
5111static std::optional<int64_t> getEffectiveImm(const MachineOperand &MO) {
5112 assert(MO.isImm() || MO.getReg().isVirtual());
5113 if (MO.isImm())
5114 return MO.getImm();
5115 const MachineInstr *Def =
5116 MO.getParent()->getMF()->getRegInfo().getVRegDef(MO.getReg());
5117 int64_t Imm;
5118 if (isLoadImm(Def, Imm))
5119 return Imm;
5120 return std::nullopt;
5121}
5122
5123/// Given two VL operands, do we know that LHS <= RHS? Must be used in SSA form.
5125 assert((LHS.isImm() || LHS.getParent()->getMF()->getRegInfo().isSSA()) &&
5126 (RHS.isImm() || RHS.getParent()->getMF()->getRegInfo().isSSA()));
5127 if (LHS.isReg() && RHS.isReg() && LHS.getReg().isVirtual() &&
5128 LHS.getReg() == RHS.getReg())
5129 return true;
5130 if (RHS.isImm() && RHS.getImm() == RISCV::VLMaxSentinel)
5131 return true;
5132 if (LHS.isImm() && LHS.getImm() == 0)
5133 return true;
5134 if (LHS.isImm() && LHS.getImm() == RISCV::VLMaxSentinel)
5135 return false;
5136 std::optional<int64_t> LHSImm = getEffectiveImm(LHS),
5137 RHSImm = getEffectiveImm(RHS);
5138 if (!LHSImm || !RHSImm)
5139 return false;
5140 return LHSImm <= RHSImm;
5141}
5142
5143namespace {
5144class RISCVPipelinerLoopInfo : public TargetInstrInfo::PipelinerLoopInfo {
5145 const MachineInstr *LHS;
5146 const MachineInstr *RHS;
5148
5149public:
5150 RISCVPipelinerLoopInfo(const MachineInstr *LHS, const MachineInstr *RHS,
5152 : LHS(LHS), RHS(RHS), Cond(Cond.begin(), Cond.end()) {}
5153
5154 bool shouldIgnoreForPipelining(const MachineInstr *MI) const override {
5155 // Make the instructions for loop control be placed in stage 0.
5156 // The predecessors of LHS/RHS are considered by the caller.
5157 if (LHS && MI == LHS)
5158 return true;
5159 if (RHS && MI == RHS)
5160 return true;
5161 return false;
5162 }
5163
5164 std::optional<bool> createTripCountGreaterCondition(
5165 int TC, MachineBasicBlock &MBB,
5166 SmallVectorImpl<MachineOperand> &CondParam) override {
5167 // A branch instruction will be inserted as "if (Cond) goto epilogue".
5168 // Cond is normalized for such use.
5169 // The predecessors of the branch are assumed to have already been inserted.
5170 CondParam = Cond;
5171 return {};
5172 }
5173
5174 void setPreheader(MachineBasicBlock *NewPreheader) override {}
5175
5176 void adjustTripCount(int TripCountAdjust) override {}
5177};
5178} // namespace
5179
5180std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
5182 MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
5184 if (analyzeBranch(*LoopBB, TBB, FBB, Cond, /*AllowModify=*/false))
5185 return nullptr;
5186
5187 // Infinite loops are not supported
5188 if (TBB == LoopBB && FBB == LoopBB)
5189 return nullptr;
5190
5191 // Must be conditional branch
5192 if (FBB == nullptr)
5193 return nullptr;
5194
5195 assert((TBB == LoopBB || FBB == LoopBB) &&
5196 "The Loop must be a single-basic-block loop");
5197
5198 // Normalization for createTripCountGreaterCondition()
5199 if (TBB == LoopBB)
5201
5202 const MachineRegisterInfo &MRI = LoopBB->getParent()->getRegInfo();
5203 auto FindRegDef = [&MRI](MachineOperand &Op) -> const MachineInstr * {
5204 if (!Op.isReg())
5205 return nullptr;
5206 Register Reg = Op.getReg();
5207 if (!Reg.isVirtual())
5208 return nullptr;
5209 return MRI.getVRegDef(Reg);
5210 };
5211
5212 const MachineInstr *LHS = FindRegDef(Cond[1]);
5213 const MachineInstr *RHS = FindRegDef(Cond[2]);
5214 if (LHS && LHS->isPHI())
5215 return nullptr;
5216 if (RHS && RHS->isPHI())
5217 return nullptr;
5218
5219 return std::make_unique<RISCVPipelinerLoopInfo>(LHS, RHS, Cond);
5220}
5221
5222// FIXME: We should remove this if we have a default generic scheduling model.
5224 unsigned RVVMCOpcode = RISCV::getRVVMCOpcode(Opc);
5225 Opc = RVVMCOpcode ? RVVMCOpcode : Opc;
5226 switch (Opc) {
5227 default:
5228 return false;
5229 // Integer div/rem.
5230 case RISCV::DIV:
5231 case RISCV::DIVW:
5232 case RISCV::DIVU:
5233 case RISCV::DIVUW:
5234 case RISCV::REM:
5235 case RISCV::REMW:
5236 case RISCV::REMU:
5237 case RISCV::REMUW:
5238 // Floating-point div/sqrt.
5239 case RISCV::FDIV_H:
5240 case RISCV::FDIV_S:
5241 case RISCV::FDIV_D:
5242 case RISCV::FDIV_H_INX:
5243 case RISCV::FDIV_S_INX:
5244 case RISCV::FDIV_D_INX:
5245 case RISCV::FDIV_D_IN32X:
5246 case RISCV::FSQRT_H:
5247 case RISCV::FSQRT_S:
5248 case RISCV::FSQRT_D:
5249 case RISCV::FSQRT_H_INX:
5250 case RISCV::FSQRT_S_INX:
5251 case RISCV::FSQRT_D_INX:
5252 case RISCV::FSQRT_D_IN32X:
5253 // Vector integer div/rem
5254 case RISCV::VDIV_VV:
5255 case RISCV::VDIV_VX:
5256 case RISCV::VDIVU_VV:
5257 case RISCV::VDIVU_VX:
5258 case RISCV::VREM_VV:
5259 case RISCV::VREM_VX:
5260 case RISCV::VREMU_VV:
5261 case RISCV::VREMU_VX:
5262 // Vector floating-point div/sqrt.
5263 case RISCV::VFDIV_VV:
5264 case RISCV::VFDIV_VF:
5265 case RISCV::VFRDIV_VF:
5266 case RISCV::VFSQRT_V:
5267 case RISCV::VFRSQRT7_V:
5268 return true;
5269 }
5270}
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.
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:2503
bool isValidAtomicOrdering(Int I)
static const MachineMemOperand::Flags MONontemporalBit0
unsigned getDeadRegState(bool B)
constexpr 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
Op::Description Desc
constexpr bool has_single_bit(T Value) noexcept
Definition bit.h:147
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
constexpr 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:1748
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:2141
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.