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