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