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