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