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