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