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