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