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